DEV Community

Jesse P. Johnson
Jesse P. Johnson

Posted on

Commit Signing - GnuPG Agent Forwarding

Overview

Most corporate networks prevent development on company issued laptops. Often developers must rely on using either virtual or cloud instances within an isolated network. This separation helps secure the rest of the network but could potentially expose the supply chain if proper precautions are not taken. Often when developers are required to sign commits, or code it is just easier to setup signing on the instance you develop from. But, it is much safer to use GnuGP agent forwarding instead leaving your keys somewhere that they can be stolen. This article will show how to setup agent forwarding for this.

Configure GPG Agent Forwarding with SSH support

First we will copy the public key we exported to the target system.

scp "${HOME}/${gpg_asc}" "${remote_user}@${remote_host}:~"
Enter fullscreen mode Exit fullscreen mode

Now import it.

ssh "${remote_user}@${remote_host}" \
gpg --import "~/${gpg_asc}"
Enter fullscreen mode Exit fullscreen mode

Configure GPG to use SSH.

cat > "${GNUPGHOME}/gpg-agent.conf" <EOF
enable-ssh-support
default-cache-ttl 600
max-cache-ttl 7200
EOF
Enter fullscreen mode Exit fullscreen mode

Ensure the gpg-agent is started when a terminal is first opened.

cat > "${HOME}/.zshrc.d/gpg-agent" <EOF
export GPG_TTY="$(tty)"
gpg-connect-agent reloadagent /bye >/dev/null
alias pinentry=/opt/homebrew/bin/pinentry
EOF
Enter fullscreen mode Exit fullscreen mode

✏️ NOTE
It's important to ensure the pinentry is setup correctly according to your distribution.

Determine the path to your local GPG socket.

extra_socket_on_local_box=$(
  gpgconf --list-dir agent-extra-socket
)
Enter fullscreen mode Exit fullscreen mode

Determine the path to the GPG socket on your remote box.

socket_on_remote_box=$(
  ssh "${remote_user}@${remote_host}" \
  gpgconf --list-dir agent-socket
)
Enter fullscreen mode Exit fullscreen mode

Setup SSH to map the GPG extra socket to that of its remote.

cat > "${HOME}/.ssh/config" <<EOF
Host gpgtunnel
  HostName ${remote_host}
  RemoteForward ${socket_on_remote_box} ${extra_socket_on_local_box}
EOF
Enter fullscreen mode Exit fullscreen mode

Reconfigure SSH so that GPG agent will use the remote socket instead starting the local one.

ssh "${remote_user}@${remote_host}" \
sudo bash -c "cat > /etc/ssd/sshd_config.d/gpg-agent.conf <<EOF
StreamLocalBindUnlink yes
EOF"
Enter fullscreen mode Exit fullscreen mode

Restart SSH.

ssh "${remote_user}@${remote_host}" \
sudo systemctl restart sshd
Enter fullscreen mode Exit fullscreen mode

Ensure remote gpg-agent is not running.

ssh "${remote_user}@${remote_host}" \
gpgconf --kill gpg-agent
Enter fullscreen mode Exit fullscreen mode

Test that everything is loaded.

ssh "${remote_user}@${remote_host}" \
gpg --list-keys; \
gpg --list-secret-keys
Enter fullscreen mode Exit fullscreen mode

Now you should be able to do commit signing from you remote development box.

References

Top comments (0)