SSH keys

This is the last in my short series of screenshot posts. The first two cover the macro/scripts SnapClip and SnapSCP; this one isn’t about screenshots per se, but it describes how to set up SSH keys on your both your server and your local Mac so the SnapSCP macro can upload your screenshots securely without forcing you to type in a password or passphrase.

Let me start by saying that not a single bit of this post is original. In fact, I don’t really know much about SSH, SSH keys, or the ssh-agent program. I’m just collecting instructions from various sources and putting them together in one place so you don’t have to bounce around from page to page, trying to piece together a process that works. Some of the instructions in this post are old; I first performed some of these steps as a Linux user 15 years ago. Some of the instructions are required only because Apple tweaked the key handling system in Sierra; I had to perform them quite recently because what had been working for years suddenly stopped after an OS upgrade.

Frankly, I’m somewhat reluctant to write this post, as my lack of expertise means I can’t really troubleshoot if things don’t work for you. Still, these steps work for me and ought to work for you if you’re running a Mac with Sierra and need to connect to a Linux or other Unix-like (including macOS) server via SSH, SCP, or SFTP.

The instructions here assume you’ll be starting from scratch. If you’ve already performed some of the steps in a previous attempt at getting SSH keys to work, look through the steps to see if you did them right and pick up where you left off.

Create the keys

Start by opening a Terminal window. You’ll probably start out in your home directory, but to be sure, run this command:

cd

Now create an RSA key pair by running this command:

ssh-keygen -t rsa

The ssh-keygen command is interactive. It will tell you what it’s doing and ask you for input. The initial response will be

Generating public/private rsa key pair.
Enter file in which to save the key (/Users/drdrang/.ssh/id_rsa):

except, of course, the default place for the key will be in your home directory, not mine. Hit the Return key to accept the default. You’ll then be asked for a passphrase:

Enter passphrase (empty for no passphrase):

Do not use an empty passphrase. You may have seen people on the internet suggesting you use an empty passphrase as a way to avoid entering a password or passphrase every time you want to connect via SSH, SCP, or SFTP. Those people are misguided. When you get done with these instructions, you’ll have the best of both worlds: a passphrase to maintain secure access and a system that doesn’t require you to enter it all the time.

What should your passphrase be? Well, that’s up to you. I used this variant of the Diceware algorithm to create a six-word passphrase, but there are lots of ways to make a good passphrase. The internet is filled with advice on this topic. You could do worse than read this article and this one from the folks at AgileBits (makers of 1Password). Their advice is geared toward generating master passwords for 1Password, but it’s applicable here, too.

After you’ve entered your passphrase, you’re asked to enter it again.

Enter same passphrase again: 

Assuming you entered it correctly the second time, you’ll be told of your success and what ssh-keygen has done:

Your identification has been saved in /Users/drdrang/.ssh/id_rsa.
Your public key has been saved in /Users/drdrang/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:toaZ40HBr/WsWVgbJrIesr6FkmIVeeyuHMpw4u0rQwE drdrang@mba.local
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|E   o.           |
|.  o oo          |
| .  +  o         |
|  .. .o S +      |
| ....o X O o     |
|=.+.o.@ + =      |
|=*+.o* = +       |
| ++B=.o o        |
+----[SHA256]-----+

I don’t know what to use the fingerprint or the randomart image for, but luckily I don’t have to. By the way, if you are an expert on this stuff and are horrified that I’ve posted something that can be reverse-engineered to get my passphrase or keys, don’t worry. This is the output of a throwaway ssh-keygen run.

At this point, you have a key pair in the .ssh directory of your home directory: a private key, id_rsa, and a public key, id_rsa.pub.

Copy the public key to the server

To get the server to understand your newly created RSA identity, you need to put a copy of your public key, id_rsa.pub, into the ~/.ssh directory on the server. There are lots of ways to do this, but the easiest is this:

ssh-copy-id -p 9876 username@12.34.56.78

where you replace username with your user name on the server, 12.34.56.78 with the IP address of the server, and 9876 with the SSH port number of the server. If your server uses 22 as the SSH port (which is the standard), you can omit the whole -p 9876 part.

You’ll get this kind of response:

