Blue background with illuminated circular lock with the Linux penguin and the word "Linux."

How to create and use Public/Private/KeyPairs with SSH

0

Image: Creative Commons: CC-by-SA

Introduction

SSH is an important mechanism for secure connections between Linux hosts. SSH is a software-based virtual private network (VPN) tool that can create a secure connection whenever needed. It can be used to securely login to any remote host so long as you have proper credentials, and it can be used to enhance tools such as tar and other backup programs like rsync so that remote hosts can be easily backed up to a local system. The scp (secure copy) program uses the SSH encrypted tunnel to copy files between a local host and a remote one.

SSH on Linux is implements using OpenSSH.1

The name Secure Shell is misleading. SSH is not a shell, it is only a set of connection protocols that enables secure, encrypted links between two computers. An SSH login to a remote host uses the default shell of the user on the remote host. In most cases this would be Bash, but some users prefer other shells and have designated them as their default shell. Whichever shell the use as their default will be the shell used for the SSH connection.

In this article we’ll explore SSH in more depth and use it to communicate between to separate VM hosts. We will also generate and use Public/Private Key Pairs for authentication that is more secure than using passwords.

SSH provides three important properties.

  1. It provides reliable authentication for the identities of the hosts as well as the users. It ensures that the hosts and users are who they claim to be.
  2. It encrypts the communication between the hosts, including the transmission of any login ID and password or Public/Private Key Pairs (PPKP).
  3. It ensures the integrity of the transmissions and can detect and notify the user if data is missing, added, or changed.

Using SSH for inter-host communications is an excellent security precaution and can prevent data that is transmitted over any part of a public network from being viewed, read, or altered. As with all security tools, SSH is not the complete solution and other security precautions must also be taken. But SSH ensures secure communications can be easily accomplished.

Preparation

You’ll need a physical host that has enough disk space, RAM, and CPUs to support two fairly small VMs in a virtual network. I use VirtualBox for my virtualization software. It is open source except for the Oracle VM VirtualBox Extension Pack. But do install the Extension Pack if you use VirtualBox. Other virtualization software will work as well so long as the two VMs can communicate with each other using TCP/IP.

Create 2 virtual machines using the specifications listed in Figure 1. Some of these configuration items are specific to VirtualBox but most virtualization tools will have equivalents. The VM’s specs for RAM, CPUs, VM names, and the size of the virtual hard drive are the same for all virtualization tools.

ItemValue
VM NamesTestVM1 and TestVM2. TestVM1 will be the local host and TestVM2 the SSHD server. These are the names used by the virtualization tool. They are not the hostnames.
Hostnamestestvm1 and testvm2. These are the hostnames that are located in the /etc/hostname files and that are displayed by the hostname and hostnamectl commands.
Machine folderUse the default. This is a VirtualBox config item.
(OS) TypeLinux. This is a VirtualBox config item.
VersionThe latest Fedora 64-bit Xfce version. At least Fedora 40 or later. This is a VirtualBox config item.
Memory size4096MB — The memory size can be changed at any time later so long as the VM is powered off. For now this should be more than enough virtual RAM.
Number of CPUs4
File locationUse the default which will be located in your home directory. This is a VirtualBox config item.
(Hard disk) File size80GB
Hard disk file type.vdi – The .vdi extension is the VirtualBox Disk Image file format. You could select other formats but this VDI format will be perfect for our needs. This is a VirtualBox config item.
Storage on physical hard diskDynamically allocated. This selection keeps the virtual disk size to only that which is needed, thus saving space on your actual storage devices. This is a VirtualBox config item.
Figure 1. The specifications for the virtual machines.

Install Fedora, or your other favorite distribution, on both hosts. Create the same non-root user on each VM. I use Test User 1 (tuser1). After rebooting both virtual machines, test to verify that you can ping each from the other.

Starting the SSHD server

Start the SSHD server on both VMs. Any Linux host can be an SSH server and it can make sense to do so in order to facilitate easy communications and the ability to work on remote hosts.

As the root user, start the SSHD server daemon and enable it so it will start on boot. The default SSHD configuration is perfect for our needs and it allows direct login by the root user; in a real world environment we would most likely change that so that direct root logins would be disallowed.

# systemctl enable --now sshd.service
Created symlink /etc/systemd/system/multi-user.target.wants/sshd.service → /usr/lib/systemd/system/sshd.service.

That was easy and our VMs are now ready for us to try out an SSH connection. In a terminal session as a non-root user on VM1, log into VM2. The IP addresses on your hosts may be different from mine.

[tuser1@testvm1 ~]$ ssh testvm2
The authenticity of host 'vm2 (192.168.10.100)' can't be established.
ECDSA key fingerprint is SHA256:NDM/B5L3eRJaalex6IOUdnJsE1sm0SiQNWgaI8BwcVs.
Are you sure you want to continue connecting (yes/no)? yes 
Warning: Permanently added 'vm2,192.168.10.100' (ECDSA) to the list of known hosts.
Password: <Enter the password for tuser1 on VM2>
[tuser1@vm1 ~]$

You must type “yes” – the full word – in order to continue the login. Then you must enter the password for tuser1 on the remote host.

The first time an SSH connection is made to any host the authenticity message is displayed along with the fingerprint of the private key of the remote host. In a very security-conscious environment we would have already received a copy of the remote host’s key fingerprint. This allows comparison so that we know we are connecting to the correct remote host. This is not the security key, it is a fingerprint that is unique to that host’s private key. It is impossible to reconstruct the original private key from which the fingerprint was generated which prevents it being used to crack into the remote host.

Now let’s look at the /home/tuser1/.ssh directory. Then look at the contents of the ~/.ssh/known_hosts file on VM1. You should see the public host key for the remote host, VM2. This file is created in the local host, the one we are connecting from, and not on the remote host, the one we are connecting to. Each host we connect to will have a unique signature of its own in our known_hosts file to identify it for future connections.

[tuser1@testvm1 ~]$ cat .ssh/known_hosts
localhost ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBL0J/wd2RJpsu2fPK0EPzFq6dCnTFk3/m3U716SD2BY
vm2 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFm+TnU+D2+O0iGkcgp47LvEN9ZQ3yKU8l2nuAMeXI6D
vm2 ssh-rsa
<SNIP>
uKMVvVC3DliZZ+GEkXd2U4vsmDht0fXH1RcnPJPBM9xPP32dhfg9Zwprwra1VJxa9icecmZbglvJj0RUgvvFp/PHZxHFVkGWKZ7ywoojFTOeFjR0xc=
vm2 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPOZ9+hEe2P3P5475c3hS45C73w52eoN/9R/dk0724/qYZ9dzNSB6yl+jH35BTIRGtzbqhnoaKTBqCTBLAQdG/c=
[tuser1@testvm1 ~]$

After accepting this key during the first connection to the remote host, the connections initialize a little faster because the two computers now know each other and can identify themselves via the keys. The host keys are stored in /etc/ssh along with the SSH client and server configuration files. List the contents of that directory to view the various key files.

Now, as the root user on VM1, connect to VM2 and verify that connection works as well. Type exit to disconnect from all SSH connections between the two VMs. Now we know that the SSH server on both hosts is working as it should and can accept connections from remote hosts.

How SSH works – briefly

Let’s look briefly at the sequence of events that take place when an SSH connection is made between hosts.

  1. On VM1 you entered the ssh testvm2 command.
  2. The local host established an unencrypted TCP connection to remote host, TestVM2.
  3. The remote host responded with its own public key to the local host which compares it to the one for that host in ~/.ssh/known_hosts. This authenticates the remote host. It does not authenticate the user.
  4. The two hosts negotiate the encryption algorithm to use and start it so that all further communications are performed through the encrypted channel.
  5. The local host prompts the user for their password and sends it to the remote host, the server, over the encrypted channel.
  6. The remote host verifies the password is correct and permits the login to proceed.
  7. The remote host launches the user’s default shell – usually Bash.

