SSH agent forwarding is a technique you can use to make deploying to a remote server simpler for you and your developers. It allows you to use you local SSH keys instead of leaving passphrase-less keys sitting on your server.
If you've already set up an SSH key, you're probably familiar with
ssh-agent. This is an app that runs in the background and keeps your key loaded into memory so you do not have to enter your passphrase every time you need to use the key. The nifty thing is, you can selectively let remote servers access your local ssh-agent as if it was running on the server. This is sort of like asking a friend to enter their password so you can use their computer.
Check out Steve Friedl's Tech Tips guide for a detailed explanation of SSH agent forwarding.
First and foremost, ensure you have your local SSH key set up and working. You can use this guide if you've not done this yet. You can test that your local key works by running
ssh -T email@example.com.
ssh -T firstname.lastname@example.org # Attempt to SSH in to github # Hi username! You've successfully authenticated, but GitHub does not provide # shell access.
We're off to a great start. Let's set up SSH to allow agent forwarding to your remote server. Open up the file at
~/.ssh/config in your text editor. If it doesn't exist, create it by running
touch ~/.ssh/config. Add the following section, replacing
example.com with your server's domain name or IP.
Host example.com ForwardAgent yes
Warning: You may be tempted to use a wildcard like
Host * to just apply this setting to all SSH connections. That's not really a good idea, as you'd be sharing access to your local SSH keys with every server you SSH to. They won't have direct access to the keys, but they will be able to use them while the connection is established. You should only add servers you intend to use agent forwarding with.
To test that agent forwarding is working with your server, you need to SSH in and run the
ssh -T email@example.com command on the server. If all is well, you'll get back the same prompt as you do locally. If you are unsure if your local key is being used, you can inspect the
echo "$SSH_AUTH_SOCK" # Print out the SSH_AUTH_SOCK variable # /tmp/ssh-4hNGMk8AZX/agent.79453
If the variable is not set, agent forwarding is not working:
echo "$SSH_AUTH_SOCK" # Print out the SSH_AUTH_SOCK variable # [No output] ssh -T firstname.lastname@example.org # Try to SSH to github # Permission denied (publickey).
Before you can make your keys work through agent forwarding, they must work locally first. Check out this guide for help setting up your local SSH keys
Not only do you need to enable agent forwarding in your user's SSH config (see above), but you may need to set it in your system's SSH settings as well. You can check if a system config file is being used by running
ssh -v example.com and checking the first few lines of the output. Make sure you use your server's domain name or IP, of course.
ssh -v example.com # Connect to example.com with verbose debug output # OpenSSH_5.6p1, OpenSSL 0.9.8r 8 Feb 2011 # debug1: Reading configuration data /Users/you/.ssh/config # debug1: Applying options for example.com # debug1: Reading configuration data /etc/ssh_config # debug1: Applying options for *
Don't forget to
exit to return to your local system!
In the example above, the file
~/.ssh/config is loaded first, then
/etc/ssh_config. We can inspect that file to see if it's overriding our options.
cat /etc/ssh_config # Print out the /etc/ssh_config file Host * SendEnv LANG LC_* ForwardAgent no
What do we have here? Our system settings file is overriding the
ForwardAgent setting. We can edit this file and remove that line.
Agent forwarding may be blocked on the server's side. Make sure
AllowAgentForwarding is set in
On most systems the OS will automatically launch ssh-agent for you. On windows, however, you need to do this manually. Check out this guide for details on how to run ssh-agent automatically when you open Git Bash.
To check to see if ssh-agent is running, inspect the
echo "$SSH_AUTH_SOCK" # Print out the SSH_AUTH_SOCK variable # /tmp/launch-kNSlgU/Listeners
You can check with:
And if no identity is available: