2

When I log in to my server via SSH, I am able to use git over ssh (private repository):

user@local:~$ ssh example.com
Welcome to Ubuntu 14.04.1 LTS (GNU/Linux 2.6.32-042stab083.2 i686)

 * Documentation:  https://help.ubuntu.com/
Last login: Thu Oct 30 10:46:22 2014 from 123.123.123.123
user@remote:~$ cd ~/path/to/project/
user@remote:~/path/to/project$ git pull
Enter passphrase for key '/home/user/.ssh/id_rsa': 
Already up-to-date.
user@remote:~/path/to/project$ ps -aux | grep ssh-agent
user     450  0.0  0.0   4396   832 pts/4    S+   10:57   0:00 grep ssh-agent
user   32680  0.0  0.0   4168   696 ?        Ss   10:50   0:00 ssh-agent
user@remote:~/path/to/project$

Note however, that I must enter the passphrase, even though in a separate session, I added the key using ssh-add to ssh-agent. Ssh-agent is still running, as shown above. I assumed this would let me use the ssh key without entering the passphrase again. I was wrong.

Since I'm using a deployment script that involved cloning or pulling the repo (depends on the project), I run it from the CI server like this:

ssh user@example.com '~/path/to/deployment/script.sh'

As a result, I get a "Permission denied (publickey)." error, since the key needs to be unlocked using a passphrase and none is given.

Are there ways around this besides creating an ssh key without a passphrase?

4

To connect to the ssh-agent, ssh client (or any other process, for that matter) needs to know how to connect to it. This information is emitted by the ssh-agent when started in the form of shell commands. Usually it looks like this:

$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-H8yPWdYCNFmT/agent.506989; export SSH_AUTH_SOCK;
SSH_AGENT_PID=506990; export SSH_AGENT_PID;
echo Agent pid 506990;

Tha spawning application usually just evaluates these commands to load the variables into the current process environment (which is then propagated to all child processes).

Thus, you need to locate the appropriate socket to connect to the right ssh-agent process (yes, you can have several agents running at the same time, even for one user). There are two ways of doing this:

  1. check the PID of the agent in question and scan all /tmp/ssh-* directories for a socket with nearest lower PID (since ssh-agent forks to become a daemon, the PID used in the name of the socket is lower than the PID of the actual daemon)

    If the program that spawned the agent in question is still running (or one of it's children is), you can extract the information from its environment:

    $ strings /proc/<PID>/environ | grep SSH_
    
  2. Always start the agent by telling it what socket it should use:

    $ ssh-agent -a /path/to/ssh_agent/socket
    

    This can come in handy for example also when you are working on a machine both locally and remotely - you can just hard-wire it into your shell initialisation scripts and when you connect to the machine where tha agent has been spawned by the desktop environment, you'll just have access to all the keys you have loaded there. The same goes for using terminal multiplexers and so on.

  • Please correct me if I got it wrong. You are saying that although an ssh-agent process is running, my ssh or git or whatever doesn't know how to connect to it, is that right? And if so, is it sufficient to recreate the environment variables originally emitted by ssh-agent to successfully connect to it in a new login session? – mingos Oct 30 '14 at 14:34
  • Correct - form what you are describing it is likely the case. This typically happens, when you log in, run ssh-agent, disconnect while keeping the agent running, and then reconnect. The new session has no knowledge about the agent spawned during the previous connection. – peterph Oct 30 '14 at 21:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.