Optimize your SSH experience

SSH is one of the tools I use on daily basis. Over time I've learned a handful of tips that helped me utilize it better. I decided to share them with you - once you learn them there's no going back.

Enable private key encryption

If you're logging into remote machines using key pair (who doesn't?) that is very convenient. You have to keep in mind though that stolen private key can cost you lot of trouble. One could easily gain access to your machines.

Obviously you can use disk encryption on device where your keys are stored. There is however an easier way to prevent that using built-in private key encryption.

> ssh-keygen -p -f ~/.ssh/id_rsa

Enter old passphrase:
Key has comment '/home/sensei/.ssh/id_rsa'
Enter new passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved with the new passphrase.

That effectively encrypts your key on disk, asking for password to decrypt every time you want to use it. Here comes your resistance - nobody wants to enter password on every single logon. Fear not, your operating system key manager will take care of it. Both gnome-keyring (on my Ubuntu) and keychain (on OSX) do a great job caching your password entry and reusing it for chosen period of time. By default this period is until end of desktop logon session and it'll also decrypt key on your login for your convenience.

So encrypt your key, there is no better time than now. In case you don't like it or want to change password, just repeat the command.

Personal ssh client config

I hardly like typing long commands and remember required options after long period of time. Typing ssh command can be great pain if your servers are configured on non-standard ports or you login to several accounts not matching your username. That's what is ~/.ssh/config for. Here's a short snippet:

Host gh
  User git
  HostName github.com

Host drug
  HostName 1.2.3.4
  Port 1234
  User drug

Host *.acme
  User pawel

Now, with this configuration in place I can clone remote repos from github with just git clone gh:drugpl/bbq.git. Also I can login directly to host 1.2.3.4 without passing plethora of options - just a ssh secret is needed. And this also works when you specify hostnames elsewhere, like here in capistrano. Finally, I can save me some typing of username, different from my local, when connecting to any host in my VPN.

Get familiar with ssh-agent

Sometimes you may want to access your remote hosts (or just a private git repository) from machines other than your local one. You obviously don't want to sprinkle your private key everywhere. That's where ssh-agent comes into play. You may even have already used ssh-agent in capistrano if you followed github docs. There's awesome explanation of ssh-agent out there, go grab it first.

My particular use case is logging into virtual machines behind a gateway, which is the only machine allowed to connect from outside network. To get to any host inside I have to first proxy through that gateway (that's how paranoid admins roll). ProxyCommand to the rescue!

Host x-gateway
  Host 1.2.3.4
  Port 1234
  User someuser

Host x-logs
  User someuser
  ProxyCommand ssh -A -q -W %h:%p x-gateway

Now I can login "directly" into x-logs with just ssh x-logs. What this directive does is logging into x-gateway with ssh-agent enabled and forwarding standard input and output to %h:%p. In this particular case %h:%p were resolved to x-logs:22.

Reuse single connection

You may have heard recently about deployment tool which:

Compare this to the likes of Vlad or Capistrano, where each command is ran separately on their own SSH sessions. Mina only creates one SSH session per deploy, minimizing the SSH connection overhead.

You can enable this feature instantly for your capistrano too. Just set in your config ControlMaster and ControlPath directives. This will make your ssh client reuse single connection to the host and reduce latency greatly on subsequent commands.

Host x-deploy
  ControlMaster auto
  ControlPath /tmp/ssh-%r@%h:%p

Keep in mind though that you may experience connection blocks on other sessions to that host when transfering big chunks of data (i.e. during rsync).

You can't use this option along with ssh tunnles. When establishing one explicitly disable this feature for this connection:

ssh -A -L 3020:x-logs:3020 -o ControlMaster=no x-gateway

Autossh

A tool that deserves a mention, especially when combined with screen is autossh. All it does is starting a copy of ssh and monitoring it, restarting it as necessary. Perfect for my remote irssi session reopened any time my laptop wakes off.

AUTOSSH_PORT=0 autossh bawaria -t 'screen -x irc'

Recap

There is obviously more you can squeeze from ssh and wasn't mentioned here. Let manual pages be your friend. I'd love to hear what you did with your's ssh config.