This page describes some of the ways in which SSH key-based authentication may fail, and some of the steps you can take to solve your problems. Key authentication failure is probably the single most common problem new users of SSH experience, and answering these questions repeatedly is exhausting.... == Overview == This overview describes the basic concepts of public key authentication for those who don't know much about it yet. Public key authentication involves the use of cryptography to ''prove'' that you possess certain credentials, without actually revealing those credentials to the other party. Specifically, the client holds a ''private key'', which may or may not be encrypted with a ''pass phrase''. The server holds the ''public key''. The client and server use a [[WikiPedia:Zero-knowledge proof]] method, in which the client ''proves'' that it holds the private key, but does not actually transmit the private key. Setting it up requires a few steps. First, a ''key pair'' (private and public keys) is generated on the client system. Then, the public key is copied to the server, (appended) to the file `~username/.ssh/authorized_keys` (a simple text file). This file tells the `sshd` program on the server that the holder of the private key which ''matches'' the public key is allowed to login as "username". The public key is not secret information, and does not need to be protected. If someone copies your public key to their own `authorized_keys` file, this only hurts ''them'', not you -- it allows you to login to their system. The private key ''is'' secret information, and should be protected as such. The private key is normally encrypted using a ''pass phrase'', which must be entered in the client system before the private key can be used. The private key's pass phrase has nothing to do with the server's ''password'' (if the server has such a thing). The two should not be confused. == Setup == Most of the commands shown on this page assume that you are using OpenSSH. There are equivalents in other implementations; they may sometimes have different names (for example, {{{ssh-keygen2}}} or {{{puttygen}}}). When in doubt, consult your documentation. For starters, please read {{{man ssh-keygen}}} (or its equivalent) on your system. This describes the basic process of generating a key pair, and then putting the public key onto the server. SSH has two ''protocols'' for communications, which are cleverly called "protocol 1" and "protocol 2". Protocol 1 is considered obsolete, and should not be used. Nevertheless, until recently, the default setting for {{{ssh-keygen}}} in [[http://www.openssh.org/|OpenSSH]] was to generate a protocol-1 keypair. So, you should always explicitly specify which type of keypair you want to generate. Protocol 2 offers several different algorithms for public key authentication. DSA is deprecated, and should no longer be used. That leaves (currently) RSA, ECDSA and ED25519. RSA was encumbered by patents a few years ago. Those patents have now expired, and RSA is the default in recent versions of OpenSSH. The other two algorithms are newer, and may not be as widely supported. So, choose your algorithm and then run the appropriate `ssh-keygen` command: {{{ ssh-keygen -t rsa # or ssh-keygen -t ecdsa # or ssh-keygen -t ed25519 }}} Note that keypair generation is usually done on the '''client''' so that the private key never needs to be transmitted anywhere. You'll be prompted for the location of your keypair (just hit Enter to accept the defaults), and the passphrase. If you use a passphrase, the private key will be encrypted. Every time the SSH client needs to read the private key, it will need to use your passphrase to open it -- either by prompting you for it, or by getting it from {{{ssh-agent}}}. This provides you with some security against theft of the private key. If you don't use a passphrase, then anyone who obtains your private key (for example, from a backup of your home directory) will be able to use it. (Setting up [[SshAgent|ssh-agent]] is not covered here.) When {{{ssh-keygen}}} is done, you will have two files, with names depending on the algorithm. Assuming you chose RSA: {{{ $HOME/.ssh/id_rsa # Private key $HOME/.ssh/id_rsa.pub # Public key }}} If you generated an ECDSA or ED25519 keypair, or if you're using a different implementation, the names will differ. Your '''private''' key should always be kept secret. If you used a passphrase, it is also encrypted. The '''public''' key should be copied to the '''server''' where {{{sshd}}} can read it. Now, before you do that, you need to realize that there are two different ''formats'' in which the public key may be stored: OpenSSH format, or SECSH format. You may need to convert the public key to whichever format the {{{sshd}}} implementation on your server knows how to read. If you generated the keypair using OpenSSH, then (obviously) your public key will be in OpenSSH format. If the {{{sshd}}} on your server is OpenSSH (which you can determine by using {{{telnet server.hostname 22}}} and reading the banner), then your key does not need conversion. If your server is running an implementation that uses the SECSH format, then you'll need to convert your public key to that format. {{{ssh-keygen}}} has flags for doing that; read the man page to see how. Likewise, if you generated your keypair using PuTTY (or something else that uses the SECSH format), and your server runs OpenSSH, then you'll need to convert your public key to OpenSSH format. Once the key is in the correct format, it should be placed into the '''file''' (not directory) named {{{$HOME/.ssh/authorized_keys}}} on the server. If you have connected to this server before, or if you've used the {{{ssh}}} client on this server before, then the {{{$HOME/.ssh}}} directory should already exist; and then all you'll need to do is concatenate your public key to the end of the {{{authorized_keys}}} file. (Some people like to use the `ssh-copy-id` program to copy their public key into the `authorized_keys` file on a server. See `man ssh-copy-id` for instructions, if your version of SSH has it.) == Troubleshooting == If you try to connect to the server, and you are still prompted for a password, then the server may have refused to honor your key. If this is the case, there are a few things you should check. The first is to make sure you understood whether you were actually being prompted for a ''password'' (by the server), or a ''pass phrase'' (by the client). If the client needs a pass phrase to decrypt the private key, this is quite different from the server rejecting the key and falling back to password authentication. This is an example of the client asking for a pass phrase: {{{ cyclops:~$ ssh golem Enter passphrase for key '/home/greg/.ssh/id_rsa': }}} This is an example of the server asking for a password: {{{ imadev:~$ ssh vandev wooledg@vandev's password: }}} Second, please note that the {{{authorized_keys}}} file uses the American spelling, not the British spelling. If you put the key into `authorised_keys` it will not work. Third, make sure that you copied the '''public key''' to the server, and not the private key. If it's not one of those, then you need to check the [[Permissions]] on everything. OpenSSH will refuse to honor your public key if it's in a place where other users might be able to write their own public keys. (If another user can write to your {{{authorized_keys}}} file, then she can put her own key there, and then login as you.) This is the part that many people mess up. Not only do you have to ensure that the {{{authorized_keys}}} file itself has no group- or world-write permission; but you also must make sure that '''every directory in the full path''' to that file is similarly free of group- or world-write permissions. For example: {{{ wooledg@hostname:~$ echo $HOME /home/wooledg wooledg@hostname:~$ ls -ld / /home /home/wooledg /home/wooledg/.ssh drwxr-xr-x 21 root root 4096 2007-07-03 08:57 / drwxrwsr-x 3 root staff 4096 2006-07-20 14:32 /home drwxr-sr-x 25 wooledg wooledg 4096 2007-07-17 17:00 /home/wooledg drwx--S--- 2 wooledg wooledg 4096 2006-07-20 14:40 /home/wooledg/.ssh ^ +-- Group write permission. }}} In many implementations, the presence of the group-write permission bit on the {{{/home}}} directory would cause {{{sshd}}} to reject an {{{authorized_keys}}} file in this user's {{{.ssh}}} directory. (There are some configuration settings that can change that, but it's typically easier and better to fix permissions on too-loose directories rather than removing SSH's safety precautions.) (Somewhere around OpenSSH 3.0 -- exact version number unknown -- the permissions on directories "above" the user's home directory stopped being checked. So, the liberal permissions on `/home` would not cause a problem in sufficiently new versions of OpenSSH. Still, it doesn't hurt to fix them.) == Further debugging == If none of the tips in the Troubleshooting section fixed the problem, then it may be time to dig deeper. First of all, it is imperative to note that ''the server will not tell the client why a key is rejected''. This is intentional, to prevent leaking information to an attacker. Therefore, no amount of `ssh -vvvv` will be of any use whatsoever. The rejection of a key cannot be diagnosed from the client side at all. A key rejection can sometimes be diagnosed from the ''server'' side, however. You will most likely need superuser (root) privileges to do so. Start by looking for a place where sshd is already logging information; often, this may be the `/var/log/auth.log` file, or some similar file. See if a reason for rejection is stated there. If not, or if no such file exists yet, then you may wish to start up a second instance of sshd on an alternative port: {{{ server# sshd -p 2200 -d }}} Keep that window open, as the debugging information is written to standard output. Then on the client, connect to the alternative port: {{{ client$ ssh -p 2200 username@server }}} If the key is rejected, a reason for the rejection should be revealed on the server. == tl;dr == For the impatient who just skimmed this to the bottom, let's recap: 1. The '''private''' key lives on the client. The '''public''' key is created on the client and gets copied to the server. Make sure you don't mix this up. 1. The '''authorized_keys''' file on the server must be spelled correctly. 1. The [[Permissions]] on '''every directory in the path to authorized_keys''' starting from root must '''not''' be group- or world-writable. ---- CategorySsh CategoryUnix