My SSH config setup

Ask me “What do you do?” If you don’t sound particularly interested, I’ll tell you “I type.” Ratchet up your inquisitiveness and I might tell you that I write computer programs or blogging software. Eventually you’ll find out that I spend most of my time in SSH. If you are the same way and you want to improve your SSH experience, you might like this article. (Unless you are using Windows.)

~/.ssh/config is where my SSH configuration is stored. I encourage you to `man ssh_config` and read about the options listed in this article. Also `man sshd_config` for more details.

Don’t live in the country.

Measured in latency, packet loss, and bandwidth, my home internet connection is pretty poor. That’s because I live in a valley where there is no ISP presence. There are two radio hops between me and the fiber network. That makes four radio hops per round-trip. To mitigate the effects of an unreliable physical network, I put these lines at the top of ~/.ssh/config:

# Do not kill connection if route is down temporarily.
TCPKeepAlive no

# Allow ten minutes down time before giving up the connection.
ServerAliveCountMax 30
ServerAliveInterval 20

# Conserve bandwith. (Compression is off by default.)
Compression yes

Label your windows

If I have many tabs in my log window, as I usually do, I need something better than the memory game to tell them apart. It’s possible to change the window title by echoing an escape sequence. My default remote .bashrc sets up the shell to update the window title with user, hostname, and working directory every time the prompt is displayed. This makes it easy to know where you are after switching tabs:

PROMPT_COMMAND='echo -ne "33]0;${USER}@${HOSTNAME}: ${PWD}07"'

However, my log connections have no shell prompt so they need another way to set their window titles. So before I start SSH I echo an escape sequence to update the window/tab title. This is shown in the BASH script a bit later.

A minor side-effect of setting your window title is that it remains set until you change it. Quitting SSH doesn’t reset the window title. So I added the PROMPT_COMMAND line above to my local .bashrc to bring the same dynamic title effect to my local shells.

Make complex connections simple

To give context to the next snippets, I must describe my windows. At least one terminal window is dedicated to tailing logs on remote servers while I run text editors and shells in other windows. At any given time there are usually two or more connections to one server and I like to run all of these through a single TCP socket. So I add lines like these for every host for which I always want a master connection:

Host sandbox.example.com
User sandbox
ControlMaster auto
ControlPath ~/.ssh/sandbox.example.com.sock

I also use cryptographic keys to eliminate password entry. Now when I `ssh sandbox.example.com` it automatically uses an existing master socket, or else creates a new master socket for reuse by subsequent connections. That’s very handy but beware: don’t close the master connection while you have unsaved changes in another tab! You might want to use screen. I take my chances.

After I have my master connection, I can start and stop shells in other windows. I connect to a small number of hosts and on each one I like to tail different files and forward different ports. So for each host I maintain a little script to help me manage the connections. Here is a sample script that starts the log connection on first invocation and shell connections subsequently:

#!/bin/bash
#/usr/local/bin/sandbox
ssh -O check sandbox.example.com
if [ "$?" == "0" ]; then
    # master already running
    ssh sandbox.example.com
else
    # change window title, start the master, and tail some logs
    echo -ne "33]0;sandbox.example.com logs07"
    ssh sandbox.example.com -D 8080 tail -F error.log debug.log
fi

This lets me set up my environment very quickly: I run sandbox in the log window to start the master, then I run the same command in any number of other windows to start shells. The commands are short and easy to remember. The startup time for shells is now much faster because the connection is already negotiated. My log windows are labeled. What else could I want?

I usually come up with tiny nicknames for my most used connections and place these in /etc/hosts with the IP of the host. This saves typing time as well as time waiting for DNS round-trips.

The only remaining annoyance is the inevitable disconnection with unsaved changes. Maybe later I’ll learn to make screen work automatically and transparently so that I never lose work due to network disruption.

11 Comments

  1. I’ve had dropped connections mess me up too many times to not use screen. I used this info to help me setup screen to auto-start/resume when I ssh into my servers: http://taint.org/wk/RemoteLoginAutoScreen

    • Thanks, Dougal. Every time I try screen I waste hours, hair, and brain cells trying to find the magic configuration that will make it work with the notorious perfect storm: Mac OS X, screen, and emacs.

      • Great post Andy but I can’t believe you don’t use screen! I don’t use emacs but I use iTerm on the Macbook. That might have the capabilities you need to run Emacs?

        • Oh yeah, iTerm here, too. Been ages since I’ve used emacs. It used to be my main editor, but I later switched to JOE, and my emacs skills deteriorated to nothingness over time.

          The main problem you might have with screen is if some of the default key-bindings conflict with emacs commands that you use. But you can remap them in your .screenrc, if necessary.

          Screen has tons of features, but I only use a small subset. Of course, there’s the “save your ass when your TCP connection drops” feature. And the fact that it lets you run multiple terminal sessions over a single connection (no big deal these days, but back in the modem dialup days? whew!) And the built-in scrollback buffer.

          But re-attaching your running session is definitely the killer feature.

        • I have tried it several times. The key mapping stuff always kills it for me. What makes life without screen tolerable is turning off keepalive and leaving my sessions open for days on end.

  2. Can I assume you already use the bash-completion scripts from MacPorts?

    It makes light work of typing out known ssh hosts and is less hairy than a bunch of /etc/hosts entries.

    • MacPorts makes me wish I had gone with Debian instead of Mac OS X.

      • Well, you could use fink instead, but it always felt dirty to me. MacPorts has gotten a lot better over the last year or so, but it’s still not too late to switch to Debian :)

        Honestly, I’d be using Debian if I weren’t so reliant on all these Mac OS X exclusive apps.

  3. What are the advantages of using a single socket?

    • It saves a bunch of time each time you reuse the master socket because the secure connection is already made; it only has to start a new login shell. Those precious seconds can add up to precious minutes every day. It may or may not make the connections perform better after that, but I’m convinced that it’s better on my internet connection. If so, it’s probably due to reduced network traffic due to the overhead of keeping additional sockets going.

  1. Tuners Use zsh & iTerm | A Fool’s Wisdom
Follow

Get every new post delivered to your Inbox.

Join 1,667 other followers

%d bloggers like this: