Wednesday, March 17, 2010

SSH Without Password

SSH login (and sftp) is a secure and convenient method of accessing data and services on remote computers. Sometimes we want to automate the secure log in. Since normally a SSH log in requires a password that corresponds to the user account on the remote computer, using SSH from a script presents a problem. Public/private certificates to the rescue!

Suppose we have a server that we want to access from scripts on two different computers. These scripts are executed periodically by cron jobs. We want to enable a no-password log in from those two computers while requiring a password SSH log in for all others. To do this, we must create a public/private key pair for each of the computers we wish to grant no-password log in privileges. The public key from each of these computers is then shared with the server we want to access. This cryptographically links the two local computers to the remote server.

The storage of these keys on both the local and remote computers is specific to user accounts. For example, suppose we have a local user account named 'getsoh' (get state of health). Every five minutes a cron job triggers a script belonging to the getsoh account that retrieves (using sftp or scp) a log on the remote server that is owned by the user 'createsoh'. We want to create the public/private key pair as user getsoh on the local computer and share the public key with the user createsoh on the remote computer. This is easy to do.
  • On the local machine as user 'getsoh', ensure that the ~/.ssh folder exists. If not create it (type: mkdir ~/.ssh). Ensure that ~/.ssh permissions are 0700.
  • Type: ssh-keygen -t rsa (accept all default settings, including an empty passphrase)
  • Two files (id_rsa and id_rsa.pub) should now be in your ~/.ssh folder.
  • On the remote machine as user 'createsoh', ensure that the folder ~/.ssh exists.
  • Copy the public key to the remote server (ex: remote.com) and append to the ~/.ssh/authorized_keys folder of user 'createsoh'. Type: cat ~/.ssh/id_rsa.pub | ssh createsoh@remote.com  'cat >> ~/.ssh/authorized_keys'
  • Remember to append to rather than overwrite the authorized_keys file in case other keys already are stored.
Remember that creating keys with an empty pass-phrase is a security risk. If someone were to retrieve your private key, they could use that to log in to the remote computers. The use of ssh-agent partially solves that risk by allowing you to use a non-empty pass-phrase and enter it only once, after which it is then cached for the duration of the session. This approach, however, cannot be used when ssh access is needed from a script run periodically by cron.

If the private key is stolen from the client, an unauthorized user will be able to login to the server hosting the public key. To minimize the risk of this occuring, an additional check can be placed in the public key on the server. At the very front of the key in the authorized_keys file, insert: from="client.net", where client.net is the client computer hostname or IP address. Wildcards are supported (i.e. *.clients.net). Multiple hosts/addresses can be used if separated by a comma. Make sure you put double quotes around the host/ip addresses.

If the only purpose of the ssh log in is to automatically run a script, additional restrictions can be defined that will increase security. Let's say that periodically, the client remotely accesses the server through ssh to copy a log file to a shared folder. Expanding on the "from" option mentioned previously, a "command" option can also be used to restrict what can be done when the automatic ssh log in occurs. Assuming that the "from" option is inserted at the front of the key in the server authorized_keys file, insert a comma and then the following:

command="~/getlog.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty

This option will run the ~/.getlog.sh command immediately after a SSH login with the key occurs and then exit.

Troubleshooting:
  •  Try the command: ssh -o PreferredAuthentications=publickey user@server.net
  • Ensure that all ~/.ssh folders have permissions of 0700
  • Ensure that the server ~/.ssh/authorized_keys file has permissions of 0600
  • Use ssh -v[vv] to generate verbose debug information. The the more 'v's the more verbose.

      Labels: , ,