Don't put your private key on a public server
Aug 25, 2010
You're administering a server (Server A), and you need access to something on another server (Server B) but access is denied from Server A because you don't have your private key on there. If this is a scenario you've run into while trying to deploy an application it's almost certain that you don't want to put your private key on the server in the home directory of your deployment user, readable to anyone that can log in as that account (i.e, people other than you!).
SSH Agent Forwarding to the rescue
To get around this SSH has built in support for forwarding on your private credentials. What happens is that when you connect to a remote server the ssh-agent
creates a unix socket and then listens to connections from ssh
, this socket is accessible only by your user account… and root.
Yes, what this in fact means is that the root user on the remote server has access to the unix socket you've created. They can't see your private keys, they're still safely held on your client, but while you're connected to the remote server the root user on that machine could potentially use that socket to connect as you to another server. In short, make sure you trust root before you set this up (still, it's better than putting your private key in your home directory where root would now be able to see they key and use it whenever they wanted).
Configure your SSH client to use Agent Forwarding
Getting it to work is as simple as adding an entry to ~/.ssh/config
(create the file if it doesn't exist):
Host remote-server.example.com
ForwardAgent yes
Just replace the Host value with the hostname or IP address of the server you are connecting to, or with *
if you're brave and want to do it automatically for all hosts.
Restarting your local SSH Agent
On my Macbook Pro I've added the following to my ~/.bash_profile
to make sure that the SSH Agent is started when I open a new terminal and that my identities (private keys) are added to it:
SSH_ENV=$HOME/.ssh/environment
function start_agent {
echo "Initializing new SSH agent..."
/usr/bin/ssh-agent | sed 's/^echo/#echo/' > ${SSH_ENV}
echo succeeded
chmod 600 ${SSH_ENV}
. ${SSH_ENV} > /dev/null
/usr/bin/ssh-add;
}
if [ -f "${SSH_ENV}" ]; then
. ${SSH_ENV} > /dev/null
ps -x | grep "^ *${SSH_AGENT_PID}" | grep ssh-agent$ > /dev/null || {
start_agent;
}
else
start_agent;
fi
Previously I led the Terraform product team @ HashiCorp, where we launched Terraform Cloud and set the stage for a successful IPO. Prior to that I was part of the Startup Team @ AWS, and earlier still an early employee @ Heroku. I've also invested in a couple of dozen early stage startups.