What are possible security issues with an SSH daemon?

I'd like to be able to SSH to my Ubuntu 10.04 office PC from the outside. I am thus thinking to start up an SSH daemon on the PC. What are the security issues, possible glitches, specific configuration settings, etc. I should be aware of?

In case it matters: this is essentially for my own use only, I don't think there will be other people using it; it's an Ubuntu 10.04 PC in a mostly Windows 7/Vista/XP environment.


The biggest concern would be people logging in as the computer's administrator over SSH. This can be done by brute force if you have an easy to guess password.

There are several safety measures that you can take, below are some of the ones I always take when setting up an SSH server and some extra.

  1. Use a strong password, consisting of at least (say) 10 upper- and lowercase letters, numbers and other characters.

  2. Jail users to their home directory. Jailed users will not be able to access/edit files that are outside their home directory. So your user will not be able to access/edit key system files. Lots of tutorials can be found online on how to jail a user. Most of them use JailKit. An example of such a tutorial can be found here. Alternatively, you can also use the OpenSSH-server's native ChrootDirectory directive. An example of a tutorial on this can be found here.

  3. Install Fail2Ban. Fail2Ban is a program that checks the authentication logs for wrong entries. When a certain limit is reached, it adds a firewall block for that certain IP for a preset amount of time. There are also several online tutorials found online about how to set up Fail2Ban with SSH, an example would be this one. The Fail2Ban homepage holds some nice and complete HOWTOs as well.

  4. Disable root login through SSH. This is the user that has access to pretty much every file on your system, disabling its shell login is therefore recommended. In the latest versions of Ubuntu, the root user is automatically disabled but it doesn't hurt to disable its SSH access anyway. This is done by editing the file /etc/ssh/sshd_config. Look for the following line and make sure there is no # in front of it.

    #PermitRootLogin no
    
  5. Use a non-standard port (E.g. not 22) This is either done through port forwarding in your router (E.g. 16121 -> 22 instead of 22 -> 22) or by making the SSH daemon listen on a different port. This will make your SSH service less easily detectable to malicious users. This is done by editing the file /etc/ssh/sshd_config. Look for the following line and change 22 to whatever port you want. Don't forget to forward the correct port in your router afterwards.

    Port 22
    
  6. Do not use passwords to log in. Besides passwords, SSH also allows login by the use of private keys. This means a key is stored on your computer on which you access the SSH of the SSH machine. When a connection is attempted, the SSH client uses the key to login to the server instead of through password authentication. Authentication keys are a lot stronger cryptographically than passwords are and therefore not so easy to crack. There are also several online tutorials found online about how to set up Key based authentication with SSH, an example would be this one. (If you SSH from windows with PuTTY, check this link for a PuTTY howto.) After you've set up the key-based authentication, you can disable the password authentication by editing the file /etc/ssh/sshd_config. Look for the following line and make sure there is no # in front of it.

    #PasswordAuthentication no
    
  7. Optionally, as @Linker3000 mentioned in his comment, you could set up a VPN tunnel to the PC you want to access through SSH and then disallow non-local network access on the SSH server. That way, no external device without a VPN connection will be able to access your SSH server. This can be done by denying ALL hosts and then allowing only the local network IPs to login. This is done by editing /etc/hosts.deny and add the following:

    sshd: ALL
    

    and to /etc/hosts.allow add the following:

    sshd: 192.168.1.*
    

    where the IP matches the one of your local network. * is a wildcard, so all IP addresses starting with 192.168.1. will be accepted. If this doesn't work, your distribution might use ssh instead of sshd. In that case, you should try ssh: 192.168.1.* and ssh: ALL instead.

  8. You could only allow specific hosts, do the same with the /etc/hosts.allow and /etc/hosts.deny as described in 6, but in /etc/hosts.allow add the following line and every host to allow separated by spaces:

    sshd: {IP OF HOST TO ALLOW 1} {IP OF HOST TO ALLOW 2} {IP OF HOST TO ALLOW 3} {ETC.}
    
  9. Allow only specific users to access your SSH server. This is done by editing the file /etc/ssh/sshd_config. Look for the following line and make sure there is no # in front of it. If it doesn't exist, create it. For example, if you want to allow john, tom and mary only, add/edit this line:

    AllowUsers john tom mary
    

    You could also deny specific users for example, if you want to deny access to john, tom and mary, add/edit this line:

    DenyUsers john tom mary
    
  10. Only allow protocol SSH2 for incoming connections. There are two versions of the SSH protocol. SSH1 is subject to security issues so using SSH 2 is recommended. This can be forced by editing the file /etc/ssh/sshd_config. Look for the following line and make sure there is no # in front of it. If it doesn't exist, create it.

    Protocol 2,1
    

    remove the ,1 so the line will be

    Protocol 2
    
  11. Don't allow users to login that have no password set. This can be forced by editing the file /etc/ssh/sshd_config. Look for the following line and make sure there is no # in front of it. If it doesn't exist, create it.

    PermitEmptyPasswords no
    
  12. And although simple and perhaps needless to say but proven crucial in multiple cases, keep your software up-to-date. Regularly update your installed packages/software.


