Securing OpenSSH

If you are a systems administrator of one or more Linux/UNIX systems, OpenSSH is likely one of the most important tools in your toolbox.
OpenSSH can be used interactively or embedded in scripts to provide
secure remote access and file transfer between systems. But, alas, danger
lies ahead. With OpenSSH, it is perilously easy to create sloppy trust
relationships or, worse, leave yourself open to common automated attacks.

Basic Security

One of the basic tenets of system security has always been to run only
the minimum required services and limit their access only to those
who need it. Linux systems make this pretty easy to do, and like most
things in the *nix world, you can do it in a number of ways. If you're
still reading this article, we assume you need to run
OpenSSH. Let's work on limiting access.

On most Linux distributions, you
have the choice of handling this at the kernel firewall level or using TCP
Wrappers (/etc/hosts.{allow|deny} files).

iptables

A simple iptables firewall
rule to limit OpenSSH only to your local subnet could be:

This tells the kernel to reject any TCP/IP packets not coming
from a specific subnet aimed at port 22. (Substitute your own
numbers as needed.) In all likelihood, you will have additional iptables
rules to protect other applications on this system, so integrate the
above into your overall firewall design.

TCP Wrappers

TCP Wrappers is a common feature on most Linux distributions, and OpenSSH
has built-in support. To implement the same rule above using TCP
Wrappers, add the following line to your /etc/hosts.deny file:

sshd: ALL EXCEPT 192.168.0.0/255.255.0.0

For most situations, it is very unlikely that OpenSSH needs to be dangling
out for the world-wild Internet to poke at. Further, it is unlikely
that OpenSSH even needs to be available to your entire organization.
I highly recommend that access be limited, using either of the above
methods, to the smallest audience possible. One common method is to
designate one or more systems specifically for the purpose of centralized
administration. Configure the rest of your systems to accept
OpenSSH connections only from these dedicated and highly secured systems.

To test whether you have limited access to OpenSSH successfully, you can try
to connect using an ssh client, or simply connect to the system using a
command-line telnet client, for example:

$ telnet mylinuxbox 22

where mylinuxbox is the hostname, and 22 is the port.

If OpenSSH is responding and open, you should see something like the
following:

SSH-1.99-OpenSSH_3.9p1

If it is successfully blocked, the connection will be refused. Try this
from multiple locations, and confirm that connections are blocked as
you expect.

Avoiding Automated Attacks

Over the years, OpenSSH has had a few remotely exploitable vulnerabilities
due to bugs. These always have been fixed quickly, with updated
versions distributed promptly. Unfortunately, a lot of networked systems
are not updated. Also, many systems simply are poorly secured.
Standard accounts with simple or blank passwords are depressingly
commonplace.

All of these are tantalizing targets for crackers and worm authors.
A number of malicious worms exist that scan for any
SSH servers and then try common vulnerabilities and passwords. If you must
have your OpenSSH port open to the world, consider changing its TCP port
number. This can be accomplished by changing the Port directive in
the sshd_config file, which is commonly in /etc/ssh/. Although any live
person trying to crack your systems would likely have little difficulty
detecting this, it is usually enough to escape the attention of large-scale automated attacks and worms.

Also, you might consider rebuilding your OpenSSH from sources after
modifying the version string. This also can help confuse automated
attacks, because many vulnerabilities are dependent on specific versions
of OpenSSH. This is done by modifying the version.h file in the OpenSSH
distribution and recompiling. Change the SSH_VERSION and SSH_PORTABLE
#define lines to anything you like, such as:

#define SSH_VERSION "MyCompany_Vers00001"
#define SSH_PORTABLE "foo"

After changing the sources, build and install. This changes the
version banner shown in the above telnet test.

Changing the port and version string does
nothing to improve security; they simply reduce the risk of being the
victim of a common exploit or worm. There is no substitute for securing
accounts and making sure your systems are running the latest patch
levels of software. If you are using Linux, use a current distribution.
Use automated update tools like yum, apt or up2date to keep your system
running the latest version of all software and libraries including
OpenSSH.

You can confirm that users are selecting good passwords
by using a cracking tool like John the Ripper (see the on-line Resources). John
the Ripper (JTR) uses the one-way encrypted passwords in /etc/shadow
to try to crack passwords. Generally speaking, easier passwords
cracked by JTR are more likely to show up in a brute-force
dictionary attack commonly used by some worms. JTR supports a wide
range of input file formats for those using LDAP, NIS, AFS Kerberos
and other authentication services.