Skip to content

Instantly share code, notes, and snippets.

@afriza
Last active February 19, 2023 14:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save afriza/7e706b9982a705146e1577fbb6f716e9 to your computer and use it in GitHub Desktop.
Save afriza/7e706b9982a705146e1577fbb6f716e9 to your computer and use it in GitHub Desktop.
Remote git signing with GPG (GnuPG / GNU Privacy Guard) over SSH Forwarding

On local machine

$ brew install gnupg pinentry-mac # macOS
$ echo 'export GPG_TTY=$(tty)' >> ~/.bashrc
$ echo 'export GPG_TTY=$(tty)' >> ~/.zshrc
$ echo "pinentry-program $(command -v pinentry-mac)" > ~/.gnupg/gpg-agent.conf # macOS
$ defaults write org.gpgtools.common UseKeychain NO # macOS
$ gpgconf --kill gpg-agent
$ gpg-connect-agent /bye

$ gpg --list-keys
$ gpg --list-keys --fingerprint
$ gpg --armor --export email@address.com > public.gpg

$ echo "
Host my-alias-to-remote-machine
    HostName remote-machine-ip-or-domain
    User remote-machine-username
    Port remote-machine-port
    Compression yes
    ConnectTimeout 25
    ServerAliveInterval 20
    ServerAliveCountMax 3
    # Adjust `S.gpg-agent` location for remote Ubuntu Linux machine.
    # For example, `1001` below is remote-machine-numeric-user-id.
    RemoteForward /run/user/1001/gnupg/S.gpg-agent $HOME/.gnupg/S.gpg-agent.extra
    # For remote macOS machine, it is something like:
    RemoteForward /Users/remote-machine-username/.gnupg/S.gpg-agent $HOME/.gnupg/S.gpg-agent.extra
    StreamLocalBindUnlink yes
    #PreferredAuthentications publickey
    #IdentityFile ~/.ssh/id_ed25519
    #ExitOnForwardFailure yes
    #StrictHostKeyChecking no
    #UserKnownHostsFile=/dev/null
" >> ~/.ssh/config

On remote machine

$ gpg --import public.gpg # or ` curl https://github.com/username.gpg | gpg --import `
$ gpg --edit-key email@address.com
gpg> # trust then quit
gpg> trust
...
Your decision? 4
...
gpg> quit

$ # Linux (Ubuntu)
$ # two-in-one: disable + stop
$ systemctl disable --user --now gpg-agent gpg-agent.socket gpg-agent-extra.socket gpg-agent-ssh.socket gpg-agent-browser.socket
$ # one-by-one: stop then disable
$ systemctl stop --user gpg-agent gpg-agent.socket gpg-agent-extra.socket gpg-agent-ssh.socket gpg-agent-browser.socket
$ systemctl disable --user gpg-agent gpg-agent.socket gpg-agent-extra.socket gpg-agent-ssh.socket gpg-agent-browser.socket
$ # mask services
$ systemctl mask --user gpg-agent gpg-agent.socket gpg-agent-extra.socket gpg-agent-ssh.socket gpg-agent-browser.socket

$ gpgconf --kill gpg-agent

$ echo '# optional but recommended for gpg-agent socket forwarding
StreamLocalBindUnlink yes
' | sudo tee /etc/ssh/sshd_config.d/StreamLocalBindUnlink.conf

$ # only if needed: delete gpg-agent files followed by relogin
$ rm /run/user/1001/gnupg/S.*
$ # relogin to remote-machine and test the setup
$ echo dummy | gpg -bsau email@address.com # test remote signing

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment