SSH Considered Harmful – Why you shouldn’t be using raw ssh sessions

No, there hasn’t been any new vulnerability found in SSH, nor am I denying the usefulness of SSH as a building block in the dev toolchain. This article is about why you shouldn’t be (and how you can avoid) using raw SSH sessions for development work.


Here’s a little story. I spent many years working in Tech, and repeatedly ran into an annoying problem. I would ssh into a remote host from my laptop, do a bunch of work, and eventually get disconnected for whatever reason. And as soon as I disconnected, I would lose a whole bunch of ssh-session context. Upon reconnecting, I had to reopen multiple terminals, navigate each of them to the directory they were in, and reopen any files that I previously had open.

I grumbled about it all the time, but did nothing about it. Until one day when I ran into a killer problem. I had to run a multi-hour job on the remote host, but had to disconnect my laptop and take it home soon. I briefly researched using nohup to get the job done. But thankfully, I mentioned this problem to my lead, and he mentioned a tool that I had never heard of before. “Start a screen session and run your command there.”

I did a little digging and found out that a screen session is simply a persistent and recoverable session, that keeps running even after the ssh connection has ended. It seemed like a glorified nohup replacement, except that it preserved your entire terminal contents, not just the running process. I started using it for long running jobs, but it took me a little longer to realize that by using screen, I could eliminate all my frustrations with ssh-disconnects entirely. Even for something as simple as reading a log-file or coding, I could do it within a screen session in order to recover more easily from ssh disconnects.

With time, I discovered tmux, tmux-tabs, iterm integration, and many more. Pretty soon, I realized that there was virtually no reason for me to ever use raw-ssh at all. By using tmux, even if I had 10 tabs open in 10 different directories running 10 different commands, I could still recover from a wifi disconnect within seconds, with no context loss at all. Why wasn’t this my default workflow all this time!?


Obviously you still need to use ssh sessions if the remote host doesn’t have tmux installed. Besides that, the only reason for me to use ssh was as an intermediate step to start my tmux session. But I soon realized even that could be automated.

function tsh { ssh -X $1 -t "tmux -CC attach -t $2 || tmux -CC new -s $2"; }

Just stick the above in your bashrc, and all you have to do from now on is run tsh my-remote-host.mycorp.com main, and you’ve seamlessly picked up from where you left off. No more messing with ssh or manually invoking tmux ever again.

The above may seem a little magical, so let’s break it down.

“function tsh”: All this does is define “tsh” as a bash function. Ie, a souped up alias.
“ssh”: Your trusty ssh tool wrapped up in a function, so you’ll never have to touch it again.
“-X”: Enables X11 forwarding, for GUI support. You can omit this if desired.
“$1”: Your first argument to the function, which should be the host you want to connect to.
“-t”: Runs the following command on the remote host interactively in a pseudo-terminal.

“tmux”: Runs tmux. Replace with screen if you like unreadable config files.
“-CC”: Uses the iterm integration. Delete this if you’re not using iterm, or don’t like the integration.
“$2”: Your second argument to the function, which should be the session name. You can replace this with a hardcoded name, if you only ever want one session per host.
“attach -t $2”: Attaches to an existing tmux session with specified name.
“|| tmux -CC new -s $2”: If the attach fails (because specified session-name does not exist), then start a new session with that name instead.

If you’re a fan of more verbose but readable code, here’s another version of the same function:

function tsh {
    host=$1
    session_name=$2
    if [ -z "$session_name" ]; then
        echo "Need to provide session-name. Example: tsh <hostname&gt; main"
        return 1;
    fi
    ssh -X $host -t "tmux -CC attach -t $session_name || tmux -CC new -s $session_name"
}

And there you go. Your days of manually dealing with ssh sessions are now over, and you never need to fear session disconnects ever again.

12 thoughts on “SSH Considered Harmful – Why you shouldn’t be using raw ssh sessions

    1. I agree with your article, as “giving away” attracts gifts sent your way; here is the one command to tell tmux to try and attach or create if session doesn’t exist:
      ssh user@server -t tmux new -A -s session_name

      You just add your other options but it will shorten the line 🙂

      Liked by 1 person

  1. As others said, you need mosh in your life. Termux on Android + mosh means I can go from work, drive, home, anywhere and maintain connection if needed.

    Like

  2. Actually the -t argument to ssh is only to make sure the session is run in a pseudo terminal. For some code that requires a terminal to work properly. May only be necessary if the host sshd doesn’t start a terminal for security reasons.
    Otherwise great advise!

    Liked by 1 person

  3. Informative! I have used screen, but tmux is new to me. That too i have heard of it after several years of using ssh. Wasted lots of valuable time. Nowdays i always started look forward of how to reduce my work through some shortcuts n tricks n automation. Anyway, thanks for the share! Today i learnt of tmux.

    Liked by 1 person

  4. I’d change the title – Raw SSH isn’t harmful, but it is limited!
    I agree with others that Mosh does what you want here, but another option is to use byobu, which is effectively an opinionated tmux config, added to a wrapper script (“byobu-enable”) that makes it so that every time you SSH/Mosh in, you get dropped into your tmux session.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s