Ssh – How to remove a port bind still used by sshd after an improper deconnection from ssh

portport-forwardingsshssh-tunnel

Note: this post is not a duplicate of SSH remote port forwarding failed.
The question here is not what causes port forwarding (temporarily) failure, we know what it is. The question is how to remove the broken sshd port bind. Thank you.

I have a server A with a dynamic IP running autossh to maintain a reverse tunnel to a machine B with a static IP.
The following code works fine:

autossh -M 0 -q -N -R2222:localhost:22 -o ServerAliveInterval 60 -o   ServerAliveCountMax 3 -o ExitOnForwardFailure yes USER@B -p PORT

However, when the connection crashes due to an IP change of A, it takes a "long" time (say an hour) to recover the connection. That's because sshd from machine B still listens to port 2222, thus preventing ssh (from machine A) to bind port 2222 after the crash.

auth.log from B contains dozens of :

Accepted publickey for USER from A port SOMEPORT ssh2: ED25519 XXXXXXXX
error: bind: Address already in use
error: channel_setup_fwd_listener_tcpip: cannot listen to port: 2222

Till the connection is finally accepted without forward failure (causing autossh stops respawning ssh, as awaited) because sshd finally no more listens to port 2222.

How could I (at least manually) tell sshd (on machine B) it should no more listen to port 2222, so I can recover the connection without waiting an hour (and without restarting machine B) ?

PS: restarting sshd does not solve the issue.

PPS: ExitOnForwardFailure yes works for me even without the =.

Best Answer

You also need to set timeout options on the ssh server so that it will drop the connection more quickly.

For example you might add to /etc/ssh/sshd_config:

ClientAliveInterval 60
ClientAliveCountMax 3