Saturday, May 11, 2013

Setting up SSH public/private keys


Setting up SSH public/private keys


This will be a short introduction "for dummies" describing how to generate and setup ssh keys between two computers.
I will be using OpenSSH version but process is similar for commercial distributions like SSH Tectia or VShell.
However you must be aware that connectivity between two different vendors my require some additional work (like converting OpenSSH public key to Tectia format before using it).


Generating SSH Keys

Linux/Unix:

On the source machine (host from which you will be initiating the connection) run:
[mike@client ~]$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/mike/.ssh/id_dsa):
Created directory '/home/mike/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/mike/.ssh/id_dsa.
Your public key has been saved in /home/mike/.ssh/id_dsa.pub.
The key fingerprint is:
df:95:5e:3a:1b:fc:30:81:2a:15:54:72:7e:1a:9d:2c mike@client.example.com
The key's randomart image is:
+--[ DSA 1024]----+
|          o.o    |
|         . + o . |
|          . E =  |
|           . * . |
|        S . o + .|
|         o o + + |
|        . o . O  |
|         .     B |
|              . .|
+-----------------+
[mike@client ~]$

You may accept default path and filenames (~/.ssh/id_dsa - private key, ~/.ssh/id_dsa.pub - public key) or provide your own.
When prompted for secret passphrase you may choose to provide such one (but then you will be asked for this passphrase every time when using this key pair) or leave this field empty to allow passwordless connectivity.

Remember to keep correct permissions to .ssh folder and its contents - some SSH versions may not work if those rights are not setup properly:
[mike@client ~]$ chmod 700 .ssh
Private key should always be readable by its owner only - this file stays on the source server and should never be shared with anyone:
[mike@client ~]$ chmod 400 .ssh/id_dsa
Public key should be writable by its owner only but it can be read by others - this file may be shared to other servers to allow passwordless connectivity:
[mike@client ~]$ chmod 644 .ssh/id_dsa.pub

Now you need to transfer public key (id_dsa.pub) to the destination machine:
[mike@client ~]$ scp ~/.ssh/id_dsa.pub mike@server.example.com:/home/mike/mike@client.example.com.pub

On the destination machine add recently copied public key to authorized_keys2 file:
[mike@server ~]$ mkdir .ssh
[mike@server ~]$ cat mike@client.example.com.pub >> .ssh/authorized_keys2
[mike@server ~]$ chmod 700 .ssh
[mike@server ~]$ chmod 644 .ssh/authorized_keys2

Finally you may test passwordless connectivity between two hosts:
[mike@client ~]$ ssh server
Last login: Sat May 11 18:23:34 2013 from client.example.com
[mike@server ~]$ 



Tricks:

Limit public key to selected hosts only

This may be an additional layer of security - you may allow only selected machines to be able to logon using selected public key.
If you know that mike will be always connecting from one host you may specify its ip address or dns name. You may also provide subnet, domain or combine both options.
Edit ~/.ssh/authorized_keys2 and add from= directive.

Examples:
from="*.example.com" ssh-dss AAAAB3NzaC1kc3MAA...yfinIwP9ZSoi0LMUM6g== mike@client.example.com
This setup will allow hosts from example.com domain to logon using mike's public key.

from="*.example.com,192.168.0.100" ssh-dss AAAAB3NzaC1kc3MAA...yfinIwP9ZSoi0LMUM6g== mike@client.example.com
This will allow hosts from example.com domain and from 192.168.0.100 host.

Debugging:
Check /var/log/secure or /var/log/authlog for entries related to sshd daemon.
Positive logon looks like:
May 11 18:42:46 server sshd[3064]: Accepted publickey for mike from 192.168.0.190 port 46816 ssh2
May 11 18:42:46 server sshd[3064]: pam_unix(sshd:session): session opened for user mike by (uid=0)
Negative logon:
May 11 18:42:06 server sshd[3005]: Authentication tried for mike with correct key but not from a permitted host (host=192.168.0.100, ip=192.168.0.100).



Limit public key to allow execution of one command only:

If you don't want to give somebody full shell access you may limit his access to one command only.
Using command= directive only chosen command will be executed when somebody will connect using particular key.
If he specify any other command during logon it will be ignored.

Example:
command="echo Bye Bye" ssh-dss AAAAB3NzaC1kc3MAA...yfinIwP9ZSoi0LMUM6g== mike@client.example.com
This setup will execute "echo Bye Bye" command after user will pass authentication process.
You may put here something more useful like svnserve or backup command.



Windows:

I prefer to use PuTTY and PuTTYgen utility.

To generate ssh key pair start PuTTYgen select key type (rsa/dsa), its strength (number of bits, 1024 or more) and click on "Generate" option.
Then save public and private key in some safe location (lets call them id_dsa.ppk and id_dsa.pub).

Copy public key to the destination's server using pscp command or copy&paste contents of that file while using PuTTY to some local file on destination server.
Once the public key is on the destination server you need to convert it first from PuTTY format to OpenSSH:
[mike@server ~]$ ssh-keygen -if id_dsa.pub > id_dsa_converted.pub
Then add id_dsa_converted.pub contents to ~/.ssh/authorized_keys2 file:
[mike@server ~]$ cat id_dsa_converted.pub >> .ssh/authorized_keys2

Now start PuTTY, go to the Connection->Data settings and fill in "Auto-login username" field (specify username that will be used on the destination server).
Then go to Connection->SSH->Auth and select "Private key for authentication" file (id_dsa.ppk).
Go back to the Session list, provide destination server name or ip address and save this connection under specified name.

Connection from Windows-based client should work fine now.

No comments:

Post a Comment