Difference between revisions of "SSH public keys"

From Noah.org
Jump to navigationJump to search
 
(7 intermediate revisions by the same user not shown)
Line 4: Line 4:
 
=== SSH Key Generation Overview with no password ===
 
=== SSH Key Generation Overview with no password ===
  
This shows how to use <b>unencrypted</b> public keys for logging in to a remote SSH server <em>without</em> a password. The basic steps are:
+
This shows how to use ''unencrypted'' public keys for logging in to a remote SSH server ''without'' a password. The basic steps are:
 
 
 
# Create an RSA key-pair with an empty password (no encryption).
 
# Create an RSA key-pair with an empty password (no encryption).
 
# Copy the public key to the remote server.
 
# Copy the public key to the remote server.
Line 11: Line 10:
  
 
Here are those steps as you would actually type them (`ssh-copy-id` does steps 2 and 3):
 
Here are those steps as you would actually type them (`ssh-copy-id` does steps 2 and 3):
 
 
<pre>
 
<pre>
ssh-keygen -q -t rsa -N '' -f ~/.ssh/id_rsa
+
ssh-keygen -q -N '' -f ~/.ssh/id_rsa
 
ssh-copy-id user@remote.example.com
 
ssh-copy-id user@remote.example.com
 
</pre>
 
</pre>
Line 19: Line 17:
 
Here is what you would do without `ssh-copy-id`. This is what `ssh-copy-id` is doing (more or less):
 
Here is what you would do without `ssh-copy-id`. This is what `ssh-copy-id` is doing (more or less):
 
<pre>
 
<pre>
ssh-keygen -q -t rsa -N '' -f ~/.ssh/id_rsa
+
ssh-keygen -q -N '' -f ~/.ssh/id_rsa
 
scp ~/.ssh/id_rsa.pub user@remote.example.com:/tmp/id_rsa.pub
 
scp ~/.ssh/id_rsa.pub user@remote.example.com:/tmp/id_rsa.pub
 
ssh user@remote.example.com "mkdir -p ~/.ssh;chmod 700 ~/.ssh;touch ~/.ssh/authorized_keys;cat /tmp/id_rsa.pub >> ~/.ssh/authorized_keys"
 
ssh user@remote.example.com "mkdir -p ~/.ssh;chmod 700 ~/.ssh;touch ~/.ssh/authorized_keys;cat /tmp/id_rsa.pub >> ~/.ssh/authorized_keys"
 
</pre>
 
</pre>
  
