There is a certain feature in
iptables that is not so well documented and may therefore be
overlooked by a lot of people (yes, including me). If you use state
NEW, packets with the SYN bit unset
will get through your firewall. This feature is there because in certain cases
we want to consider that a packet may be part of an already
ESTABLISHED connection on, for instance, another firewall.
This feature makes it possible to have two or more firewalls, and for one of the
firewalls to go down without any loss of data. The firewalling of the subnet
could then be taken over by our secondary firewall. This does however lead to
the fact that state NEW will allow pretty much any kind of
TCP connection, regardless if this is the initial 3-way handshake or not. To
take care of this problem we add the following rules to our firewalls
INPUT, OUTPUT and
FORWARD chain:
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j LOG \
--log-prefix "New not syn:"
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
| The above rules will take care of this problem. This is a badly documented
behavior of the Netfilter/iptables
project and should definitely be more highlighted. In other words, a huge
warning is in its place for this kind of behavior on your firewall.
|
Note that there are some troubles with the above rules and bad Microsoft TCP/IP
implementations. The above rules will lead to certain conditions where packets
generated by Microsoft product gets labeled as state NEW
and hence get logged and dropped. It will however not lead to broken
connections to my knowledge. The problem occurs when a connection gets closed,
the final FIN/ACK is
sent, the state machine of Netfilter closes
the connection and it is no longer in the conntrack table. At this point the
faulty Microsoft implementation sends another packet which is considered as
state NEW but lacks the SYN bit
and hence gets matched by the above rules. In other words, don't worry to much
about this rule, or if you are worried anyways, set the
--log-headers option to the rule and log the headers too
and you'll get a better look at what the packet looks like.
There is one more known problem with these rules. If someone is currently
connected to the firewall, let's say from the LAN,
and you have the script set to be activated when running a
PPP connection. In this case, when you start the
PPP connection, the person previously connected through
the LAN will be more or less killed. This only applies
when you are running with the conntrack and nat code bases as modules, and the
modules are loaded and unloaded each time you run the script. Another way to get
this problem is to run the rc.firewall.txt script from a
telnet connection from a host not on the actual firewall. To put it simply, you
connect with telnet or some other stream connection. Start
the connection tracking modules, then load the NEW not
SYN packet rules. Finally, the telnet
client or daemon tries to send something. the
connection tracking code will not recognize this connection as a legal
connection since it has not seen packets in any direction on this connection
before, also there will be no SYN bits set since it is
not actually the first packet in the connection. Hence, the packet will match to
the rules and be logged and after-wards dropped to the ground.