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.
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.
Great tutorial Mark! Some additions:
Interesting history: autossh was released in 2002, OpenSSH added support for
ServerAliveInterval/ServerAliveCountMaxin 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=yeswill produce a hard fail if ssh fails to bind to the port (when a previous session is still hanging around), something likeError: remote port forwarding failed for listen port 9001. In practice it may take ~3 minutes before the zombie session is killed.Setting
ClientAliveInterval/ClientAliveCountMaxmay reduce the time, but with systemd we can just useExecStartPre=to kill any hanging ssh connections.kill_bad_ssh.sh
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.(the
-allows the script to fail, eg when there are no previous ssh sessions to kill)