This is a beginners’ guide to SSH. It covers how to set it up, some basics on keypair management and a couple of useful configurations.

Simply stated, SSH is the main way to access a remote system (the host) and to operate it from our local computer (the client). SSH is a shell tool (command line), although desktop software can leverage it and wrap the SSH connection with a graphical user interface.

For what concerns servers, SSH is the quickest way to manage a server in a single machine setup (accessing a cluser via SSH is impractical).
When beginners start playing around with a Linux server they will probably do it through SSH and, in general, it’s the easiest way to quickly configure and manage a server.

What and How

How do we use SSH?
Let’s say we are using our personal computer with our personal user account. When we issue the command:

1
$ ssh myusername@192.168.0.15

We will access the machine that appears on the network (local or the whole internet) as 192.168.0.15 and login as the user myusername. The user myusername must exist on the remote computer, while the identifier of the computer can be either an IP address (as seen in the example above) or a human readable domain name, like mywebsite.com.

Once the connection is estabilished, our terminal (or other client) will become a window on the host system, and we will be able to operate on it as if we were accessing it directly.

Client Authentication

SSH access requires client authentication. As mentioned above, by client we mean our local computer, from which the SSH connection is initiated. More specifically, the client is the software running on our computer that we are using to connect via SSH, and typically it’s a shell terminal.
The authentication can be based either on username and password or on keypair authentication. The latter is the most common way, as it’s more secure and can be configured and automated. Let’s see the difference.

With username and password authentication we have to type our password:

1
2
$ ssh myusername@remote.host.address.com
myusername@remote.host.address.com's password: 

With keypair authentication we provide our private key (stored in a file). If the key is protected with a passphrase we will be asked to type it in:

1
2
$ ssh -i /path/to/privatekey/file myusername@remote.host.address.com
Enter passphrase for key '/path/to/privatekey/file': 

The passphrase is optional but strongly recommended. Needless to say, private keys are to be considered sensitive data.

I’m afraid the details of keypair authentication are beyond the scope of this blog post.
The wikipedia article linked above is a good place to start, and there are a lot of resources on the web that explain how to set it up. In addition, cloud computing providers like Amazon will automatically setup keypair authentication for you.

The rest of this article is not exclusive to keypair-authenticated SSH connections.

SSH commands and configuration

When using the ssh command we need to provide the ditails of the connection. They usually are:

  • the username of the remote user we want to login as,
  • the IP address of domain name of the host computer.

In addition, if we want to use keypair authentication we will need to indicate the path to the identity file.
If we don’t specify it, SSH will try to either use the private key stored in ~/.ssh/id_rsa (default name and location) or to authenticate with username and password.
Of course we don’t want to be limited to the default id_rsa file, and we can indicate a diverse file using the -i flag, as seen before.

The resulting command is quite verbose, as it requires to specify different usernames, URLs and keys for the various hosts we connect to.

A quick and dirty solution would be a shell alias. For example, we can insert this line in our ~/.profile file:

1
alias goto_myserver='ssh -i ~/.ssh/custom_name_rsa username@somewhat.long.url.of.myserver.com'

This will allow us to SSH to our server with the shortcut:

1
$ goto_myserver  

The file ~/.profile is the file used to configure the command line shell on Unix-like systems. Most systems (Linux and Macs), however, default to using Bash, and bash relies on the ~/.bash_profile file instead (~/.bash_login on OS X). Other shells like zsh use other files too, but then if you are a zsh user you probably don’t need me to tell you that. Actually, why are you even reading this guide?

Now, a shell alias might work, but it’s not an ideal solution. For more advanced configurations we need to use a SSH config file: ~/.ssh/config.

The config file is a text files containing configuration directives that will make our lives much easier. There are tens of available options, but here I’ll focus on how to preconfigure host authentication details and how to setup host aliases.

Matching Patterns

Configuration directives are grouped using the Host directive, used to define a host match. Any directive associated to a Host group will only affect SSH connections matching that specific Host definition.

The Host directive’s arguments are patterns that will be matched against the hostnames provided with ssh command. Patterns can be either:

  • a host address, either as URL or IP
  • an alias, eg: my_personal_site
  • an asterisk (*), interpreted as a wildcard

As an example, let’s assume that our ~/.ssh/config file contains the following directives:

1
2
3
4
5
6
7
8
9
10
11
12
Host *
  some_directive 1

Host www.a.public.address.url.com
  some_directive 2
  some_directive 3

Host booya rofl.lol.net
  some_directive 4

Host *.mydomain.com
  some_directive 5

And now some examples of how the ssh command can be invoked, followed by the directives that will be applied in the specific cases.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ ssh www.example.com
    # some_directive 1

$ ssh www.a.public.address.url.com
    # some_directive 1
    # some_directive 2
    # some_directive 3

$ ssh subdomain.public.address.url.com
    # some_directive 1

$ ssh booya
    # some_directive 1
    # some_directive 4

$ ssh rofl.lol.net
    # some_directive 1
    # some_directive 4

$ ssh crazymonkey.mydomain.com
    # some_directive 1
    # some_directive 5

Configuration Directives

Once we have defined some Host directives to fit our needs, it’s time to add the configuration directives. Here are the most common ones:

  • User myusername specifies the username of the remote host’s account you wish to connect as.
  • HostName url.or.ip.address.com is used when the Host directive indicates an alias, and specifies the actual address of the remote host.
  • IdentityFile ~/.ssh/custom_name specifies what private key file should be used.
  • IdentitiesOnly yes forces SSH to only accept the identity files provided in the config file (the system’s SSH agent could try to provide more).
  • AskPassGUI no (OS X only) disables the graphical password pop-up, forcing SSH to use the default command line prompt. The problem with the pop-up dialog is that it will cache the password for the whole session. If one decides to protect a private key with a passphrase, caching it until the system is rebooted is not a great idea, IMHO.

These five directives are enough to greatly improve our SSH experience.
Here is an example configuration file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Host *
    IdentitiesOnly yes
    AskPassGUI no

Host github.com
    User git
    IdentityFile ~/.ssh/github_key

Host site_u1
    HostName site.example.com
    User user_1
    IdentityFile ~/.ssh/example_com_key_1

Host site_u2 site.example.com
    HostName site.example.com
    User user_2
    IdentityFile ~/.ssh/example_com_key_2

Host blog
    HostName myawesomeblog.com
    User bloguser

The first group contains options that will be applied to any connection.

The second group sets the private key file for github connections. Notice that the Host pattern is an actual URL. This way the statement will be picked up by any automatic script accessing the URL directly, such us git when doing git push (when using a SSH style remote).

The third group is a standard way to access a remote host using an alias. It just specifies host address, username and private key file.

The fourth group points to the same host of the third, but will login using a different remote account (and a different private key). In addition, it uses the fully qualified host address as a second pattern. This is useful when we want to access a host both manually (using the alias) and programmatically. There are a number of tools that automatize server management by automatically connecting to remote hosts and executing commands, and they will try to connect using the standard URL, not an alias.

The last group is the simplest. It uses an alias and only specifies host address and account name. The corresponding command $ ssh blog will know what to do, but it will also ask for the standard password.