Howto: Setting up public key password-less 'ssh' access

====================================
Original post by J65nko @ daemonforums.org
====================================



* Introduction
* Generate public and private RSA key pair with 'ssh-keygen'
* View the RSA key pair
* Copy the public key 'id_rsa.pub' to the server
* Check the '.ssh/authorized_keys' file
* Home work/assignment

Introduction

Buried rather deep in the ssh(1) page, a very terse outline is given how public key authentication works, how to create keys and distribute them.

For more information about public key authentication see http://en.wikipedia.org/wiki/Public-key_cryptography.

Code:
     Public key authentication works as follows: The scheme is based on pub-
     lic-key cryptography, using cryptosystems where encryption and decryption
     are done using separate keys, and it is unfeasible to derive the decryp-
     tion key from the encryption key.  The idea is that each user creates a
     public/private key pair for authentication purposes.  The server knows
     the public key, and only the user knows the private key.  ssh implements
     public key authentication protocol automatically, using either the RSA or
     DSA algorithms.  Protocol 1 is restricted to using only RSA keys, but
     protocol 2 may use either.  The HISTORY section of ssl(8) contains a
     brief discussion of the two algorithms.

     The file ~/.ssh/authorized_keys lists the public keys that are permitted
     for logging in.  When the user logs in, the ssh program tells the server
     which key pair it would like to use for authentication.  The client
     proves that it has access to the private key and the server checks that
     the corresponding public key is authorized to accept the account.

     The user creates his/her key pair by running ssh-keygen(1).  This stores
     the private key in ~/.ssh/identity (protocol 1), ~/.ssh/id_dsa (protocol
     2 DSA), or ~/.ssh/id_rsa (protocol 2 RSA) and stores the public key in
     ~/.ssh/identity.pub (protocol 1), ~/.ssh/id_dsa.pub (protocol 2 DSA), or
     ~/.ssh/id_rsa.pub (protocol 2 RSA) in the user's home directory.  The us-
     er should then copy the public key to ~/.ssh/authorized_keys in his/her
     home directory on the remote machine.  The authorized_keys file corre-
     sponds to the conventional ~/.rhosts file, and has one key per line,
     though the lines can be very long.  After this, the user can log in with-
     out giving the password.

These steps of the last paragraph are a little bit confusing because 'ssh' knows a ssh protocol 1 and a protocol 2. And in addition, two types of public keys are supported: RSA and DSA.

SSH protocol 1 is unsafe and should be avoided. See the Wikipedia ssh article.

Leaving out the protocol 1 stuff and only choosing RSA keys the procedure can be rephrased as follows:

Code:
    The user creates his/her key pair by running ssh-keygen(1).

    This stores the private key in ~/.ssh/id_rsa (protocol 2 RSA)
    and stores the public key in ~/.ssh/id_rsa.pub (protocol 2 RSA)
    in the user's home directory. 

    The user should then copy the public key to ~/.ssh/authorized_keys
    in his/her home directory on the remote machine.

Generate public and private RSA key pair with 'ssh-keygen'

From ssh-keygen(1):

Code:
     ssh-keygen generates, manages and converts authentication keys for
     ssh(1).  ssh-keygen can create RSA keys for use by SSH protocol version 1
     and RSA or DSA keys for use by SSH protocol version 2.  The type of key
     to be generated is specified with the -t option.  If invoked without any
     arguments, ssh-keygen will generate an RSA key for use in SSH protocol 2
     connections.

Not being lazy we specify the RSA key type with the -t option.

Code:
$ ssh-keygen -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/home/j65nko/.ssh/id_rsa): Enter 
Created directory '/home/j65nko/.ssh'.
Enter passphrase (empty for no passphrase):  Enter 
Enter same passphrase again:  Enter 
Your identification has been saved in '/home/j65nko/.ssh/id_rsa'.
Your public key has been saved in '/home/j65nko/.ssh/id_rsa.pub'.
The key fingerprint is:
40:e5:83:2a:bf:20:61:92:73:c7:7e:b6:13:da:05:e1 [email]j65nko@protogoras.utp.xnet[/email]

