Use GPGTools for SSH-logins on Mac OS X

In this post, I show how you set up your shell environment on a Mac to allow SSH authentication with a GPG key.

This solutions works for multiple shell-instances, even if you close them occasionally or if your Mac went to sleep.

What you need:

Setup launch-agent for gpg-agent

The gpg-agent daemon will replace your ssh-agent. It will provide your authentication key to your ssh-client to allow it to authenticate against the ssh-server.

The gpg-agent needs to run in daemon-mode. To automize this process, we create a launch agent. So we start our shell, change into our launch agent directory an create a new agent with vi.


sheldon@mainframe:~$ cd ~/Library/LaunchAgents
sheldon@mainframe:~/Library/LaunchAgents$ vi org.gnupg.gpg-agent.plist 

We put this xml-snippet into the file and replace YOUR_USERNAME with our real username:

	  
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" 
   "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>org.gnupg.gpg-agent</string>
    <key>ProgramArguments</key>
    <array>
      <string>/Users/YOUR_USERNAME/bin/start-gpg-agent.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
  </dict>
</plist>

We save and close vi and go back to our user directory. There we create the directory bin and make it visible only to us.


sheldon@mainframe:~/Library/LaunchAgents$ cd ~
sheldon@mainframe:~$ mkdir bin
sheldon@mainframe:~$ chmod 700 bin

Startup script for gpg-agent

We change into this new directory and create a new shell-script.


sheldon@mainframe:~$ cd bin
sheldon@mainframe:~/bin$ vi start-gpg-agent.sh 

Now we paste this snippet into the shell-script:


if test -f $HOME/.gpg-agent-info && \
  kill -0 `cut -d: -f 2 $HOME/.gpg-agent-info` 2>/dev/null; then
    GPG_AGENT_INFO=`cat $HOME/.gpg-agent-info`
    export GPG_AGENT_INFO
else
  eval `/usr/local/bin/gpg-agent --daemon --write-env-file`
fi
export GPG_TTY=`tty`

This script ensures that only one single instance of the gpg-agent is running at a time. We save and close vi. Now, we make this script executable.


sheldon@mainframe:~/bin$ chmod 700 start-gpg-agent.sh
sheldon@mainframe:~/bin$ d ..
sheldon@mainframe:~$

Gpg-agent configuration file

We have to tell our gpg-agent to support ssh. This can be done by a single line on the shell:


sheldon@mainframe:~$ echo "enable-ssh-support" >> ~/.gnupg/gpg-agent.conf

Bash profile

Finally, we have to add a couple of lines to our ~/.bash_profile. If this file does not exist, we create it.


sheldon@mainframe:~$ vi .bash_profile

We add append these line to the end of the file:


export GPG_TTY=$(tty)
if [ -f "${HOME}/.gpg-agent-info" ]; then
  . "${HOME}/.gpg-agent-info"
  export GPG_AGENT_INFO
fi

We save and close vi. We make the file executable, if it isn’t already.


sheldon@mainframe:~$ chmod 700 .bash_profile

That’s it. Now, we close the shell and log out of OS X. When we log back in, the gpg-agent is started in the background.

Testing

When we open a shell and type in ssh-add -l, we should see the ssh-fingerprints of our gpg-keys:


sheldon@mainframe:~$ ssh-add -l
4096 42:23:30:61:1d:6d:ac:87:9b:f5:2c:de:e5:28:52:e6 cardno:000500001D18 (RSA)
2048 d4:88:84:df:d3:28:d2:75:5e:27:ca:cc:24:12:54:02  (RSA)

We can use the output of ssh-add -L (notice the capital L!) in the file authorized_keys on the server.


sheldon@mainframe:~$ ssh-add -L
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABA...PLN5OjW7w== cardno:000500001D18
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAA...tMA+t0qDQ== 

Thanks

… go to Dietrich Schmidt who created this how-to in the first place.