Context
I would like to use GPG authentication subkeys instead of SSH keys.
I would also like to use gpg-agent
to manage password caching for these keys.
I am running in a headless environment, so I would like to use pinentry-curses
for my password entry program, but I am fine with anything that works in a headless environment.
My development workflow is such that I am working in multiple tmux
sessions and panes, and need to be able to git push
from any of them.
Problem
The problem occurs when I attempt to do so. Instead of pinentry
popping up in my current pane, it pops up in a random other pane (or sometimes perhaps no pane at all, but it's possible there are just too many to search through). To resolve this, I need to kill that pane and pinentry-curses
and even then it still fails at times.
What I've Tried
Configurations I've Tried
My current configuration is as follows, though I've tried a plethora over the past couple weeks to attempt to get this working.
# ~/.zshrc
unset SSH_AGENT_PID
if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
fi
if [[ $SSH_AUTH_SOCK == /tmp/* ]]; then
ln -sf $SSH_AUTH_SOCK $HOME/.ssh-agent-sock
export SSH_AUTH_SOCK=$HOME/.ssh-agent-sock
fi
export GPG_TTY=$(tty)
gpg-connect-agent updatestartuptty /bye >/dev/null
# ~/.gnupg/gpg-agent.conf
pinentry-program /usr/sbin/pinentry-curses
default-cache-ttl 600
max-cache-ttl 7200
enable-ssh-support
# ~/.gnupg/gpg.conf
use-agent
# ~/.gnupg/sshcontrol
MYFINGERPRINTS
# ~/.ssh/config
Host localhost
ForwardAgent yes
AddKeysToAgent ask
Links I've Tried
- gpg2 pinentry fails without X
- Best Practices for SSH, tmux & GnuPG Agent
- Pinentry fails with gpg-agent and SSH
- https://wiki.archlinux.org/index.php/GnuPG#SSH_agent
- https://gist.github.com/andrewlkho/7373190
- https://www.linode.com/docs/security/authentication/gpg-key-for-ssh-authentication/
- https://opensource.com/article/19/4/gpg-subkeys-ssh
Update: Working Configuration (thanks again to @SystematicFrank)
# ~/.zshrc
export GPG_TTY=$(tty)
# ~/.gnupg/gpg-agent.conf
pinentry-program /usr/bin/pinentry-curses
default-cache-ttl 600
max-cache-ttl 7200
enable-ssh-support
# ~/.gnupg/gpg.conf
use-agent
# ~/.gnupg/sshcontrol
MYFINGERPRINTS
# ~/.ssh/config
Host localhost
ForwardAgent yes
AddKeysToAgent ask
Match host * exec "gpg-connect-agent UPDATESTARTUPTTY /bye"
Best Answer
The problem is that you are calling
gpg-connect-agent updatestartuptty
every time you open a terminal, so pinentry points itself to the latest shell.What you actually want is not the latest shell terminal, but the one you are connecting from (when calling ssh)
For that the easiest way is telling .ssh/config to execute the update command from the tty you are connecting. This is the magic line you are missing: