You are on page 1of 8

git - Start ssh-agent on login - Stack Overow

Join the Stack Overflow Community

Stack Overflow is a community of 6.9 million


programmers, just like you, helping each other.
Join them; it only takes a minute:

Sign up

Start ssh-agent on login

I have a site as a remote Git repo pulling from Bitbucket.com using an SSH alias. I can manually start the ssh-agent on my server but I ha
do this every time I login via SSH.

I manually start the ssh-agent:

eval ssh-agent $SHELL

Then I add the agent:

ssh-add ~/.ssh/bitbucket_id

Then it shows up when I do:

ssh-add -l

And I'm good to go. Is there any way to automate this process so I don't have to do it every time I login? The server is running RedHat 6.2
(Santiago).

git ssh bitbucket redhat ssh-agent

edited May 20 '14 at 17:43


random
7,257 7 44 66

1 of 8
git - Start ssh-agent on login - Stack Overow

2 Anything you want to do every time you login should in .profile (terminal logins) or .xinitrc (for GUI logins).
Barmar Sep 18 '13 at 18:50

Ah! I was using .bash_profile... What's the difference between .profile and .bash_profile?
Pathsofdesign Sep 18 '13 at 18:54

1 Not sure why you're running the command that way in the first place. ssh-agent <command> runs
<command> as a subprocess of ssh-agent , so you're starting a new shell. I think you want eval
ssh-agent . Barmar Sep 18 '13 at 20:53

5 .bash_profile is specific to bash, .profile is generic to all POSIX shells. bash will look first for
.bash_profile , then default to .profile . Barmar Sep 18 '13 at 20:54

3 The correct way to spawn ssh-agent for a "standard" (POSIX-compatible) shell is eval $(ssh-agent
-s) . Note also that you have to make sure you properly get rid of the agent when you log out, so it's also
advisable to put trap 'kill $SSH_AGENT_PID' EXIT in your .profile after the line which starts the
agent. kostix Sep 19 '13 at 10:16

9 Answers

Please go through this article. You may find this very useful:

http://mah.everybody.org/docs/ssh

Just in case the above link vanishes some day, I am capturing the main piece of the solution
below:

This solution from Joseph M. Reagle by way of Daniel Starin:

Add this following to your .bash_profile

SSH_ENV="$HOME/.ssh/environment"

function start_agent {
echo "Initialising 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;
}

# Source SSH settings, if applicable

if [ -f "${SSH_ENV}" ]; then
. "${SSH_ENV}" > /dev/null
#ps ${SSH_AGENT_PID} doesn't work under cywgin
ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
start_agent;
}
else
start_agent;
fi

This version is especially nice since it will see if you've already started ssh-agent and, if it
can't find it, will start it up and store the settings so that they'll be usable the next time you
start up a shell.

edited Jan 16 '14 at 7:05 answered Sep 20 '13 at 10:57


Litmus
5,096 4 19 34

2 of 8
git - Start ssh-agent on login - Stack Overow

2 Machine restart is not necessary. You can just reload .bash_profile using source
~/.bash_profile in your current shell session. Machine restart will also work because that will load the
new config anyway. Litmus Jul 16 '14 at 8:49

4 Use SSH_ENV="$HOME/.ssh/env" (i.e. just not /environment) Why? sshd uses ~/.ssh/environment (see
man page : PermitUserEnvironment). Github also recommend this in their solution -
help.github.com/articles/ Andrew Murphy Sep 13 '14 at 8:22

3 This script worked for me when I put it in my ~/.bashrc file (not my ~/.profile or ~/.bash_profile). The first
time I open a local console it prompts for the passphrase, everything works from that point on without
further prompting. Cheers. andrew pate Feb 19 '15 at 11:38

1 Adding the ssh-agent start command in .bashrc will make scp command not work. Dzanvu Mar 18
'15 at 8:14

1 Still annoying... you have to do this every time you log in... even if you don't use ssh. Need to make this
fire off every time ssh is called... and ideally, you should be able to configure which hosts cause which
keys to load. Erik Aronesty Jul 22 '16 at 15:30

The accepted solution have following drawbacks:

it is complicated to maintain;
it evaluates storage file which may lead to errors or security breach;
it starts agent but doesn't stop it which is close equivalent to leaving the key in ignition.

If your keys do not require to type password, I suggest following solution. Add the following to
your .bash_profile very end (edit key list to your needs):

exec ssh-agent $BASH -s 10<&0 << EOF


ssh-add ~/.ssh/your_key1.rsa \
~/.ssh/your_key2.rsa &> /dev/null
exec $BASH <&10-
EOF

It have following advantages:

much simpler solution;


agent session ends when bash session ends.

It have possible disadvantages:

