Help on module ssh-ident: NAME ssh-ident - Wrapper around ssh to prepare ssh-agent and load identities. FILE /opt/projects/ssh-ident.git/ssh-ident DESCRIPTION This script starts ssh-agents and loads keys 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 Main features of ssh-ident: - loads ssh-agents and keys on demand. - can prepare 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 provides isolation when using agent forwarding and allows to use multiple accounts on sites like github, unfuddle and gitorious easily. - automatically shares the same agent across multiple login sessions. - works if your home directory is on NFS and prevents multiple agents for the same account (and identity) from running. - allows to specify options for the loaded keys. For example, you can provide a -t 60 to keep keys loaded only for 60 seconds. Or -c, to always ask for confirmation before using a key. Example of use ============== 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. 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. 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. 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. # DEFAULT_IDENTITY = "foo" # This is entirely optional. 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", } 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 identities, 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 # 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 in 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" To point somewhere else if you so desire. CLASSES __builtin__.object AgentManager Config class AgentManager(__builtin__.object) | Manages the ssh-agent for one identity. | | Methods defined here: | | FindUnloadedKeys(self, keys) | Determines which keys have not been loaded yet. | | Args: | keys: dict as returned by FindKeys. | | Returns: | iterable of strings, paths to private key files to load. | | GetLoadedKeys(self) | Returns an iterable of strings, each the fingerprint of a loaded key. | | LoadKeyFiles(self, keys) | Load all specified keys. | | Args: | keys: iterable of strings, each string a path to a key to load. | | LoadUnloadedKeys(self, keys) | Loads all the keys specified that are not loaded. | | Args: | keys: dict as returned by FindKeys. | | RunSSH(self, argv) | Execs ssh with the specified arguments. | | __init__(self, identity, config) | Initializes an AgentManager object. | | Args: | identity: string, identity the ssh-agent managed by this instance of | an AgentManager will control. | config: object implementing the Config interface, allows access to | the user configuration parameters. | | Attributes: | identity: same as above. | config: same as above. | agents_path: directory where the config of all agents is kept. | agent_file: the config of the agent corresponding to this identity. | | Parameters: | DIR_AGENTS: used to compute agents_path. | BINARY_SSH: path to the ssh binary. | | ---------------------------------------------------------------------- | Static methods defined here: | | EscapeShellArguments(argv) | Escapes all arguments to the shell, returns a string. | | GetAgentFile(path, identity) | Returns the path to an agent config file. | | Args: | path: string, the path where agent config files are kept. | identity: string, identity for which to load the agent. | | Returns: | string, path to the agent file. | | GetPublicKeyFingerprint(key) | Returns the fingerprint of a public key as a string. | | IsAgentFileValid(agentfile) | Returns true if the specified agentfile refers to a running agent. | | RunShellCommand(command) | Runs a shell command, returns (status, stdout), (int, string). | | RunShellCommandInAgent(agentfile, command) | Runs a shell command with an agent configured in the environment. | | ---------------------------------------------------------------------- | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined) class Config(__builtin__.object) | Holds and loads users configurations. | | Methods defined here: | | Get(self, parameter) | Returns the value of a parameter, or causes the script to exit. | | Load(self) | Load configurations from the default user file. | | __init__(self) | | ---------------------------------------------------------------------- | Static methods defined here: | | Expand(value) | Expand environment variables or ~ in string parameters. | | ---------------------------------------------------------------------- | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined) | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | defaults = {'BINARY_SSH': '/usr/bin/ssh', 'DEFAULT_IDENTITY': '$USER',... FUNCTIONS FindIdentity(argv, config) Returns the identity to use based on current directory or argv. Args: argv: iterable of string, argv passed to this program. config: instance of an object implementing the same interface as the Config class. Returns: string, the name of the identity to use. FindIdentityInList(elements, identities) Matches a list of identities to a list of elements. Args: elements: iterable of strings, arbitrary strings to match on. identities: iterable of (string, string), with first string being a regular expression, the second string being an identity. Returns: The identity specified in identities for the first regular expression matching the first element in elements. FindKeys(identity, config) Finds all the private and public keys associated with an identity. Args: identity: string, name of the identity to load strings of. config: object implementing the Config interface, providing configurations for the user. Returns: dict, {"key name": {"pub": "/path/to/public/key", "priv": "/path/to/private/key"}}, for each key found, the path of the public key and private key. The key name is just a string representing the key. Note that for a given key, it is not guaranteed that both the public and private key will be found. The return value is affected by DIR_IDENTITIES and PATTERN_KEYS configuration parameters. main(argv)