How to: passwordless ssh
How do I set up a ssh connection between my local client and a remote machine? Which key should I use? How do I setup a passwordless ssh?
AWS has made virtual machines (EC2) ubiquitous. You can launch and stop them as will, log into them, create new accounts, etc. Then you start digging into remote control for multiple users. How do I set up a ssh connection between my local client and a remote machine? Which key should I use? How do I setup a passwordless ssh? These are the practical questions answered in this post.
ssh, which stands for Secure Shell, is a network protocol that establishes an encrypted communication between two hosts. It is used to securely launch a command on a remote host, to log into that host, or to securely move files between the two hosts (via the command scp
). It uses public and private keys to establish a handshake between the two hosts, so that they can agree on a fast cipher for the rest of the communication.
Assume you are user johnsmith on localhost, and you want to set up a passwordless ssh as johnny on remotehost. First thing you need is to generate your public and private keys. This is done with ssh-keygen
:
johnsmith@localhost:~$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/johnsmith/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in id_rsa. Your public key has been saved in id_rsa.pub. The key fingerprint is: a1:81:5a:05:d0:be:fe:cd:27:37:aa:58:57:24:c1:70 johnsmith@localhost The key's randomart image is: +--[ RSA 2048]----+ | .o..ooE | | .o ... | | .o . o . | | o. o + | | . .. S . | | . . | | . . . | | .o +. + | | ..o.+= . | +-----------------+
You will be prompted for a key name and a passphrase. Leave the passphrase empty. By default the public and private keys are stored in directory ~/.ssh
as id_rsa.pub
and id_rsa
respectively. You can choose to name the keys as you please. This is useful when you want to access different remote systems with different keys –more on this later.
The type of the key, indicated with the option –t
, is either rsa
or dsa
. It describes the cryptographic algorithm used for the handshake. It is still debated whether RSA or DSA is better. I would recommend RSA though because:
ssh-keygen
forces the DSA key to be exactly 1024 bits. On the other hand, the RSA key bit length can be set using the–b
option, up to 2^15 = 32768 bits. The RSA key is 2048 bits by default, which is considered safe.- DSA is pushed by government agencies…
Whenever you ssh the remote host as johnny, you need to enter johnny’s password. That is not practical when writing scripts that invoke commands on remote machines. Also a password can be guessed or stolen –using brute-force approaches, or with social engineering techniques (phishing, impersonation, etc).
Much more practical and safer is to have a passworless ssh. We are going to allow public key-based authentication on the remote host. This means that a guest with a private key that matches a public key authorized by the remote host will be granted access without a password.
First, we need to add your public key to the remote host’s set of authorized key. Simply login to the remote host, edit its ~/.ssh/authorized_keys
file, and cut-and-paste your public key (in our example, id_rsa.pub
) to the file. We can also use scp
to transfer the file. scp
stands for Secure Copy, and is built on top of ssh:
# Copy the public key on the remote host as 'foo' johnsmith@localhost:~$ scp ~/.ssh/id_rsa.pub johnny@remotehost:foo johnny@remotehost's password: id_rsa.pub 100% 425 0.4KB/s 00:00 # Log into remote host johnsmith@localhost:~$ ssh johnny@remotehost johnny@remotehost's password: johnny@remotehost> # Add the public key to the authorized keys johnny@remotehost> cat foo >> ~/.ssh/authorized_keys ; rm foo
Make sure that the file permission is proper: the .shh
files may not be written or read but by the user.
johnny@remotehost> chmod 700 ~/.ssh johnny@remotehost> chmod 600 ~/.ssh/authorized_keys johnny@remotehost> ls –al ~/.ssh total 12 drwx------ 2 johnny johnny 4096 Oct 25 01:39 ./ drwx--x--- 19 johnny nobody 4096 Oct 26 04:31 ../ -rw------- 1 johnny johnny 425 Oct 25 01:39 authorized_keys
Finally, make sure that the remote host’s ssh
is configured for public key-based recognition. Look for the following lines in the /etc/sshd/sshd_config
file, which configures the ssh server:
PubkeyAuthentication yes RSAAuthentication yes PasswordAuthentication no
The first two lines authorize authentication with an RSA public key. The third line specifies whether a username + password authentication is allowed. If set to no
, only passwordless ssh is allowed on the remote host: password cracking on the host becomes irrelevant. You can access the remote host only if you have the correct private key.
Note that if you need to modify the /etc/sshd/sshd_config
configuration file, you will have to restart the ssh server:
johnny@remotehost> /etc/init.d/ssh restart
That’s it. The remote host will grant (passwordless) access to guests with the appropriate private key only –no more password. Your local client is the only system to store your private key, thus only you can access the remote host.
If you want to manage several remote systems independently, you can create a key pair for each system, for instance naming the keys host1_id.pub
and host1_id
for host host1
. You can then ssh a specific host using the –i
option to authenticate yourself with the appropriate private key, e.g.:
johnsmith@localhost:~$ ssh –i ~/.ssh/host2_id johnny@host2.com 'echo "I am `who am i` on `hostname`"' I am johnny on host2 johnsmith@localhost:~$
Have fun with your array of remote hosts, and be safe!