Tricks for making ssh/scp connections better

Secure connections can be even more secure or even less troublesome if you use a key pair and do it right.

Both ssh and scp work fine when used with your account password. But when you use a public/private key pair to make your connections to systems, your connections require that both the key and the passphrase be provided. So, you're taking advantage of an additional level or protection. Anyone wanting to break into your account would need both your private key and your passphrase -- not just your password -- to log in. Basically, a "passphrase" serves as a password, but the term is meant to be something of a reminder that you should make it more elaborate than the 12 letters and numbers or so that you might normally use. Your passphrase might be "Take me out to the ball game" or "Is there anybody out there?". Better yet, toss in some gobbledygook so that even your friends who know you love baseball or Pink Floyd won't have a clue. When you create a public/private key pair, you will end up with two files -- one that contains your private key and one that contains your public key. They're easy to tell apart because one (the public one) ends in ".pub".

-rw------- 1 shs techies 1675 Jan 12 13:41 rsa_key
-rw-r----- 1 shs techies  400 Jan 12 13:41

If you create your key pair using a passphrase, you will likely notice that the private key file is using an additional level of encryption. The top of your private key file will look something like this. Notice lines 2 and 3.

$ head -8 id_rsa
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,F39B8F8B92963017


This file is an ASN.1 data structure and is serialized using DER and then base64-encoded. These terms relate to how the data in the files are represented, encoded, decoded and transmitted independently of machine-specific encoding. If you don't use a passphrase, your file will look something like this:

$ head -6 rsa_test

Using a passphrase gives you an extra layer of security and is a highly recommended practice. There are, however, times -- such as when you want to automate a process that moves files between systems or run commands remotely -- that a passphrase-free connection is really the only way to go. If you can't be at your desk at 1 AM to enter the passphrase when you want to transmit an important files between systems, setting up a connection that doesn't require one is both appealing and a very good option. And, fortunately, it's a fairly easy process, too -- as long as you're careful about a few things. So, if you want to automate tasks or simplify connections with other systems, you can forgo the need to manually enter a password (or passphrase) by setting up an account so that you can connect without one.

Step 1

The first step is to create your key pair. Generally, you would do this on the "client" system -- the one that initiates the connections. The public and private keys are not tied to the system, however. They're really tied to each other. In other words, only keys that are created as a pair are of any use. They are mathematically related. In fact, you could create your key pairs on a completely separate system if you really wanted to. The command to create a key pairs is ssh-keygen, but you can use the ssh-keygen command with or without additional options. If you simply enter ssh-key, you will be asked to provide a passphrase -- twice -- and you will generate an rsa key pair.

$ ssh-keygen
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:

Alternately, you could provide an empty passphrase on the command line like this:

$ ssh-keygen -N ''

The two keys that are created are your public key (the that ends in .pub) and your private key.

-rw------- 1 shs techies 1675 Jan 12 12:22 id_rsa
-rw------- 1 shs techies  400 Jan 12 12:22

The (excuse the pun) "key" is to keep your private keep private, no matter what. You will need it on the system from which you will initiate connections. Only your public key (the one that ends in .pub) should be copied to the system(s) you want to connect to. And keep in mind that you can use a single public key to connect to as many systems as you'd like. If I have accounts on 50 servers, have all those servers set up for password-free login, and then want to be able to push a file to each of them, I could do that easily like this -- much less painful that typing a password, never mind a passphrase, never mind a *different* per-host password! While this setup might save you a lot of pain, don't overlook how much it increases the need to keep you base system (i.e., the one you are ssh'ing from) that much more secure.

$ for sys in `cat server-list`
> do
>   scp myfile.conf $sys:/apps
> done

To generate a key pair, you would use the ssh-keygen command. If you don't specify, it will default to using rsa. If you use -N '' as an argument string, you won't even be prompted for a passphrase.

$ ssh-keygen -N '' -f rsa_key
Generating public/private rsa key pair.
Your identification has been saved in rsa_key.
Your public key has been saved in
The key fingerprint is:

You can check the length of an existing key with another ssh-keygen command. Keep in mind that key lengths are in bits, not bytes, so the file size won't tell you what you want to know.

$ ssh-keygen -l -f
2048 98:d3:c7:5b:f9:fd:f8:1b:e1:a6:41:54:9f:1a:09:66

Notice the 2048 at the beginning of the output. That is the key length. If you use -b (bits), you could make your key longer and, presumably, even more secure.

$ ssh-keygen -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/home/shs/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/shs/.ssh/id_rsa.
Your public key has been saved in /home/shs/.ssh/
The key fingerprint is:

Step 2

Next, copy your public key to the system that you want to connect to in a password-free fashion. If you don't already have a .ssh folder on that system, you will have to create one. On the local system:

$ scp ~/.ssh/rsa_key yourlogin@remhost:~yourlogin

On the remote (target) system:

$ mkdir ~/.ssh
$ chmod 700 ~/.ssh

Step 3

Put your public key in your .ssh/authorized_keys file on the remote system. The authorized_keys file tells the remote system which users and systems should be trusted to log in with your key. $ ls *pub -rw-r----- 1 shs techies 400 Jan 12 12:22 $ cat >> ~/.ssh/authorized_keys And, just in case your permissions are not right:

$ chmod 600 ~/.ssh/authorized_keys

In fact, you could chmod 600 everything in your .ssh directory. Remember that ssh will ignore keys and prompt for a password if it doesn't like the permissions on your files. If you get prompted for a password when you should be set up for password-free ssh, check your permissions. That's a likely place to find problems.

Step 4

Check it out. Use an scp or ssh command to test your setup.

$ ssh remotesystem date
Sun Jan 12 15:35:07 EST 2014
$ echo "OK, this should work" > hope
$ scp hope shs@remotesystem
hope                     100%    9     0.0KB/s   00:00

Whenever I've run into a problem with passphrase-free ssh/scp and been prompted for my password instead of my passphrase, the problem boiled down to some file permissions not being quite right. Keep in mind that ssh can be very picky about about permissions and will often refuse to cooperate if your settings are not just right. Error on the side of caution. Nothing in your .ssh directory should require group or world permissions of any kind.

Read more of Sandra Henry-Stocker's Unix as a Second Language blog and follow the latest IT news at ITworld, Twitter and Facebook.

Join the Network World communities on Facebook and LinkedIn to comment on topics that are top of mind.
Take IDG’s 2020 IT Salary Survey: You’ll provide important data and have a chance to win $500.