September 18th, 2007
Scrutinizing SSH
In my previous post titled Bolting on Security, I mentioned that port 22 is generally not scrutinized as much as 445 when being allowed through a firewall. Obviously the situation varies from incident to incident, but I wanted to say that port 22 really should be looked at more closely. All is not always roses and peaches when you allow port 22, but I am going to explain some of the saving graces of SSH that can make it less threatening in some hairy situations.
The Threats
Let us first start with what is wrong with allowing SSH through a firewall. Then we will address each problem one by one. The problems are:
- Buffer overflow bugs have led to system compromise.
- Shell access can often be obtained when none is necessary.
- SSH supports weak forms of authentication—like passwords.
- SSH allows the forwarding of connections between the client and the server.
- SSH helps facilitate X11 forwarding, allowing graphical programs to run remotely.
Buffer Overflows
This is your greatest threat to giving up root access to your server, but fortunately there is something you can do to reduce the risk of break-in to negligible levels. That something is to turn on privilege separation. The only SSH daemon that supports privilege separation is OpenSSH and its more recent derivatives. Fortunately, OpenSSH is a full featured SSH server so even if you are not using it, you should be able to switch to it without much difficulty.
Note that despite Sun SSH being a derivative of OpenSSH, Sun has chosen not to implement privilege separation and thus you would need to replace it. I have badgered people at Sun about this. I can tell you they had a reasonable excuse for omitting it from Solaris 9, but they really dropped the ball with Solaris 10. I hope they can do better for Solaris 11. Your mileage may vary on other operating systems, but the free ones generally use OpenSSH by default.
The reason privilege separation is so good is that it causes the majority of the SSH server code to run with no privileges in a chrooted jail. The little bit of SSH that runs with full root privilege is scrutinized much more closely by the OpenBSD team and security researchers, so it is considered very safe. I do not know of any exploitable vulnerabilities ever found in the privileged code after OpenSSH introduced privilege separation a few years ago (though I may have missed one).
To activate it, create an sshd user (the unprivileged account) and a /var/empty directory (the jail). Then set the UsePrivilegeSeparation
option to “yes” in sshd_config and restart your server. You can test if privilege separation is active by looking at your process list after you connect. When privilege separation is in use there will always be two extra processes for each SSH connection, one privileged owned by root, and one unprivileged owned by a regular account (authenticated user) or the sshd account (unauthenticated user). Without privilege separation there is always just one extra process per connection.
Since you need to be using OpenSSH or a derivative to use privilege separation, I will assume you are using it for the rest of this post.
Shell Access When None is Necessary
Sometimes you only want to give someone the ability to transfer files via SCP or SFTP, two protocols that use SSH. Traditionally you have to give full access to a shell to allow only file transfers with SSH.
One solution that has been around for quite some time is a program called scponly. You use scponly as the default shell for “file transfer only” accounts, and it disallows command line and command access. This program has previously had a few security problems that has occasionally allowed an authenticated user to “break out” into a shell, but overall has been very good. The maintainers take its security seriously.
Password Authentication
Password authentication is great if you—oh who am I kidding!? Password authentication is bad, and if you are trying to keep things apart by a firewall and there is a good chance that an attacker will start trying out passwords against your open port, then you better have something better than password authentication protecting the accounts.
SSH can be configured to disallow password authentication and require stronger credentials. Just set the PasswordAuthentication
option to “no” and those pesky little weak passwords will not be a problem. Of course you will need to set up something else, such as SSH keys, Kerberos, or a challenge-response mechanism. If you are in a high-security situation, you should consider using some form of two-factor authentication.
Support for Forwarding Connections
SSH can be used to forward connections, effectively bridging two networks to a limited extent. If you are scrutinizing the security of an SSH server on the other side of a firewall, you will want to turn this off. Do so by setting AllowTcpForwarding
to “no”.
However, perhaps there is one port in particular that you do want to forward with SSH through your firewall. This could be used to encrypt an insecure channel as it travels over an untrusted network, or it can allow an “outsider” to connect to a service inside your firewall. Whatever the reason, you have a means of limiting what is allowed through at the server side. This is done with the PermitOpen
option on newer versions of OpenSSH—it can be used to limit what target systems and ports the server allows clients to forward to. Even if you have full control of the client system, it always helps to add a layer of security on the server side, too.
Support for Forwarding X11 Displays
When it was released in the mid-90s, one of the biggest problems facing Unix users was how to run their X11 graphical applications securely. The security of an X program was usually dependent on weak host-level security, and as a result anyone with a login on the system with the X client (the program) could also run an X client to snoop or annoy the user. There was also a cookie-based authentication available, but it was difficult to teach users how to use it.
Along came SSH, and not only did it replace Telnet by providing a secure shell connection, it also provided a means to automatically configure the cookie-based authentication for X11 and forwarded the traffic over the encrypted channel. Good for you when connecting to your company server internally. Bad for you when you do not fully trust a user or an account that needs access to the system through a firewall.
This one is easy to disable, too. Just set the X11Forwarding
option to “no”.
Summary
Do not be afraid to allow SSH through your firewall, but take reasonable precautions and know your SSH server. Know how to disable the features you do not need. Get the SSH client to use the strongest form of authentication available. Read the man pages for ssh_config and sshd_config and be familiar with many of their options. Someday, when you need to boost the security of a connection somewhere, you will be glad you did.