If no user is specified as part of the ssh command in user@host format, the user ID issuing the command is assumed by SSH to be the logged-in user ID to connect with on the remote host.

SSH can multiplex many different concurrent channels over the single authenticated connection. This allows tunneling of login sessions and TCP forwarding so that other protocols such as the X Window System, that are not normally encrypted can use this encrypted channel.

SSH today is normally implemented with OpenSSH1. Until September of 2000, SSH was encumbered with patents and other proprietary restrictions, but those all expired at that time. There are still commercial versions of SSH available but there is no reason to use them on Linux. Fedora, and at least some other distributions I have tried, install both the client and server by default. Root access is not allowed by default but can be configured both during installation and later.

Public / Private Keypairs

As an alternative to using passwords, a Public/Private Keypair (PPKP) could be used. PPKPs are used to enhance security by – mostly – removing the need for passwords to initiate SSH connections to a remote host. For the user, this is more secure because it eliminates the need to memorize and the temptation to write down long and complex but good passwords.The PPKP may also use an arbitrarily long optional passphrase for an additional level of security.

Each host already has a PPKP that was generated during first boot after install. Those key host pairs are stored in the /etc/ssh directory. The host’s public key is swapped at the first SSH connection during the initial handshaking protocols. These host keys are used to positively identify the hosts to each other and are used to launch the initial encryption of the connection so that the authentication sequences are secure.

In this section, we’ll discuss user-level PPKs.

How PPKPs work

Suppose that I want to send you encrypted messages that only you – and others with the public key – can read. I need to be able to encrypt it and you need to be able to decrypt it. Cryptology texts are full of ways to do this that involve various types of keys and varying levels of security. Shared keys are fine until the key is compromised. I may not know that the key we share has been compromised and will keep sending messages that can be intercepted and read by the very people I might want to keep them from.

The use of public/private key pairs resolves this problem in a very elegant and secure manner. The key (if you will pardon the pun) is that the public key is the only one that can decrypt messages encrypted by the private key and the private key is the only one that can decrypt messages encrypted with the public key. I had to think about that for a few minutes when I first heard it.

  1. Create a public/private key pair.
  2. Send the public key to the remote computer which will be decrypting my messages and encrypting the reply messages back to me.
  3. Encrypt messages with the private key and send then to the remote computer.
  4. The encrypted message is decrypted by the remote computer using public key.
  5. To respond, the remote computer encrypts the message using the public key from my host and sends it to my host.
  6. The message encrypted by the public key is decrypted on the local host using the private key.

These messages are the data contained in the TCP packets sent between the computers. This PPKP solution can also work for entire emails or other types of messages to keep them secure.

There are some interesting implications from all this. First, anyone who has the public key can decrypt the messages (data packets) that I send. Therefore I can send my one public key to many different computers and then use SSH to connect to them all using the single private key. I do not need a separate set of keys for each computer.

Another inference that we can make is that anyone with the public key can send me messages. However only I can initiate a conversation by using the private key. If another host wishes to initiate a conversation they must create a PPKP and send a copy of their public key to me. So someone cannot just obtain a copy of my public key and then use it to initiate encrypted connections to my host computer.

I could send my public key to the user of the host on the other end in an email and the user at that end could then append it to their ~/.ssh/authorized_keys file. However, there is a tool that I can use to install my public key on the remote host so long as I have the password of the user account with which I want to communicate. Therefore, without the cooperation of a friendly user at the remote host, or already having my own user account and password, I cannot just push my public key across the network and login to any random remote host. This is all very nice and secure which is, of course, the intention.

So I am limited to SSH connections to remote hosts on which I have an account and know the original password. This reduces to the user (or the root user) having an account on both VM1 and VM2 and sending the public key from one host to another.

Generating and Using a PPKP

Perform this exercise as the non-root user on both VM1 and VM2 hosts.

