|ordinary||one for each host||none, but lots of passwords encourage weak passwords and password reuse|
|public key||same for each host w/ public key||none if passphrase used, otherwise susceptible to users with root on machines storing private key|
|public key with agent support||same for each host w/ public key||user with root on machine with agent|
|public key with agent forwarding||same for each host w/ public key||user with root on machine with agent or intermediate machine|
Creating a Private/Public Key Pair
$ ssh-keygen -t rsa [-C EMAIL_ADDRESS]
The private key appears in ~/.ssh/id_rsa and the public key appears in ~/.ssh/id_rsa.pub
$ ssh-keygen -t dsa
The files that are created are ~/.ssh/id_dsa and ~/.ssh/id_dsa.pub
If you do not protect your private key with a passphrase, then anyone who gets a hold of your private key file can masquerade as you. In particular anyone with root access to the machines on which your unprotected private key is kept will be able to masquerade as you.
If you misplace the public key, you can recover it from the private key:
$ ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub
By default ssh and scp will use ~/.ssh/id_rsa or ~/.ssh/id_dsa. You can use the -i flag to specify a different private key.
SSH Config File
This is the file ~/.ssh/config. It can be used on a per host basis to change the default user, port, and identity file:
Host foo.com User bar Port 42 IdentityFile ~/.ssh/id_quux
Publishing a Public Key
$ scp ~/.ssh/id_rsa.pub REMOTE_HOST:HOME $ ssh REMOTE_HOST $ mkdir .ssh $ chmod 0700 .ssh $ cat id_rsa.pub >> ~/.ssh/authorized_keys $ rm id_rsa.pub
Launching a Shell with Agent Support
This creates a zsh session. You will be prompted for your passphrase once. Subsequent challenges will be handled automatically by the agent.
$ ssh-agent sh -c 'ssh-add && zsh'
The downside of using an agent is that it uses a socket. Anyone with root access on the machine running the agent can masquerade as you as long as the agent is running.
Using Agent Forwarding
Run the ssh-agent command like in the previous command. Then use ssh -A to connect to the intermediate host. You will then be able to perform actions on any remote hosts on which you have public keys, even though the private key is not on the intermediate host.
$ ssh-agent zsh $ ssh-add $ ssh -A REMOTE_HOST
User agent forwarding means you don't have to put your private key on the intermediate host, but as long as you are logged in to the intermediate machine there is a socket which someone with root access to the intermediate machine could use to masquerade as you.
Mac OS X has software called Keychain, which starts an ssh agent via launchd at login.
Keychain can be locked or unlocked via the padlock icon in the menu bar, or using the security command at the command line:
$ security lock-keychain -a $ security unlock-keychain
A keychain is created when a Mac is set up, and they can be stored in iCloud. The files are in ~/Library/Keychains.
RSA or DSA
In the past, the export of RSA technology from the USA was restricted, but the restrictions were greatly reduced in January 2000.
There are differences in performance between RSA and DSA but they are irrelevant for normal use.
I haven't seen a convincing argument that one key type is stronger than the other. RSA keys can be generated of arbitrary length using ssh-keygen -b BITS. The default is 2048 bits. DSA keys are always 1024 bits.
Host Keys and Man-in-the-Middle Attacks
Whenever you ssh to a remote host for the first time, the public key of the remote host is kept in ~/.ssh/known_hosts. This protects against future man-in-the-middle attacks but does not protect against a man-in-the-middle attack that is already in place when you first log in. In practice the security provided is poor because if the public key of the host changes, most people will simply delete the old key by editing ~/.ssh/known_hosts. Old keys can also be removed with ssh-keygen -R. Public keys for hosts will change when hardware is replaced and IP addresses or domain names are re-used. Also, I think it is possible to assign a new public key to a host by removing and re-installing the OpenSSH software.
The ~/.ssh/known_hosts file is normally built up over time as you ssh to various hosts, but you can create it all at once (or reset it) with
$ ssh-keyscan HOST1,HOST2,HOST3,... > ~/.ssh/known_hosts
If a local host cannot access a remote host directly, one can use ssh to tunnel through a proxy host.
ssh -f PROXY_USER@PROXY_HOST -L LOCAL_PORT:REMOTE_HOST:REMOTE_PORT -N
The -f flag puts ssh in the background and the -N prevents exiting because we are not running a command.
If the ssh command succeeds, then if a process connects to localhost:LOCAL_PORT, it will be forwarded to REMOTE_HOST:REMOTE_PORT.
Use Putty or OpenSSH under Cygwin
This tool is similar to telnet or nc, except that the connection is encrypted:
$ openssl s_client -connect localhost:30001 -quiet