2.3. SSH#

The Secure Shell (SSH) protocol is a network protocol that allows secure access to systems running an SSH server over a network (e.g. the Internet). All the communications from the client (e.g. your workstation for example) to the server (e.g. a remote workstation) are encrypted.

SSH is widely used, examples of applications are

  • accessing severs remotely (student workspace hosted by the school, supercomputers, Git servers, remote workstation, …) with or without password,

  • transferring or syncing files,

  • mounting a directory on a remote server as a local filesystem.

SSH client and server are present on most operating systems, including macOS, most distributions of Linux, and even (recent) versions of Windows.

2.3.1. Access to a remote computer#

To access a remote computer via ssh, the administrator of the server needs to set up your account. You should have a username and a password.

2.3.1.1. Password-based authentication#

The SSH command to access a remote server with a password is as follows

ssh username@hostname

where username is the username associated with your account on the remote computer and hostname is the name associated with the remote computer. The latter can be an IP address or a domain name.

This command will prompt you for your password (associated to your account on the remote computer), and will then open a terminal session on the remote computer.

Note

The first time you connect to a remote computer, it will ask you if you want to add the host to known_hosts, which is a file you can find in ~/.ssh

In this example, hostname is used to get the current IP address. We log from 172.17.0.3 to 172.17.0.2 for the first time.

2.3.1.2. Key-based authentication#

Using SSH, there is an alternative to password-based authentication which uses a public key and a private key. More precisely, it uses an asymmetric encryption algorithm where the public key is used for encryption, and the private key is used for decryption.

The idea is that the user generates both keys, and send the public key to the remote computer. Then, each time the user wants to connect to the remote computer, the remote computer will “challenge” the user sending a message encrypted using the public key. The user will send back the decrypted message, which can only be done with the private key. Note this is done automatically behind the scenes using the same command as before.

This approach is usually considered safer than password-based authentication, mainly because the private key never leaves the user’s workstation. But remark that if the private key is stolen (by someone accessing your workstation for example), then the remote computer is compromised (as compromised as if your password was stolen). That is why it is advised to add a layer of security by encrypting the private key itself with a passphrase, which is suggested when creating the keys.

Finally, this approach provides passwordless access to the remote computer, meaning you can access several times to the remote computer, without having to type your password each time.

Creating private and public keys

To create a pair of public/private keys, you need to use the following command

ssh-keygen

It will first ask you about the name of the file (default to ~/.ssh/id_rsa), and for a passphrase. Note that the latter is optional, if given, it is used to encrypt the private key adding a new layer of security. It will then create two files: ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub by default, the first is the private key, and the second the public key.

Sending a public key to a remote computer

Once the pair of public and private keys is created, you need to send the public key to the remote computer. It can be done with the following command

ssh-copy-id username@hostname

If the public key name differs from the default, add the flag -i path/to/my_id_rsa.pub.

Accessing a remote computer with key-based authentication

If the private key is not encrypted, in other words, if there is no passphrase, then you can connect to the remote computer using the same command as in Password-based authentication, and it will not prompt you for your password.

If the private key is encrypted, each time you will try to connect, it will prompt you for the passphrase to use the private key. To avoid this and still have passwordless access to the remote computer, you can use ssh-agent that will cache the decrypted key for the rest of your terminal session.

You first need to call this command to set up ssh-agent

eval $(ssh-agent)

and then, you can cache a key using ssh-add

ssh-add ~/.ssh/id_rsa

In this manner, you can access the remote computer using ssh as before.

2.3.1.3. Configuration file#

If you want to avoid remembering all the usernames, domain names, and command-line options, you can set up a configuration file where you can write everything once.

This file does not exist by default, so first you need to create it

touch ~/.ssh/config

The format of the configuration file is as follows

Host hostname1
    Option1 value
    Option2 value

Host hostname2
    Option1 value

A minimal configuration file using our previous example with hostname as the host and username as the username gives

Host my_host
    HostName hostname
    User username

With this configuration file, one can use ssh MyHost instead of ssh username@hostname. Here we do not gain a lot since this is a simple example, but a configuration file can quickly be useful.

2.3.2. Transferring files#

Several file transfer mechanisms based on SSH exist. You can always use either password or key-base authentication,

2.3.2.1. Secured copy protocol#

scp simply reads the source file and writes it to destination.

scp local_file host:local_file_sent_to_remote
scp host:remote_file remote_file_sent_to_local

2.3.2.2. rsync#

rsync is highly configurable tool for copying files. It can be used locally, or over a network with SSH. One difference with scp is that it uses a “delta transfer algorithm”, meaning in particular that only the difference between the source and target files will be sent.

It has many flags allowing for fine-tuning of its behaviour. Here are some:

  • -a to keep almost 1 everything the same recursively.

  • -u to not update if files at destination are newer.

  • --progress to show the progress of the transfer

Note

Remark that when we try to send local_file.txt the second time, nothing is sent. This is because there is no difference between the local and remote versions of local_file.txt.

2.3.3. SSH Bastion#

Usually remote computers are not directly accessible from the Internet. You first need to access to a remote server (called “Bastion”) from which you can access to a remote computer. It allows isolating a private network (where the remote computer is) from the Internet, making it only accessible via the Bastion.

To automate the process of first connecting to the bastion, and then to the remote computer, you can use the following command

ssh -J username@bastionname username@hostname

where bastion is the domain name of the SSH bastion. You can also use the following configuration file that defines the bastion host and the remote computer

Host my_bastion
    HostName bastionname
    User username

Host my_host
    HostName hostname
    User username
    ProxyJump my_bastion

You can then connect to the bastion using ssh my_bastion, or directly to the remote computer with ssh my_host. It will prompt you for your password twice if you use a password-based authentication, or you can send your public key to both remote servers to use key-based authentication.

In this example, we log from 172.17.0.3 to 172.17.0.2 via 172.17.0.4 usung key-based authentication.

2.3.4. Notes for VS Code users#

VS Code has useful extensions to work on a remote computer.

  • Remote - SSH can be used to open a folder on a remote computer running an SSH server. In practice, this will open a new VS Code window (workspace in VS Code jargon) where you can interact with the remote files and folders, open a terminal on the remote computer, and even install extensions. This way, one can work on this remote folder using all the usual VS Code features (intellisense, code navigation, debugging, and so on) as if it was local. I refer to its documentation, but note that it will find SSH targets defined in Configuration file.

  • SSH FS is another alternative I use when the previous extension is not available, which can happen if the operating system on the remote computer is not supported. It mounts a remote filesystem as a local workspace folder. The integration with VS Code is not as advanced as with the previous extension since the workspace is local. Features like intellisense, code navigation, debugging will not work since it does not have access the remote environment, but basic features such as syntax highlighting should work and this is often enough.

2.3.5. References#

1

The main exception concerns hard links, see documentation for more information.