KeePass + ssh

I've been using KeePass Professional Edition for a few months now, and I'm always discovering new things to do with it. For example, I've got HQ photos of my driver's license so that I can go to the gym without carrying my full wallet (if that's illegal I totally don't do that). I've got a couple of shared databases that sync off my main personal database that I can share with family and friends, which means I change update my accounts without the old hassle of texting everyone the new credentials. I keep all of my work identities in KeePass, both for personal and employer accounts (with different databases, of course).

Today I was messing around in my gaming environment (which, until I take the time to set up another SSD with a real OS, is also my dev environment) and finally got sick of re-entering my ssh credentials on reloading bash. I've begun taking my online identity a bit more seriously and I'm building a collection of keys for everything. It's safe, but it's insanely annoying to have to re-enter all those passphrases more than once, say, a month.

Background

Typically on Linux, ssh-agent persists with the session. Also typically on Linux, bouncing a machine is pretty rare. I can't remember the last time I logged out to log out, because I usually just lock the machine.

On Windows, however, closing all active bash shells kills off the processes. Microsoft says this a feature, while the internet hates it. For someone like me running ssh-add more than once in my .zpreztorc, it's horrible and I hate it.

This is where KeePass steps in...

as an ssh-agent: KeeAgent is a fantastic crossplatform tool that functions as an ssh-agent capable of reading keys directly from your database.

as a typist: For situations where you aren't able to foward the agent or aren't starting from a configured instance of KeePass, Auto-Type has you covered.

By always forwarding your agent (e.g. ssh -A ...), you can handle all of the keys via KeePass on your machine, instead of managing different keys on each machine.

Adding keys

The official docs for KeeAgent are awesome and have way more screenshots than I want to take. Basically, make your key like normal, use KeePass to generate the passphrase, and attach both the private and public files.

If, like me, you plan on building as many keys as you have passwords, you should uncheck the "Add key to agent when database is opened/unlocked" and instead manage it through KeeAgent.
The agent works by forwarding as many keys as possible, so you can lock yourself out of a server if you load too many keys at once.

Running KeePass as an ssh-agent

The basics

Set up KeeAgent as the Agent and export a socket:
I use ssh-keeagent.sock instead of ssh-agent.sock to keep origin explicit.

This step is really smart. Like the author, I've had trouble with SSH_AGENT_PID in the past. The service throws the generated config into a local file, removing the headache of exporting the variables.

I had to modify this a bit to get it to work with my prezto setup. Placing it in my .zshrc meant it was running in every new bash.exe, so I ps | awk to find the proper SSH_AUTH_SOCK if it's already running.

match($2, /\/tmp.*keeagent[^,]*/, a) searches the second column (see the space between socat and UNIX?) for a /tmp path containing keeagent and stores it in a.

print a[0] sends off the matched string, if any.

Using python

With python you can directly convert the socket (gist | fork with additional features) instead of using socat. I haven't tried this, but it seems pretty solid. I might eventually run it in a VM at work.

KeePass Auto-Type

If you, for whatever reason, aren't forwarding/can't forward your agent, KeePass is still insanely useful. I use for server-specific users whose config I don't want to leave the server (if it doesn't leave the server, I know it's insecure when I see it in the wild). I make a template per user and reference things everywhere. Here's a breakdown of a sample user:

I'm abusing URL as hostname, and the password is actually the key's passphrase.

I include a string field for each of the CLI options (sure, specifying options and a config file is overkill, but you get the point).

This is where the magic happens. I've beefed up the autotype to include all of the variables. I could actually use URL:Port instead of a custom variable, but I like having a custom variable because I can create a default template with port 22 and not worry about always appending :22 to the URL.