The authenticity of host '12.34.56.78 (12.34.56.78)' can't be established.
RSA key fingerprint is b1:2d:33:67:ce:35:4d:5f:f3:a8:cd:c0:c4:48:86:12.
Are you sure you want to continue connecting (yes/no)?

Type yes in response to the question and you’ll see

Warning: Permanently added '12.34.56.78' (RSA) to the list of known hosts.
username@12.34.56.78's password:

Go ahead and type in your server password (not your SSH passphrase; the server doesn’t know it yet) and you’ll see something like this:

Now try logging into the machine, with "ssh 'username@12.34.56.78'", and check in:

  ~/.ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

At this point, you should have a file named known_hosts in the .ssh folder on your Mac.

To make sure everything worked, try to log into the server:

ssh -p 9876 username@12.34.56.78

Now you should be prompted for your SSH passphrase, not your user password, because the server knows you through your public key.

Check the authorized_keys file on the server:

cat ~/.ssh/authorized_keys

You should see a stream of characters that matches the contents of ~/.ssh/id_rsa.pub on your Mac.

At this point, you may be wondering what you’ve gotten yourself into. You used to be able to log into the server with just a password. Now you need this ridiculously long passphrase. Patience, grasshopper, we’re nearly there.

Configure your keychain

So far, there’s nothing Mac-specific in these instructions. The things you’ve been doing on your Mac would work just as well on any computer. That’s about to change.

SSH allows you to manage your keys through the ssh-agent utility. Discussions of ssh-agent you may find on the web often refer to a keychain. This is not the Keychain that Mac and iOS devices use to manage passwords, but Apple has kind of tied the two ideas together. With a little work, we can get our SSH keys automatically entered when we start a SSH, SCP, or SFTP session the same way Keychain can automatically enter our username and password when we visit Amazon.

It’s this keychain stuff that changed with Sierra. Some of what follows applies to both pre-Sierra and Sierra, some applies to Sierra only. I’ll point out which is which.

Sierra and pre-Sierra: First, add your private key to the keychain using the ssh-add command:

ssh-add -K ~/.ssh/id_rsa
ssh-add -A

Now your keys are being managed by the keychain, and you should be able to log into the server without being asked for your passphrase.

Sierra only: Unfortunately, Sierra doesn’t maintain your keychain across restarts. By default, this forces you to re-enter the two ssh-add commands every time you restart your Mac. But there’s a way around it.

Look in your ~/.ssh folder for a file named config. If you have one, open it up in a text editor. If not, create one and open it in a text editor.1 Add the following lines to it:

Host *
  UseKeychain yes
  AddKeysToAgent yes
  IdentityFile ~/.ssh/id_rsa

With this addition, Sierra should maintain your keychain across restarts, and your SSH keys will be managed automatically. And for the purposes of taking and uploading screenshots, the SCP command that’s buried in the SnapSCP macro will run without needing you to enter a passphrase.

Credits

As I said, I’m no expert on SSH or keys. Over the years, though, I’ve read several articles on these topics, and a couple have really stood out. First, this one from Digital Ocean gives the the most succinct description of creating keys and getting them installed on your server. Digital Ocean actually has a lot of good, practical articles on getting things working on a Linux server. I’d be reading them even if ANIAT wasn’t hosted there.

As for key management on the Mac, this Super User Q&A is the best, especially Jeff McCarrell’s discussion of ssh-agent and ChrisJF’s config file solution for Sierra. What would we do without the StackExchange family of sites?

Update 03/1/2017 7:03 AM
Two updates from readers:

  • Chris Finazzo directed me to this Apple Technical Note, which confirms the keychain changes in Sierra and the way to work around them. If you feel uncomfortable running code from a comments-driven website, this should settle your fears.

  • Michael Bishop says ssh-copy-id wasn’t included with OS X until Sierra. I don’t have a pre-Sierra machine available to confirm, but that seems right. While writing the post, I tried to link to an Apple-hosted man page for ssh-copy-id and found that there wasn’t one, even though running man ssh-copy-id brings one up. I suspect this is related to Apple relegation of man pages to the “legacy” section of its developer website. They’re probably not putting much effort into adding new man pages to the site.


  1. If you do a lot of SSH work, the config file is also a great way to set up shortcuts to servers you commonly access. For example, my config file allows me to SSH into my iMac at work with a simple ssh work command. ↩︎