I’m a huge lover of KeePass (NOT KeePassXC), it’s by far the most advanced password manager (I mean, what password manager supports case-sensitive, regular expression XPath-selector search and replace operations on its internal XML tree? It’s a feature that I’ve used extensively to manage my hundreds of passwords with custom fields; but I digress already…). KeePass has this one particular feature that, if missing in any other password manager, is an immediate deal-breaker for me: SSH Agent Integration. It’s such a good feature for many reason, but I will elaborate on that in another article.

Yesterday, I finally asked myself: “Wait, is there a Keepass2Android SSH Agent integration”? Keepass2Android is the de facto KeePass Android app. However, at least right now, there is no way to make it interact with Termux. This is quite unfortunate, since it is relatively common for me to ssh to servers from my phone, on the bus, in my bed, or while I’m walking (yeah…). Up until now, these were the only possibilities I knew:

  1. Logging in with a password
  2. Logging in with a password-less key
  3. Logging in with a password-protected key (enter password every time)
  4. Logging in with a password-protected key (add to agent on shell startup)
  5. Logging in with a password-protected key (manually manage agent when needed)

All these cases have significant convenience and/or security problems:

  1. Bad security practice & enter password every single time & no auto-fill
  2. Bad security practice
  3. No auto-fill, enter password every single time
  4. No auto-fill, enter password every time you open a shell, even if you don’t want to ssh
  5. No auto-fill, manually starting the ssh agent sucks, although could be automated via smart ssh wrapper

After all these years, I finally found a way that has:

  1. Good security
  2. Enter the password only when needed, and decide for how long to keep it active (i.e. until screen off)
  3. Auto-fill

And it requires the following apps/packages:

  1. OpenKeychain
  2. OkcAgent
  3. pkg install okc-agents in Termux
  4. Keepass2Android (or any other password manager that supports auto-fill)

And here’s a GIF of the authentication flow:

GIF that shows the superior auth flow, TBD

Setup#

OpenKeychain#

First, you need to install the OpenKeychain app, preferrably from F-Droid. Then, create a new PGP key by clicking on the three dots in the top right corner, click “Manage my keys” (next), “CREATE MY KEY” (next), enter a name (next), email (next), optionally publish on keyservers, and finally “CREATE KEY”.

Then, click the key from the “My keys” overview, click the three dots in the top right corner, “Advanced”, “Subkeys”, then click the pencil in the top right corner and then the floating action button in the bottom right.

Now, importantly, DO NOT select “Ed25519 / Cv25519” as the subkey type. For me, it could never properly authenticate. I tested “RSA 2048 and “RSA 4096” which worked nicely, although of course they are quite a bit longer.

Select “Authentication” as the usage and decide on whether it should expire or not, then click “OK”, which will close the dialoge, and then click “SAVE” to actually generate the subkey.

Then, go to “SHARE” and click the copy symbol besides the text that says “Share as SSH public key with…” to copy the public key string (for authorized_keys later).

Then go back, and again click on the same three dots in the top right corner, then click “Change password”. Generate a secure password in your mobile password manager (preferrably Keepass2Android) and enter it here. I recommend diceware with at least 6 title case words, dashes as separators, and a few trailing numbers.

You can close the app now.

OkcAgent App#

Install the OkcAgent App from F-Droid. After opening, click “ADD SSH KEY”. If this is the first time, it will ask you to “Allow access to OpenKeychain” and give instructions on how to revoke that access. Click “ALLOW” and select the authentication subkey that you just created.

You can close the app now.

okc-agents in Termux#

Install the okc-agents package in termux (pkg i okc-agents will automatically do a apt update before). Add this line to your .bashrc to start the agent in every shell:

eval "$(okc-ssh-agent)"

This will set the usual SSH environment variables, for example:

SSH_AUTH_SOCK="/data/data/com/termux/files/usr/tmp/okc-ssh-ak67VeXyba/agent.9831"; export SSH_AUTH_SOCK
SSH_AGENT_PID=9832; export SSH_AGENT_PID

Running ssh-add -l should now give an output similar to this:

4096 SHA256:qyvKTZsNaiY3d8Qd+q0qtJU5LM+C/D+I7j5FxOFALng MyKey <mykey@example.com> (5b79d2751445ca27) (RSA)

Public Key Setup#

This is where you need your clipboard contents. Conventionally, you would now ssh into the host you’re interested in and add the public key from your clipboard to the authorized_keys file of the user that you’re interested in logging into conveniently. You could also send this public key via other channels to your laptop and do the process there, or whatever your setup is.

After that, make sure you’re back in your local Termux session

Keepass2Android#

I’m assuming you have Keepass2Android already installed and configured to your liking. The next steps might be different for different flavours and versions of Android.

First, run ssh <host>, where <host> is either a configured host from your ssh config or an actual username@host pair. If you haven’t configured you ssh config in particular ways, then ssh will now go through the entries of your ssh-agent and try them one-by-one (well, I think you can only have one SSH Agent connection, so you will certainly only have one entry in your agent), eventually finding that entry where the fingerprints match (I’m actually not 100% on the details of this process, take it with a grain of salt).

You should then get a clickable notification asking you to enter your password and the option to decide how long to remember the password (“until screen off”, “for one hour”, “for one day”, “until cleared”). Here, the auto-fill details will be different from keyboard to keyboard, and also between Android versions. In my case, the keyboard I use (HeliBoard) has a suggestions that reads “Fill with Keepass2Android” which I can click. It then opens the Keepass2Android app, where I can choose the entry from where to take the password, after which it will ask whether I would like to “Remember [the] search text”, so it can perform auto-fill the next time, to which you say “Yes” of course.

Afer that, it should’ve filled the password entry. As soon as you click “UNLOCK”, it will authenticate you and you should be ssh’ed to the host. Disconnecting now and logging back in should work immediately, and if you’ve selected “until screen off”, turning your screen off and on, then disconnecting and reconnecting should notify you once again for your password, which should now be auto-filled with just a click/a few clicks since you probably have to unlock your password manager.

Note that if you select “until cleared”, I have yet to find a way to actually “clear” it. After trial and error, I figured out that it is the cache of the OpenKeychain app that you have to clear, but I searched everywhere for dedicated buttons inside the app, to no avail.

Optionally, you can now also export the PGP key and save it inside the password entry, but this step is definitely optional.

Anyways, congrats! This is it. The best SSH on Termux workflow that I know of. Have fun!

But wait, there’s more#

What I have yet to play around with is the “USE SECURITY TOKEN” option when creating/managing keys in OpenKeychain. It allows you to use NFC smart cards or the NFC functionality of some YubiKeys to do the authentication, which is also pretty neat, but I usually find that less convenient unless I have a YubiKey literally as a necklace or implanted in my arm, which I don’t. And my intentionally low-end phone doesn’t support NFC, so there’s that.