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:

User sandbox
ControlMaster auto
ControlPath ~/.ssh/

I also use cryptographic keys to eliminate password entry. Now when I `ssh` 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:

ssh -O check
if [ "$?" == "0" ]; then
    # master already running
    # change window title, start the master, and tail some logs
    echo -ne "33]0; logs07"
    ssh -D 8080 tail -F error.log debug.log

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.