On the VM1 host, use the following command to create a public / private key pair. The -b 2048 option generates a key that is 2048 bits in length, the minimum allowable length is 1024 bits. By default this command generates an RSA key but we could also specify other key types. RSA is considered to be very secure so we will use RSA. We will press Enter to respond to all inquiries so as to take all of the defaults.

[tuser1@testvm1 ~]$ ssh-keygen -b 2048
Generating public/private rsa key pair.
Enter file in which to save the key (/home/tuser1/.ssh/id_rsa): <Enter>
Enter passphrase (empty for no passphrase): <Enter>
Enter same passphrase again: <Enter>
Your identification has been saved in /home/tuser1/.ssh/id_rsa.
Your public key has been saved in /home/tuser1/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:y/y5kKXhceb093iLg3Xh0ZGIqFBsEZSTXi3cdKh22fY tuser1@testvm1
The key's randomart image is:
+---[RSA 2048]----+
| +=* =.o.. .     |
| . * = =.. o     |
| + + o o o       |
| o o o o o.      | 
| S * . o o       |
| + % . .    E    |
| O  . +   o      |
| o o   o.   o.   |
| +. . o  o  o    |
+----[SHA256]-----+
[tuser1@testvm1 ~]$

The host key’s fingerprint and/or the randomart image can be used to verify the validity of a public key for the host. It cannot be used to recreate the original public or private keys and it cannot be used for communication. It is used only to visually verify the validity of the key with an image that is easier to visually compare than a pair of long keys.

Now that we have generated our key pair, look again at the contents of the ~/.ssh directory for the user on TestVM1. You should see two new files, id_rsa which is the private key, and id_rsa.pub which is the public key. The .pub extension kind of gives that away.

These days it is not necessary to send our public keys via email, sneakernet, or other off-network type of delivery. We have a nice tool for that. Do this as the non-root user on TestVM1.

[tuser1@testvm1 ~]$ ssh-copy-id testvm2
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/tuser1/.ssh/id_rsa.pub"
The authenticity of host 'vm2 (10.0.2.11)' can't be established.
ECDSA key fingerprint is SHA256:NDM/B5L3eRJaalex6IOUdnJsE1sm0SiQNWgaI8BwcVs.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Password: <Enter password of tuser1 on the remote host>
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'testvm2'"
and check to make sure that only the key(s) you wanted were added.

As the non-root user on VM1, open a terminal session and ssh to VM2. Verify that you are logged in to the VM2 host. You should do some simple tests on the remote host like listing files and so on. Let’s copy a file from VM1 to VM2. On VM1 open a new terminal session if necessary. Create a file in your home directory on VM1.

[tuser1@testvm1 ~]$ dd if=/dev/urandom of=random.txt bs=512 count=500
500+0 records in
500+0 records out
256000 bytes (256 kB, 250 KiB) copied, 0.00304606 s, 84.0 MB/s
[tuser1@testvm1 ~]$ ll rand*
-rw-rw-r-- 1 tuser1 tuser1 256000 Jun 18 14:50 random.txt

Now we can copy this file to the remote host. We use the tilde, ~, which expands to the home directory of the student user on the remote host. We could also have used `pwd` to specify the pwd which just happens to be the user’s home directory at this moment.

[tuser1@testvm1 ~]$ scp random.txt testvm2:~
[tuser1@testvm1 ~]$

Use a terminal session on TestVM2 to verify that the file has been copied to TestVM2. You could login to TestVM2 from TestVM1 to do this. Be aware that disruption of the expected SSH protocol stream by comments added to your login can cause SSH and SCP to fail without an error. That’s one reason it’s important to verify that the file was actually copied to TestVM2.

Create a PPKP for the root user on TestVM1 and copy the public key to TestVM2. Also create PPKPs for both the root and student users on the TestVM2 host and copy them to TestVM1. This sets up a situation where users can SSH easily from one host to another.

