Typically with IP tables you would either drop or reject traffic. For TCP is there a way to have iptables instead send a syn back but forget the connection?
3 Answers
xtables-addons
has the TARPIT
target (man page):
TARPIT
Captures and holds incoming TCP connections using no local per-connection resources.TARPIT only works at the TCP level, and is totally application agnostic. This module will answer a TCP request and play along like a listening server, but aside from sending an ACK or RST, no data is sent. Incoming packets are ignored and dropped.
On Debian/Ubuntu, the package is xtables-addons-common
.
There are several not very nice things one could do; a RST packet could be inserted which unless the hosts involved have unusual and customized firewall configurations the RST will cause the connection to be closed. Another method would be to accept the connection but then somehow remove the state entry; this might look something like
...
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp --syn -m tcp --dport 22 -j ACCEPT
...
possibly also with logging (to act on via a log scanner such as sec.pl
) or some other module that with conntrack-tools
installed runs a command similar to
conntrack -D -s 192.0.2.42
after 192.0.2.42 has connected via ssh to remove the state table entry for that IP.
-
LOG, TEE, REDIRECT, etc for another service to handle it is a possibility but I am wondering how to do it with purely iptables as well. Internally it must have the capability if it can RST to SYN instead. It might at least need a counter for it's seq though.– jgmjgmJul 20, 2018 at 0:03
-
TPROXY and NOTRACK or even drop/reject on the client's third shake all get very close but still require a tcp endpoint to respond rather than pure client and iptables only.– jgmjgmJul 20, 2018 at 1:30
send a syn back but forget the connection?
That means to generate a SYN/ACK but to not track the connection.
Not really, kind of.
First thing first: Why?
If the SYN is to a closed port then either:
drop the packet and avoid any more processing.
if you are going to answer with anything, and the attacker will receive an answer revealing that you are there, then: just answer with a RST. An entirely possible and common iptables answer:
You can send back a RST with iptables -p tcp [...] -j REJECT --reject-with tcp-reset.
If the SYN is to a open port then either:
allow the server (service) handle the request as it see fit.
help the server with a SYNPROXY.
Mitigating SYN Floods With SYNPROXY
Which is actually trying to protect the server against a SYN-ACK Flood DDoS attack. This is not the same as you are asking and it can not be. There could not be two entities (server and iptables) both answering with SYN/ACK at the same time to the same packet. It is either one or the other.
But SYNPROXY is clever. How it works (and a bit more):
When a SYNPROXY is used, clients transparently get connected to the SYNPROXY. So the 3-way TCP handshake happens first between the client and the SYNPROXY:
Clients send TCP SYN to server A
At the firewall, when this packet arrives it is marked as UNTRACKED
The UNTRACKED TCP SYN packet is then given to SYNPROXY
SYNPROXY gets this and responds (as server A) with TCP SYN+ACK (UNTRACKED)
Client responds with TCP ACK (marked as INVALID or UNTRACKED in iptables) which is also given to SYNPROXY
Once a client has been connected to the SYNPROXY, SYNPROXY automatically initiates a 3-way TCP handshake with the real server, spoofing the SYN packet so that the real server will see that the original client is attempting to connect:
SYNPROXY sends TCP SYN to real server A. This is a NEW connection in iptables and happens on the OUTPUT chain. The source IP of the packet is the IP of the client
The real server A responds with SYN+ACK to the client
SYNPROXY receives this and responds back to the server with ACK. The connection is now marked as ESTABLISHED
Once the connection has been established, SYNPROXY leaves the traffic flow between the client and the server
So, SYNPROXY can be used for any kind of TCP traffic. It can be used for both unencrypted and encrypted traffic, since it does not interfere with the content itself.
Having said all that ...
You can not set a SYNPROXY in a port that has no server (it won't work).
So, for closed ports, you need a server, maybe a fake server, but a server anyway.
Python - Scapy - Show all your ports as open
Related:
-
As far as I am aware SYNPROXY doesn't actually need a server. The point of it is to not bother the server unnecessarily. So maybe SYNPROXY will work with it behind a block to servers and maybe a block from anything from the client but SYN.– jgmjgmJul 20, 2018 at 1:00
-
If you don't mind I'll edit your answer to only the pertinent info. The link you gave is really bad too :D. Very silly stuff like claiming ICPM is never useful and specifying loads of complex rules sometimes rather than just having default drop. They also put in a rule that might not play nice with synproxy (block invalid).– jgmjgmJul 20, 2018 at 1:03