Protect your privates!

Published: 2010-08-10
Last Updated: 2010-08-11 00:42:23 UTC
by Daniel Wesemann (Version: 1)
5 comment(s)

In view of all the brute force attacks still being attempted against Secure Shell (SSH), we have long since been extolling the virtues of forgoing passwords and moving to RSA/DSA keys instead.

While key based login indeed nicely addresses the problem of password guessing attacks, it looks like many a Unix admin has been less than diligent in the implementation. In pretty much every Unix security audit recently, we've come across unprotected or badly protected SSH private keys (id_dsa, id_rsa). Some reside plain flat out in the open, in /tmp and such. Others are found in world-readable tar "backup" archives of user and administrator home directories. Some are even built into home-grown Linux RPM and Solaris PKG packages, ready to be plucked off an install server.

It probably goes without saying, but let's repeat it nonetheless:

  • Whoever can access a TAR/ZIP/GZ archive, can read all its contents. Be super careful when you create a "temporary" archive copy of everything residing in a home directory. This copy is bound to include the ".ssh" directory, and the private keys therein
  • Whoever can access a RPM or PKG package, can read all its contents. Yes it is "convenient" to have the SSH keys that are part of your home-grown admin script suite already within the install package. But then don't be surprised if others make use of this convenience, too.

In a Unix penetration test within a company or academic institution network, we often first go looking for files and directories that can be read without authentication. Most large organizations have an "install server" from where they stage their new Unix systems, and often we find these install servers to openly share the package filesystem over NFS for"everyone". Other good choices are home directories, all too often also exported via NFS to "everyone". Once read access is established, we can go hunting:

$find /mnt/some_exported_fs \( -name "id_dsa" -o -name "id_rsa" \) -exec ls -ald \{\} \;
$find /mnt/some_exported_fs -type d -name ".ssh" -exec ls -al \{\} \;
$find /mnt/some_exported_fs -type f -name "*.tar" -print -exec tar tvf \{\} \; | egrep "(^/|id_dsa|id_rsa|.ssh)"

...etc. Adapt as needed for your environment.

To better protect your privates, please consider to

  1. add a passphrase for all private keys that are used interactively. "ssh-keygen -p" can be used to add a passphrase to an existing private key
  2. use a forced command for all private keys that are used in system automation, to limit the abuse potential. Use "command=/bin/foo/bar" in an authorized_keys file to limit what the corresponding private key can do

Keys without passphrase look differently from those that have one. If you want to make sure that your users also protect their privates, you can (as root) search for keys without passphrase with the following command

#find / \( -name "id_dsa" -o -name "id_rsa" \) -exec egrep -L "Proc-Type" \{\} \; 2>/dev/null

Newer DSA/RSA Keys contain the string "Proc-Type" as part of the key file when a password is set on the key. The above command lists all those key files where this isn't the case ("egrep -L")

If you got additional tips on how to protect SSH private keys on Unix, or how to best locate misplaced / unprotected private keys, please let us know.


Keywords: ssh
5 comment(s)


Whenever I read phrases like "the virtues of forgoing passwords and moving to RSA/DSA keys instead." I feel compelled to point out that while this is good for internal access to remote systems, if you're using using SSH to allow external access to your network, keys are, in my view, potentially a bad idea.

Once a private key you created has left your network, its owner can easily reset the passphrase to null and leave lying about on every computer they use and there's nothing you can do to stop or track this beyond telling the user not to do it. And as I don't trust users that much, I find passwords, where I can enforced changes, complexity and existence much more secure.
Its good to add:
umask 0077
to Your login scripts
Further restricting how these key can be used on your client systems is also wise. The authorized_keys file has may options that can be useful (e.g. no-pty, no-X11-forwarding, from="pattern-list" and the especially useful command="command") which are listed in the sshd man page.
I strongly believe that you should NOT make any login available to an untrusted IP in the first place. If you cannot get to the door you cannot get into the server(s) through it.

Lock down your SSH and any other remote access to trusted IPs only. This applies to inside nets as well. Keep an admin network range on a separate VLAN for administration of servers, routers, firewalls and switches. Those without a trusted IP don't get in.

I always use the KISS method. It just works!

Al is right. In addition to using keys, you should restrict the locations for users where possible. Using "AllowUsers <user>@<ip>" you can limit access on an individual basis. There's also AllowGroups. man sshd_config for more options.

Diary Archives