Setting up an account on a Linux system that allows you to log in or run commands remotely without a password isn’t all that hard, but there are some tedious details that you need to get right if you want it to work. In this post, we’re going to run through the process and then show a script that can help manage the details.
Once set up, passwordless access is especially useful if you want to run ssh commands within a script, especially one that you might want to schedule to run automatically.
It’s important to note that you do not have to be using the same user account on both systems. In fact, you can use your public key for a number of accounts on a system or for different accounts on multiple systems.
Here’s how to set this up.
Which system to start on?
First, you need to start on the system from which you want to issue commands. That's the system that you will use to create the ssh keys. You also need to have access to the account on the remote system on which those commands will be run.
To keep the roles clear, we’ll call that first system in our scenario the “boss” since it will issue commands to be run on the other system.
Thus, the command prompt:
boss$
If you do not already have a public/private key pair set up for your account on the boss system, create one using a command like that shown below. Note that you can choose between the various encryption algorithms. (Either RSA or DSA is generally used.) Note that to access the system without typing a password, you will need to enter no password for the two prompts shown in the dialog below.
If you already have a public/private key pair associated with this account, skip this step.
boss$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/myself/.ssh/id_rsa): Enter passphrase (empty for no passphrase): <== just press the enter key Enter same passphrase again: <== just press the enter key Your identification has been saved in /home/myself/.ssh/id_rsa. Your public key has been saved in /home/myself/.ssh/id_rsa.pub. The key fingerprint is: SHA256:1zz6pZcMjA1av8iyojqo6NVYgTl1+cc+N43kIwGKOUI myself@boss The key's randomart image is: +---[RSA 3072]----+ | . .. | | E+ .. . | | .+ .o + o | | ..+.. .o* . | | ... So+*B o | | + ...==B . | | . o . ....++. | |o o . . o..o+ | |=..o.. ..o o. | +----[SHA256]-----+
The command shown above will create both a public and a private key. What one encrypts, the other will decrypt. So, the relationship between these keys is critical and the private key should never be shared. Instead, it should stay in your .ssh folder on the boss system.
Notice that your public and private keys, on creation, will be saved in your .ssh folder.
The next step is to copy the public key to the system you want to access from the boss system without using a password. You can use scp to do this though, at this point, you’ll still need to enter your password. In this example, that system is called “target”.
boss$ scp .ssh/id_rsa.pub myacct@target:/home/myaccount myacct@target's password:
On the target system (the one on which the commands will be run), you will need to install your public key. If you don’t have a .ssh directory (e.g., if you’ve never used ssh on that system), running a command like this will set one up for you:
target$ ssh localhost date target$ ls -la .ssh total 12 drwx------ 2 myacct myacct 4096 Jan 19 11:48 . drwxr-xr-x 6 myacct myacct 4096 Jan 19 11:49 .. -rw-r--r-- 1 myacct myacct 222 Jan 19 11:48 known_hosts
Still on the target system, you then need to add the public key you transferred from the “boss” system to your .ssh/authorized_keys file. The command below will add the key to the end of the file if it exists already or create the file and add the key if the file does not exist.
target$ cat id_rsa.pub >> .ssh/authorized_keys
Next, you need to make sure that the permissions on your authorized_keys file are set to 600. If not, run the chmod 600 .ssh/authorized_keys command.
target$ ls -l authorized_keys -rw------- 1 myself myself 569 Jan 19 12:10 authorized_keys
Also check to be sure that permissions on your .ssh directory on the target system are set to 700. Fix the permissions with chmod 700 .ssh if needed.
target$ ls -ld .ssh drwx------ 2 myacct myacct 4096 Jan 14 15:54 .ssh
At this point, you should be able to run a command remotely from your boss system to your target system without entering a password. This should work unless the target user account on the target system has an old public key for the same user and host as the one you’re trying to connect from. If so, you should be able to remove the earlier (and conflicting) entry.
Using a script
Using a script can make some work a lot easier. In the example script below, however, the one annoying problem that you’ll run into is that you’ll have to enter the target user’s password numerous times before the password-free access is configured. One option would be to break the script into two parts – the commands that need to be run on the boss system and the commands that need to be run on the target system.
Here’s the do-it-all version of the script:
#!/bin/bash # NOTE: This script requires that you have the password for the remote acct # in order to set up password-free access using your public key LOC=`hostname` # the local system from which you want to run commands from # wo a password # get target system and account echo -n "target system> " read REM echo -n "target user> " read user # create a key pair if no public key exists if [ ! -f ~/.ssh/id_rsa.pub ]; then ssh-keygen -t rsa fi # ensure a .ssh directory exists in the remote account echo checking for .ssh directory on remote system ssh $user@$REM "if [ ! -d /home/$user/.ssh ]; then mkdir /home/$user/.ssh; fi" # share the public key (using local hostname) echo copying the public key scp ~/.ssh/id_rsa.pub $user@$REM:/home/$user/$user-$LOC.pub # put the public key into the proper location echo adding key to authorized_keys ssh $user@$REM "cat /home/$user/$user-$LOC.pub >> /home/$user/.ssh/authorized_ke ys" # set permissions on authorized_keys and .ssh (might be OK already) echo setting permissions ssh $user@$REM "chmod 600 ~/.ssh/authorized_keys" ssh $user@$REM "chmod 700 ~/.ssh" # try it out -- should NOT ask for a password echo testing -- if no password is requested, you are all set ssh $user@$REM /bin/hostname
The script has been configured to tell you what it is doing each time you will have to enter a password. Interaction will look something like this:
$ ./rem_login_setup target system> fruitfly target user> lola checking for .ssh directory on remote system lola@fruitfly's password: copying the public key lola@fruitfly's password: id_rsa.pub 100% 567 219.1KB/s 00:00 adding key to authorized_keys lola@fruitfly's password: setting permissions lola@fruitfly's password: testing -- if no password is requested, you are all set fruitfly
After the scenario shown above, you'd be able to log into lola's account on fruitfly like this:
$ ssh lola@fruitfly [lola@fruitfly ~]$
Once passwordless login is set up, you’ll both be able to log in from the boss system to the target system without a password and run arbitrary ssh commands. Running without a password in this way does not imply that your account is less secure. However, protecting your password on the boss system could become considerably more important depending on the nature of the target.