One of the port scanning defenses that one of our network defense appliances at work takes is the approach of defending against port scans by responding to every SYN on a closed or filtered port with a stateless SYN+ACK. This shifts the burden back to the party who sent the SYN, and doesn’t consume any memory or other resources on the server side. If the party who sent the SYN is doing mass SYN scans with raw SYNs, the outcome will be inaccurate results. If the party who sent the SYN is doing anything with the actual connection, like scraping headers, OS detection, protocol analysis, etc., they will experience a tarpitting effect as they timeout trying to continue to use the connection after the SYN+ACK.
I recreated this defense using nftables and the synproxy syntax. At the end of my input chain, before it would have went to policy drop, I added:
tcp flags syn jump SYNPROXY
Then I added a new SYNPROXY chain that does the following:
chain SYNPROXY {
synproxy mss 1460 wscale 7 sack-perm timestamp
tcp flags syn,ack drop
}
With this change, you can see that port scans of bx.ee now return every port as open.