Now SSH from the tuser1 account on TestVM2 to the tuser1 account on TestVM1. Run a couple simple tests to verify the host and user account ID. Then exit from the SSH connection.

[tuser1@testvm2 ~]$ ssh testvm1
Last login: Thu May 30 14:39:56 2019 from 10.0.2.11
[tuser1@testvm1 ~]$ pwd
/home/tuser1
[tuser1@testvm1 ~]$ hostname
testvm1
[tuser1@testvm1 ~]$ whoami
tuser1 pts/4 2019-06-20 08:12 (192.168.0.182)
[tuser1@testvm1 ~]$ exit

Even without a passphrase, using a PPKP is more secure than a basic SSH connection using a password.

X-forwarding

We now have SSH working and tested so there’s more fun stuff ahead. Let’s start by running a GUI program on the remote host with the display of the program’s window on the local host. Most GUI desktop systems use Wayland2 windowing system, or the X Window System3, aka, X, as their underlying windowing engines. X-forwarding works in either event because they both use the same protocols.

Perform this experiment as the tuser1 on the TestVM1 host.

First, we need to enable X-forwarding via SSH on TestVM2. Edit /etc/ssh/sshd_config with your favorite editor. Find the entry # X11Forwarding no on or about line 101 and change it to X11Forwarding yes. Be sure to uncomment the line by removing the leading pound ( # ) symbol. Then, as root, restart the sshd service.

root@testvm2:/etc/ssh# systemctl restart sshd.service

Now SSH from TestVM1 to TestVM2 using the -X (uppercase) option to specify the use of X-forwarding. If you see a message regarding the Xauthority file it is normal at this stage and the file will be created if necessary.

[tuser1@testvm1 ~]$ ssh -X testvm2
Last login: Wed Jun 19 08:31:28 2019 from 10.0.2.21
/usr/bin/xauth: file /home/tuser1/.Xauthority does not exist
[tuser1@testvm1 ~]$ thunar &
[1] 2683
[tuser1@testvm1 ~]$

The ampersand (&) after the command specifies that the command is to run in the background; that returns the terminal session to a command prompt while leaving the GUI program to run. That will not affect running the specified program like Thunar or xeyes but if you run Thunar without the & the terminal session does not return to a command prompt. You would need to terminate Thunar or login remotely again to get a command line from which to launch xeyes.

The result of this is shown Figure 2 as a screen capture of the TestVM1 host desktop. It shows the effects of using X-forwarding via SSH to display the Thunar file manager running on TestVM2 on the desktop of TestVM1. Navigate around the directory structure on TestVM2 for a bit.

Figure 2: The Thunar window from TestVM2 is shown on the desktop of TestVM1. Click on the image for a larger view.

Now install some fun and interesting Xorg programs. As root on TestVM2, install the xeyes and xclock packages on TestVM2. Do not install these on TestVM1.

[root@testvm2 ~]# dnf -y install xeyes xclock

As the student user on StudentVM2 try out the xeyes program. The number, 23848, is the PID of the running xeyes instance. That number will be different for you.

[tuser1@testv2 ~]$ xeyes &
[1] 23848
[tuser1@testv2 ~]$

Kill this instance of xeyes using the window buttons at the top of the Xfce desktop. The xeyes program must be moved or closed from the application bar because it has no window frame to manipulate.

Now, as tuser1 on TestVM1, try to start xeyes (X eyes). It fails because we did not install the xeyes package on TestVM1.

[tuser1@testvm1 ~]$ xeyes &
-bash: xeyes: command not found
[1]+ Exit 127 xeyes
[tuser1@testvm1 ~]$

Now, from the TestVM1 desktop, use the SSH connection to TestVM2 that has X-forwarding enabled. Enter the same command. Move the mouse pointer to see the eyes follow it. Figure 3 shows a snapshot of what that looks like.

Figure 3: The eyes for the xeyes program show up on TestVM1 even though the program is running on TestVM2. Click to enlarge the image.

