Seamless SSH with tmux and KiTTY

I’ve found the Raspberry Pi to be great for running little servers. For example, I recently discovered ZNC, which can hold open my IRC session even when my laptop is asleep and play back the channel history for me when it wakes back up. I highly recommend it if you use IRC much.

Since I’m running Windows on my laptop, I typically use PuTTY to remotely manage my Pi. However, it recently came to my attention that there is a fork of PuTTY called KiTTY that adds some nice features (along with a more modern-looking icon!), so I think I’ll use that from now on.

One nice thing that KiTTY provides is the ability to reconnect your SSH sessions automatically when the network is interrupted or your computer goes to sleep. This is very convenient when combined with the auto-login feature.

However, restarting your session is not that useful if you lose all the programs that were running in the previous session. That is where tmux comes in.

tmux is a terminal multiplexer that allows you to mirror a terminal session across multiple devices as well as do nifty things like run multiple programs in the same terminal with a split-screen view. Most importantly, it allows your programs to continue running when you disconnect from the session so that you can reconnect to the same session at a later time.

The functionality of tmux is very similar to that of GNU screen; however, I chose tmux because I read that it is easier to use and more actively maintained. You can get tmux with the following APT command:

sudo apt-get install tmux  

The most important tmux commands are tmux new to start a new session and tmux attach to attach to an existing session. Executing either of these commands will drop you into a new shell, but there will be a green status bar at the bottom of the screen letting you know you are in a tmux session.

To make the sessions easier to manage I created the following script at /usr/local/bin/attach:

#!/bin/bash

# Use current terminal as session name if unspecified.
if [ -n "$1" ]; then  
    SESSION="$1"
else  
    SESSION=`tty`
fi

# Remove /dev prefix from name.
SESSION=`echo "$SESSION" | sed 's/^\/dev\///'`

# Replace current shell with tmux session.
if tmux has -t "$SESSION"; then  
    exec tmux attach -t "$SESSION"
else  
    exec tmux new -s "$SESSION"
fi  

Then I set up KiTTY to automatically execute this command on login:

/usr/local/bin/attach tty1

This will create and/or attach to a tmux session called tty1 every time I log in. Note that tty1 is also the name of the first virtual console, because I thought it would be neat to have my ssh session mirrored on the console (and vice versa). Therefore, I also configured local logins to use tmux as their shell by adding the following line to /etc/login.defs:

FAKE_SHELL /usr/local/bin/attach  

Finally, although not really related to SSH, I wanted the pi user to be always logged in to the console, so I modified the appropriate /etc/inittab entry as follows:

1:2345:respawn:/sbin/getty --noclear 38400 tty1 -a pi  

Now I can close down my SSH sessions without losing my application state, and I can even continue them on the physical console if I so desire.

The only caveat I found was that in one instance where I rebooted the Pi while KiTTY was still connected, I somehow ended up with two separate instances of tmux that had the same session name but weren’t communicating with each other. However, this only occurred once and is somewhat of an edge case, so I’m not overly concerned about it.

That’s all I have to say about KiTTY and tmux. Hope it is helpful to someone!

Luke Sandell

Read more posts by this author.

comments powered by Disqus