While I was preparing to write an upcoming post about moving directly to certbot from SSLForFree now that they've merged with ZeroSSL, I realized that I'd not actually ever written a post about one of the components I use all the time, including for my new certbot process: public key authentication.
What Is Public Key Authentication?
Ultimately, it's a more secure asymmetric encryption method to communicate across devices than a simple password would provide. Further, key authentication can be set up in ways that bolster automation processes and also helps keep passwords out of configuration files or cron jobs (don't do that).
SSH.com has a simple overview that outlines the components of public key (or key pair) authentication.
Why Is It Awesome?
No passwords at runtime. Full stop.
How To Start
Ultimately, using key auth requires the following:
- Generating a public/private key pair;
- Sending the public key to the destination (remote) server/endpoint;
- Authorizing the public key; and
Generating The Key Pair
It's very simple to generate a key pair on a Linux (or similar) source system: use
user@local:$ ssh-keygen -t rsa -b 4096
Walking through the steps with the above command will mint you a fresh public/private key pair. Note that while it's a good idea to use a password/passphrase for the private key as prompted, it is not required and having a private key password will require minor additional configuration to use in runtime (with an automation process, for example).
There are other programs available (such as PuTTY) for Windows which include utilities for generating keys outside of Linux.
Distributing The Public Key
It's of utmost importance to not distribute the private key. Anyone (or anything) with the private key will be able to use it without question anywhere the public key has been authorized. By default the public key (in Linux) will be of the naming convention
id_rsa.pub and generally live in your home (
Copy this file by whatever means you see fit or necessary to remote machines. There are utilities specifically made for this, but a simple sftp/scp command or session works as well as any.
Authorizing The Public Key
On the remote machine, you can easily run a command like follows to "authorize" the public key:
user@hostname:$ cat id_rsa.pub >> ~/.ssh/authorized_keys
Once this has been processed, you're ready to connect!
Some Pre-Connection Caveats
All of the above assumes this is a Linux or Linux-like source and destination points. Additional steps are required to convert keys for use within Windows directly.
Additionally, there can be some caveats in setting up your first authorized_key: permissions must be very specifically set on the files and directories. For that reason, if you're not super familiar with the process it may be simpler to use the ssh-copy-id command which, assuming OpenSSH is in use, appears to set all of the appropriate permissions for a fresh set of files. I've never personally used the command, but it looks cool and useful.
Assuming all is well with the underlying configuration, connecting henceforth is as simple as using the following command:
user@local:$ ssh -i ~/.ssh/super_private_key user@hostname
You should more or less immediately be presented with the command line on the remote machine!
From personal experience, there are several scenarios where it is not necessary to use the
-i argument, but it is best to use it if you can (to be certain which key is in play, etc.).
Similar arguments can be passed along to
scp, among others.
For the endpoints where I might often log in at the command line (i.e. not always as a scripted task, but interactively for various reasons), I love to create an alias (in
alias server1='ssh -i ~/.ssh/super_private_key user@hostname'
And then from the command line I can simply connect by:
Life Changing Stuff
I've been using key authentication for several years, including with GitHub, and I can affirm it's truly life changing stuff. There's a little setup involved, and admittedly at first if/when it's not going well can be extremely frustrating, but stick with it and Google around. Most often I've found out that it's a wonky permission somewhere in the local or remote
.ssh directories, a bad copy/paste between platforms, or sometimes just as simple as having the public key in the
authorized_hosts file of the wrong remote account.
Headline image via giphy