When you run screen
on the server, you actually have two terminal sessions at once: the first one you SSH'd in with, and a second, "local" one that is managed by the screen
command. If the first session is terminated for any reason without exiting screen
properly first, these two sessions will automatically separate from each other, and when you establish a new SSH session, screen
allows you to reconnect to the existing second session.
If the timeout that is cutting off your connections is something like a firewall cutting off an existing connection for inactivity, the problem in that is the firewall may have no method to signal the cut-off to either end of the connection, until the end in question attempts to send something over the connection that has been cut off.
So if the firewall cuts off the SSH connection and you then enter even a single character on the SSH connection, the firewall will send back a TCP Reset to the SSH client and you see that the connection has been cut off. But the SSH server side is not necessarily aware of it: if the server has not attempted to send anything to you, it may still be sitting there, waiting for any input from you, on a TCP connection that is -as far as the server knows- still connected but idle.
In this particular case, you'll need the -D
option in the screen -DR
to rip off the screen
session from the old SSH session even if screen
thinks it is still connected.
As a side effect, it will cause the server to attempt to send output (the "disconnected" message from screen
, and a new shell prompt) on the initial, cut-off SSH session, the firewall will send a TCP Reset back, and so the sshd
on server side will finally get the information that the old SSH connection has been interrupted at the network level, and will clean it up.
But if the thing causing your SSH session to time out is something at the server causing your first SSH session to terminate, for example the server administrator setting the ClientAliveCountMax
to 0 in sshd_config
and ClientAliveInterval
to some non-zero value as a hack to get a sort-of inactivity timeout from sshd
, then your old SSH session will have fully disconnected and the screen
session will already be waiting for you in an already-separated state. In that case, just screen -R
would be sufficient to reconnect to it... but additionally specifying the -D
option won't hurt in this case.
By the way, abusing the ClientAliveInterval
and ClientAliveCountMax
settings in sshd_config
that way is a pretty unreliable way to set up an user inactivity timeout, as the client side can work around it without knowing that they're doing it. This is because ClientAliveInterval
is about monitoring activity on the level of the SSH connection, not actual user activity.
If the user of the SSH client is experiencing network timeout issues, they might set ServerAliveInterval
in their ~/.ssh/config
(or an equivalent setting on a non-OpenSSH client). If the client's ServerAliveInterval
is set shorter than the firewall's connection inactivity timeout, it would cause the SSH client to automatically send an encrypted SSH "are you still there?" packet on inactivity, and the sshd
at the server would reply to it, resetting the inactivity timers on the firewall.
But setting a client-side ServerAliveInterval
with a shorter timeout value would also cause the server to never reach the ClientAliveInterval
timeout as long as the SSH connection is actually working, defeating the supposed "user inactivity timeout".
Unfortunately some security hardening standard seems to have incorporated this ClientAliveInterval
-based user inactivity timeout hack, and so some security auditors may require it, even though it's not really fit for its supposed purpose.