|
NAMEkeychain - Manager for ssh-agent, gpg-agent and private keys. Compatible with POSIX systems. SYNOPSISkeychain [ -hklQqV ] [ --clear --confhost --confallhosts --debug --extended --gpg2 --help --ignore-missing --list --noask --nocolor --nogui --noinherit --nolock --quick --quiet --ssh-allow-forwarded --ssh-rm --ssh-spawn-gpg --systemd --version ] [ --ssh-agent-socket path ] [ --dir dirname ] [ --host name ] [ --lockwait seconds ] [ --stop which ] [ --timeout minutes ] [ --wipe which ] [ keys... ] INTRODUCTIONKeychain helps you to manage SSH and GPG keys in a convenient and secure manner. It acts as a frontend to "ssh-agent" and "ssh-add", but allows you to easily have one long running "ssh-agent" process per system, rather than the norm of one "ssh-agent" per login session. This dramatically reduces the number of times you need to enter your passphrase. With "keychain", you only need to enter a passphrase once every time your local machine is rebooted. Keychain also makes it easy for remote cron jobs to securely "hook in" to a long running "ssh-agent" process, allowing your scripts to take advantage of key-based logins. Keychain also supports GnuPG 2.1 and later, and will automatically start gpg-agent if any GPG keys are referenced on the command-line, and will ensure these credentials are cached in memory and available for use. Keychain supports most UNIX-like operating systems. It supports integration with Bourne-compatible, csh-compatible and fish shells. Additional documentation for Keychain can be found on "https://www.funtoo.org/Funtoo:Keychain" in the Keychain wiki page. LIFECYCLETypically, you configure keychain to run when you first log in to a system. If you are using Bourne shell or bash, you will create a "~/.profile" or "~/.bash_profile" file and include the following line in it: eval "$(keychain --eval id_rsa)" Keychain will start ssh-agent if one isn't already running. Keychain then checks to make sure your private keys (in this example, "id_rsa") are loaded into the agent. If they are not, you are prompted for any passphrase necessary to decrypt them, so that they are cached in memory and available for use. In addition to printing some user-friendly output to your terminal, keychain will also output important ssh-agent environment variables, which the "$( )" (you can also use "` `") captures, and the "eval" evaluates, setting these variables in your current shell. These ssh-agent environment variables are also written to "~/.keychain/${HOSTNAME}-sh", so that subsequent logins and non-interactive shells such as cron jobs can source the file to access the running ssh-agent and make passwordless ssh connections using the cached private keys -- even when you are logged out. These files are collectively called pidfiles. The key files specified on the command-line will be searched for in the "~/.ssh/" directory, and keychain will expect to find the private key file with the same name, as well as a ".pub" public key. Keychain will also see if any GPG keys are specified, and if so, prompt for any passphrases to cache these keys into "gpg-agent". Typically, private SSH key files are specified by filename only,
without path, although it is possible to specify an absolute or relative
path to the private key file as well. Private key files can be symlinks to
the actual key as long as your system has the
"readlink" command available. More
advanced features are available for specifying keys as well -- see the
In addition, for GPG keys specified, similar steps will be taken to ensure that gpg-agent has the GPG key cached in memory and ready for use. STREAMLINING AND SIMPLIFICATIONKeychain 2.9.0 has been streamlined, and with this maintenance several command-line options have been retired as they are not completely necessary. This simplifies the use of the tool by making it more intuitive to use. The files created in ~/.keychain have also been cleaned up. This section details all the important changes. PIDFILE CHANGES"Pidfile" is the nickname for files created in "~/.keychain" which can then be sourced by your scripts to access a running agent. When using gpg-agent for GPG keys, keychain will no longer create a "~/.keychain/${HOSTNAME}-sh-gpg" pidfile. This file is no longer needed as the canonical GPG socket inside "~/.gnupg/" will be used to detect the running gpg-agent, which is the modern convention. GnuPG 2.1 and later have stopped using environment variables to find the agent, so we follow this upstream change. IMPROVED DEBUGGINGA new --debug option is now available which will print additional information related to keychain's decisions regarding why and how an agent was found -- or not. NEW (AND DEPRECATED) OPTIONSThis section provides an overview of new and deprecated command-line options. For full details on each option, see the respective option definition under "OPTIONS". Keychain 2.9.2 The "--confhost" option has been deprecated. Instead of "--confhost hostname", use "--extended host:hostname". This extended format allows multiple keys of multiple types (SSH, GPG and SSH-from-hostname) to be specified on the command-line together. This is also fully compatible with "--confallhosts", and keychain now de-duplicates the list of keys to be loaded. Keychain 2.9.1 The short-lived "--ssh-wipe" and "--gpg-wipe" options that appeared only in version 2.9.0 were replaced with "--wipe which" to work similarly to the "--stop" option, and allows you to specify "ssh", "gpg" or "all". Keychain 2.9.0 The "--agents" option is now deprecated. Keychain will always ensure an ssh-agent or equivalent is running, or if "--ssh-spawn-gpg" is used, potentially a gpg-agent for the purpose of storing SSH keys if no running ssh-agent is available. To simply use a gpg-agent if one is already running, falling back to launching ssh-agent if no agent is available, use the "--ssh-allow-gpg" option. Specifying a GPG key on the command-line will instruct keychain to enable gpg-agent functionality automatically. This eliminates an option that you need to specify ("--agents ssh,gpg") when invoking keychain, and for many will avoid spawning a GPG agent you may not be using. Specifying the "--agents" option will now display a warning that it's deprecated, but keychain will not abort. The "--inherit" option, which took one of four arguments, has been deprecated. Keychain's default behavior remains that of preferring to use an ssh-agent or equivalent referenced by its pidfile, falling back to finding an ssh-agent in its environment. By default, keychain will not use a gpg-agent socket for SSH keys unless at least "--ssh-allow-gpg" is specified. Similarly, the use of any forwarded SSH agent connection is disabled by default and can be enabled via "--ssh-allow-forwarded". Again, see the full documentation for each option in the "OPTIONS" section. You can still influence keychain's behavior via the still-present "--noinherit" option which will prevent all detection of existing SSH agents via the environment. The "--clear" option is still available, but isn't intended to be a "standalone" option, meaning that it is used to perform an initial clearing of cached keys before loading any specified keys when Keychain is run. To perform the sole action of wiping all cached keys, use the "--wipe" action. To remove an individual cached SSH private key or keys, use the "--ssh-rm" keyfile option. The "--stop" option will now only stop any running ssh-agent processes, and still supports three possible options: "mine", "others" and "all". It no longer stops gpg-agent processes, which tend to get auto-respawned by GPG tools, so killing gpg-agent typically doesn't make a lot of sense. BETTER GNUPG INTEGRATIONKeychain can now use an existing gpg-agent that has been started in your environment to store ssh keys, rather than spawning its own ssh-agent, by using the "--ssh-allow-gpg" option. If you would like keychain to spawn gpg-agent instead of ssh-agent, and use it to store SSH keys, specify the "--ssh-spawn-gpg" option. Without either option, keychain will not use an SSH_AUTH_SOCK that is provided by gpg-agent, and will spawn an official ssh-agent process. In addition, behind the scenes, keychain now uses the gpg-connect-agent executable to restart the agent, get official PID and socket information, etc. Please note that while gpg-agent provides full compatibility with ssh-agent, its password prompt is handled by pinentry and its store may encrypt your in-memory keys. For this reason, consider this new feature experimental, and use GitHub issues to report back any anomalies or suggested improvements for gpg-agent integration. DISPLAY CHANGESWhen keychain uses gpg-agent for either GnuPG or SSH support, then keychain will display the GnuPG socket file in its output, rather than the PID. Since the socket file has the "~/.gnupg" path in it, this communicates to you that gpg-agent, not ssh-agent, is active. If you see an integer PID, this means that ssh-agent is being used. =head2 STREAMLINED STARTUP By default, keychain will always ensure that an ssh-agent should be started. It will only start a gpg-agent if a GPG key is referenced on the command-line. Modern versions of gpg-agent also support the caching of SSH keys, allowing it to be a drop-in replacement for ssh-agent. With keychain 2.9.0, a new "--ssh-spawn-gpg" option has been added, which when specified will give keychain permission to spawn a gpg-agent in place of ssh-agent. CODE OPTIMIZATIONWith keychain 2.9.0, there has been significant code cleanup, reducing the size of the script from 1500 lines to about 1100 lines. In addition, the script is now fully compliant with ShellCheck <https://shellcheck.net>, which will be hugely helpful to ensure continued POSIX shell compatibility moving forward. AGENT DETECTION AND STARTUP ALGORITHMThis section documents the official algorithm used for detecting and if necessary starting ssh-agent, to facilitate understanding as well as developer maintenance of the codebase. DEFINITIONSThere are several important definition related to the algorithm:
ALGORITHM OVERVIEWWhen the keychain script is run, it will first attempt to find a running ssh-agent.
THE QUICK SHORT-CIRCUITWhen the --quick option is specified, a special algorithm will run prior to the main agent-detection algorithm listed above. A pidfile, if it exists, will be evaluated as per Phase 1 of the main algorithm. If a valid running agent is found, it will be queried for valid keys. If at least one valid key is loaded into the agent, the quick start is considered successful, and keychain will skip the regular agent startup algorithm, and will use this found agent. SUMMARY AND RATIONALEThe keychain ssh-agent detection and startup algorithm is somewhat sophisticated for a reason. There is an intention behind its behavior. The algorithm has been specifically designed to prefer an agent spawned by keychain, or previously adopted, if that agent is currently available. This is by design, because other system software could spawn ssh-agent and/or gpg-agent processes, and we want keychain to not coerced into using these new agents which may suddenly appear in the environment unexpectedly when new desktop sessions start and in other circumstances. If keychain is too "suggestible", it will lose track of the agent which currently holds valid keys, which can result in unncessary prompting for passphrases, and general confusion. OPTIONS
EXAMPLESThis snippet should work in most shells to load two ssh keys and one gpg key: eval `keychain --eval id_rsa id_dsa 0123ABCD` For the fish shell, use the following format: if status --is-interactive
keychain --eval --quiet -Q id_rsa | source
end
If you have trouble with that in csh: setenv SHELL /bin/csh
eval `keychain --eval id_rsa id_dsa 0123ABCD`
This is equivalent for Bourne shells (including bash and zsh) but doesn't use keychain's --eval feature: keychain id_rsa id_dsa 0123ABCD
[ -z "$HOSTNAME" ] && HOSTNAME=`uname -n`
[ -f $HOME/.keychain/$HOSTNAME-sh ] && \
. $HOME/.keychain/$HOSTNAME-sh
This is equivalent for C shell (including tcsh): keychain id_rsa id_dsa 0123ABCD
host=`uname -n`
if (-f $HOME/.keychain/$host-csh) then
source $HOME/.keychain/$host-csh
endif
Likewise, the following commands can be used in fish: keychain id_rsa id_dsa 0123ABCD
test -z "$hostname"; and set hostname (uname -n)
if test -f "$HOME/.keychain/$hostname-fish"
source $HOME/.keychain/$hostname-fish
end
To load keychain variables from a script (for example from cron) and abort unless id_dsa is available: # Load keychain variables and check for id_dsa
[ -z "$HOSTNAME" ] && HOSTNAME=`uname -n`
. $HOME/.keychain/$HOSTNAME-sh 2>/dev/null
ssh-add -l 2>/dev/null | grep -q id_dsa || exit 1
SEE ALSOssh-agent(1), gpg-agent(1), ssh-add(1), ssh(1) NOTESKeychain was created and is currently maintained by Daniel Robbins. If you need to report a bug or request an enhancement, please report it to the GitHub project page at <https://github.com/funtoo/keychain>. For more information about keychain, please visit <https://www.funtoo.org/Funtoo:Keychain>.
|