Thursday, February 16, 2012

Password-less Login Using SSH Pre-Shared Keys



Way back when I started working with Unix (otherwise known as "the olden days" or "days of yore"), one of the tricks we used was a concept known as "remote login" and the "Berkeley R commands". This was based on a number of things, most of them depending on either the /etc/hosts.equiv or the ${HOME}/.rhosts file to establish the trusting relationship. Configuring these would allow you the ability to do some really neat things. Among them, copying files from one host to another using a command like rcp /tmp/file user@remotehost:/tmp/file without being asked for a password. This made for some really neat scripting opportunities and made it much easier to manage multiple systems.

Unfortunately, the Berkeley "R" commands are notoriously insecure. The way that the trusting was done was based entirely on the username and hostname of the remote user on the remote host. Literally, you told the server to trust "jmorrow@remotehost.mydomain.com". The problem with this is that all that was required was knowledge of the trusting relationship. All you had to do was set up a machine named "remotehost.mydomain.com" and create a "jmorrow" user on it. Then you could go anywhere that that trusting relationship allowed.

Fortunately for us, the cool features that were introduced by the Berkeley "R" commands are implemented much more securely in the SSH protocol and toolset.

The SSH Protocol can use pre-shared keys to establish trusting relationships. In this case, each node has both a public and a private key. When the client talks to the server, the client offers a " key". The server, which maintains a list of trusted "public keys", then compares that key to it's database to determine if it actually trusts the client. If the client passes the test, then it is allowed in without any further challenge. This can be very useful for administrators, automated file transfer, also for scripting interactions between hosts. Note that this is not a "Machine A" trusts "Machine B" relationship. It is "user@machinea" trusts "user@machineb".

For the purposes of this article, the "server" is the node that you are logging into from the "client". So, the "server" is the one that is doing the trusting. The terms "server" and "client" refer only to the role being played by each component in the ssh communications session. I should also mention that Oracle Real Application Clusters (RAC) depends on this relationship as well.

Generate your public/private key pairs [Both Client and Server]

The server (user@host) needs to have one, and each client (user@host) that is being trusted needs to have one.

Execute these two commands (in a Unix/Linux environment) to create both your rsa and your dsa keys. You will be prompted for a location to store the files (typically under ${HOME}/.ssh), and for a passphrase. In all cases, it's ok to accept the defaults.

ssh-keygen -t rsa
ssh-keygen -t dsa

If you know you don't want to use a passphrase, you could generate the keys with these two commands:

ssh-keygen -t rsa -f ${HOME}/.ssh/id_rsa -N ""
ssh-keygen -t dsa -f ${HOME}/.ssh/id_dsa -N ""

Transfer the public key files from the client to the server

I prefer to make sure that I have a uniquely named copy of the public keys (makes it easier to transfer to another box when first establishing the relationship).

cd ${HOME}/.ssh
ls -1 id_[dr]sa.pub |while read LINE
do
cp ${LINE} ${LINE}.`whoami`@`hostname -s`
done

Now copy these files to the server:

scp ${LINE}.`whoami`@`hostname -s` trustinguser@trustingserver:.ssh/.

Copy the public keys you're trusting into the authorized_keys file

Here, we'll need to put those keys into the authorized_keys file. Do this for each of the files that you transferred in the previous step.

cd ${HOME}/.ssh
cat >> authorized_keys

Make sure permissions are correct

If the permissions on these files are too open, the trusting relationship will not work. Here are my recommendations:

chmod 600 ${HOME}/.ssh/auth*
chmod 700 ${HOME}/.ssh
chmod 644 ${HOME}/.ssh/id_[dr]sa.pub*
chmod 600 ${HOME}/.ssh/id_[dr]sa

Now, you should be able to ssh from the client to the server witout being prompted for a password.

James

No comments:

Post a Comment