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 tail
ing 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.
30.222672
-98.159425