Now start xclock remotely and have some fun with this for a minute or two and then close down Thunar, xclock, and xeyes.

This capability can be both fun and useful. I’ve used it to run the Xfce Settings Manager to make some changes to a remote system. This is not a common task as most settings, even desktop ones, can be modified remotely using the command line.

The X Window System

Because X-forwarding over SSH is a client/server type of operation, let’s look at the details a little more closely.

Tip: Although some people call it X Windows or X-Windows, to be technically and legally correct, it should be called the “X Window System” or just “X”.

It seems pretty clear that a standard SSH connection takes place from the client on the local host to a server on the remote host. We have, in fact done that over the course of these experiments. But is that also true of X-forwarding over SSH?

To understand this we need to know more about the X Window System. Wikipedia has a rather old article describing the X Window System and some of its history. The short version is that the X Window System is a windowing system for Unix-like operating systems such as Linux. X does not do anything other than provide the primitive graphical tools to create and manipulate windows and objects on a bit-mapped display. It does not impose any aspect of the user interface such as how it looks or how users and application programs can interact with it.

The X Window System uses a client-server model which separates the applications and their requests from the server functions that fulfill those requests. This allows X to be versatile and creates the basis for X-forwarding. However it is necessary to think about the client-server model from the perspective of the application rather than of the user, which is how we normally think of it. We used SSH from the local host, TestVM1 to connect to the remote host, TestVM2, and then started applications running on TestVM2 with the applications’ windows displayed on TestVM1.

  1. We use the mouse on TestVM1 to select a folder in the instance of Thunar running on TestVM2.
  2. Thunar, running on TestVM2 opens the folder and generates a series of graphical commands that cause the redrawing of the Thunar window. This is a client request to the X server on TestVM1.
  3. Those commands are sent to TestVM1 where the X server translates them into the new images in the Thunar window. This is the X server fulfilling the request from the client.

Most of the time, the server and the client are located on the same host but they can be located on different hosts as seen in this experiment. This is only possible because the client and server functions are separate and communicate both locally and remotely using standard network protocols. But that’s part of a different story.

Remote commands

Although using SSH to perform remote commands may sound like logging in to a remote computer using SSH and then typing in commands on the remote Bash shell, there is a significant difference. And that little difference is what makes SSH such a powerful tool. Let’s start with a simple task like checking the contents of a directory on the remote host.

Perform this experiment as the student user on StudentVM1. Our objective is to determine the contents of the student user’s home directory on the remote host. As the student user on the StudentVM1 host, run the following command. This can only be accomplished without using a password if a PPKP is in place.

The quotes in the command are used to delimit the command being sent to the remote host but can actually be dispensed with for simple commands like this. For more complex commands, such as we will see further along in this experiment, they are quite useful and necessary.

[tuser1@testvm1 ~]$ ssh studentvm2 "ls -l"
total 284
drwxr-xr-x. 2 student student 4096 Dec 24 08:19 Desktop
drwxr-xr-x. 2 student student 4096 Dec 22 13:15 Documents
drwxr-xr-x. 2 student student 4096 Dec 22 13:15 Downloads
drwxr-xr-x. 2 student student 4096 Dec 22 13:15 Music
drwxr-xr-x. 2 student student 4096 Dec 22 13:15 Pictures
drwxr-xr-x. 2 student student 4096 Dec 22 13:15 Public
-rw-rw-r--. 1 student student 256000 Jun 19 08:16 random.txt
drwxr-xr-x. 2 student student 4096 Dec 22 13:15 Templates
drwxr-xr-x. 2 student student 4096 Dec 22 13:15 Videos

Now a bit more fun with this.