interactive ssh-add command will influence only one session, which is in fact an issue only
in very untypical circumstances;
unusable if typing password is required;
started shell becomes non-login (which doesn't influence anything AFAIK).

Note that several ssh-agent processes is not a disadvantage, because they don't take more
memory or CPU time.

edited Apr 8 '15 at 17:46 answered Apr 8 '15 at 16:44


midenok
322 3 8

This worked nicely for me. Thanks! voam Feb 28 '16 at 2:02

I've got SSH keys in a directory outside of $HOME in Windows 10, using Git Bash. Changing the path to
the RSA was all I needed to do to get this working. TYVM! kayleeFrye_onDeck Mar 18 '16 at 4:58

Thank you - this was perfect. Nice and simple. I didn't need anything more complicated. slimflem Apr 15
'16 at 2:54

3 of 8
git - Start ssh-agent on login - Stack Overow

I would argue that "If your keys do not require to type password" is close equivalent to leaving the key
in ignition. Bruno Bronosky Oct 3 '16 at 22:51

At least, it is on your own host, not somewhere on the network. midenok Oct 4 '16 at 7:23

Old question, but I did come across a similar situation. Don't think the above answer fully achieve
whats needed. The missing piece is keychain,

sudo apt-get install keychain

Will do what's needed in this case. (if not installed) Check http://unix.stackexchange.com
/questions/90853/how-can-i-run-ssh-add-automatically-without-password-prompt For more
details

answered Jul 23 '14 at 4:46


xelber
1,458 10 20

keychain does not work for me according to the instructions given. I added to .bash_profile and ssh still
asks for password every time. i tried it multiple times in same shell. no dice. going back to basic ssh-agent
approach javadba Jul 23 '14 at 20:12

Add eval keychain --eval id_[yourid file] to .bashrc xelber Sep 11 '14 at 5:16

Thx. I am doing different way now, but have taken note. javadba Sep 11 '14 at 6:30

Very easy and it works this way, thanks @xelber! Valter Henrique Nov 4 '15 at 5:54

On Arch Linux, the following works really great (should work on all systemd-based distros):

Create a systemd user service, by putting the following to ~/.config/systemd/user/ssh-


agent.service :

[Unit]
Description=SSH key agent

[Service]
Type=forking
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
ExecStart=/usr/bin/ssh-agent -a $SSH_AUTH_SOCK

[Install]
WantedBy=default.target

Setup shell to have an environment variable for the socket ( .bash_profile, .zshrc, ... ):

export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"

Enable the service, so it'll be started automatically on login, and start it:

systemctl --user enable ssh-agent


systemctl --user start ssh-agent

Add the following configuration setting to your ssh config file ~/.ssh/config (this works since
SSH 7.2):

AddKeysToAgent yes

This will instruct the ssh client to always add the key to a running agent, so there's no need to
ssh-add it beforehand.

edited Aug 16 '16 at 18:03 answered Aug 16 '16 at 17:25

4 of 8
git - Start ssh-agent on login - Stack Overow

spheenik
191 1 4

Add this to your ~/.bashrc :

if [ ! -S ~/.ssh/ssh_auth_sock ]; then
eval `ssh-agent`
ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock
ssh-add -l | grep "The agent has no identities" && ssh-add

This should only prompt for a password the first time you login after each reboot. It will keep
reusing the ssh-agent as long as it stays running.

answered Jul 27 '16 at 17:28


Collin Anderson
5,141 3 34 37

1 I like this solution it's very simple. Statwonk Feb 16 at 3:24

So I used to use the approaches described above, but I kind of prefer the agent to die when my
last bash session ends. This is a bit longer than the other solutions, but its my preferred
approach. The basic idea is that the first bash session starts the ssh-agent. Then each additional
bash session checks for the config file ( ~/.ssh/.agent_env ). If that is there and there is a
session running then source the environment and create a hardlink to the socket file in /tmp
(needs to be on the same filesystem as the original socket file). As bash sessions shut down
each deletes its own hardlink. The last session to close will find that the hardlinks have 2 links
(the hardlink and the original), removal of the processes own socket and killing of the process will
result in 0, leaving a clean environment after the last bash session closes.

# Start ssh-agent to keep you logged in with keys, use `ssh-add` to log in
agent=`pgrep ssh-agent -u $USER` # get only your agents
if [[ "$agent" == "" || ! -e ~/.ssh/.agent_env ]]; then
# if no agents or environment file is missing create a new one
# remove old agents / environment variable files
kill $agent running
rm ~/.ssh/.agent_env

# restart
eval `ssh-agent`
echo 'export SSH_AUTH_SOCK'=$SSH_AUTH_SOCK >> ~/.ssh/.agent_env
echo 'export SSH_AGENT_PID'=$SSH_AGENT_PID >> ~/.ssh/.agent_env
fi

# create our own hardlink to the socket (with random name)


source ~/.ssh/.agent_env
MYSOCK=/tmp/ssh_agent.${RANDOM}.sock
ln -T $SSH_AUTH_SOCK $MYSOCK
export SSH_AUTH_SOCK=$MYSOCK

end_agent()
{
# if we are the last holder of a hardlink, then kill the agent
nhard=`ls -l $SSH_AUTH_SOCK | awk '{print $2}'`
if [[ "$nhard" -eq 2 ]]; then
rm ~/.ssh/.agent_env
ssh-agent -k
fi
rm $SSH_AUTH_SOCK
}
trap end_agent EXIT
set +x

5 of 8
git - Start ssh-agent on login - Stack Overow

answered Sep 15 '15 at 17:46


Micah
363 2 7

Thank you for this gem. Thank you very much. Xunnamius May 6 '16 at 20:30

I solved it by adding this to the /etc/profile - system wide (or to user local .profile, or
.bash_profile).

# SSH-AGENT
#!/usr/bin/env bash
SERVICE='ssh-agent'
WHOAMI=`who am i |awk '{print $1}'`

if pgrep -u $WHOAMI $SERVICE >/dev/null


then
echo $SERVICE running.
else
echo $SERVICE not running.
echo starting
ssh-agent > ~/.ssh/agent_env
fi
. ~/.ssh/agent_env

This starts a new ssh-agent if not running for user, or re-sets the ssh-agent env parameter
if running.

answered May 29 '15 at 13:39


TheFrog
11 1

Like your answers a lot. It made working from cygwin / linux hosts a lot easier. I combined
start and end functions to make it secure.

SSH_ENV="$HOME/.ssh/.agent_env"

function start_agent {
echo "Initialising new SSH agent..."

eval `/usr/bin/ssh-agent`
echo 'export SSH_AUTH_SOCK'=$SSH_AUTH_SOCK >> ${SSH_ENV}
echo 'export SSH_AGENT_PID'=$SSH_AGENT_PID >> ${SSH_ENV}

echo succeeded
chmod 600 "${SSH_ENV}"
. "${SSH_ENV}" > /dev/null
/usr/bin/ssh-add;
}

# Source SSH settings, if applicable


if [ -f "${SSH_ENV}" ]; then
. "${SSH_ENV}" > /dev/null
#ps ${SSH_AGENT_PID} doesn't work under cywgin
ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
start_agent;
}
else
start_agent;
fi

