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
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
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.