App-Utility-SSH-key-agent

From KRayWiki
Jump to navigation Jump to search
See Also 
App-Utility-SSH-Agent
App-Utility

To use an ssh-agent in a given terminal session, a user is normally required to manually set SSH_AUTH_SOCK and SSH_AGENT_PID environment variables using information provided by ssh-agent. It is often tedious to recall the values beyond the point when ssh-agent is initially started. key-agent helper scripts are usually able to automatically determine appropriate values and assign them to the environment variables.

Superior 'lsof' Edition

The lsof edition key-agent aliases are known to work with SCO OpenServer 5.0.7 but do not appear to work with modern Linux distributions. These aliases also do not work in MSYS/MSYS2 environments due to lack of an lsof command.

When they work, the lsof-based aliases are superior as they check ssh-agent sockets for a valid owner process. They cannot work if elevated permissions are required by lsof to obtain a PID (this appears to be true for modern Linux). More detail on this topic may be found by reading the kbulgrien's post here: https://stackoverflow.com/questions/2358518/

The aliases auto-set SSH_AUTH_SOCK and SSH_AGENT_PID per any existing ssh-agent sockets owned by the user.

key-agent-find

alias key-agent-find='export SSH_AUTH_SOCK=$(test -d /tmp/ssh-* && for _F_ in $(pushd ${HOME} >/dev/null; ls -rt $(find /tmp/ssh-* -name "agent.*" -user $(id -un) -print 2>/dev/null) "" 2>/dev/null; popd >/dev/null); do _P_=$(lsof -Fp ${_F_} | sed s/p//); test -n "${_P_}" && kill -0 ${_P_} && echo ${_F_} && stty echo && break; done)'

This alias is used by key-agent and is not normally used directly.

  1. Set a working directory with user permissions.
  2. Find all ssh-agent sockets owned by the user running the command.
  3. Sort any found sockets in oldest to newest order so as to prefer older agents over newer ones. This avoids associating with a new agent if a new one was inadvertently started when an older one was already useable.
  4. Check sockets to see if they are open in a currently running process. lsof reports owning PIDs. kill -0 each reported PID to test it for validity. This is likely redundant as lsof shouldn't report the PID if it isn't running. In any event kill -0 only tests a PID for validity and does not actually signal the process.
  5. Ignore any socket that is not associated with a valid PID.
  6. Stop searching for sockets upon finding the first that has a valid PID.
  7. Return the socket in an SSH_AUTH_SOCK environment variable.
  8. Restore the original working directory.

key-agent-run

alias key-agent-run='ssh-agent; key-agent-find'

This alias is used by key-agent and is not normally used directly.

  1. If called, start a new ssh-agent instance, and use key-agent-find to identify its socket.

key-agent

alias key-agent='key-agent-find; test -z "${SSH_AUTH_SOCK}" && key-agent-run; test -n "${SSH_AUTH_SOCK}" && export SSH_AGENT_PID=$(lsof -Fp ${SSH_AUTH_SOCK} | sed s/p//); ssh-add -l'

This alias is used by an end-user use; it calls other aliases as needed.

  1. Use key-agent-find to attempt to find a socket with an associated PID. If a useable socket was found, SSH_AUTH_SOCK will return non-empty.
  2. If SSH_AUTH_SOCK is empty, meaning no usable agent was found, use key-agent-run to start a new one and re-run ssh-agent-find to load the SSH_AUTH_SOCK variable.
  3. Though SSH_AUTH_SOCK should be non-empty at this point, nothing more is done if a socket was not found. Debug is out-of-scope for this document, but bear in mind that this lsof-based set of aliases does not work if lsof does not report a PID as can happen on some Linux that require elevated permissions to do so.
  4. When SSH_AUTH_SOCK is non-empty, lsof is used again to identify the PID, but this time, the PID is captured in an SSH_AGENT_PID environment variable.
  5. Presuming that SSH_AGENT_PID returns non-empty, and it should since lsof already was used to identify the socket, ssh-add -l notifies the user of any keys already loaded into the agent, if any. If no PID was set, ssh-add should generate an error message.

ssh-add

  1. If key-agent reports "The agent has no identities", it is up to the user to run ssh-add to load any required keys the agent should hold.

Enhanced Edition

