SSH from master to agents nodes

Purpose

The purpose of this post is to learn how to easily connect a master node to different agent nodes using SSH. To provision all the machines involved in this example we are going to use shell scripts but we could do the same using a provisioning tool like Ansible. These are some possible scenarios:

  • We have a Jenkins master node and we need various agent nodes to perform specific tasks.
  • We have a cluster of machines that need to be connected.
  • We need to implement a secure master/slave database replication for MySQL or PostgreSQL.
  • We own different servers and we simply want access them from our local machine in a passwordless authentication way.

Before you begin

A Linux/Mac OS machine is required to follow this tutorial.

Step 1 - Create a SSH key pair (public/private)

Run ssh-keygen setting a passphrase and a destination (by default ~/.ssh/id_rsa ~/.ssh/id_rsa.pub). I strongly recommend to add a strong passhprase, to do it you can use pwgen or apg commands for example.

If you don’t have ssh-keygen binary you can easily install it by typing:

# Debian/Ubuntu
apt-get update -y && apt-get install openssh-client -y

# Alpine Linux
apk add --update openssh-client

# Fedora/CentOS
yum update && yum install openssh-clients -y

Double check ssh-keygen created a private and public key files.

Keep these keys in a safe place using LastPass for example and avoid to upload at least the private key in a remote git repository (..but if you have to do it, use encryption, ansible-vault can help you).

Step 2 - Create an OS user on every agent node

You should create an OS user on every agent node with:

  • Home folder
  • Sudo (passwordless)
  • Public key in ~/.ssh/authorized_keys file.

2.1 Creating a user with home folder

The following command creates a new user my_new_user with a home directory /home/my_new_user:

useradd -m my_new_user
passwd my_new_user

2.2 Adding sudo (passwordless) to my_new_user

Make sure sudo is installed otherwise run:

apt-get update && apt-get install sudo -y

Add my_new_user to the sudoer group (you must be a privileged user):

echo "my_new_user ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers

Check my_new_user can use sudo without typing its password:

su my_new_user
sudo apt-get install tree -y

2.3 Adding public key to my_new_user home folder

Run the following commands to setup the key:

$ mkdir -p  ~/.ssh
$ chmod 700 ~/.ssh
$ vim ~/.ssh/authorized_keys
# Add the public key  ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys

Step 3 - SSH from master node to agent nodes

Once all nodes have a user and a public key you can place the private in your host/master node and SSH to them:

ssh -i /private_key_path/id_rsa my_new_user@[MY_AGENT_NODE_IP]

This post can be used to create a secure communication between Jenkins master and Jenkins agents. Note that in this case agent nodes need Java as well (apt-get install openjdk-8-jdk-headless).