Difference between revisions of "SSH keys"

From ArchWiki
Jump to: navigation, search
(More cleanup, sorry Mortal Combat quote!)
(More cleanup, note the connection control section has been removed, see talk for details)
Line 61: Line 61:
 
  Enter passphrase for key '/home/mith/.ssh/id_dsa':
 
  Enter passphrase for key '/home/mith/.ssh/id_dsa':
  
If you are unable to login with the key, double check the permissions on the authorized_keys file.
+
If you are unable to login with the key, double check the permissions on the <code>authorized_keys</code> file.
  
 
= Remember key passphrases =
 
= Remember key passphrases =
  
Now what makes this path almost as easy as a no-passphrase key? The magic word is ssh-agent.. What it does is basically asking you once every session for the passphrase of your private key and every time you would have to type it in, <code>ssh-agent</code> does it for you. <code>ssh-agent</code> is included in the <code>openssh</code> package so no trouble there...<br>
+
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.
<pre>
+
 
mith@middleearth||[[~]]:~ > ssh-agent
+
== ssh-agent ==
SSH_AUTH_SOCK=/tmp/ssh-vEGjCM2147/agent.2147; export SSH_AUTH_SOCK;
+
 
SSH_AGENT_PID=2148; export SSH_AGENT_PID;
+
ssh-agent is the default agent included with OpenSSH.
echo Agent pid 2148;
+
 
</pre>
+
$ ssh-agent
<br>
+
SSH_AUTH_SOCK=/tmp/ssh-vEGjCM2147/agent.2147; export SSH_AUTH_SOCK;
When you run <code>ssh-agent</code> it will print out what environment variables it would use... Well to make <code>ssh-agent</code> use these variables run
+
SSH_AGENT_PID=2148; export SSH_AGENT_PID;
<pre>
+
echo Agent pid 2148;
mith@middleearth||[[~]]:~ > eval `ssh-agent`
+
 
Agent pid 2157
+
When you run <code>ssh-agent</code> it will print out what environment variables it would use... To make use  of these variables run the command through the <code>eval</code> command.
</pre>
+
 
The process id will vary for you of course. Adding <code>eval `ssh-agent`</code> to your <code>.bashrc</code> is an option so it's started every time you create a new shell.<br>
+
$ eval `ssh-agent`
 +
Agent pid 2157
 +
 
 +
You can add this to your <code>.bashrc</code> so that it will be run whenever you create a new shell:
 +
 
 +
$ cat 'eval `ssh-agent`' >> ~/.bashrc
 +
 
 +
Node the correct quotes, the first ones are single quotes, where as the second are curly single quotes!
 +
 
 
Now that the <code>ssh-agent</code> is running, we need to tell it that we have a private key and where that is.
 
Now that the <code>ssh-agent</code> is running, we need to tell it that we have a private key and where that is.
<pre>
 
mith@middleearth||[[~]]:~ > ssh-add .ssh/id_dsa
 
Enter passphrase for .ssh/id_dsa:
 
Identity added: .ssh/id_dsa (.ssh/id_dsa)
 
</pre>
 