= after having edited the SSH config file, don't forget to restart the daemon to apply changes. Restart the daemon by executing:

sudo /etc/init.d/ssh restart

or

sudo /etc/init.d/sshd restart

depending on which distribution of Linux you are using.


A few tips:

  1. Use Key based authentication, which is WAY more secure than passwords
  2. SSH 2 only
  3. Disable Root logins
  4. For the paranoid, change the port from the standard port 22
  5. For convenience, use a tool to map your IP to a DNS name, like Dyndns or its ilk. You can go a long time with the same IP, but that one time your traveling and need it, you'll find you got issued a new one.
  6. Of course, only allow the port needed for SSH (port 22, or a non-standard if you choose) through your firewall.

The main risk is forgetting that you're running an ssh server and putting a weak password on an account. There are attackers out there that systematically try common account names (like webmaster and bob) and weak passwords. You can eliminate this risk by forbidding password logins (put PasswordAuthentication no in sshd_config, and either also put UsePAM No or disable password authentication in the PAM settings for ssh). An intermediate measure is to restrict ssh logins to a whitelist of users with AllowUsers or AllowGroups in sshd_config.

Note that allowing password logins is not in itself a security problem. Weak passwords and snooped passwords are the problems, and allowing password authentication in the ssh server is an enabler. To protect against password snooping, never type your password on a machine you don't fully trust (but then if you do trust a machine you might as well install a private key on it, and then you don't need password authentication).

The minimum requirement to use an ssh client on a machine is that you trust that there won't be an active hijacking of the ssh communication (a man-in-the-middle attack is possible if it's running on the client machine — you think you're typing commands into a pristine ssh client but the client is in fact transmitting your authentication data faithfully but also inserting a trojan horse into the communication afterwards). This is a weaker requirement than trusting there won't be a password snooper (usually performed through a keylogger, but there are other less automated methods such as shoulder surfing). If you do have the minimum trust but still fear snoopers, you can use one-time passwords (OpenSSH supports them through its PAM support).

Of course, as any other program that interacts with machines outside your control (not just network servers but also clients), you must keep up with security updates.


Three things came across my mind:

  1. If you open default port 22 then pretty soon it will get detected and your PC will be hammered by brute force attacks. I suggest you configure sshd to listen to some other port or do port mapping on your firewall. While this is not a magic bullet it will sure save you same CPU cycles at least.

    Port 12345

  2. Explicitly disable password authentication and use keys only. Any key will be better than the most complex password you can remember.

    PasswordAuthentication no

  3. Even though Ubuntu has root user disabled by default, explicitly disable root login

    PermitRootLogin no