Home > Software engineering >  ssh-agent in bash script causes many dead processes
ssh-agent in bash script causes many dead processes

Time:02-23

I use a bash script (deploy.sh) to deploy my application to a shared host. As part of the deployment process, I clone the latest code from bitbucket using the script below:

eval `ssh-agent -s`
ssh-add ~/.ssh/SHA256-XXX.priv
git clone [email protected]:username/gng2.git --branch $branchname --single-branch

It seems that this script causes a lot of "dead" processes on the shared host, and when I reach a limit, my app does not work any more as there is no more free process. Please see some examples of dead processes below:

699      65313  0.0  0.0   7112  1752 ?        Ss   Jan04   0:00 ssh-agent -s
699      67925  0.0  0.0   7112  1744 ?        Ss   Feb07   0:00 ssh-agent -s
699      70469  0.0  0.0   7112  1612 ?        Ss   Jan04   0:00 ssh-agent -s
699      71078  0.0  0.0   7112  2352 ?        Ss   Feb10   0:00 ssh-agent -s 

The support team at the hosting company helped to track down that the dead processes are started by my deploy script:

[email protected]:~$ grep -ril "ssh-agent" .
./www/example.com/gng2-core/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
./www/example.com/gng2-core/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php
./www/example.com/gng2-core/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php
./www/example.com/repos/gng2/deploy/scripts/deploy.sh
./www/example.com/repos/deploy.sh

This article suggests that my script may "spawns a distinct ssh-agent instance which remains running with the added keys in memory even after logout, unless explicitly killed"

How do I need to change my script so that it does not create so many (dead) processes? Can I simply add the following to the end of my script to solve this problem?

eval `ssh-agent -k`

Or is there a better solution to this problem?

CodePudding user response:

Your script probably shouldn't start ssh-agent; it should make use of an ssh-agent that's already running. That way, the user is responsible for starting a single agent that can be used by multiple invocations of the script.

The simplest thing you can do, though, is simply add either

kill $SSH_AGENT_PID

or

ssh-agent -k

to the end of your script to kill the agent that was just started. One of the things the eval command does is sets the value of SSH_AGENT_PID to the process ID of the just-started agent.

(The former is useful if you have, for whatever reason, multiple concurrent agents, so that you kill the correct agent.)

CodePudding user response:

This on multiple folds has to be dealt with carefully:

First check an ssh-agent is not already available

#!/usr/bin/env bash

# Limit risk of leaving script with an ssh key unlocked
# Keep in mind that SIGKILL cannot be trapped, so it is not 100% abuse-proof
# So remove all pending authorizations
trap 'ssh-add -D 2>/dev/null"' EXIT INT

# Spawn an ssh agent for a limited time only if none already available
if [ -z "$SSH_AUTH_SOCK" ] && [ -z "$SSH_AGENT_PID" ] ! ; then
  # Runs the agent only for the next 5 minutes
  eval 'ssh-agent -t 600'
fi

# Now that we know an ssh-agent is available
# we can register our ssh key with an expiration timeout
# so the authentication does not remain exposed for too long
ssh-add -t 600 # expire in 5 minutes

About security precautions when using an ssh-agent:

https://goteleport.com/blog/how-to-use-ssh-agent-safely/

  • Related