Since the lsof edition does not work on modern Linux installations, the enhanced scripts are presently the best choice on Linux systems. Despite any weaknesses, the scripts are normally reliable and very useful.

Though these scripts represent a significant improvement over the legacy and improved edition aliases, the ssh-agent PID is computed improperly in the same way that it is with the legacy and improved editions. This does not appear to impede functionality other than breaking the ability to kill the agent in use via "ssh-agent -k".

  • The key-agent-run and key-agent aliases remain unmodified.
  • The script checks the user's available sockets on oldest to newest order.
    • This means an agent with already loaded identities is more likely to be picked in the event that the user may have been inadvertently started new agents when an older agent already existed.
  • netstat is used to disregard sockets without a running listener.
    • netstat is slower than commands used by other editions.

key-agent-find

alias key-agent-find='export SSH_AUTH_SOCK=$(for _F_ in $(pushd >/dev/null; ls -rt "" $(find /tmp/ssh-* -name "agent.*" -user $(id -un) -print 2>/dev/null) 2>/dev/null; popd >/dev/null); do netstat -a | grep -E -- ${_F_} >/dev/null && echo ${_F_} && break; done)'

Improved Edition

Since both the lsof edition and netstat editions do not work under MSYS, the following improved scripts are presently the best choice for use with MSYS. Despite the weaknesses, the scripts are normally reliable and very useful.

Though this edition represents a minor improvement over legacy edition aliases, their weaknesses persist.

  • The key-agent-run and key-agent aliases remain unmodified.
  • The key-agent-find alias is identical to the legacy edition EXCEPT that the script now consistently picks the oldest socket every time.
    • This means an agent with already loaded identities is more likely to be picked in the event that the user may have been inadvertently started new agents when an older agent already existed.
    • Unfortunately, the oldest socket is also the one most likely to be a leftover socket whose process has since died.

key-agent-find

alias key-agent-find='export SSH_AUTH_SOCK=$(pushd ${HOME} >/dev/null; ls -rt "" $(find /tmp/ssh-* -name "agent.*" -user $(id -un) -printf "%p " 2>/dev/null) 2>/dev/null | head -1 | sed "s/[*\/=>@|]\$//"; popd >/dev/null)'

Legacy Edition

This set of aliases has been fairly reliably used on Linux systems for quite some time even though they are known to have particular weaknesses:

  1. If a user has multiple ssh-agent sockets in existence for whatever reason, key-agent-find just picks one without making any attempt to determine usability.
    • As long as a user has only a single agent at any time, and, as long as killed agents properly clean up their associated sockets, this these aliases have a long track record of usefulness.
    • If an agent is killed before it has a chance to clean up its associated socket, these aliases can fail because key-agent-find often picks the socket with no owner.
    • If a user inadvertently starts multiple agents by manually issuing ssh-agent commands, these aliases cannot be relied upon to consistently pick the agent instance that already has identities loaded.
  2. This edition actually is flawed in that the actual PID of the ssh-agent process is not correctly identified.
    • The incorrect PID usually does not matter on many Linux installations as ssh-agent there are able to work when only SSH_AUTH_SOCK is set, even if SSH_AGENT_PID is set to an incorrect PID.
    • The incorrect PID does prevent killing the currently used agent via "ssh-agent -k".
    • The reason a wrong PID is set is because the socket is named by a process that forks of an agent and then terminates. The socket name contains the PID that terminates. The PID of the forked agent is simply the original PID plus one, but it is quite likely unsafe to assume this is always true even if it is true most of the time on a lightly loaded system.
  3. This edition does not work with the SCO OpenServer 5.0.7 ssh-agent.

When the aliases malfunction, the user must either remove irrelevant sockets, or, remove all sockets and kill all running agents. This is not something most users will feel comfortable with.

key-agent-find

alias key-agent-find='export SSH_AUTH_SOCK=$(find /tmp/ssh-* -name "agent.*" -user `id -un` -print -a -quit 2>/dev/null)'

key-agent-run

alias key-agent-run='ssh-agent; key-agent-find'

key-agent

alias key-agent='key-agent-find; test -z "${SSH_AUTH_SOCK}" && key-agent-run; export SSH_AGENT_PID=${SSH_AUTH_SOCK#*.}; ssh-add -l'