funtoo / keychain

keychain ssh-agent front-end
http://www.funtoo.org
GNU General Public License v2.0
762 stars 108 forks source link

Suggest alternatives (use gpg-agent systemd unit) #138

Open uhthomas opened 2 years ago

uhthomas commented 2 years ago

At the time of writing, keychain has seen no activity in over four years. It might be helpful to suggest alternatives given there is no desire to maintain the project.

I've found that gpg-agent and systemd have not only proven to be a suitable replacement, but also have improved quality of life by reducing shell startup times by 64ms~ (130ms~ at the extreme). There is an excellent article on the Arch Linux wiki which explains how to setup and configure gpg-agent. Most importantly, gpg-agent can emulate ssh-agent.

keychain performance

One of the main reasons for seeking alternatives is the poor performance and consequential large impact keychain imposed on shell startup times.

# -Q for quick (seems slower?)
❯ hyperfine 'keychain -q -Q --noask --agents gpg,ssh 86930F1CE9E00625 id_ed25519'
Benchmark 1: keychain -q -Q --noask --agents gpg,ssh 86930F1CE9E00625 id_ed25519
  Time (mean ± σ):      64.0 ms ±  13.8 ms    [User: 60.3 ms, System: 14.2 ms]
  Range (min … max):    56.3 ms … 126.2 ms    23 runs

  Warning: The first benchmarking run for this command was significantly slower than the rest (126.2 ms). This could be caused by (filesystem) caches that were not filled until after the first run. You should consider using the '--warmup' option to fill those caches before the actual benchmark. Alternatively, use the '--prepare' option to clear the caches before each timing run.
❯ hyperfine 'keychain -q --noask --agents gpg,ssh 86930F1CE9E00625 id_ed25519'
Benchmark 1: keychain -q --noask --agents gpg,ssh 86930F1CE9E00625 id_ed25519
  Time (mean ± σ):      55.6 ms ±   2.5 ms    [User: 49.3 ms, System: 15.9 ms]
  Range (min … max):    50.4 ms …  62.0 ms    45 runs

gpg-agent systemd user unit

Rather than reading the Arch Linux wiki, this should work as a quick-start and tl;dr.

The gpg-agent systemd user units are enabled by default (at least on Arch Linux).

❯ systemctl --user status gpg-agent
● gpg-agent.service - GnuPG cryptographic agent and passphrase cache
     Loaded: loaded (/usr/lib/systemd/user/gpg-agent.service; static)
     Active: active (running) since Tue 2022-02-01 11:54:18 GMT; 11min ago
TriggeredBy: ● gpg-agent.socket
             ● gpg-agent-ssh.socket
             ● gpg-agent-extra.socket
             ● gpg-agent-browser.socket
       Docs: man:gpg-agent(1)
   Main PID: 1708 (gpg-agent)
      Tasks: 1 (limit: 19177)
     Memory: 428.0K
        CPU: 66ms
     CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/gpg-agent.service
             └─1708 /usr/bin/gpg-agent --supervised

Feb 01 11:54:18 matryoshka systemd[459]: Started GnuPG cryptographic agent and passphrase cache.
Feb 01 11:54:18 matryoshka gpg-agent[1708]: gpg-agent (GnuPG) 2.2.32 starting in supervised mode.
Feb 01 11:54:18 matryoshka gpg-agent[1708]: using fd 3 for std socket (/run/user/1000/gnupg/S.gpg-agent)
Feb 01 11:54:18 matryoshka gpg-agent[1708]: using fd 4 for ssh socket (/run/user/1000/gnupg/S.gpg-agent.ssh)
Feb 01 11:54:18 matryoshka gpg-agent[1708]: using fd 5 for extra socket (/run/user/1000/gnupg/S.gpg-agent.extra)
Feb 01 11:54:18 matryoshka gpg-agent[1708]: using fd 6 for browser socket (/run/user/1000/gnupg/S.gpg-agent.browser)
Feb 01 11:54:18 matryoshka gpg-agent[1708]: listening on: std=3 extra=5 browser=6 ssh=4

Emulate ssh-agent:

/etc/security/pam_env.conf
SSH_AGENT_PID  DEFAULT=
SSH_AUTH_SOCK DEFAULT="${XDG_RUNTIME_DIR}/gnupg/S.gpg-agent.ssh"

Cache passphrases for a really long time:

~/.gnupg/gpg-agent.conf
max-cache-ttl 60480000
default-cache-ttl 60480000

default-cache-ttl-ssh 60480000
max-cache-ttl-ssh 60480000

Restart the gpg-agent systemd user unit to apply changes.

❯ systemctl --user restart gpg-agent

Assuming keys have already been added to gpg-agent, everything should work as expected. This approach doesn't ask for all passphrases upfront, at shell login, but I'm sure it's possible to write something to do this if desired. Personally, I don't want that functionality as it is incompatible with some terminal configurations (i.e zsh4humans).

I hope this is helpful!

basnijholt commented 2 years ago

This is great, thanks a lot.

Is anyone aware of a solution that would work on MacOS too?

mrl5 commented 2 years ago

hello @uhthomas - if you'd like to report a bug kindly use https://bugs.funtoo.org/

you can also reach us on Discord - for more info check https://www.funtoo.org/Welcome