DEV Community

Discussion on: Create a reverse SSH tunnel for remote access to a restricted Linux machine

Collapse
 
frankenlist profile image
Frankenlist

Great tutorial Mark! Some additions:

  • Interesting history: autossh was released in 2002, OpenSSH added support for ServerAliveInterval/ServerAliveCountMax in 2004.

  • If you want to bind to ports below 1024 your ssh user will either need to be root or use the usual tricks to allow it.

  • ExitOnForwardFailure=yes will produce a hard fail if ssh fails to bind to the port (when a previous session is still hanging around), something like Error: remote port forwarding failed for listen port 9001. In practice it may take ~3 minutes before the zombie session is killed.
    Setting ClientAliveInterval/ClientAliveCountMax may reduce the time, but with systemd we can just use ExecStartPre= to kill any hanging ssh connections.

kill_bad_ssh.sh

#!/bin/bash
set -euf -o pipefail

PORT=$1;

SSH_PID=$(lsof -i 4:"$PORT" | grep '(LISTEN)' | awk '{print $2}');

kill "$SSH_PID"
Enter fullscreen mode Exit fullscreen mode

If you are binding to an arbitrary port (eg 9001), you can simplify the script with SSH_PID=$(lsof -t -i:"$PORT"). But if you are binding to say 443/80 ports, and some other service happens to make an http request at the same time, it will also show up in lsof.

ExecStartPre=-/usr/bin/ssh root@xx.xx.xx.xx '/root/kill_bad_ssh.sh 1000'
Enter fullscreen mode Exit fullscreen mode

(the - allows the script to fail, eg when there are no previous ssh sessions to kill)

Collapse
 
texasdiaz profile image
Danny Diaz

Hey! Great tutorial. The one thing that kicked our butt was the fact that we weren't running an SSH server on the restricted machine - we completely didn't realize it wasn't running. Mentioning that and how to start the ssh.service might be a good add to this tutorial (and maybe adding a user if you don't want to log in with the same user). Anyway, again, great tutorial thanks.