Hacking Linux Exposed





previous article
next article
Secure Passwordless Logins with SSH Part 2
By Bri Hatch.

Summary: How to create passwordless logins to allow remote administration tasks securely with SSH - setting up your SSH identities.

Setting up your accounts to allow identity-based authentication gives you several new options to allow passwordless access to those accounts. The end goal is to allow passwordless access that can only run specific commands, rather than full fettered login ability, but we'll start with the more general solution as our first step.

To enable identity-based authentication, you must first create an SSH identity. An SSH identity is simply a private/public key pair, which are similar in functionality to to PGP keys, or SSL keys and SSL certificates. You place a copy of the identity public key into the file $HOME/.ssh/authorized_keys on any account you wish to enable access using this key. You keep the private key on the SSH client machine - your laptop, personal workstation, etc. When you connect from your client, the ssh program will offer to use identity-based authentication for each key it has available. If the server sees the public key in $HOME/.ssh/authorized_keys, it tells the SSH client to prove that it has the private key and if the client can meet the challenge, the access is granted.[1]

For the remainder of these articles, I'll assume you are using a recent version of OpenSSH, 3.4p1 or better.[2] So, let's make a test key:

  $ cd $HOME 
  $ mkdir identity-test
  $ cd identity-test
  $ ssh-keygen -f id_rsa -t rsa
  Generating public/private rsa key pair.
  Enter passphrase (empty for no passphrase): <enter>
  Enter same passphrase again: <enter>

  Your identification has been saved in id_rsa.
  Your public key has been saved in id_rsa.pub.
  The key fingerprint is:
  c3:af:e9:6c:2f:19:4d:b5:1a:a9:40:06:54:e6:60:08 jdoe@localhost

  $ ls
  id_rsa     id_rsa.pub

There are two major versions of the SSH protocol, SSH1 and SSH2. An SSH identity is tied to a specific SSH protocol version, so you need to decide on which protocol to use and pick an appropriate identity format from that. Most clients default to using the SSH2 protocol, however you can explicitly pick which protocol to use by adding a -1 or -2 option to your ssh command line, which will select SSH1 or SSH2 respectively.

An SSH identity comes in three formats:

TypeCommand line argsProtocol
RSA1-t rsa1SSH 1 protocol only
RSA-t rsaSSH 2 protocol only
DSA-t dsaSSH 2 protocol only

With the ssh-keygen listing above, we created an RSA key by using the -t rsa option, thus this is an SSH2 protocol identity (so we might want to add -2 to our command line just to be explicit). The identity is stored in two parts. The private key is in id_rsa and the public part is in id_rsa.pub.

For sake of argument, I'll assume we're using the SSH2 protocol, and include -2 on the command lines just to be verbose.

Important Note:
When you create an SSH identity, you can 'encrypt' your private key. If the server allows you to authenticate with this key, your SSH client will ask you to decrypt the key so it can use it. This is a good idea for identities - otherwise anyone who can read the file (for example the root user on your system) can use it to authenticate as you. (You can protect your key file with a passphrase while making it possible to use it without typing the passphrase each time using ssh-agent, but I won't get into that here. If you're interested in this, you might want to try using Keychain as well, as it makes identities more manageable.)

Now in our case, we will be putting restrictions on this key such that it cannot do anything except the commands we will allow, from the hosts we allow. Thus it's easiest to create the key with no passphrase, and let paranoid file permissions handle the security of the key. I'll show a quick way to easily handle passphrase-protected keys at the end of our journey, but for now let's stick to passwordless keys.

So, now it is time to tell the remote account that we trust this test key. You need to include the public key (id_rsa.pub) in the file $HOME/.ssh/authorized_keys on the remote account. You can do this in several ways.

Believe it or not, my standard method. Log into the remote account, open up $HOME/.ssh/authorized_keys with your favourite editor[3] and paste it at the end of the file.

If you don't have a $HOME/.ssh/authorized_keys file on the remote system, you can simply copy the id_rsa.pub to it directly:

  local$ ssh username@server 'mkdir .ssh'
  password: (type password for username@server)
  local$ scp ~/identity-test/id_rsa.pub username@server:.ssh/authorized_keys
  password: (type password for username@server again)

The SSH server is paranoid, and will refuse to honour your authorized_keys settings if they have poor file permissions, so you should lock down your files and directories:

  username@server$ cd $HOME
  username@server$ chmod go-w .

  username@server$ cd $HOME/.ssh
  username@server$ chmod 700 .
  username@server$ chmod 600 *

So, let's test logging in with this key. Since we have put the test key in a non-standard place, we will need to reference it explicitly on the command line:

  local$ ssh username@server -i $HOME/identity_test/id_rsa
  username@server$ hostname
  username@server$ exit

  local$ ssh username@server -i $HOME/identity_test/id_rsa "echo Success!"

In the first example we logged into the server interactively, while in the second we ran the echo command on the server, never logging in for real. Neither time did we need our Linux password, or an identity passphrase. Right now we've set up trust that would allow someone with this key to log in or run any commands on this server account from anywhere.

If you're having trouble getting this to work, you should check the server logs and see if it provides any insight, as well as running ssh with the -v flag. It's possible the server does not allow identity authentication - check /etc/ssh/sshd_config on the server for entries such as the following:

  # Allow Identity Auth for SSH1?
  RSAAuthentication yes
  # Allow Identity Auth for SSH2?
  PubkeyAuthentication yes

When you're done testing this, you should delete the entry from ~/.ssh/authorized_keys on the server. Next week we'll set it up to be usable only from your designated machines, and only be able to run authorized commands.

If you're interested in setting up seamless identity authentication without the limits we'll be setting up, you may want to check out two pieces of software:

William Sterns maintains a program called ssh-keyinstall, available at http://www.stearns.org/ssh-keyinstall that helps you create and install your SSH identities on your remote servers.

Keychain by Daniel Robbins and available at http://www.gentoo.org/proj/en/keychain.xml helps you set up per-host ssh-agents automatically. By having a single ssh-agent with decrypted copies of your identities, you can have passwordless identity authentication while leaving your identities encrypted on disk. Robbins has a detailed description of how you use Keychain, and several extensive series of articles about SSH Identity authentication available through IBM DeveloperWorks linked from the Keychain page.


[1] The server and client go through a bit of mathematical rigamarole to prove that the client possess the secret key. The specifics aren't material to this discussion, If you want more information, check the SSH man pages, RFC, or the SSH book by O'Reilly.

[2] Earlier versions of OpenSSH required you distinguish between SSH1 and SSH2 protocols (the latter needed to have keys placed in $HOME/.ssh/authorized_keys2.) SSH.com's version of the SSH server and client have the same functionality as OpenSSH, but implements things in a very different way.

[3] vim, naturally.

Bri Hatch is Chief Hacker at Onsight, Inc and author of Hacking Linux Exposed and Building Linux VPNs. He's been using SSH to secure his remote logins since Tatu posted the first version of the code - even if the administrators of those machines refused to install it for him. Bri can be reached at bri@hackinglinuxexposed.com.

Copyright Bri Hatch, 2002

This is the December 26, 2002 issue of the Linux Security: Tips, Tricks, and Hackery newsletter. If you wish to subscribe, visit http://lists.onsight.com/ or send email to Linux_Security-request@lists.onsight.com.

previous article
next article