- 1 What are SSH Keys?
- 2 Remember key passphrases
- 3 Troubleshooting
- 4 Useful Links / Information
What are SSH Keys?
SSH keys are an implementation of public-key cryptography. They solve the problem of brute-force password attacks by making them computationally impractical. Additionally, by using SSH keys, you can easily connect to a server, or multiple servers, without having to enter your password for each system.
It is possible to setup your keys without a passphrase, however that is unwise as if anyone gets hold of your key they can use it. This guide describes how to setup your system so that a passphrase is used to encrypt the private key and must be entered to use it.
Generating SSH Keys
If you don't already have OpenSSH installed, install it now as it is not installed by default on Arch.
# pacman -S openssh
The keys can then be generated by running the ssh-keygen command as a user:
$ ssh-keygen -b 521 -t ecdsa -C"$(id -un)@$(hostname)-$(date --rfc-3339=date)" Generating public/private ecdsa key pair. Enter file in which to save the key (/home/mith/.ssh/id_ecdsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/mith/.ssh/id_ecdsa. Your public key has been saved in /home/mith/.ssh/id_ecdsa.pub. The key fingerprint is: 3a:43:37:6d:e2:5b:97:e2:6f:e2:80:f9:23:97:70:0c mith@middleearth
It will prompt you for a location (which you should leave as the default), however the passphrase is the important bit! You should already be aware of the criteria that make a good passphrase.
So what did we just do? We generated a 521 bit long (Template:Codeline) public/private ECDSA (Template:Codeline) key pair with an extended comment including the data (Template:Codeline) via the Template:Codeline command.
Elliptic curve cryptography provides smaller key sizes and faster operations for equivalent estimated security. It was introduced as the preferred method for authentication in OpenSSH 5.7, see OpenSSH 5.7 Release Notes. ECDSA keys might not be compatible with systems that ship old versions of OpenSSH.
If you want to create a RSA (2048-4096 bit) or DSA (1024 bit) key pair instead of ECDSA just use Template:Codeline or Template:Codeline and don't forget to increase the key size, running Template:Codeline without (Template:Codeline) will provide reasonable defaults.
Copying the keys to the remote server
Now you have generated the keys you need to copy them to the remote server.
If your key file is named Template:Filename you can simply do
$ ssh-copy-id your-server.org
or if you need to use different user name
$ ssh-copy-id firstname.lastname@example.org
If your key filename is different you'll get an error saying "/usr/bin/ssh-copy-id: ERROR: No identities found". In this case you have to provide the location of the identity:
$ ssh-copy-id -i ~/.ssh/id_ecdsa.pub email@example.com
If you need to specify a port, include it within the host declaration:
$ ssh-copy-id -i ~/.ssh/id_rsa.pub '-p 221 username@host'
By default, for OpenSSH, the public key needs to be concatenated into Template:Filename.
$ scp ~/.ssh/id_ecdsa.pub firstname.lastname@example.org:
This copies the public key (Template:Filename) to your remote server via Template:Codeline (note the Template:Codeline at the end of the server address). The file ends up in the home directory, but you can specify another path if you like.
$ ssh email@example.com firstname.lastname@example.org's password: $ mkdir ~/.ssh $ cat ~/id_ecdsa.pub >> ~/.ssh/authorized_keys $ rm ~/id_ecdsa.pub $ chmod 600 ~/.ssh/authorized_keys
The last two commands remove the public key from the server (which isn't needed now), and sets the correct permissions on the authorized_keys file.
If you now disconnect from the server, and attempt to reconnect, you should be asked for the passphrase of the key:
$ ssh email@example.com Enter passphrase for key '/home/mith/.ssh/id_ecdsa':
If you are unable to login with the key, double check the permissions on the Template:Filename file.
Also check the permissions on the Template:Filename directory, which should have write permissions off for 'group' and 'other'. Run the following command to disable 'group' and 'other' write permissions for the Template:Filename directory:
$ chmod go-w ~/.ssh
Disabling password logins
Setting up SSH keys is not enough to gain any security benefit. You must also disable password logins:
Remember key passphrases
Now you can login to your servers by using a key instead of a password, but how is this any easier, as you still need to enter the key passphrase? The answer is to use a SSH agent, a program which remembers the passphrases of your keys! There a number of different tools available, so have a read through and choose the one which seems best for you.
ssh-agent is the default agent included with OpenSSH.
$ ssh-agent SSH_AUTH_SOCK=/tmp/ssh-vEGjCM2147/agent.2147; export SSH_AUTH_SOCK; SSH_AGENT_PID=2148; export SSH_AGENT_PID; echo Agent pid 2148;
$ eval `ssh-agent` Agent pid 2157
You can add this to Template:Filename so that it will be run whenever you open a session:
# echo 'eval `ssh-agent`' >> /etc/profile
Note the correct quotes, the outer ones are single quotes, where as the inner ones are backticks!
Now that the Template:Codeline is running, we need to tell it that we have a private key and where that is.
$ ssh-add ~/.ssh/id_ecdsa Enter passphrase for /home/user/.ssh/id_ecdsa: Identity added: /home/user/.ssh/id_ecdsa (/home/user/.ssh/id_ecdsa)
We were asked for our passphrase, entered it, that's all. Now you can login to your remote server without having to enter your password while your private key is password-protected. Sweet isn't it?
The only downside is that a new instance of Template:Codeline needs to be created for every new console (shell) you open, that means you have to run Template:Codeline every time again on each console. There is a workaround to that with a program or rather a script called keychain which is covered in the next section.
Using GnuPG Agent
The GnuPG agent, distributed with the Template:Package Official package, has OpenSSH agent emulation. If you use GPG you might consider using its agent to take care of all of your keys. Otherwise you might like the PIN entry dialog it provides and its passphrase management, which is different from keychain.
Once gpg-agent is running you can use ssh-add to approve keys, just like you did with plain ssh-agent. The list of approved keys is stored in the Template:Filename file. Once your key is approved you will get a PIN entry dialog every time your passphrase is needed. You can control passphrase caching in the Template:Filename file. The following example would have gpg-agent cache your keys for 3 hours:
# Cache settings default-cache-ttl 10800 default-cache-ttl-ssh 10800
Other useful settings for this file include the PIN entry program (GTK, QT or ncurses version), keyboard grabbing and so on...:
# Environment file write-env-file /home/username/.gnupg/gpg-agent.info # Keyboard control #no-grab # PIN entry program #pinentry-program /usr/bin/pinentry-curses #pinentry-program /usr/bin/pinentry-qt4 pinentry-program /usr/bin/pinentry-gtk-2
Keychain manages one or more specified private keys. When initialized it will ask for the passphrase for the private key(s) and store it. That way your private key is password protected but you won't have to enter your password over and over again.
Install keychain from the extra repo:
# pacman -S keychain
Create the following file and make it executable: Template:File
eval `keychain --eval --agents ssh id_dsa`
Close your shell and open it again. Keychain should come up and if it's your first run it will ask your for the passphrase of the specified private key.
See also the next section to learn how to go about Xsessions and keychain. Of course, you do still not need to use ssh-agent manually. Just install on of the x11-ask-keypass variants and you are good to go.
Using ssh-agent and x11-ssh-askpass
You need to start the ssh-agent everytime you start a new Xsession. The ssh-agent will be closed when the X session ends.
Install a variant of x11-ssh-askpass which will ask your passphrase everytime you open a new Xsession. Either use the original x11-ssh-askpass from AUR or go with either ksshaskpass (uses kdelibs):
# pacman -S ksshaskpass
or openssh-askpass (uses qt):
# pacman -S openssh-askpass
After installing these, closing your Xsession and relogging you will henceforth be asked your passphrase on Xsession init without any further work.
If it appears that the SSH server is ignoring your keys, ensure that you have the proper permissions set on all relevant files.
For the local machine:
$ chmod 700 ~/ $ chmod 700 ~/.ssh $ chmod 600 ~/.ssh/id_ecdsa
For the remote machine:
$ chmod 700 ~/ $ chmod 700 ~/.ssh $ chmod 600 ~/.ssh/authorized_keys
Failing this, run the sshd in debug mode and monitor the output while connecting:
# /usr/sbin/sshd -d