[tuser1@testvm1 ~]$ ssh studentvm2 "cp random.txt textfile.txt ; ls -l"
total 536
drwxr-xr-x. 2 student student 4096 Dec 24 08:19 Desktop
drwxr-xr-x. 2 student student 4096 Dec 22 13:15 Documents
drwxr-xr-x. 2 student student 4096 Dec 22 13:15 Downloads
drwxr-xr-x. 2 student student 4096 Dec 22 13:15 Music
drwxr-xr-x. 2 student student 4096 Dec 22 13:15 Pictures
drwxr-xr-x. 2 student student 4096 Dec 22 13:15 Public
-rw-rw-r--. 1 student student 256000 Jun 19 08:16 random.txt
drwxr-xr-x. 2 student student 4096 Dec 22 13:15 Templates
-rw-rw-r--. 1 student student 256000 Jun 20 08:22 textfile.txt
drwxr-xr-x. 2 student student 4096 Dec 22 13:15 Videos

So that works as we expect. But try the same command without quotes. You will see that the remote command ends at the semicolon that the local shell uses to delimit the final command. The quotes are required so that the shell can properly send the entire command to the remote host.

Tip: Bash shell aliases such as the ll command are not available when using remote commands. So be careful when using scripts containing remote commands to not use command aliases.

Remote backups

The term “remote backups” may be a bit misleading, even with what we now know about running commands remotely. For many years I used a script to perform backups on my main workstation and several remote hosts. I used remote commands to perform the remote backups to the local workstation. Making backups of remote hosts is much easier than you might think.

Perform this experiment as the root user on TestVM1. We start with the simple task of creating a backup of the TestVM2 remote host with the resulting backup stored on TestVM1. We will make a backup of /home, /root, and /etc. and store the backup tarball in testvm1://tmp.

[root@testvm1 ~]# ssh testvm2 "tar -cvf /tmp/studentvm2.tgz /home /etc /root ; ls -l /tmp "

Now verify that the tarball /tmp/testvm2.tgz contains the files we expect. But do it from StudentVM1.

Now let’s look at something and try to make a bit of sense from it.

[root@testvm1 ~]# ssh testvm2 "tar -c /home /etc /root"

Do you see what happened? The data stream from the tar command that was executed on the remote host, TestVM2, is sent across the SSH connection to the standard out (STDOUT) of the terminal session on the local host, TestVM1. So now we have the data stream from a remote host here on our local host just waiting to be piped or redirected – on our local host.

Got it yet? Note where we place the closing quote in this simple command line program.

[root@testvm1 ~]# ssh testvm2 "tar -cz /home /etc /root" > /tmp/testvm2.tgz ; ls -l /tmp 
tar: Removing leading `/' from member names
tar: Removing leading `/' from hard link targets
total 287352
<snip>
-rw-r--r-- 1 root root 6259259 Jun 20 08:57 testvm2.tgz
<snip>

We have used an SSH tunnel with a remote tar command to create a stream consisting of the backup data from the remote host. That data stream is sent across the SSH tunnel to STDOUT on the local host where it can be used with other commands through pipes or redirected to a file.

We have now performed a backup of a remote host and stored the backup file on the local host, all with a simple command line program.

Summary

Once I had created an easy and elegant method for creating backups of remote hosts using tar and SSH, the next step for me was to create a script that would perform that same backup on several hosts and then set up a cron job or a systemd timer to do those backups every night. I used this method to perform backups for many years but eventually found that using rsync for backup provide more flexibility and meet my needs better. However this use of SSH and tar graphically illustrates the power and flexibility of SSH.

SSH uses two levels of authentication, first authenticating the hosts themselves and then user authentication. It encrypts the entire session including the authentication and all of the data transmission. SSH is very secure and can be used to transmit data securely over public networks.

SSH features such as remote command execution and data stream transmission over the encrypted connection enable powerful solutions for things like backups using simple tools like tar. SSH also provides X-forwarding so that we can run graphical programs on the remote host with their windows on our local host.


  1. OpenSSH, http://www.openssh.com ↩︎
  2. Wikipedia, Wayland, https://en.wikipedia.org/wiki/Wayland_(display_server_protocol) ↩︎
  3. Wikipedia, X Window System, https://en.wikipedia.org/wiki/X_Window_System ↩︎