Good fences make good neighbors.

Robert Frost, Mending Wall

Locking down SSH

10 January 2009

Although ssh is far more secure than telnet, it is also subject to exploits. Even so, it can be made more secure than it is in it’s default distribution. Here’s what I do to make ssh for Mac OS X less subject to being hacked. Much of this is based on an article originally published at The instructions are involved, but you’ll just need to set this up once and then you’ll be running secured.

Suppose you have one computer that you want to log into remotely (say, your office computer) from another computer (say, your laptop). The computer you would like to log onto remotely, the office computer, is known as the Server, and the computer that you will be logging in from, the laptop, is known as the Client.

1. In the Terminal on the Server, type

mkdir ~/.ssh

to create the directory that will hold the file containing the public keys (authorized_keys) that we make below, as well as the list of known hosts (known_hosts), which is updated when someone successfully logs in.

2. On the Server, open Preferences ... Sharing ... Services and check Remote Login. Verify that it starts and record the address that appears at the bottom (ssh username@location). This will start the ssh daemon.

3. In the Terminal on the Client, type

ssh-keygen -b 1024 -t dsa

When asked for where to store the key, press enter to accept the default location. When asked for a passphrase, enter a strong passphrase.

It is also possible to create an RSA key, which can be of longer length than a DSA key. I have been unable to find any definitive statements about which is more secure. However, RSA is apparently limited to ssh protocol 1, whereas DSA is required for ssh protocol 2. Since protocol 1 will be disabled below, we will use DSA. DSA is currently limited to 1024 bits.

4. In the Terminal on the Client, type

scp ~/.ssh/ username@serverip:~/.ssh/authorized_keys

on one line, replacing username and serverip with the address given above on the Server. This copies the public key to the server and creates a new authorized_keys file, or overwrites it if it already exists. To have multiple keys on one computer, you'll need to append the new key to the authorized_keys file (see below).

5. In the Terminal on the Server, type

sudo pico /private/etc/sshd_config

Search for each of the following keywords below (use ctrl-W if using pico) and edit the lines to appear as shown below. In particular, make sure the yes or no is correctly chosen and make sure the comment symbol (#) is removed from the beginning of each of these lines. Below each line that you need to type is an explanation in oblique type, which you should not enter.

PermitRootLogin no

Prevents anyone from logging as root

PasswordAuthentication no

Disables logging in by passwords, thereby forcing use of public/private key pairs. Prevents brute-force password guessing.

PermitEmptyPasswords no

Prevents the ability to log in without a password

PubKeyAuthentication yes

Allows the ability to log in with a public key

RSAAuthentication no

Disables RSA authentication

RhostsRSAAuthentication no

Disables host-based authentication

ChallengeResponseAuthentication no

Disables challenge-response types of authentication

UsePAM no

Disables PAM authentication

StrictModes yes

Insures the strict use of file permissions on the key file and home directory

LoginGraceTime 30

Allows only 30 seconds to authenticate, instead of the default 2 minutes. Slows down a person trying to guess, but won't affect a script attack.

KeyRegenerationInterval 1h

Makes sure that the server key used for encryption is changed frequently. If someone is listening, this will limit the amount of data they can use for cracking the encryption.

ServerKeyBits 768

Makes sure that the encryption key is long enough to make cracking the encryption difficult.

Protocol 2

Disables SSH protocol 1, which is known to be insecure

AllowUsers username

Replace username with your username. This allows only the listed users to log in. Someone trying to break in would have to first learn the names of the users on the machine.

LogLevel INFO

Increases the amount of logging information, so that failed attempts can be recognized

MaxAuthTries 3

Slows down brute-force attacks.

IgnoreRhosts yes

HostbasedAuthentication no

RhostsAuthentication no

All three disable various forms of host-based authentication.

AllowTcpForwarding no

X11Forwarding no

Turns off forwarding for these; should be enabled only if needed

Port 1618

You can use any number besides the default port of 22, provided that port is not in use. Some argue that this is just security through obscurity and is really no help compared to other security measures. It does help to hide your machine from at many automated break-in scripts.

Save the file (If using pico, type Ctrl-O, then Return) and exit (Ctrl-X in pico.)

6. On the Server, go to Preferences ... Sharing ... Services, turn off remote login and turn it back on.

7. In the Terminal on the Client, type

sudo pico /private/etc/ssh_config

Search and edit the following lines to match, as was done on the server:

RSAAuthentication no

PasswordAuthentication no

Save the file (Ctrl-O, then Return) and exit (Ctrl-X)

If you would like to do tunneling to a different server that has only password authentication, you will need to change this line on the Client to (although it renders the Client less secure):

PasswordAuthentication yes

8. Restart the Client. At this point, you are running a secure ssh server. If you don’t need to add any additional users, you can stop here.

9. To allow an additional user to ssh into their account on the Server, do the following:

a. In the Terminal on the Client, type

ssh-keygen -b 1024 -t dsa

When asked for where to store the key, press enter to accept the default location. When asked for a passphrase, enter a strong passphrase.

b. On the Client, copy the file ~/.ssh/ to a USB stick. Insert the USB stick into the Server while logged into the user's account and copy this file from the USB to the user's account as ~/.ssh/authorized_keys

c. On the Server, type

sudo pico /private/etc/sshd_config

and add the user name at the end of the line AllowUsers username, with no comma separating the existing user name and the new user name

d. On the Server, go to Preferences ... Sharing ... Services, turn off remote login and turn it back on.

e. The new user should now be able to log onto the Server.