Why isn't net.ipv4.tcp_rfc1337 enabled by default?
The tcp_rfc1337 setting seems to have a solution for TIME-WAIT Assassination.
The first problem is that old duplicate data may be accepted erroneously in new connections, leading to the sent data becoming corrupt.
The second problem is that connections may become desynchronized and get into an ACK loop because of old duplicate packets entering new connections, which will become desynchronized.
The third and last problem is that old duplicate packets may enter newly established connections erroneously and kill the new connection.
From what I read, to solve the problems, what the setting does is ignore the RST (reset) packets while the socket is in its TIME-WAIT state.
So, why isn't this setting enabled by default? What are the disadvantages of using this?
I actually learned about this variable when I was researching about stopping SYN flooding attacks. Do you think this setting helps with stopping them?
Solution 1:
I agree with Greg's comment. RFC 1337 is an Informational RFC only and not part of the TCP standard. To ensure that there isn't any unexpected changes in production networks, it makes sense to keep this feature disabled by default and leave it up to the network admins to decide if they would like to enable it for testing.
Dropping RST packets for sockets in TIME-WAIT wouldn't appear to have any negative consequences however that doesn't mean there aren't any - perhaps an odd edge case which hasn't been fully explored.
Interestingly, the kernel documentation for tcp_rfc1337 appears to be incorrect:
tcp_rfc1337 - BOOLEAN
If set, the TCP stack behaves conforming to RFC1337. If unset,
we are not conforming to RFC, but prevent TCP TIME_WAIT
assassination.
Default: 0
If the option is set, we conform to RFC 1337 and drop RST packets, preventing TIME-WAIT Assassination. If the option is unset (default), we do not conform to RFC 1337 are are susceptible to TIME-WAIT Assassination.
Solution 2:
I found the kernel source code and to me the doc is correct : default = 0 : kill
if (th->rst) {
/* This is TIME_WAIT assassination, in two flavors.
* Oh well... nobody has a sufficient solution to this
* protocol bug yet.
*/
if (sysctl_tcp_rfc1337 == 0) {
kill:
inet_twsk_deschedule_put(tw);
return TCP_TW_SUCCESS;
}
}
The default makes sense : the RFC is Informational, so you must set this knob (value = 1) to comply to it.