I have been working on implementing synproxy in nftables. In this post I am going to explain its usage basics to mitigate TCP SYN-flood attacks!
What a TCP SYN-flood attack is?
When a connection is created in Linux the kernel allocates system’s resources
to handle the connection. This is translated into a lock for each socket in the
“listen” state. This does not happen only with SYN packets, also with all the
three-way handshake states.
Therefore, an attacker can mass send fake packets to the victim to exhaust its resources.
How does synproxy work?
The idea of synproxy is to prevent false connection starts from consuming
victim resources. To do this, it acts as a transparent proxy that responds to
the attacker without tracking the connection until the 3-way handshake is
mss: This option allow us to indicate the mss value announced to the client. It should match the backend mss.
wscale: This option allow us to indicate the wscale value announced to the client. Again, it should match the backend wscale.
timestamp: This flag pass to the client the timestamp option (this is needed for selective acknowledge and window scaling).
sack-perm: This flag pass to the client the selective acknowledge option.\
First, we need to determine the tcp options used by the backend from an external system.
Then we need to switch tcp_loose mode off, so conntrack will mark out-of-flow packets as state INVALID.
Make SYN packets untracked.
And finally catch the UNTRACKED SYN packets and INVALID states 3-way-handshake packets and send them to synproxy. Also, we need to drop invalid packets that were not matched by synproxy.
The outcome ruleset should be something similar to this one below.
I hope this post has been useful to you! If you have any question don’t hesitate to contact me.