Home > Linux > Configure OpenSSH Public Key Encryption with Keychain for Passwordless SSH Logins

Configure OpenSSH Public Key Encryption with Keychain for Passwordless SSH Logins

Public key encryption is a powerful tool that you can use with SSH in order to achieve logins to remote hosts without entering a password everytime.  It can be much more secure than using simple password authentication.  It is also ideal for use with unattended scripting and automation when a password cannot be entered to authenticate.

In this example I will authenticate between two SSH systems, aptly named “client1” and “server1”.  Server1 is the host that we want to log in to without a password.  In this example I am using an RPM based Red Hat Enterprise/Centos/Scientific Linux system, but it should be similar for most other Linux distributions and Windows tools such as Cygwin.

First on client1 run the ssh-keygen utility to generate a public/private key pair.  On my system it will default to RSA type with 2048 bit encryption depth.  You will also want to enter a passphrase to decrypt your private key.  It is a good idea to make the passphrase very complex with numbers and caps included. Avoid the temptation to leave the passphrase blank because later we will set up keychain and the ssh-agent utility to avoid entering the passphrase every time we log in.

[aaron@client1 ~]$ ssh-keygen

Generating public/private rsa key pair.
Enter file in which to save the key (/home/aaron/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/aaron/.ssh/id_rsa.
Your public key has been saved in /home/aaron/.ssh/id_rsa.pub.

Now you will want to copy the user’s public key to the server we want to authentication in to.  One thing to note is that with the minimal server install of Red Hat Enterprise/Scientific Linux 6, the openssh-clients package does not get installed.  This will prevent us from using secure copy (SCP) to copy the public key to the server.  Since I will use SCP in the future I will make sure the clients package is installed on the Linux SSH servers.  You could run something like this from your client if on Red Hat/Scientific or just do it locally on the server.

[aaron@client1 ~]$ ssh root@server1 "yum -y install openssh-clients"

Now we will copy the public key over:

[aaron@client1 ~]$ scp ~/.ssh/id_rsa.pub aaron@server1:

The authenticity of host 'server1 (192.168.1.101)' can't be established.
RSA key fingerprint is 5c:83...
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'server1,192.168.1.101' (RSA) to the list of known hosts.
aaron@server1's password:
id_rsa.pub                                    100%  392     0.4KB/s   00:00

Now we need to login to the remote server.  We need to create the “~/.ssh” directory where we will place the public key in a special file to allow us to authenticate with it.  Unfortunately I wasn’t able to remotely chain commands together to make this directory automatically because SELinux denies this right and the openssh client software itself must create the directory.  So we have to login to the server and then run the ssh command to set it up the first time.

[aaron@client1 ~]$ ssh server1

aaron@server1's password:
Last login: Mon Mar 21 17:11:09 2011 from client1

Now run “ssh” and attempt to connect to any host to set up the ~/.ssh directory.  We can simply choose “no” when prompted if we want to continue, we don’t need to connect to a host to get the directory created.

[aaron@server1 ~]$ ssh localhost

The authenticity of host 'localhost (::1)' can't be established.
RSA key fingerprint is 10:01...
Are you sure you want to continue connecting (yes/no)? no

Now copy the user public key into the authorized_keys file under “~/.ssh”, we also need to set the permissions on the file to allow only this user to read/write the file:

[aaron@server1 ~]$ cat id_rsa.pub >> ~/.ssh/authorized_keys
[aaron@server1 ~]$ chmod 600 ~/.ssh/authorized_keys

And we’ll now exit to go back to the client:

[aaron@server1 ~]$ exit
logout
Connection to server1 closed.

Finally let’s test to make sure the server will use the user’s public/private key pair for encryption rather than passwords:

[aaron@client1 ~]$ ssh server1

Enter passphrase for key '/home/aaron/.ssh/id_rsa':
Last login: Tue Mar 22 14:40:52 2011 from client1

The prompt asked for the passphrase so it should now be using the public/private key pair.  Now exit again back to the client:

[aaron@server1 ~]$ exit

Keychain and SSH-Agent Configuration

Now we will use keychain along with ssh-agent to cache our decrypted private key in memory so that we won’t have to enter the passphrase each time we login with ssh to the server.  While there is a minor security risk in doing this it is much more secure than using a private key with no passphrase.

First ensure that the keychain package is installed, it should be available on most Linux environments (including Cygwin).  I am using Scientific Linux so for it or Red Hat/CentOS it should be available at RPMForge repository. I am on Scientific Linux 6/32-bit:

[aaron@client1 ~]$ su -c 'rpm -ivh http://apt.sw.be/redhat/el6/en/i386/rpmforge/RPMS/rpmforge-release-0.5.2-2.el6.rf.i686.rpm'

And install the keychain package:

[aaron@client1 ~]$ su -c 'yum -y install keychain'

First test that keychain can access and launch the ssh-agent to decrypt the private key and load it into memory:

[aaron@client1 ~]$ /usr/bin/keychain ~/.ssh/id_rsa

* keychain 2.7.0 ~ http://www.funtoo.org
* Starting ssh-agent...
* Starting gpg-agent...
* Adding 1 ssh key(s): /home/aaron/.ssh/id_rsa
Enter passphrase for /home/aaron/.ssh/id_rsa:
* ssh-add: Identities added: /home/aaron/.ssh/id_rsa

Now we need to tell the current session to use the ssh-agent if it is already running:

[aaron@client1 ~]$ source ~/.keychain/${HOSTNAME}-sh > /dev/null

That should do it.  You will now be able to authenticate without entering the passphrase everytime:

[aaron@client1 ~]$ ssh server1
Last login: Tue Mar 22 14:45:56 2011 from client1
[aaron@server1 ~]$

Now edit the “.bash_profile” file and append the content we entered manually above to run when we start a login session. This will prompt you to decrypt the RSA private key with the passphrase at the next login if the ssh-agent doesn’t have the key decrypted already in memory:

$ vi ~/.bash_profile

# Start Keychain
/usr/bin/keychain ~/.ssh/id_rsa
source ~/.keychain/${HOSTNAME}-sh > /dev/null

I have noticed that on Linux that the ssh-agent will keep running with the private key decrypted until the client is rebooted.  If the client is on Windows in an environment like Cygwin the ssh-agent will stay running until the user is fully logged out of their desktop session.

Reference

http://www.ibm.com/developerworks/library/l-keyc.html

Categories: Linux Tags:
  1. Santosh Tiwary
    February 1, 2013 at 12:28 pm

    You have explained very clearly about ssh.I have read many documents about ssh but your post is very helpful.

    Thanx

  1. No trackbacks yet.

Leave a comment