<br>
 
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 <code>ssh-agent</code> needs to be created for every new console (shell) you open, that means you have to run <code>ssh-add</code> every time again on each console. There is a workaround to that with a program or rather a script called [http://www.gentoo.org/proj/en/keychain/index.xml keychain] which is covered in the next section.
 
  
====Using keychain====
+
$ ssh-add .ssh/id_dsa
 +
Enter passphrase for .ssh/id_dsa:
 +
Identity added: .ssh/id_dsa (.ssh/id_dsa)
 +
 
 +
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 <code>ssh-agent</code> needs to be created for every new console (shell) you open, that means you have to run <code>ssh-add</code> every time again on each console. TThere is a workaround to that with a program or rather a script called [http://www.gentoo.org/proj/en/keychain/index.xml keychain] which is covered in the next section.
 +
 
 +
=== Using keychain ===
 
[http://www.gentoo.org/proj/en/keychain/index.xml 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.
 
[http://www.gentoo.org/proj/en/keychain/index.xml 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.
  
Line 102: Line 111:
 
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.
 
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.
  
====Using ssh-agent and x11-ssh-askpass====
+
=== 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.<br>
+
Install x11-ssh-askpass which will ask your passphrase everytime you open a new Xsession:<br>
+
<code>sudo pacman -S x11-ssh-askpass</code>
+
  
Prepend this into your <code>~/.xsession</code> :
+
You need to start the ssh-agent everytime you start a new Xsession. The ssh-agent will be closed when the X session ends.
<pre>
+
eval `/usr/bin/ssh-agent`
+
SSH_ASKPASS=/usr/lib/openssh/x11-ssh-askpass ssh-add < /dev/null
+
# then the end of the file with for example "exec dwm"
+
</pre>
+
  
====SSH connection control====
+
Install x11-ssh-askpass which will ask your passphrase everytime you open a new Xsession:
In ~/.ssh/config, add the following lines:
+
host *
+
    controlmaster auto
+
    controlpath /tmp/ssh-%r@%h:%p
+
What this does is set a "master control" socket when you make an SSH connection. The socket is named based on the <code>controlpath</code> setting (<code>%r</code> = username, <code>%h</code> = hostname, <code>%p</code> = port).
+
  
This master socket is used for each successive connection after the first, as long as one connection still exists. That is, if you connect via <code>ssh myuser@myhost.com</code>, a socket named <code>/tmp/ssh-myuser@myhost.com:22</code> is created. If you then ssh again to the same host, the socket is found and the remote ssh session is told to spawn a new shell. This shell does not require a login, and spawns immediately, as you're already logged in.
+
# pacman -S x11-ssh-askpass
  
 +
Prepend this into your <code>~/.xsession</code>:
 +
 +
eval `/usr/bin/ssh-agent`
 +
SSH_ASKPASS=/usr/lib/openssh/x11-ssh-askpass ssh-add < /dev/null
 +
# then the end of the file with for example "exec dwm"
  
 
= PuTTY =
 
= PuTTY =
 +
 
The above procedure is a bit complicated when using PuTTY on Windows since PuTTY can't directly use keys generated by ssh-keygen. The private key needs to be converted using PuTTYgen which you can find [http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html here]. The procedure is then as follows:
 
The above procedure is a bit complicated when using PuTTY on Windows since PuTTY can't directly use keys generated by ssh-keygen. The private key needs to be converted using PuTTYgen which you can find [http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html here]. The procedure is then as follows:
#Generate the key pair with ssh-keygen on you Linux computer (you can log in with your usual username/password using PuTTY)
+
 
#Add the public key to the ''~/.ssh/authorized_keys'' file
+
# Generate the key pair with ssh-keygen on you Linux computer (you can log in with your usual username/password using PuTTY)
#Move the private key to the Windows machine
+
# Add the public key to the ''~/.ssh/authorized_keys'' file
#Load the private key with PuTTYgen and click ''Save private key''. This will convert the key so that PuTTY can use it.
+
# Move the private key to the Windows machine
#Start PuTTY, go to ''SSH''->''Auth'' and find the private key. Then simply connect to your Linux machine. You will be prompted for your username and passphrase (if you chose to enter one when you generated the keys).
+
# Load the private key with PuTTYgen and click ''Save private key''. This will convert the key so that PuTTY can use it.
 +
# Start PuTTY, go to ''SSH''->''Auth'' and find the private key. Then simply connect to your Linux machine. You will be prompted for your username and passphrase (if you chose to enter one when you generated the keys).
 +
 
 
Note that reversing the procedure, that is, generating the key pair with PuTTYgen and converting the public key with ssh-keygen, will NOT work.
 
Note that reversing the procedure, that is, generating the key pair with PuTTYgen and converting the public key with ssh-keygen, will NOT work.
  

Revision as of 17:41, 13 April 2009

Template:I18n links start Template:I18n entry Template:I18n entry Template:I18n entry Template:I18n links end

What are SSH Keys?

By using SSH Keys (a public and private key to be precise), you can easily connect to a server, or multiple servers, without having to enter your password for each system.

Note that 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 passphrases are remembered securely.

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 1024 -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/mith/.ssh/id_dsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/mith/.ssh/id_dsa.
Your public key has been saved in /home/mith/.ssh/id_dsa.pub.
The key fingerprint is:
x6:68:xx:93:98:8x:87:95:7x:2x:4x:x9:81:xx:56:94 mith@middleearth

It will prompt you for a location (which you should leave as the default), however the passphrase is the important bit! I hopefully need not tell you the rules of a good passphrase?

So what did we just do? We generated a 1024 bit long (-b 1024) public/private dsa (-t dsa) key pair with the ssh-keygen command. You can also create a rsa key (-t rsa). You can leave out the bit length parameter (default bit length is 1024).

Copying the keys to the remote server

Now you have generated the keys you need to copy them to the remote server. By default, for OpenSSH, the public key needs to be concatinated into ~/.ssh/authorized_keys.

$ scp .ssh/id_dsa.pub mith@metawire.org:

This copies the public key (id_dsa.pub) to your remote server via scp (note the : at the end of the server address). The file ends up in the home directory, but you can specify another path if you like.

Next up, on the remote server, you need to create the ~/.ssh directory if it doesn't exist and concatinate the key authorized_keys file:

$ ssh mith@metawire.org
mith@metawire.org's password:
$ mkdir ~/.ssh
$ cat ~/id_dsa.pub >> ~/.ssh/authorized_keys
$ rm ~/id_dsa.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 mith@metawire.org
Enter passphrase for key '/home/mith/.ssh/id_dsa':

If you are unable to login with the key, double check the permissions on the authorized_keys file.

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

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;

When you run ssh-agent it will print out what environment variables it would use... To make use of these variables run the command through the eval command.

$ eval `ssh-agent`
Agent pid 2157

You can add this to your .bashrc so that it will be run whenever you create a new shell:

$ cat 'eval `ssh-agent`' >> ~/.bashrc

Node the correct quotes, the first ones are single quotes, where as the second are curly single quotes!

Now that the ssh-agent is running, we need to tell it that we have a private key and where that is.

$ ssh-add .ssh/id_dsa
Enter passphrase for .ssh/id_dsa:
Identity added: .ssh/id_dsa (.ssh/id_dsa)

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 ssh-agent needs to be created for every new console (shell) you open, that means you have to run ssh-add every time again on each console. TThere is a workaround to that with a program or rather a script called keychain which is covered in the next section.

Using keychain

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

Edit your ~/.bashrc and add the following lines:

/usr/bin/keychain -Q -q ~/.ssh/id_dsa
[[ -f $HOME/.keychain/$HOSTNAME-sh ]] && source $HOME/.keychain/$HOSTNAME-sh

If necessary, replace ~/.ssh/id_dsa with ~/.ssh/id_rsa. For those using a non-Bash shell, see keychain --help or man keychain for details on other shells.

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.

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 x11-ssh-askpass which will ask your passphrase everytime you open a new Xsession:

# pacman -S x11-ssh-askpass

Prepend this into your ~/.xsession:

eval `/usr/bin/ssh-agent`
SSH_ASKPASS=/usr/lib/openssh/x11-ssh-askpass ssh-add < /dev/null
# then the end of the file with for example "exec dwm"

PuTTY

The above procedure is a bit complicated when using PuTTY on Windows since PuTTY can't directly use keys generated by ssh-keygen. The private key needs to be converted using PuTTYgen which you can find here. The procedure is then as follows:

  1. Generate the key pair with ssh-keygen on you Linux computer (you can log in with your usual username/password using PuTTY)
  2. Add the public key to the ~/.ssh/authorized_keys file
  3. Move the private key to the Windows machine
  4. Load the private key with PuTTYgen and click Save private key. This will convert the key so that PuTTY can use it.
  5. Start PuTTY, go to SSH->Auth and find the private key. Then simply connect to your Linux machine. You will be prompted for your username and passphrase (if you chose to enter one when you generated the keys).

Note that reversing the procedure, that is, generating the key pair with PuTTYgen and converting the public key with ssh-keygen, will NOT work.


Useful links / information