Usually it's bad to use <em>unencrypted</em> public keys for logging in to remote servers without a password. Only use unencrypted keys in limited circumstances where you want a privileged account to have automatic access to a remote server. Examples of this are accounts for backup processes. On the other hand, if you are just looking to make life easier because you don't like typing passwords, then you should learn about `ssh-agent`. That will give you most of the advantages of using unencrypted public keys without the risk.
+
Generally, it's unwise to use '''unencrypted''' public keys for logging in to remote servers. If someone gets access to your private key then they can use it to access any account where the public key has been installed. Only use unencrypted keys in limited circumstances where you want a privileged account to have automatic access to a remote server. Examples of this are accounts for backup processes. On the other hand, if you are just looking to make life easier because you don't like typing passwords, then you should learn about `ssh-agent`. That will give you most of the advantages of using unencrypted public keys without the risk.
 +
 
 +
=== Script to generate user keys ===
 +
 
 +
<pre>
 +
#!/bin/sh
 +
 
 +
# This is a script. This script is the documentation. To read the
 +
# documentation, simply read the script. This script. The one you're reading.
 +
# See? You're doing it. You're reading the documentation.
 +
 
 +
# Options
 +
#
 +
# Pass username as the first argument; otherwise, 'noah' is assumed.
 +
USERNAME=${1:-noah}
 +
 
 +
echo "# Initialize key directory, files, and permissions."
 +
mkdir ~/${LOGNAME}.ssh
 +
chmod 700 ~/${LOGNAME}.ssh
 +
ssh-keygen -q -N '' -f ~/${LOGNAME}.ssh/id_rsa
 +
chmod 600 ~/${LOGNAME}.ssh/id_rsa
 +
chmod 644 ~/${LOGNAME}.ssh/id_rsa.pub
 +
 
 +
echo
 +
echo "# MANUAL STEP: Someone needs to copy ~/${LOGNAME}.ssh/ to remote host."
 +
echo "# MANUAL STEP: Then someone needs to append this to the appropriate"
 +
echo "# authorized_keys file."
 +
echo
 +
echo "# Example connection command that should now work:"
 +
echo "ssh -i ~/${LOGNAME}.ssh/id_rsa ${LOGNAME}@example.com"
 +
</pre>
  
 
=== The `ssh-copy-id` Script ===
 
=== The `ssh-copy-id` Script ===
Line 70: Line 98:
 
<pre>
 
<pre>
 
openssl rsa -des3 -in ~/.ssh/id_rsa -out ~/.ssh/id_rsa
 
openssl rsa -des3 -in ~/.ssh/id_rsa -out ~/.ssh/id_rsa
 +
</pre>
 +
 +
==== Regenerate public key from private key (create id_rsa.pub file from a id_rsa file) ====
 +
 +
You can regenerate a public key from a private key. This can be handy when transferring credentials from one server to another. You only need to copy the private key. The '''-y''' option of '''ssh-keygen''' will output the public key of a private key file.
 +
<pre>
 +
ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub
 +
</pre>
 +
 +
Note that OpenSSH public keys have a '''comment''' field. That's the third field which often contains the username or email address of the owner of the public key. Regenerating the public key from a private key cannot recover this comment field. This does not matter for OpenSSH authentication, but some applications use this field, so beware. In the example below the address '''noah@noah.org''' is the comment field.
 +
<pre>
 +
ssh-rsa AAAAB3NzaC1yc2EAXAADL8lc0Y4yP51/z5OPiE8p0ThbfKGZjEuzfJjuAdBlNuw/g6NJf+t+CdGdQKfQAgkcnUbgy5jUkKkrie8RNFKMu3JwuI9gKUgUfj1DfQLJrrqMgvRMlBCo51p/OvqzDisUJ0YbFw5d4wt/czwadnqV109huoLTBbH5AQABAAABAQC1RZeWyzs0GHcoDWrxnWNRQQBYNYDMLkTzANVQrnPoV4Rj9Ffxgib48YWha+ki5Vvwcq0MDmV4jyYlXJ6y3VP3VL6VpobaBq9O1FTkXc5BAUlfknwxFgFOPJENShJwxC4JiD16vG1BHFNSkgESYdBJ66bcwExRPi3gESGU/OFbfdL/1H8p+Z0B noah@noah.org
 
</pre>
 
</pre>
  
Line 178: Line 218:
  
 
* The SSH2 protocol specifies a format for storing public keys. Some SSH servers (such as ssh.com's) require a public key in this format in order to accept authentication with the corresponding private key. Others, such as OpenSSH, use a different format. I don't know what to do about this.
 
* The SSH2 protocol specifies a format for storing public keys. Some SSH servers (such as ssh.com's) require a public key in this format in order to accept authentication with the corresponding private key. Others, such as OpenSSH, use a different format. I don't know what to do about this.
* When cutting and pasting the public key BEWARE that it should be a single line. If you cut and paste from a terminal window then it is likely that you will get newline characters added where your terminal wrapped the line. If you use vi then the line may wrap and APPEAR to be multiple lines, but it is really one single line. When you paste it to a new window it may look the same, but the copy will likely contain newline characters. This will not work.
+
* When cutting and pasting the public key beware that '''it should be a single line'''. If you cut and paste from a terminal window then it is possible that you will get newline characters added where your terminal or text editor wrapped the line.
* Make sure you are using the correct version. Earlier versions of OpenSSH used two files, authorized_keys and authorized_keys2. Secure SSH uses something else with keys in an entirely different format.
+
*. Earlier versions of OpenSSH used two files, '''authorized_keys''' and '''authorized_keys2'''. Secure SSH uses something else with keys in an entirely different format.
  
 
== Newbie SSH Notes ==
 
== Newbie SSH Notes ==
Line 192: Line 232:
  
 
You can further secure your Private Key by encrypting it
 
You can further secure your Private Key by encrypting it
so that you need a pass work to use it. This way
+
so that you need a password to use it. This way
even if someone gets a copy of your Private Key that
+
even if someone gets a copy of your Private Key they
 
won't be able to use it.
 
won't be able to use it.
  

Latest revision as of 11:22, 27 March 2015


SSH Key Generation Overview with no password

This shows how to use unencrypted public keys for logging in to a remote SSH server without a password. The basic steps are:

  1. Create an RSA key-pair with an empty password (no encryption).
  2. Copy the public key to the remote server.
  3. Add the public key to the authorized_keys file on the remote server.

Here are those steps as you would actually type them (`ssh-copy-id` does steps 2 and 3):

ssh-keygen -q -N '' -f ~/.ssh/id_rsa
ssh-copy-id user@remote.example.com

Here is what you would do without `ssh-copy-id`. This is what `ssh-copy-id` is doing (more or less):

ssh-keygen -q -N '' -f ~/.ssh/id_rsa
scp ~/.ssh/id_rsa.pub user@remote.example.com:/tmp/id_rsa.pub
ssh user@remote.example.com "mkdir -p ~/.ssh;chmod 700 ~/.ssh;touch ~/.ssh/authorized_keys;cat /tmp/id_rsa.pub >> ~/.ssh/authorized_keys"

Generally, it's unwise to use unencrypted public keys for logging in to remote servers. If someone gets access to your private key then they can use it to access any account where the public key has been installed. Only use unencrypted keys in limited circumstances where you want a privileged account to have automatic access to a remote server. Examples of this are accounts for backup processes. On the other hand, if you are just looking to make life easier because you don't like typing passwords, then you should learn about `ssh-agent`. That will give you most of the advantages of using unencrypted public keys without the risk.

Script to generate user keys

#!/bin/sh

# This is a script. This script is the documentation. To read the
# documentation, simply read the script. This script. The one you're reading.
# See? You're doing it. You're reading the documentation.

# Options
#
# Pass username as the first argument; otherwise, 'noah' is assumed.
USERNAME=${1:-noah}

echo "# Initialize key directory, files, and permissions."
mkdir ~/${LOGNAME}.ssh
chmod 700 ~/${LOGNAME}.ssh
ssh-keygen -q -N '' -f ~/${LOGNAME}.ssh/id_rsa
chmod 600 ~/${LOGNAME}.ssh/id_rsa
chmod 644 ~/${LOGNAME}.ssh/id_rsa.pub

echo
echo "# MANUAL STEP: Someone needs to copy ~/${LOGNAME}.ssh/ to remote host."
echo "# MANUAL STEP: Then someone needs to append this to the appropriate"
echo "# authorized_keys file."
echo
echo "# Example connection command that should now work:"
echo "ssh -i ~/${LOGNAME}.ssh/id_rsa ${LOGNAME}@example.com"

The `ssh-copy-id` Script

OpenSSH comes with `ssh-copy-id` which makes it much easier to setup your local host to connect to a remote server via SSH. This will put your key on the remote server example.com. After doing this you will be able to connect using your key. If your key is unencrypted then you will be able to connect without a password. If the key is encrypted and ssh-agent is not running then you will have to enter your key password (not to be confused with the account password on the remote server).

ssh-copy-id username@example.com

SSH key fingerprint

Some tools will store public keys and then refer to them by their fingerprint. If you don't know the fingerprint to your own key then this can be confusing. This command will show the fingerprint of your default public key:

ssh-keygen -lf ~/.ssh/id_rsa.pub
ssh-keygen -lf ~/.ssh/id_dsa.pub

Creating an encrypted key

Having an key pair with an unencrypted private key is dangerous. If anyone gets access to your private key this is as good as having your password. This creates an encrypted key in ~/.ssh/id_rsa:

ssh-keygen

If you want to change the default output to some other file besides ~/.ssh/id_rsa:

ssh-keygen -f /tmp/id_rsa.example

Unencrypt your existing key

You can remove the encryption from a key. If you do this then then you can connect from your local machine to the remote password without any password. You may also do this if you want to change the password. Just remove the old encryption then encrypt it again. To unencrypt:

openssl rsa -in ~/.ssh/id_rsa -out ~/.ssh/id_rsa

Encrypt your existing key

If you want to require a password then encrypt the key. This assumes that your key is not already encrypted. This will overwrite your key. To encrypt:

openssl rsa -des3 -in ~/.ssh/id_rsa -out ~/.ssh/id_rsa

Regenerate public key from private key (create id_rsa.pub file from a id_rsa file)

You can regenerate a public key from a private key. This can be handy when transferring credentials from one server to another. You only need to copy the private key. The -y option of ssh-keygen will output the public key of a private key file.

ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub

Note that OpenSSH public keys have a comment field. That's the third field which often contains the username or email address of the owner of the public key. Regenerating the public key from a private key cannot recover this comment field. This does not matter for OpenSSH authentication, but some applications use this field, so beware. In the example below the address noah@noah.org is the comment field.

ssh-rsa AAAAB3NzaC1yc2EAXAADL8lc0Y4yP51/z5OPiE8p0ThbfKGZjEuzfJjuAdBlNuw/g6NJf+t+CdGdQKfQAgkcnUbgy5jUkKkrie8RNFKMu3JwuI9gKUgUfj1DfQLJrrqMgvRMlBCo51p/OvqzDisUJ0YbFw5d4wt/czwadnqV109huoLTBbH5AQABAAABAQC1RZeWyzs0GHcoDWrxnWNRQQBYNYDMLkTzANVQrnPoV4Rj9Ffxgib48YWha+ki5Vvwcq0MDmV4jyYlXJ6y3VP3VL6VpobaBq9O1FTkXc5BAUlfknwxFgFOPJENShJwxC4JiD16vG1BHFNSkgESYdBJ66bcwExRPi3gESGU/OFbfdL/1H8p+Z0B noah@noah.org

Permission problems with SSH

Ssh is very picky about permissions on the ~/.ssh directory and files. Sometimes you may do something to mess up these permissions. Run the following to fix most permissions problems. You may have to do this on both the remote host and local host.

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub  
chmod 644 ~/.ssh/authorized_keys
chmod 644 ~/.ssh/known_hosts

Also no directory above ~/.ssh can have 'group' or 'other' write permissions.

SSH Agent

When you ssh to a remote server where you have previously added your public key to authorized_keys then the remote server will ask your ssh client to confirm your public key. If your private key is not encrypted then your ssh client will confirm the keys without your help. If your private key is encrypted then your ssh client will ask you for your password to decrypt your private key.

You can have ssh cache your private key password so that you only need to enter it once. To do this, ssh uses ssh-agent to cache passwords. The ssh-agent sits in the background and caches the password to your private keys. On most desktop distros such as Ubuntu an ssh-agent is started when you login. The ssh-agent doesn't do anything until you add a private key to the cache. This will add your private key to the ssh-agent cache.

ssh-add

The agent will ask you for your password. Now the agent running in the background has your password and private key. When the ssh client later needs to confirm a public key it will first ask the ssh-agent if it has the key and password cached. If it does then the ssh client can confirm your keys without your help.

Debugging Your Agent

Most distros that feature a display manager such as xdm, gdm, or kdm will start an ssh-agent when you login. This is started as part of the xinit process. For example if you use KDE, then kdm is your display manager. Kdm will start X, which starts startkde, which starts ssh-agent.

root      4100  0.0  0.0   2688   640 ?        Ss   18:18   0:00 /usr/bin/kdm
root      4116  2.6  1.5  35236 23788 tty7     Ss+  18:18   0:16  \_ /usr/bin/X -br -nolisten tcp :0 vt7 -auth /var/run/xauth/A:0-HgufQc
root      4130  0.0  0.0   3664  1388 ?        S    18:18   0:00  \_ -:0         
noah      4896  0.0  0.0   1660   504 ?        Ss   18:19   0:00      \_ /bin/sh /usr/bin/startkde
noah      5113  0.0  0.0   4480  1004 ?        Ss   18:19   0:00          \_ /usr/bin/ssh-agent /usr/bin/dbus-launch --exit-with-session /usr/bin/startkde
noah      5168  0.0  0.0   1580   352 ?        S    18:19   0:00          \_ kwrapper ksmserver

You can check if an agent is running by using this command:

$ ps auxww | grep agent
noah      5113  0.0  0.0   4480  1004 ?        Ss   18:19   0:00 /usr/bin/ssh-agent /usr/bin/dbus-launch --exit-with-session /usr/bin/startkde

If you don't have an agent running you can put one in your .xsession. Or you can run it manually at any time from the command line:

$ exec ssh-agent bash

Older notes

steps on local and remote servers
local server remote server
ssh-keygen -t rsa

Press enter when it asks you for a passphrase. This will set no passphrase. Or use

 ssh-keygen -t rsa -N 

to set an empty new password.

This generates the following files under ~/.ssh/

  • id_rsa -- Keep this secret!
  • id_rsa.pub -- Copy this to Remote
Copy id_rsa.pub to remote server:
scp ~/.ssh/id_rsa.pub user@remote.example.com:/tmp/id_rsa.pub

You will still need your password at this point.

Append /tmp/id_rsa.pub key to ~/.ssh/authorized_keys:
cat /tmp/id_rsa.pub >> ~/.ssh/authorized_keys

If you get an error saying "~/.ssh/authorized_keys: No such file or directory" it means that there is no .ssh directory for this user (this user has never used ssh before). Simply create an empty .ssh directory with 700 permissions:

mkdir ~/.ssh
chmod 700 ~/.ssh
You should now be able to ssh to the remote server without a password:
ssh user@remote.example.com

Things that often cause trouble

These are usually only problems when working with older SSH servers.

  • The SSH2 protocol specifies a format for storing public keys. Some SSH servers (such as ssh.com's) require a public key in this format in order to accept authentication with the corresponding private key. Others, such as OpenSSH, use a different format. I don't know what to do about this.
  • When cutting and pasting the public key beware that it should be a single line. If you cut and paste from a terminal window then it is possible that you will get newline characters added where your terminal or text editor wrapped the line.
  • . Earlier versions of OpenSSH used two files, authorized_keys and authorized_keys2. Secure SSH uses something else with keys in an entirely different format.

Newbie SSH Notes

Create a key pair

This creates a Public Key and a Private Key. The Public Key is what you can give to other people. Key is a bit of a misnomer. It's really more of a Public Lock. You keep the key. You can give the lock to anyone and they can lock stuff with it, but they can't unlock it. They can give you the locked data and only you can unlock it with your Private Key.

You can further secure your Private Key by encrypting it so that you need a password to use it. This way even if someone gets a copy of your Private Key they won't be able to use it.

Copy Public Key to remote server

Start a Key Agent

Add your private key to the Agent