SSH Tricks Part II
This article is part two of SSH tricks, the first article is available at . In this article we will take a look at; public key authentication, building a list of known hosts using the “ssh-keyscan” utility to help defend against man in the middle attacks and installing the DenyHosts package to help defend against brute force attacks.
Public key authentication
Public key authentication is becoming very popular, the reason for this is because public key authentication provides stronger security over the traditional password authentication. Public key authentication provides a stronger security mechanism because two credentials are required to authenticate successfully. The first credential is a passphrase which is used to unlock the public and private key pair and the second credential is a public/private key which is require to authenticate against the SSH server.
Public key authentication with passphrase
In this section we are going to configure public key authentication with a passphrase. The command we will use to generate the public and private keys is the “ssh-keygen” utility, Figure 1 shows the command used to create a public and private key pair. Table 1 explains what each qualifier does.
damian@linux-c5jb:~> ssh-keygen -t rsa -v -C "Damian Myerscough" -b 4096 Generating public/private rsa key pair. Enter file in which to save the key (/home/damian/.ssh/id_rsa): Created directory '/home/damian/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/damian/.ssh/id_rsa. Your public key has been saved in /home/damian/.ssh/id_rsa.pub. The key fingerprint is: 37:2b:9c:ec:bd:63:18:9d:e9:0f:56:bd:95:82:3b:a6 Damian Myerscough
Figure 1: SSH public and private key generation.
The command shown in Figure 1 will create two keys within the “~/.ssh/” directory. The two files that will be created are “id_rsa” which is the private key and “id_rsa.pub” which is the public key, when performing public key authentication the “id_rsa.pub” file has to be on the remote host.
|-t rsa||This qualifier selects the type of encryption algorithm you would like to use. The two algorithms available are “RSA” and “DSA”.|
|-v||This qualifier enables verbose.|
|-C “Damian Myerscough”||This qualifier allows you to make a comment about the keys.|
|-b 4096||This qualifier specifies the number of bits which will be stored in the key. The default key size is 2048 bits.|
Table 1: ssh-keygen qualifiers explained.
Once you have successfully created you’re public and private key pair, you will need to copy the public key onto the remote host for public key authentication to occur. The command to securely copy the public key to the remote host is “ssh-copy-id“. Figure 1.1 shows the public key being securely copied to another machine.
damian@linux-c5jb:~> ssh-copy-id -i .ssh/id_rsa.pub firstname.lastname@example.org 15 The authenticity of host '192.168.2.140 (192.168.2.140)' can't be established. RSA key fingerprint is d5:74:15:49:a6:eb:d7:36:10:0d:e4:0b:7b:3b:8e:a9. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.2.140' (RSA) to the list of known hosts. Password: Now try logging into the machine, with "ssh 'email@example.com'", and check in: .ssh/authorized_keys to make sure we haven't added extra keys that you weren't expecting.
Figure 1.1: Securely copying the SSH public key.
Once you have copied the public key onto the remote host you can check to see if it was successful by SSHing into the remote host as shown in Figure 1.2.
damian@linux-c5jb:~> ssh firstname.lastname@example.org Enter passphrase for key '/home/damian/.ssh/id_rsa': Last login: Tue Jan 29 15:45:08 2008 linux-zc4s:~ #
Figure 1.2: Connecting to remote host and using public key authentication.
If you are not prompted to enter your passphrase then there has been an error in copying the public key to the remote host, you can check this simply by connecting to the remote host as normal and checking the “~/.ssh/authorized_keys” file exists and has your public key. Figure 1.3 shows the contents of the “authorized_keys” file.
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAgEAqagKwJcwdX/6zxa91bK1YRndN7QCVYyfZm8l11tVQYZ+rm98J3jH8mJp55MVEh+F/i4Xl6GGNcqrn5hcCeO/6iNlGGs+PkRjAc5VyFS5zC+n5GFQPFm+BGMOa0RBOav6EQt0y3udQlua3eA1zARchxjbKhpuEEK1nZHYyiBg9DTW+Z+goTFWkh/RngPYHmEoxKWZjrUQee8d0iWMJeBXlp12IrdRkc35GtOabkv4owZ3lnxSEKFkI0U8BWSB0Zx1/HKQfSBzwKyrNjxFf7frVEcHkQ1Nd/ggdfSHK9Mb7BpS2VoBbDl7hoV2sW6IDOwzFBHOHbFLKSVY157A21at39ckMA6BvY0QMSfqzT6g+X04bf5ICDvsBkVMRqA/Ye/xUcsr3YqgkV6pbUq0U9CNUwNV3izdYa3EzVfNy2cSQDdYLf2x/ZL0FCH73tsNa/n3ottljQtztqy+k15Qh7y4jZjYe08xkjQCPwVp3US69YjSWfHoB7sCYO34rgKm3B55Yu9zP//94VCZljlbdp+xOfPN6Hj9rvU0arNdZrpAgZwSjQhS5YGYCWReefL8keX6+U/Hy04Dmd+WTHR9PIEu5ti4Mf8ZsNrvn4RzD5kp6ztKLN51IudvhvThPCQbp6prntq8ulShJu1UKYxh0ugRcDzTO1/x++MHEAqW3iUthwk= Damian Myerscough
Figure 1.3: “authorized_keys” file contents.
The contents shown in Figure 1.3 is just one line but has been wrapped here because it was too long.
Public key authentication without password
Public key authentication without a password is almost identical to creating a public key with a passphrase, however, this time we will manually copy the SSH public key just to show you how else you can copy your SSH public key to a remote host.
The first step is to generate a public and private key, this can be done by using the “ssh-keygen” command as shown in Figure 1. However, this time when you are asked for a passphrase you can simply press enter and you will have a passwordless key.
Once you have successfully created a public and private key pair you can copy the public key to the remote host using the “scp” command as shown in Figure 1.4.
damian@linux-c5jb:~> scp ~/.ssh/id_rsa.pub email@example.com:~/.ssh Password: id_rsa.pub 100% 740 0.7KB/s 00:00
Figure 1.4: Securely copying the public key to the remote host.
Once you have successfully copied the public key to the remote host you will have to extract the contents from the “id_rsa.pub” file and copy it into a file called: “authorized_keys” as shown in Figure 1.5.
linux-zc4s:~/.ssh # cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
Figure 1.5: Adding the public key to the “authorized_keys” file.
Public key configuration
Once you are happy that you’re public key has been installed on the remote machine and you can authenticate using the key you can edit the “/etc/ssh/sshd_config” file to only permit public key authentication. The two directives that need to be modified are “PasswordAuthentication” and “UsePAM”, these two directives need to be set to “no” as shown in Figure 1.6.
PasswordAuthentication no UsePam no
Figure 1.6: SSH daemon configuration.
Once you have made the changes to the SSH configuration file you will need to restart the SSH daemon, this can be done by using the “service” command as shown in Figure 1.7.
linux-zc4s:~ # service sshd restart Shutting down SSH daemon done Starting SSH daemon done
Figure 1.7: Restarting the SSH daemon.
Once the SSH daemon has been restarted, public authentication will be the only method of authenticating.
Building a “known_hosts” file
In this section of the article we will look at building a list of know hosts using the “ssh-keyscan” command, you maybe wondering why you would want to build a list of know hosts. The reason for this is because when you build a list of know hosts you are able to notice changes to the servers public key thus allowing you to detect a man in the middle attacks.
In this article we will scan two machines for their public keys as shown in Figure 2, Table 2 explains what each qualifier does.
linux-zc4s:~/.ssh # ssh-keyscan -p 22 -t rsa,dsa 192.168.2.1, 192.168.2.2 > ~/.ssh/known_hosts # 192.168.2.1 SSH-2.0-OpenSSH_4.3p2 Debian-9 # 192.168.2.1 SSH-2.0-OpenSSH_4.3p2 Debian-9 # 192.168.2.2 SSH-2.0-OpenSSH_4.3 # 192.168.2.2 SSH-2.0-OpenSSH_4.3
Figure 2: Building a SSH “known_hosts” file.
|-p 22||This qualifier specifies the port in which to scan.|
|-t rsa,dsa||This qualifier specifies the types of keys you would like to retrieve, in this example we retrieve the RSA and DSA public keys.|
|192.168.2.1, 192.168.2.2||This is the list of IP addresses which will be scanned, make sure you have a space after each comma (,).|
|> ~/.ssh/known_hosts||This directs the keys into a file know as “known_hosts” which holds a list of known hosts.|
Table 2: “ssh-keyscan” qualifiers explained.
Once you have a list of known hosts you will be able to detect man in the middle attacks. If their is a server that has had its public key regenerated or some malicious user is trying to perform a man in the middle attack you will be notified with a message similar to Figure 2.1.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that the RSA host key has just been changed. The fingerprint for the RSA key sent by the remote host is ce:d1:73:28:79:35:15:0c:66:9a:58:e1:08:c6:d5:6a. Please contact your system administrator. Add correct host key in /root/.ssh/known_hosts to get rid of this message. Offending key in /root/.ssh/known_hosts:1 RSA host key for 192.168.2.1 has changed and you have requested strict checking. Host key verification failed.
Figure 2.1: SSH know_hosts notification.
The above message was produce by regenerating a servers public and private key pair. This message would also occur if malicious users were performing a man in the middle attacks too.
Defending against brute force attacks
In this part of the article we are going to install “DenyHosts”, this package is installed on more than 27,000 machines. The first step we need to do is download the “DenyHosts” package from  website and install the require dependencies. Table 3 lists the required dependencies which can be install using YaST.
|python-dev||This package includes files and libraries mandatory for building python modules.|
Table 3: DenyHosts dependency file.
Once you have installed the “python-dev” package you can begin to extract the “DenyHosts-2.6.tar.gz” archive as shown in Figure 3.
linux-c5jb:~/usr/src/DenyHosts-2.6 # python setup.py install
Figure 3: Installing DenyHosts package.
Once the installation has finished you will need to rename two files. The first file you will need to rename is “denyhosts.cfg-dist” to “denyhosts.cfg” and “daemon-control-dist” to “daemon-control“. The second step is to copy the “denyhosts.py” to the “/usr/bin” directory, once you have done that you can create the following directory “/etc/denyhosts” and copy the “denyhosts.cfg” configuration file into that directory.
Once you have moved the DenyHosts configuration file into the “/etc/denyhosts” directory you will need to edit the “denyhosts.cfg” file to suite your needs. In this article I will not explain the configuration file because it is already well documented, just make sure that the “SECURE_LOG” is set to “/var/log/messages“.
Once you are happy with your configuration you will need to edit the “daemon-control” file, Figure 3.1 shows the directives that need to be modified.
DENYHOSTS_BIN = "/usr/bin/denyhosts.py" DENYHOSTS_LOCK = "/var/lock/subsys/denyhosts" DENYHOSTS_CFG = "/etc/denyhosts/denyhosts.cfg"
Figure 3.1: daemon-control configuration.
Once you have edited the “daemon-control” file you can move the file into the “/etc/init.d” directory, once you have moved the file into the “/etc/init.d” directory you can rename it to “denyhosts” to make it more understandable. The next step is to add the “denyhosts” to the system service by using the “chkconfig” command as shown in Figure 3.2.
linux-c5jb:~/usr/src/DenyHosts-2.6 # cp daemon-control /etc/init.d/denyhosts linux-c5jb:~/usr/src/DenyHosts-2.6 # chmod 700 /etc/init.d/denyhosts linux-c5jb:~/usr/src/DenyHosts-2.6 # chown root:root /etc/init.d/denyhosts linux-c5jb:~/usr/src/DenyHosts-2.6 # chkconfig --add /etc/init.d/denyhosts
Figure 3.2: Configuring DenyHosts as a system service.
Once you have setup DenyHosts you can use the “service” command to start and stop the script as shown in Figure 3.3.
linux-c5jb:/etc/init.d # service denyhosts start starting DenyHosts: /usr/bin/env python /usr/bin/denyhosts.py --daemon --config=/etc/denyhosts/denyhosts.cfg
Figure 3.3: Starting the DenyHosts service.
Once you have DenyHosts running any previous offenders will be added to the “/etc/hosts.deny” file which will block their connections.
OpenSSH is an excellent package as it provides very flexible features to help manage you’re server securely. In this article we looked at the power of public key authentication which provides a much more secure method of logging into servers.