- 1 How to Generate and Install SSH Keys
- 2 SSH Performance
- 3 Configuring the Server
How to Generate and Install SSH Keys
This section describes how to generate and install SSH keys in order to access a remote server from your client PC without SSH password authentication. This increases security and comfort.
Generate the Key Pair
First of all, think about how the file pair should be named:
- Filenames should have prefix id_rsa_ per convention.
- It is best to properly name the keys.
The key name usually contains the name of the remote system. This way, it is easy to discard private keys for remote systems that do not exist anymore. You may want the mention of the local system too in the key name, if you plan to use one key per PC.
- A date in the filename helps easily discard old key files with lost private key counterparts.
The following Bash commands generate a good filename (and a similar key comment) with a minimum of fuss:
TMPSTR="username_description_$(date "+%Y_%m_%d")" ssh-keygen -t rsa -P '' -b 4096 -C "$TMPSTR" -f "$HOME/.ssh/id_rsa_$TMPSTR"
In the command above:
- -b 4096 is the key length
- -P '' means no password
You can password-protect the private key file at the cost of convenience. The ssh-agent can help reduce prompting.
- -C is the comment placed inside the .pub files
Two key files with names like these are generated:
id_rsa_username_description_2019_21_01 (private key) id_rsa_username_description_2019_21_01.pub (public key)
On Microsoft Windows, you can use graphical tools PuTTYgen or KiTTY -keygen to generate the key pair.
Copy the Public Key to the Server
The following Bash command places a copy of the public key on the remote server:
ssh-copy-id -i "$HOME/.ssh/id_rsa_$TMPSTR" -p 22 firstname.lastname@example.org
In the command above, -p 22 is the TCP port number where the SSH server is listening on. This is normally TCP port 22, but it may vary for security reasons.
Alternatively, you can manually append the contents of the .pub key file to ~/.ssh/authorized_keys on the server using your favourite text editor.
Tool ssh-copy-id does not work on OpenWrt routers using the Dropbear SSH server. For these systems, either manually edit the /etc/dropbear/authorized_keys file, or use the following command:
ssh -p 22 email@example.com "cat - >> /etc/dropbear/authorized_keys" <"$HOME/.ssh/id_rsa_$TMPSTR.pub"
When doing this manually, or with the alternative ssh commands above, there are a number of things you have to look out for. Directory ~/.ssh may not exist on the server yet. File permissions on that directory and in any files inside it may need to be more restrictive than usual. And watch out for missing end-of-line characters when automatically appending text with cat to the authorized_keys file. Tool ssh-copy-id does all that automatically.
Try the New Key
ssh -i "$HOME/.ssh/id_rsa_$TMPSTR" -p 22 firstname.lastname@example.org
Consider Backing up the Key Pair Outside Your Current PC
This is important if you decide to disable SSH password authentication on the server for security reasons. If you then lose your private key, you may not be able to remotely log on to the server anymore.
Copying the Private Key File to Another Computer
If you copy the private key file to another client computer, make sure the user is the owner of that file (which is usually the case), and that the file permissions are more restrictive than usual, or the private key file will not be used:
chown $USER ~/.ssh/id_rsa_username_description_2019_21_01 chmod 0600 ~/.ssh/id_rsa_username_description_2019_21_01
Permissions 0600 mean -rw------- (only the owner can read and write).
Create or edit file ~/.ssh/config on your client PC in order to avoid having to specify the "ssh -i" argument and other connection options every time.
This is an example ~/.ssh/config file:
# Indentation below is not mandatory, but it improves readability. # Defaults for all hosts. Host * # Only use the files explicitly mentioned. Otherwise, the SSH client # will try all keys until one works. This can easily lead to confusion. IdentitiesOnly yes # - 'Host' is just a friendly name. You can use the same address # as in HostName. # - 'User' is the username on the remote machine. # - 'CheckHostIP' can normally be turned off with little security # implications. Otherwise, you will get a security prompt every time # the server IP changes, which you may find annoying. # - Optionally add "StrictHostKeyChecking no" if frequent prompting # on an experimental network bugs you. Host MyRemotePc HostName remotepc.com Port 22 User username IdentityFile /home/username/.ssh/id_rsa_username_description_2019_21_01 CheckHostIP no
Note that the ~/.ssh/config file will not be used unless it has the right owner and permissions:
chown $USER ~/.ssh/config chmod 600 ~/.ssh/config
Permissions 0600 mean -rw------- (only the owner can read and write).
Simple performance test:
pv /dev/urandom | ssh -T user@remote_host 'cat > /dev/null'
The cipher choice can have a great impact on performance, especially on slow processors.
The list of supported ciphers on the server, and which ones are enabled by default, is in "man 5 sshd_config".
This command lists the currently-enabled ciphers on the server:
sudo sshd -T | grep ciphers | perl -pe 's/[, ]/\n/g' | grep --invert-match '^ciphers$' | sort -u
List the ciphers that the SSH client supports:
ssh -Q cipher | sort
For trusted networks, you are often advised to use option "-o Ciphers=arcfour", because the arcfour cipher is very fast. Unfortunately, this advice is no longer feasible, because many SSH servers, like the one in Ubuntu 16.04, do not enable arcfour by default. Even if you turn it on, many clients, like the one in Ubuntu 18.04, do not support arcfour at all. And changing your Linux distribution's SSH server configuration file is inconvenient, because it tends to be automatically updated. Unfortunately, there is no way to turn encryption completely off, not even on a connection basis.
I had a performance problem between a slow Ubuntu 16.04 laptop and an Ubuntu 18.04 server, and the only workable cipher alternatives were email@example.com and firstname.lastname@example.org . I did not see any performance advantage compared to the default cipher.
If your intend to copy large amount of files, and SSH performance is getting in the way, consider using SAMBA or NFS instead.
Configuring the Server
Change the Port Number
A simple way to make life difficult for automated attackers is to change the default SSH port number. See configuration option Port in /etc/ssh/sshd_config.
How to Disable Password Login
For security reasons, it is often a good idea to disable password login on the SSH server.
You need to be careful that you do not lock yourself out. So test beforehand that you can log in with SSH keys without any problems.
Edit /etc/ssh/sshd_config and set the following configuration options:
ChallengeResponseAuthentication no PasswordAuthentication no # I am not sure yet whether turning this off is actually desirable: UsePAM no
Restart the SSH server like this:
# Without systemd: sudo /etc/init.d/ssh restart # With systemd. Beware that your SSH service may be called 'sshd' instead: sudo systemctl restart ssh
Disabling System Version Advertising
If you telnet to your SSH server port, you will see this kind of version hint:
This is a little worrying from a security point of view, because it is not advertising some SSH version level, but the exact server version and operating system version. It is too much information for a potential attacker.
Apparently, the first part (SSH-2.0-OpenSSH_7.6p1) is hard-coded, and cannot be changed easily. But the second part (Ubuntu-4ubuntu0.3) can be removed with /etc/ssh/sshd_config configuration option "DebianBanner no".