Many systems automatically install OpenSSH. However, you should check the version (using ssh -V
) and update if necessary (using sudo apt update && sudo apt upgrade openssh-server
), as well as harden the default installation to avoid known vulnerabilities in the server’s implementation itself. You should also consider further restricting certain users, groups, and especially (possibly automated) clients who need access to a login shell, in accordance with the principle of least privilege.
Installing¶
Most operating system distributions provide the openssh-server
package. Install it on a Debian-based GNU/Linux distribution by invoking:
sudo apt update && sudo apt install openssh-server
Configuring¶
Configure SSH server¶
TK-TODO
Configure SSH client¶
We strongly recommend that you configure your SSH client as soon as you have authentication credentials for logging in to an SSH server. Not only does this make your use of SSH simpler and faster, correct configurations help prevent operational security blunders such as attempting to log in using an unintended username, which may be logged on the remote system.
Assumptions:
- Let
example.com
be the server to which you will be authenticating. - Let
the_server
be your personal alias for the server. - Let
example_user
be the remote username that you are intended to authenticate as. - Let
~/.ssh/example_com_rsa
be the SSH private key file you are using for passwordless authentication.
Do this to configure the SSH client on your local system given the above assumptions:
- Log in to the (unprivileged) user account you normally use on your system.
- In your local system user’s
~/.ssh/config
file, add the followingHost
block:
Host the_server HostName example.com User example_user IdentityFile ~/.ssh/example_com_rsa
- Save the file.
This ensures that you can access the correct server with the correct username simply by invoking ssh the_server
.
Hardening¶
In order to use SSH most securely, you should consider performing the following procedures, derived from this "Secure Secure Shell" article, among other sources, such as the sshd
manual page. In a nutshell, these instructions provide the following:
- Network-based hardening through careful selection of permissible key exchange algorithms, ciphers, and other cryptographic implementations.
- Host-based hardening through Operating System-level and application-level configuration options.
- Deactivation of undocumented and risky features (i.e., security vulnerability CVE-2016-0777).
Harden SSH server¶
Do this to harden your OpenSSH installation:
- In the server’s
/etc/ssh/sshd_config
file, prepend the following lines, which will preempt the application of any similar configuration directives that appear later in the file. (See the sshd_config(5) manual page for more details and configuration options.)
# Network security considerations. # Consider moving off a default port. #Port 22 # Consider listening only on the local interface and setting up a Tor Onion service instead; this blocks LAN access. #ListenAddress 127.0.0.1 # Cryptographic selections. KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256 Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com # Server authentication. Protocol 2 HostKey /etc/ssh/ssh_host_ed25519_key HostKey /etc/ssh/ssh_host_rsa_key # Client authentication. PasswordAuthentication no ChallengeResponseAuthentication no PubkeyAuthentication yes # Host-based security considerations. UsePrivilegeSeparation sandbox AllowGroups ssh-users # Choose a `root` user login policy. This should probably either be `no` (to disable root login completely) # or `forced-commands-only` (to allow the root user access only to a whitelisted command). PermitRootLogin no #PermitRootLogin forced-commands-only # Don't tell clients our operating system, they don't care. DebianBanner no
- If you chose to include the
diffie-hellman-group-exchange-sha256
key exchange algorithm (in the list of acceptableKexAlgorithms
), edit the/etc/ssh/moduli
file (seemoduli(5)
for details) to remove small (i.e., weak) primes using the following (bash
) commands:
awk '$5 > 2000' /etc/ssh/moduli > "${HOME}/moduli" # print lines where the fifth column is greater than 2000 wc -l "${HOME}/moduli" # make sure there is something left in the file; we should see a positive integer sudo cp "${HOME}/moduli" /etc/ssh/moduli # replace the original moduli file with the filtered one rm "${HOME}/moduli" # remove the temporary moduli file
- If the
/etc/ssh/moduli
file doesn’t exist, then create it:
sudo ssh-keygen -G /etc/ssh/moduli.all -b 4096 sudo ssh-keygen -T /etc/ssh/moduli.safe -f /etc/ssh/moduli.all sudo mv /etc/ssh/moduli.safe /etc/ssh/moduli sudo rm /etc/ssh/moduli.all
- If you chose to include the
- Remove any existing but unused SSH keys, and regenerate the remaining recommended ones with stronger parameters (longer key sizes):
cd /etc/ssh sudo rm ssh_host_*key* sudo ssh-keygen -t ed25519 -f ssh_host_ed25519_key -N "" < /dev/null sudo ssh-keygen -t rsa -b 4096 -f ssh_host_rsa_key -N "" < /dev/null
- Create the special-purpose
ssh-users
group:
sudo groupadd ssh-users
- Before a user will be permitted to log in over SSH, they must be added to the
ssh-users
group withsudo usermod -a -G ssh-users $THE_USERNAME
(where$THE_USERNAME
is the username of the user to be added to the group; you will probably want to add your own user account, at a minimum). - Finally, test the configuration with
sshd -t
orsshd -T
for an extended check. No errors indicates a reasonable configuration file.
Test and apply the new configuration¶
Once configured as above, you can apply the new sshd_config
on the server:
# Test the configuration again, just in case, and if the syntax check passes,
# send the main SSH server's process a hangup signal.
sudo sshd -t && sudo systemctl kill --kill-who=main --signal=SIGHUP sshd
Note that this might kill your connection, so be certain you can still access the server through some other means if the configuration does not take.
Harden SSH client¶
Do this to harden your SSH client:
- On your personal computer, in your user’s
~/.ssh/config
file, prepend the following lines, which will preempt the application of any similar configuration directives that appear later in the file. (See the ssh_config(5) manual page for more details and configuration options.)
# Make it easier to use Tor Onion services. Host *.onion ProxyCommand nc -x 127.0.0.1:9050 %h %p # If you prefer to use socat(1) instead of nc(1), use the following line instead: #ProxyCommand socat - SOCKS4A:localhost:%h:%p,socksport=9050 # If you use GitHub, you will need a special KexAlgorithms line. Host github.com KexAlgorithms diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1 Host * # Don't send extraneous identity keys (which leaks metadata about who you are during the SSH connection). IdentitiesOnly yes ChallengeResponseAuthentication no PasswordAuthentication no PubkeyAuthentication yes KexAlgorithms diffie-hellman-group-exchange-sha256 HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,ssh-rsa # The default macOS client prior to High Sierra 10.13.x only support a subset of the above HostKeyAlgorithms. # If you are using a macOS client, you may need to comment the above line and uncomment this one: #HostKeyAlgorithms ssh-rsa-cert-v01@openssh.com,ssh-rsa Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr # macOS clients only support a strict subset of the above Ciphers. # If you are using a macOS client, you may need to comment the above line and uncomment this one: #Ciphers aes256-ctr,aes192-ctr,aes128-ctr MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com # macOS clients only support a strict subset of the above MACs. # If you are using a macOS client, you may need to comment the above line and uncomment this one: #MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com # Protect against CVE-2016-0777. UseRoaming no # macOS users may want to store public key passphrases in their macOS Keychain facility: #UseKeychain yes # Clients may also wish to automatically load public keys into `ssh-agent(1)` upon use: #AddKeysToAgent confirm
- Generate (or re-generate) your client’s identity keys with strong values:
# Generate an RSA key with 4096 bits. Use the new SSH key format (`-o`), with 100 key derivation function rounds (-a). ssh-keygen -t rsa -b 4096 -o -a 100 # ED25519 keys are always saved in the new SSH key format. ssh-keygen -t ed25519 -a 100
- Copy your newly generated SSH public key to your user’s
~/.ssh/authorized_keys
file on the server, possibly usingssh-copy-id(1)
(or any file transfer mechanism). - Remove unhashed addresses from your
known_hosts
file(s):
ssh-keygen -H # If everything looks okay, then... rm -i ~/.ssh/known_hosts.old # ...delete the backup file created by `ssh-keygen`.
Apply application-level restrictions¶
Before you apply application-level restrictions, consider whether or not your use case requires access to a shell in the first place. If you can avoid creating an Operating System user account and providing a login shell entirely, you may be able to position yourself with a stronger security posture since you will never have exposed the possibility of gaining direct shell access to potential attackers in the first place. The rest of this section assumes you have already come to the conclusion that a shell provided by SSH is required.
Restrict allowed commands based on authorized SSH keys¶
TK-TODO: Use thecommand="…"
option in theauthorized_keys
file to restrict logins made with specific public keys to a specific command invocation.