I'll be the first to admit my security has room for improvement. Until last year, I was reusing passwords intermixed with a terribly simple mnemonic. Until a few months ago, my phone and computer were totally unencrypted. I've been fighting the change because it's scary. I'm also very lazy and have been dreading the extra work involved with good security. I've put off updating SSH credentials for about two years now for that exact reason.
I decided to at least pretend like I was doing something about that this morning. It's a gargantuan task: managing many keys with many passphrases on many machines with so much typing involved. Rather than actually sitting down to update things, I poked around man pages and Stack Overflow for a bit, avoiding more than anything else. Somehow I managed to put together a halfway decent solution that, so far, seems to remove almost all the heavy lifting.
- Full Scripts
If you've never used KeePass or KeeAgent, start here. I've written about the two together before.
On the other hand, it should be possible to set up most of this with the vanilla
ssh-agent or something more opinionated like
kdewallet5. Taking KeePass and KeeAgent out of the equation, in my opinion, generates way more work, but YMMV.
KeePass hasn't been thrilled with
i3 and my theme choices. I apologize for the strange layouts. Unless you decide to go and change everything it doesn't normally look this bad. I was too excited about the solution to go and undo all my tweaks.
Simply put, managing a ton of keys is a serious pain. If, like me, you've never really delved into the myriad ways to beef up your settings, you'll hit a few snags:
- You have to manually add a ton of keys to
ssh-agent, which means typing passphrases for days when your power goes out, killing the longest continuous uptime you've had in months
- You have to juggle keys in the agent, as most servers have a fairly low retry count (default is, I believe, six)
- You have to manually enter the passphrases for anything specified in your config that's not active in your agent, which seems like a waste of time if you're just going to have to juggle anyway
Those statements, built on experience and prevailing wisdom, touch on some pretty major annoyances. However, they all suffer from a perspective problem. They begin with the assumption that a user has many keys and connects to many machines. That's very true. But it ignores a very important detail: while there are many possible permutations of key and machine, the number of successful permutations is much smaller and (in theory) proper matchings are already known.
ssh_config defines a vehicle to specify proper matchings. Providing an
IdentityFile (or several) per host establishes a match.
ssh from trying anything not specified in the config or CLI, effectively sidestepping the retry issue.
IdentityAgent provides an agent failsafe (or multiple agents in tandem). KeePass and KeeAgent glue everything together with remembered credentials, making the config much more powerful.
~/.ssh/some_key is in KeePass and available to KeeAgent, this simple config is enough to get you started:
1 2 3 4 5 6
All of this will make much more sense after a good example. I'm going to build everything from scratch and try to illustrate the pain points I believe I've mitigated.
To demonstrate something closer to an ideal environment, I've generated ten keys. They're all ridiculously weak and shouldn't be used in production (passphrase was passed via the CLI, which should be enough warning).
With the keys in hand, I populated the KeePass database next. Each entry's password is the passphrase to the key, and the keys themselves are attached to the entries.
The easiest way to make things work is to allow KeeAgent to use each entry. If you don't, you'll have to manually add the key later (which has its uses).
All told, this is about seven more active keys than I'm used to having around. It's a strange feeling, to say the least.
To make things as simple as possible, I created a
vagrant box that will act as the remote. I did a few things:
dummy_key_10(the last in the list) as
dummy_user's primary key (also
- Removed password access (forcing a key exchange)
- Lowered the number of attempts to three
vagrant exposes its own
ssh-config, which we'll use to to access the box and later as a template for our own.
We're going to try to connect with all the keys active.
Quick and unsurprising.
We can just as quickly get in with a simple config file.
1 2 3 4 5 6
The key path is fairly important.
ssh attempts to load the key, sees KeeAgent already has it available, and moves on. Without a local copy of the key, there's nothing for
ssh to go off of. (I think; this is an educated guess using the debug logs. Might not be 100% accurate.)
ssh_config and KeePass/KeeAgent are very powerful tools. Together they mitigate the need to juggle keys and constantly enter passphrases.
IdentitiesOnly, and a little bit of setup will make using more than one key a painless endeavor. Until you have to update them all...
These are in the repo but I also wanted to lay out everything here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26