# create our own hardlink to the socket (with random name)


MYSOCK=/tmp/ssh_agent.${RANDOM}.sock
ln -T $SSH_AUTH_SOCK $MYSOCK
export SSH_AUTH_SOCK=$MYSOCK

6 of 8
git - Start ssh-agent on login - Stack Overow

end_agent()
{
# if we are the last holder of a hardlink, then kill the agent
nhard=`ls -l $SSH_AUTH_SOCK | awk '{print $2}'`
if [[ "$nhard" -eq 2 ]]; then
rm ${SSH_ENV}
/usr/bin/ssh-agent -k
fi
rm $SSH_AUTH_SOCK
}
trap end_agent EXIT
set +x

thanks again

edited Dec 17 '15 at 14:58 answered Dec 17 '15 at 10:53


Ajay2707 Knelis
3,253 3 14 36 11 1

"ps -p <pid>" should work on all linux/cygwin Erik Aronesty Jul 22 '16 at 15:34

Sorry for being so late:

Users of the fish shell can use this script to do the same thing.

# content has to be in .config/fish/config.fish


# if it does not exist, create the file
setenv SSH_ENV $HOME/.ssh/environment

function start_agent
echo "Initializing new SSH agent ..."
ssh-agent -c | sed 's/^echo/#echo/' > $SSH_ENV
echo "succeeded"
chmod 600 $SSH_ENV
. $SSH_ENV > /dev/null
ssh-add
end

function test_identities
ssh-add -l | grep "The agent has no identities" > /dev/null
if [ $status -eq 0 ]
ssh-add
if [ $status -eq 2 ]
start_agent
end
end
end

if [ -n "$SSH_AGENT_PID" ]
ps -ef | grep $SSH_AGENT_PID | grep ssh-agent > /dev/null
if [ $status -eq 0 ]
test_identities
end
else
if [ -f $SSH_ENV ]
. $SSH_ENV > /dev/null
end
ps -ef | grep $SSH_AGENT_PID | grep -v grep | grep ssh-agent > /dev/null
if [ $status -eq 0 ]
test_identities
else
start_agent
end
end

edited Mar 11 '16 at 7:23 answered Sep 7 '15 at 11:54


Daniel Gerber
914 10 20

7 of 8
git - Start ssh-agent on login - Stack Overow

Thanks. It would however be better to post the contents of the Gist here, to preserve it for posterity.
herrbischoff Mar 9 '16 at 20:12

thanks for the hint.. Daniel Gerber Mar 11 '16 at 7:23

8 of 8