A public key can be secured with a passphrase. By specifying a passphrase you will be prompted for this phrase, instead of the login password of the remote box.
ssh-keygen(1) has this to say about the passphrase:

Code:
     The program also asks for a passphrase.  The passphrase may
     be empty to indicate no passphrase (host keys must have an
     empty passphrase), or it may be a string of arbitrary length.
     A passphrase is similar to a password, except it can be a
     phrase with a series of words, punctuation, numbers, whitespace,
     or any string of characters you want.  Good passphrases are
     10-30 characters long, are not sim- ple sentences or otherwise
     easily guessable (English prose has only 1-2 bits of entropy
     per character, and provides very bad passphrases), and contain
     a mix of upper and lowercase letters, numbers, and non-alphanu-
     meric characters.  The passphrase can be changed later by using
     the -p option.

     There is no way to recover a lost passphrase.  If the passphrase
     is lost or forgotten, a new key must be generated and copied
     to the corresponding public key to other machines.

The 'id_rsa' and 'id_rsa.pub' entries of the ssh-keygen(1) FILES section:

Code:
     ~/.ssh/id_rsa
             Contains the protocol version 2 RSA authentication identity of
             the user.  This file should not be readable by anyone but the us-
             er.  It is possible to specify a passphrase when generating the
             key; that passphrase will be used to encrypt the private part of
             this file using 3DES.  This file is not automatically accessed by
             ssh-keygen but it is offered as the default file for the private
             key.  ssh(1) will read this file when a login attempt is made.

     ~/.ssh/id_rsa.pub
             Contains the protocol version 2 RSA public key for authentica-
             tion.  The contents of this file should be added to
             ~/.ssh/authorized_keys on all machines where the user wishes to
             log in using public key authentication.  There is no need to keep
             the contents of this file secret.

View the RSA key pair


Because it did not already exist ssh-keygen created a '.ssh' directory with very restricted permissions

Code:
$ ls -ld .ssh
drwx------  2 j65nko  j65nko  512 Jun 16 20:27 .ssh

Also the private key 'id_rsa' has very restricted file permissions: readable and writable by user only.

The public key 'id_rsa.pub' is readable by the world.

Code:
$ ls -al .ssh
total 16
drwx------  2 j65nko  j65nko   512 Jun 16 20:27 .
drwxr-xr-x  3 j65nko  j65nko   512 Jun 16 20:28 ..
-rw-------  1 j65nko  j65nko  1675 Jun 16 20:27 id_rsa
-rw-r--r--  1 j65nko  j65nko   408 Jun 16 20:27 id_rsa.pub

Code:
$ cd .ssh
$ cat id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAnziCaL2QQVhGcGwNxjHkviWFLMrIyAvtoZytyVH+UduCnhySenOzU46CXC6qTSojhkM8
v6a4nZA40DGy85VzjyBNDyughcQZLDYouZ1iRB/N9TWIxGbuIrUtjpAD+hZzG5NbJ5uiClUJGu9kt8eeO4id47dxaSKTjB+p073AoPk+
O8CGNFAUisqIvD4iE/BxuB8rT6VUdoVsJjEINQD3MvF83LCNft2oUSmNQOo4kExONas37IajCpnnQMAEDOduwroR2rSUyeXrmOunzZYl
== j65nko@protogoras.utp.xnet

Copy the public key 'id_rsa.pub' to the server

Code:
$ cat id_rsa.pub | ssh j65nko@192.168.222.44 'cat >>.ssh/authorized_keys' 

The authenticity of host '192.168.222.44 (192.168.222.44)' can't be established.
RSA key fingerprint is 1a:1f:ab:96:c7:ad:1a:3f:9c:e8:2d:73:0f:28:98:07.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.222.44' (RSA) to the list of known hosts.
j65nko@192.168.222.44's password: .......
Explanation of the command:

cat id_rsa.pub | ssh j65nko@192.168.222.44
The 'cat' program displays the contents of the 'id_rsa.pub>' on standard output. This output is piped through a ssh connection with 192.168.222.44, where it appeas on standard input.

The ssh connection is passed the command 'cat >>.ssh/authorized_keys', which will append the standard input to the file '.ssh/authorized_keys' on the 192.168.222.44 box. After this command has finished, the ssh connection will terminate.

IMPORTANT: Note the use of single quotes around the command. This is to prevent the current shell on the client machine from interpreting the shell ">>' file append symbols.


====================================
Original post by J65nko @ daemonforums.org
 
====================================
Original post by J65nko @ daemonforums.org
====================================



The ssh(1) FILES entry for 'authorized_keys':

Code:
     ~/.ssh/authorized_keys
             Lists the public keys (RSA/DSA) that can be used for logging in
             as this user.  The format of this file is described in the
             sshd(8) manual page.  This file is not highly sensitive, but the
             recommended permissions are read/write for the user, and not ac-
             cessible by others.

From now on we should be able to ssh in to 192.168.222.44 without being asked for a password.

But as a famous Dutch football coach said: "Each advantage has it's disadvantage". So walking away from you box while still logged in, will not only allow anyone access to your own box, but also to the 192.168.222.44 server!

Check the '.ssh/authorized_keys' file

We 'ssh' in to the server to double check our work.

Code:
$ ssh j65nko@192.168.222.44 'ls -ld .ssh ; ls -al .ssh ; tail -2 .ssh/authorized_keys' 

drwx------  2 j65nko  j65nko  512 Mar 10 01:55 .ssh
total 52
drwx------   2 j65nko  j65nko   512 Mar 10 01:55 .
drwxr-xr-x  50 j65nko  j65nko  7680 Jun 16 20:12 ..
-rw-r--r--   1 j65nko  j65nko  1216 Jun 16 20:31 authorized_keys
-rw-------   1 j65nko  j65nko  1675 Nov 11  2006 id_rsa
-rw-r--r--   1 j65nko  j65nko   402 Nov 11  2006 id_rsa.pub
-rw-r--r--   1 j65nko  j65nko  8493 Jun 14 03:09 known_hosts

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAnziCaL2QQVhGcGwNxjHkviWFLMrIyAvtoZytyVH+UduCnhySenOzU46CXC6qTSojhkM8
v6a4nZA40DGy85VzjyBNDyughcQZLDYouZ1iRB/N9TWIxGbuIrUtjpAD+hZzG5NbJ5uiClUJGu9kt8eeO4id47dxaSKTjB+p073AoPk+
O8CGNFAUisqIvD4iE/BxuB8rT6VUdoVsJjEINQD3MvF83LCNft2oUSmNQOo4kExONas37IajCpnnQMAEDOduwroR2rSUyeXrmOunzZYl
== j65nko@protogoras.utp.xnet

Here we tell ssh to execute 'ls -ld .ssh ; ls -al .ssh ; tail -2 .ssh/authorized_keys' on the server 192.168.222.44.

As you can see we are not prompted for a password, nor a passphrase.

Another possibility not to be bothered with too much password stuff is to use 'ssh-agent'. But that is for another guide or howto

Home work/assignment

What is the sh command to set the recommended permissions of the 'authorized_keys' file?


====================================
Original post by J65nko @ daemonforums.org
 
does anybody know how to disable password login completely leaving only ssh key option for high security server? I tried different options under /etc/ssh/ssh_config but to no avail.
 
striperbsd said:
does anybody know how to disable password login completely leaving only ssh key option for high security server?

Disable all authentication forms (except PubkeyAuthentication) in sshd_config. The two key ones to shut off to disable "password login" are PasswordAuthentication and ChallengeResponseAuthentication.
 
If I may add a sample config file:

Code:
Port 22
Protocol 2

HostKey /etc/ssh/ssh_host_key
HostKey /etc/ssh/ssh_host_dsa_key

KeyRegenerationInterval 1h
ServerKeyBits 1024

SyslogFacility AUTH
LogLevel INFO

PermitRootLogin no
StrictModes yes
MaxAuthTries 2

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
RhostsRSAAuthentication no
HostbasedAuthentication no
IgnoreUserKnownHosts yes
IgnoreRhosts yes
PasswordAuthentication no
ChallengeResponseAuthentication yes
UsePAM no

AllowUsers sampleuser sampleftpuser sampletunnel

Subsystem sftp internal-sftp

Match User sampletunnel
 ForceCommand /usr/local/bin/rsync

Match User sampleftpuser
 ChrootDirectory /home/sampleftpuser
 X11Forwarding no
 AllowTcpForwarding no
 PermitTunnel no
 ForceCommand internal-sftp

Should have everything needed. Pubkey Auth and also 3 example users who are able to connect with their corresponding keys.

One can login (sampleuser), one is intend to be used for rsync (sampletunnel) and finally the sampleftpuser can use SFTP.

Doesn't matter if more users exist and even if they've valid keys, logins will be denied.
 
Changing Port won't increase security, it just keeps the logs smaller.
And - this is just an example config.
 
anyway, it's worth mentioning. and if it sops 80% from probing your ssh, then it does increase security....
there might be 1 of 50 ppl who will check all ports, but 49 wont (used imaginary numbers)
 
It's not security, it obscurity.

I'm not saying running SSH on a port different than 22 isn't useful at least in some cases, but it's obscurity, which is something different from security, and it most definitely is not a substitute for choosing strong passwords and properly configuring/securing a SSH server, either of which make a brute-force attack infeasible anyway ...
 
Thanks for the howto, this makes it plain and simple.
I just set mine up so that my laptop (which of course may be coming from any IP, so other means of host-specific security hold inherent difficulties) connects to my home "server" using a 4096-bit RSA key. Very cool.

Now, I've got to ask. I've done some Googling and it doesn't seem that there is a definitive answer...

1) Is this *absolutely* THE most secure way of doing SSH? (definitely guards against MITM and other replay/sniffing attacks, etc)

2) On average, how long do you expect it would take someone with sufficient resources to break it?

3) If it is so secure, and everyone is going to hate me for asking this, would it be safe to turn on root logins? I've heard all the "you should never do that" before. I just mean, is there enough confidence in this method to say "yes, I trust my system in the deepest way possible"?

Thanks in advance for the input.
 
illiadum said:
If [pubkey authentication] is so secure, and everyone is going to hate me for asking this, would it be safe to turn on root logins?

Possibly. If you go this route I would suggest using:
Code:
PermitRootLogin without-password

I would also recommend that you use a mechanism for helping to ensure that root comes in only from IP addresses that you'd expect. Some combination of the AllowUsers/AllowGroups/DenyUsers/DenyGroups directives with the form root(at)host.here should do the trick, if implemented properly. *

See the manpages for sshd_config(5) for details.

* Of course this all assumes that you're actively monitoring, updating, and reacting to events on your system. And that this isn't your only layer of security. Etc., etc.
 
Awesome howto, works great, I've got two devices that I use to ssh into my server regularly. Is there a way to use more than 1 key?

If I do

Code:
$ cat id_rsa.pub | ssh j65nko@192.168.222.44 'cat >>.ssh/authorized_keys' 

The authenticity of host '192.168.222.44 (192.168.222.44)' can't be established.
RSA key fingerprint is 1a:1f:ab:96:c7:ad:1a:3f:9c:e8:2d:73:0f:28:98:07.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.222.44' (RSA) to the list of known hosts.
j65nko@192.168.222.44's password: .......

from box1 with it's key then run that again from box2 after creating another key foer it will this let me add the second key or overwrite key1?
 
You are responding to a two-year-old thread. But yes, it can be done. I can recommend the new Michael Lucas book "SSH Mastery". In the meantime, see ssh-agent(1).

Please create a new thread for further discussion.
 
Back
Top