Salesforce, Python, SQL, & other ways to put your data where you need it

Need event music? 🎸

Live and recorded jazz, pop, and meditative music for your virtual conference / Zoom wedding / yoga class / private party with quality sound and a smooth technical experience

Configuring public-private key pairs so 2 Linux machines can talk

16 Sep 2020 🔖 linux tutorials integration
💬 EN

Table of Contents

Recently, I needed a sysadmin colleague to set up an ETL tool to make Linux Server #1 (on which the ETL tool runs) send a file to, and execute commands on, Linux Server #2. I had the privilege of watching and taking notes.

THANK YOU to my colleagues for this tutorial!

Log in

From your own desktop computer, log into the command-line interface of both servers with your personal username on the servers, using software that can present you a command line over a secure connection protocol like SSH.

Elevate your privileges

On each server’s command line, type the following to elevate your privileges to those of an appropriate user on the server.

In my sysadmin’s case, she needed to log into server #1 as the user used by the ETL tool and into server #2 as the user typically considered responsible for running the command she was going to execute on that machine.

sudo -iu appropriate_username

Open each server user’s .ssh directory

Most likely, you’re already in the “home” directory for the elevated-privileges user you just became.

You could check with the pwd (“present working directory”) command.

Anyway, it should have a hidden folder whose name begins with a period inside of it called .ssh.

To change directories into the home directory, you can do:

cd $HOME

Or you can do:

cd ~

If you’d like to verify that there’s a .ssh directory, do:

ls -la | grep ".ssh"

If you see a directory get listed out – it’s there!

Now that you’re already in the “home” directory, you can type:

cd .ssh

If your command-line interface had been exploring some other folder on the operating system, you coudl have typed:

cd ~/.ssh

Validate server 1 keys

In server #1’s ~/.ssh folder, run:

ls -l

On server #1 (the server things will be coming from), you’re looking for the existence of two files that represent, respectively, the private key and the public key of a “pair.”

For example, one might be called called id_rsa and the other called

If those were their names, run the following commands to look at their contents:

cat id_rsa

The one that is the private key will be a lot longer and will typically say the words “PRIVATE KEY” in all caps towards the beginning and end of the file.

Presuming that id_rsa looks like a private key, you might want to verify that is actually the correct “public key” corresponding to it, and that someone hasn’t left clutter on the server.

You can do that by executing the following command:

ssh-keygen -y -f ~/.ssh/id_rsa

If its output, which likely starts with the phrase “ssh-,” matches the output of cat, then indeed contains the right “public key” content for the “private key” in id_rsa.

Note that there might be an extra appropriate_username@server_name tacked onto the end of the content of that doesn’t appear in the fresh ssh-keygen computation. It looks like you can include it or exclude it – your choice.

If the contents of seem wrong, and if you’re new enough to system administration to be reading this blog post, go consult with a senior system administrator before changing anything.

Validate server 2 authorized keys

In server #2’s ~/.ssh folder, run:

ls -l | grep "authorized_keys"

On server #2 (the server you need server #1 to talk to), you’re looking for the existence of a file called authorized_keys.

If you don’t see it, you’ll need to create it and set its read/write permissions appropriately.

(Note: if you’re new enough to system administration to be reading this blog post, go consult with a senior system administrator before changing anything.)

If you do see authorized_keys, you’ll have to make sure that the contents of server #1’s public key (e.g. ` are in it:

cat authorized_keys

Read through it and verify whether it includes the contents of your “public key” file (including any “appropriate_server_1_username@server_1_name” suffix) from server #1.

If the public key isn’t included, or if the authorized_keys file doesn’t exist at all, run this command, substituting the contents of your “public key” file from server #1 for PUBLIC_KEY_HERE.

echo "PUBLIC_KEY_HERE" >> authorized_keys

Be really careful not to accidentally copy and paste the private key from server #1 into this file.

Now read through authorized_keys again and make sure the file has a new line including the appropriate server-#1 public key at the end of it:

cat authorized_keys

File permissions

Finally, if authorized_keys didn’t previously exist, you’ll need to set the new permissions appropriately.

Linux will refuse to use a ~/.ssh/authorized_keys file for inter-server communications that is editable by anyone but the server user that “owns” it.

You’ll want authorized_keys to display permissions something like “-rw-------” at the far-left side of an ls -l command’s output.

Run this:

chmod 600 authorized_keys

Now verify the permissions are correct:

ls -l | grep "authorized_keys"

Run a hello world

In server #1’s command line, run:

ssh appropriate_server_2_username@server_2_name echo hello
  • If you see the word “hello” on the next line, followed by a return to your server #1 command line prompt, everything went well. Server #1 can now initiate connections to server #2.
  • If you see a prompt appropriate_server_2_username@server_2_name's password:, something went wrong with getting the two servers to use keys for authentication. Talk to a senior sysadmin for help.

Note that when it comes to actually running your code, you might have to play some games with command line program options. For example, I needed to run my program like this to make it recognize my_command_name just like it would if I were logged into server 2’s actual command line:

$ ssh -t appropriate_server_2_username@server_2_name 'ksh -lc "my_command_name thing_that_comes_after_command_name"'
--- ---