diff --git a/README b/README.md similarity index 51% rename from README rename to README.md index 1b7f719..334e96b 100644 --- a/README +++ b/README.md @@ -1,33 +1,36 @@ -Help on module ssh-ident: +sh-ident -NAME - ssh-ident - Start and use ssh-agent and load identities as necessary. +Use this script to start ssh-agents and load ssh keys on demand, +when they are first needed. -FILE - /opt/projects/ssh-ident.git/ssh-ident +[//]: # (Should this section on installing, beginning at "All you + have to do..." and ending with "... a few more lines described + below", be in this first section of the README? I was thinking + that this information might belong better at the beginning of the + "Installation" section below.) -DESCRIPTION - Use this script to start ssh-agents and load ssh keys on demand, - when they are first needed. - - All you have to do is modify your .bashrc to have: - - alias ssh='/path/to/ssh-ident' - - or add a link to ssh-ident from a directory in your PATH, for example: - - ln -s /path/to/ssh-ident ~/bin/ssh +All you have to do is modify your .bashrc to have: + +```` +alias ssh='/path/to/ssh-ident' +```` - If you use scp or rsync regularly, you should add a few more lines described - below. +or add a link to ssh-ident from a directory in your PATH, for example: + +```` +ln -s /path/to/ssh-ident ~/bin/ssh +```` + +If you use scp or rsync regularly, you should add a few more lines +described below. - In any case, ssh-ident: +In any case, ssh-ident: - - will create an ssh-agent and load the keys you need the first time you +- will create an ssh-agent and load the keys you need the first time you actually need them, once. No matter how many terminals, ssh or login sessions you have, no matter if your home is shared via NFS. - - can prepare and use a different agent and different set of keys depending +- can prepare and use a different agent and different set of keys depending on the host you are connecting to, or the directory you are using ssh from. This allows for isolating keys when using agent forwarding with different @@ -35,285 +38,324 @@ DESCRIPTION It also allows to use multiple accounts on sites like github, unfuddle and gitorious easily. - - allows to specify different options for each set of keys. For example, you +- allows to specify different options for each set of keys. For example, you can provide a -t 60 to keep keys loaded for at most 60 seconds. Or -c to always ask for confirmation before using a key. - Installation - ============ - - All you need to run ssh-ident is a standard installation of python >= 2.6, - python > 3 is supported. - - If your system has wget and are impatient to use it, you can install - ssh-ident with two simple commands: - - mkdir -p ~/bin; wget -O ~/bin/ssh goo.gl/MoJuKB; chmod 0755 ~/bin/ssh - - echo 'export PATH=~/bin:$PATH' >> ~/.bashrc - - Logout, login, and done. SSH should now invoke ssh-ident instead of the - standard ssh. - - - Alternatives - ============ - - In .bashrc, I have: - - alias ssh=/home/ccontavalli/scripts/ssh-ident - - all I have to do now is logout, login and then: - - $ ssh somewhere - - ssh-ident will be called instead of ssh, and it will: - - check if an agent is running. If not, it will start one. - - try to load all the keys in ~/.ssh, if not loaded. - - If I now ssh again, or somewhere else, ssh-ident will reuse the same agent - and the same keys, if valid. - - - About scp, rsync, and friends - ============================= - - scp, rsync, and most similar tools internally invoke ssh. If you don't tell - them to use ssh-ident instead, key loading won't work. There are a few ways - to solve the problem: - - 1) Rename 'ssh-ident' to 'ssh' or create a symlink 'ssh' pointing to - ssh-ident in a directory in your PATH before /usr/bin or /bin, similarly - to what was described previously. For example, add to your .bashrc: - - export PATH="~/bin:$PATH" - - And run: - - ln -s /path/to/ssh-ident ~/bin/ssh - - Make sure `echo $PATH` shows '~/bin' *before* '/usr/bin' or '/bin'. You - can verify this is working as expected with `which ssh`, which should - show ~/bin/ssh. - - This works for rsync and git, among others, but not for scp and sftp, as - these do not look for ssh in your PATH but use a hard-coded path to the - binary. - - If you want to use ssh-ident with scp or sftp, you can simply create - symlinks for them as well: - - ln -s /path/to/ssh-ident ~/bin/scp - ln -s /path/to/ssh-ident ~/bin/sftp - - 2) Add a few more aliases in your .bashrc file, for example: - - alias scp='BINARY_SSH=scp /path/to/ssh-ident' - alias rsync='BINARY_SSH=rsync /path/to/ssh-ident' - ... - - The first alias will make the 'scp' command invoke 'ssh-ident' instead, - but tell 'ssh-ident' to invoke 'scp' instead of the plain 'ssh' command - after loading the necessary agents and keys. - - Note that aliases don't work from scripts - if you have any script that - you expect to use with ssh-ident, you may prefer method 1), or you will - need to update the script accordingly. - - 3) Use command specific methods to force them to use ssh-ident instead of - ssh, for example: - - rsync -e '/path/to/ssh-ident' ... - scp -S '/path/to/ssh-ident' ... - - 4) Replace the real ssh on the system with ssh-ident, and set the - BINARY_SSH configuration parameter to the original value. - - On Debian based system, you can make this change in a way that - will survive automated upgrades and audits by running: - - dpkg-divert --divert /usr/bin/ssh.ssh-ident --rename /usr/bin/ssh - - After which, you will need to use: - - BINARY_SSH="/usr/bin/ssh.ssh-ident" - - - Config file with multiple identities - ==================================== - - To have multiple identities, all I have to do is: - - 1) create a ~/.ssh-ident file. In this file, I need to tell ssh-ident which - identities to use and when. The file should look something like: - - # Specifies which identity to use depending on the path I'm running ssh - # from. - # For example: ("mod-xslt", "personal") means that for any path that - # contains the word "mod-xslt", the "personal" identity should be used. - # This is optional - don't include any MATCH_PATH if you don't need it. - MATCH_PATH = [ - # (directory pattern, identity) - (r"mod-xslt", "personal"), - (r"ssh-ident", "personal"), - (r"opt/work", "work"), - (r"opt/private", "secret"), - ] - - # If any of the ssh arguments have 'cweb' in it, the 'personal' identity - # has to be used. For example: "ssh myhost.cweb.com" will have cweb in - # argv, and the "personal" identity will be used. - # This is optional - don't include any MATCH_ARGV if you don't - # need it. - MATCH_ARGV = [ - (r"cweb", "personal"), - (r"corp", "work"), - ] - - # Note that if no match is found, the DEFAULT_IDENTITY is used. This is - # generally your loginname, no need to change it. - # This is optional - don't include any DEFAULT_IDENTITY if you don't - # need it. - # DEFAULT_IDENTITY = "foo" - - # This is optional - don't include any SSH_ADD_OPTIONS if you don't - # need it. - SSH_ADD_OPTIONS = { - # Regardless, ask for confirmation before using any of the - # work keys. - "work": "-c", - # Forget about secret keys after ten minutes. ssh-ident will - # automatically ask you your passphrase again if they are needed. - "secret": "-t 600", - } - - # This is optional - dont' include any SSH_OPTIONS if you don't - # need it. - # Otherwise, provides options to be passed to 'ssh' for specific - # identities. - SSH_OPTIONS = { - # Disable forwarding of the agent, but enable X forwarding, - # when using the work profile. - "work": "-Xa", - - # Always forward the agent when using the secret identity. - "secret": "-A", - } - - # Options to pass to ssh by default. - # If you don't specify anything, UserRoaming=no is passed, due - # to CVE-2016-0777. Leave it empty to disable this. - SSH_DEFAULT_OPTIONS = "-oUseRoaming=no" - - # Which options to use by default if no match with SSH_ADD_OPTIONS - # was found. Note that ssh-ident hard codes -t 7200 to prevent your - # keys from remaining in memory for too long. - SSH_ADD_DEFAULT_OPTIONS = "-t 7200" - - # Output verbosity - # valid values are: LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG - VERBOSITY = LOG_INFO - - 2) Create the directory where all the identities and agents - will be kept: - - $ mkdir -p ~/.ssh/identities; chmod u=rwX,go= -R ~/.ssh - - 3) Create a directory for each identity, for example: - - $ mkdir -p ~/.ssh/identities/personal - $ mkdir -p ~/.ssh/identities/work - $ mkdir -p ~/.ssh/identities/secret - - 4) Generate (or copy) keys for those identities: - - # Default keys are for my personal account - $ cp ~/.ssh/id_rsa* ~/.ssh/identities/personal +## Installation - # Generate keys to be used for work only, rsa - $ ssh-keygen -t rsa -b 4096 -f ~/.ssh/identities/work/id_rsa +All you need to run ssh-ident is a standard installation of python >= 2.6, +python > 3 is supported. - ... - - - Now if I run: - - $ ssh corp.mywemployer.com - - ssh-ident will be invoked instead, and: - - 1) check ssh argv, determine that the "work" identity has to be used. - 2) look in ~/.ssh/agents, for a "work" agent loaded. If there is no - agent, it will prepare one. - 3) look in ~/.ssh/identities/work/* for a list of keys to load for this - identity. It will try to load any key that is not already loaded in - the agent. - 4) finally run ssh with the environment setup such that it will have - access only to the agent for the identity work, and the corresponding - keys. - - Note that ssh-ident needs to access both your private and public keys. Note - also that it identifies public keys by the .pub extension. All files in your - identities subdirectories will be considered keys. - - If you want to only load keys that have "key" in the name, you can add - to your .ssh-ident: - - PATTERN_KEYS = "key" - - The default is: - - PATTERN_KEYS = r"/(id_.*|identity.*|ssh[0-9]-.*)" +If your system has wget and are impatient to use it, you can install +ssh-ident with two simple commands: + +```` +mkdir -p ~/bin; wget -O ~/bin/ssh goo.gl/MoJuKB; chmod 0755 ~/bin/ssh +echo 'export PATH=~/bin:$PATH' >> ~/.bashrc +```` + +Logout, login, and done. SSH should now invoke ssh-ident instead of the +standard ssh. - You can also redefine: - DIR_IDENTITIES = "$HOME/.ssh/identities" - DIR_AGENTS = "$HOME/.ssh/agents" +### Alternative installation methods - To point somewhere else if you so desire. +In .bashrc, I have: + +```` +alias ssh=/home/ccontavalli/scripts/ssh-ident +```` + +all I have to do now is logout, login and then: + +```` +$ ssh somewhere +```` +ssh-ident will be called instead of ssh, and it will: + +- check if an agent is running. If not, it will start one. +- try to load all the keys in ~/.ssh, if not loaded. - BUILDING A DEBIAN PACKAGE - ========================= +If I now ssh again, or somewhere else, ssh-ident will reuse the same agent +and the same keys, if valid. + + +### Installing for use with scp, rsync, etc. + +Using scp, rsync, and most similar tools internally invokes ssh. If +you don't tell them to use ssh-ident instead, key loading won't +work. There are a few ways to solve the problem: + +1) Rename 'ssh-ident' to 'ssh' or create a symlink 'ssh' pointing to +ssh-ident in a directory in your PATH before /usr/bin or /bin, similarly +to what was described previously. For example, add to your .bashrc: + + ```` + export PATH="~/bin:$PATH" + ```` + + And run: + + ```` + ln -s /path/to/ssh-ident ~/bin/ssh + ```` + + Make sure `echo $PATH` shows `~/bin` *before* `/usr/bin` or `/bin`. You +can verify this is working as expected with `which ssh`, which should +show `~/bin/ssh`. + + This works for rsync and git, among others, **but not for scp and sftp**, as these do not look for ssh in your PATH but use a hard-coded path to the binary. + + If you want to use ssh-ident with scp or sftp, you can simply create +symlinks for them as well: + + ```` + ln -s /path/to/ssh-ident ~/bin/scp + ln -s /path/to/ssh-ident ~/bin/sftp + ```` - If you need to use ssh-ident on a debian / ubuntu / or any other - derivate, you can now build debian packages. +2) Add a few more aliases in your .bashrc file, for example: + + ```` + alias scp='BINARY_SSH=scp /path/to/ssh-ident' + alias rsync='BINARY_SSH=rsync /path/to/ssh-ident' + ... + ```` + + The first alias will make the 'scp' command invoke 'ssh-ident' instead, +but tell 'ssh-ident' to invoke 'scp' instead of the plain 'ssh' command +after loading the necessary agents and keys. + + >Note that aliases don't work from scripts - if you have any script that +you expect to use with ssh-ident, you may prefer method 1), or you will +need to update the script accordingly. - 1. Make sure you have devscripts installed: +3) Use command specific methods to force them to use ssh-ident instead of +ssh, for example: + + ```` + rsync -e '/path/to/ssh-ident' ... + scp -S '/path/to/ssh-ident' ... + ```` - sudo apt-get install devscripts debhelper +4) Replace the real ssh on the system with ssh-ident, and set the +`BINARY_SSH` configuration parameter to the original value. - 2. Download ssh-ident in a directory of your choice (ssh-ident) + On Debian based system, you can make this change in a way that + will survive automated upgrades and audits by running: + + ```` + dpkg-divert --divert /usr/bin/ssh.ssh-ident --rename /usr/bin/ssh + ```` + + After which, you will need to use: + + ```` + BINARY_SSH="/usr/bin/ssh.ssh-ident" + ```` + + +## Configuration for use with multiple identities - git clone https://github.com/ccontavalli/ssh-ident.git ssh-ident +To have multiple identities, all I have to do is: + +1) create a ~/.ssh-ident file. In this file, I need to tell ssh-ident which identities to use and when. The file should look something like: + + ```` + # Specifies which identity to use depending on the path I'm running ssh + # from. + # For example: ("mod-xslt", "personal") means that for any path that + # contains the word "mod-xslt", the "personal" identity should be used. + # This is optional - don't include any MATCH_PATH if you don't need it. + MATCH_PATH = [ + # (directory pattern, identity) + (r"mod-xslt", "personal"), + (r"ssh-ident", "personal"), + (r"opt/work", "work"), + (r"opt/private", "secret"), + ] + + # If any of the ssh arguments have 'cweb' in it, the 'personal' identity + # has to be used. For example: "ssh myhost.cweb.com" will have cweb in + # argv, and the "personal" identity will be used. + # This is optional - don't include any MATCH_ARGV if you don't + # need it. + MATCH_ARGV = [ + (r"cweb", "personal"), + (r"corp", "work"), + ] + + # Note that if no match is found, the DEFAULT_IDENTITY is used. This is + # generally your loginname, no need to change it. + # This is optional - don't include any DEFAULT_IDENTITY if you don't + # need it. + # DEFAULT_IDENTITY = "foo" + + # This is optional - don't include any SSH_ADD_OPTIONS if you don't + # need it. + SSH_ADD_OPTIONS = { + # Regardless, ask for confirmation before using any of the + # work keys. + "work": "-c", + # Forget about secret keys after ten minutes. ssh-ident will + # automatically ask you your passphrase again if they are needed. + "secret": "-t 600", + } + + # This is optional - dont' include any SSH_OPTIONS if you don't + # need it. + # Otherwise, provides options to be passed to 'ssh' for specific + # identities. + SSH_OPTIONS = { + # Disable forwarding of the agent, but enable X forwarding, + # when using the work profile. + "work": "-Xa", + + # Always forward the agent when using the secret identity. + "secret": "-A", + } + + # Options to pass to ssh by default. + # If you don't specify anything, UserRoaming=no is passed, due + # to CVE-2016-0777. Leave it empty to disable this. + SSH_DEFAULT_OPTIONS = "-oUseRoaming=no" + + # Which options to use by default if no match with SSH_ADD_OPTIONS + # was found. Note that ssh-ident hard codes -t 7200 to prevent your + # keys from remaining in memory for too long. + SSH_ADD_DEFAULT_OPTIONS = "-t 7200" + + # Output verbosity + # valid values are: LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG + VERBOSITY = LOG_INFO + +2) Create the directory where all the identities and agents +will be kept: + + ```` + $ mkdir -p ~/.ssh/identities; chmod u=rwX,go= -R ~/.ssh + ```` - 3. Build the .deb package: +3) Create a directory for each identity, for example: + + ```` + $ mkdir -p ~/.ssh/identities/personal + $ mkdir -p ~/.ssh/identities/work + $ mkdir -p ~/.ssh/identities/secret + ```` - cd ssh-ident && debuild -us -uc +4) Generate (or copy) keys for those identities: + + ```` + # Default keys are for my personal account + $ cp ~/.ssh/id_rsa* ~/.ssh/identities/personal + + # Generate keys to be used for work only, rsa + $ ssh-keygen -t rsa -b 4096 -f ~/.ssh/identities/work/id_rsa + ... + ```` + +Now if I run: + +```` +$ ssh corp.mywemployer.com +```` + +ssh-ident will be invoked instead, and: + +1) check ssh argv, determine that the "work" identity has to be used. +2) look in ~/.ssh/agents, for a "work" agent loaded. If there is no +agent, it will prepare one. +3) look in ~/.ssh/identities/work/* for a list of keys to load for this +identity. It will try to load any key that is not already loaded in +the agent. +4) finally run ssh with the environment setup such that it will have +access only to the agent for the identity work, and the corresponding +keys. + +>Note that ssh-ident needs to access both your private and public keys. Note +also that it identifies public keys by the .pub extension. All files in your +identities subdirectories will be considered keys. + +If you want to only load keys that have "key" in the name, you can add +to your .ssh-ident: + +```` +PATTERN_KEYS = "key" +```` + +The default is: + +```` +PATTERN_KEYS = r"/(id_.*|identity.*|ssh[0-9]-.*)" +```` + +You can also redefine: + +```` +DIR_IDENTITIES = "$HOME/.ssh/identities" +DIR_AGENTS = "$HOME/.ssh/agents" +```` - 4. Profit: +To point somewhere else if you so desire. - cd ..; dpkg -i ssh-ident*.deb +## Building a Debian package - CREDITS - ======= +If you need to use ssh-ident on a debian / ubuntu / or any other +derivative, you can now build debian packages. + +1. Make sure you have devscripts installed: + + ```` + sudo apt-get install devscripts debhelper + ```` + +2. Download ssh-ident in a directory of your choice (ssh-ident) + + ```` + git clone https://github.com/ccontavalli/ssh-ident.git ssh-ident + ```` - - Carlo Contavalli, http://www.github.com/ccontavalli, main author. - - Hubert depesz Lubaczewski, http://www.github.com/despez, support - for using environment variables for configuration. - - Flip Hess, http://www.github.com/fliphess, support for building - a .deb out of ssh-ident. - - Terrel Shumway, https://www.github.com/scholarly, port to python3. - - black2754, https://www.github.com/black2754, vim modeline, support - for verbosity settings, and BatchMode passing. - - Michael Heap, https://www.github.com/mheap, support for per - identities config files. - - Carl Drougge, https://www.github.com/drougge, CVE-2016-0777 fix, - fix for per user config files, and use /bin/env instead of python - path. +3. Build the .deb package: + + ```` + cd ssh-ident && debuild -us -uc + ```` +4. Profit: + + ```` + cd ..; dpkg -i ssh-ident*.deb + ```` + +## Credits + +- Carlo Contavalli, http://www.github.com/ccontavalli, main author. +- Hubert depesz Lubaczewski, http://www.github.com/despez, support +for using environment variables for configuration. +- Flip Hess, http://www.github.com/fliphess, support for building +a .deb out of ssh-ident. +- Terrel Shumway, https://www.github.com/scholarly, port to python3. +- black2754, https://www.github.com/black2754, vim modeline, support +for verbosity settings, and BatchMode passing. +- Michael Heap, https://www.github.com/mheap, support for per +identities config files. +- Carl Drougge, https://www.github.com/drougge, CVE-2016-0777 fix, +fix for per user config files, and use /bin/env instead of python +path. + +[//]: # (FIXME: what should be done with the below information on + CLASSES, FUNCTIONS, & DATA? + I am unfamiliar with the source code of this project, but when I + read the README, I don't see an immediate need for this + information to be in the README. Should it be moved to a separate + file instead?) + +```` CLASSES __builtin__.object AgentManager @@ -586,5 +628,4 @@ DATA LOG_INFO = 3 LOG_WARN = 2 print_function = _Feature((2, 6, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0)... - - +````