3

Background

I am on Debian 10 Buster. I started running a Tor relay on my home IP address. A dedicated full-fledged server is probably not the most energy efficient way, but I want to try it out. And since I stopped running Bitcoin daemon, there is plenty of traffic available. In spite, I do have a purely networking question, from past experience I know it does not belong to our sister site dedicated to this topic.


Research

This morning I came across a very old answer on ServerFault, and since I was curious, I applied those rules, see below a complete list. I have added some more rules I have found somewhere else. Simplified it and made some nice structure of it.

I'd like to ask if the following rules can have any measurable results now in 2019 with kernel 4.19.0-2-amd64?


From the iptables' IPv4 file - /etc/iptables/rules.v4:

--append INPUT --proto all --fragment                                --jump DROP    --match comment --comment "all fragmented packets"
--append INPUT --proto all --match state --state INVALID             --jump DROP    --match comment --comment "all invalid packets"
--append INPUT --proto icmp --match u32 ! --u32 "0x4&0x3fff=0x0"     --jump DROP    --match comment --comment "icmp fragmented packets"
--append INPUT --proto icmp --match length --length 1492:65535       --jump DROP    --match comment --comment "icmp oversized unfragmented packets"
--append INPUT --proto tcp ! --syn --match state --state NEW         --jump DROP    --match comment --comment "new non-syn packets"
--append INPUT --proto tcp --tcp-flags  ALL  NONE                    --jump DROP    --match comment --comment "NULL scan"
--append INPUT --proto tcp --tcp-flags  ALL  ALL                     --jump DROP    --match comment --comment "Xmas scan"
--append INPUT --proto tcp --tcp-flags  ALL  FIN,URG,PSH             --jump DROP    --match comment --comment "stealth scan"
--append INPUT --proto tcp --tcp-flags  ALL  SYN,RST,ACK,FIN,URG     --jump DROP    --match comment --comment "pscan 1"
--append INPUT --proto tcp --tcp-flags  SYN,FIN  SYN,FIN             --jump DROP    --match comment --comment "pscan 2"
--append INPUT --proto tcp --tcp-flags  FIN,RST  FIN,RST             --jump DROP    --match comment --comment "pscan 3"
--append INPUT --proto tcp --tcp-flags  SYN,RST  SYN,RST             --jump DROP    --match comment --comment "SYN-RST scan"
--append INPUT --proto tcp --tcp-flags  ACK,URG  URG                 --jump DROP    --match comment --comment "URG scans"
--append INPUT --proto tcp --tcp-flags  ALL  SYN,FIN                 --jump DROP    --match comment --comment "SYN-FIN scan"
--append INPUT --proto tcp --tcp-flags  ALL  URG,PSH,FIN             --jump DROP    --match comment --comment "nmap Xmas scan"
--append INPUT --proto tcp --tcp-flags  ALL  FIN                     --jump DROP    --match comment --comment "FIN scan"
--append INPUT --proto tcp --tcp-flags  ALL  URG,PSH,SYN,FIN         --jump DROP    --match comment --comment "nmap-id scan"

Thus far, after 0.5 days, I can only see rules #2 and #5 catching some packets:

2       67 13972 DROP       all  --  any    any     anywhere             anywhere             state INVALID /* all invalid packets */
5      158 81683 DROP       tcp  --  any    any     anywhere             anywhere             tcp flags:!FIN,SYN,RST,ACK/SYN state NEW /* new non-syn packets */

after 1.25 days, still catching only on the one TCP rule and on the INVALID one:

2      178 26785 DROP       all  --  any    any     anywhere             anywhere             state INVALID /* all invalid packets */
5      467  241K DROP       tcp  --  any    any     anywhere             anywhere             tcp flags:!FIN,SYN,RST,ACK/SYN state NEW /* new non-syn packets */

after 7 days, still catching only on the one TCP rule and on the INVALID one + I see a lot of DROPs on the INPUT chain in general, I did not notice that before:

Chain INPUT (policy DROP 62772 packets, 17M bytes)
2     3475  355K DROP       all  --  any    any     anywhere             anywhere             state INVALID /* all invalid packets */
5     2459 1324K DROP       tcp  --  any    any     anywhere             anywhere             tcp flags:!FIN,SYN,RST,ACK/SYN state NEW /* new non-syn packets */

Question

Are the other rules considered obsolete as they get filtered elsewhere or something else?

3
+50

To complete @roaima's answer, and really just because you wanted all the tiny details, here is the reason those two rules below can't match on most configurations:

--append INPUT --proto all --fragment                                --jump DROP

and

--append INPUT --proto icmp --match u32 ! --u32 "0x4&0x3fff=0x0"     --jump DROP

--match u32 ! --u32 "0x4&0x3fff=0x0" is just a convoluted low-level method to write --fragment except maybe it includes the MF flag in addition: the fragment offset (+ flag MF) is the u32 word at offset 4 in the IP packet (0x4), in its lowest bits part (&0x3fff): a non null value is equivalent to having a fragment (or announcing more fragments).

But because there's (at least) --match state the module nf_conntrack is loaded which in turn requires the module nf_defrag_ipv4. This defragmentation is done at PREROUTING hook priority -400, thus not allowing anything after to ever see fragments but just a newly built reassembled packet. Later kernels permit to load the raw table at a lower priority:

# modinfo -p iptable_raw
raw_before_defrag:Enable raw table before defrag (bool)

thus allowing to see those packets, but only in the raw table (where obviously conntrack can't be used).

Now also to be really thorough, contrary to my previous example, by default Debian buster won't use ip_tables or any iptable_* modules, because for iptables, Debian buster uses by default iptables-nft which is iptables translated over nftables but still sometimes using iptables-extensions' xt_* modules.

UPDATE: This will still allow the u32 module to be used and be working, but will prevent to try and alter the rule via nft (eg can't be saved then restored, and emulation for now would always choose priority -300 for the chain raw/PREROUTING).

root@buster-amd64:~# update-alternatives --display iptables|head -3
iptables - auto mode
  link best version is /usr/sbin/iptables-nft
  link currently points to /usr/sbin/iptables-nft


# iptables -A INPUT -p udp --fragment -j DROP
# iptables -A INPUT -p icmp --match u32 ! --u32 "0x4&0x3fff=0x0" -j DROP
# iptables -S INPUT
-P INPUT ACCEPT
-A INPUT -p udp -f -j DROP
-A INPUT -p icmp -m u32 ! --u32 "0x4&0x3fff=0x0" -j DROP
# nft --debug=netlink list ruleset -a
ip filter INPUT 4 
  [ meta load l4proto => reg 1 ]
  [ cmp eq reg 1 0x00000011 ]
  [ payload load 2b @ network header + 6 => reg 1 ]
  [ bitwise reg 1 = (reg=1 & 0x0000ff1f ) ^ 0x00000000 ]
  [ cmp neq reg 1 0x00000000 ]
  [ counter pkts 0 bytes 0 ]
  [ immediate reg 0 drop ]

ip filter INPUT 5 4 
  [ meta load l4proto => reg 1 ]
  [ cmp eq reg 1 0x00000001 ]
  [ match name u32 rev 0 ]
  [ counter pkts 4 bytes 4096 ]
  [ immediate reg 0 drop ]

table ip filter { # handle 5
    chain INPUT { # handle 1
        type filter hook input priority 0; policy accept;
        meta l4proto udp ip frag-off & 8191 != 0 counter packets 0 bytes 0 drop # handle 4
        meta l4proto icmp # u32 ! "0x4&0x3fff=0x0" counter packets 4 bytes 4096 drop # handle 5
    }

    chain FORWARD { # handle 2
        type filter hook forward priority 0; policy accept;
    }

    chain OUTPUT { # handle 3
        type filter hook output priority 0; policy accept;
    }
}

Note that rule handle #5 has a comment placed before u32, not because it's not working, but because it can't be handled by native nft. Bytecode dump won't show the actual payload check which is stored elsewhere but will behave as intended, and the counter will increase when an actual fragment is received and dropped.

  • (just revised my claim: iptables-nft handles correctly the u32 match, but this can't be shown completely or further handled by nft commands) – A.B Mar 22 at 19:44
2

I would suggest that your flag combinations (rule 6 et seq) are pretty much all caught by rule 2, --state INVALID.

I run a fairly tight set of rules on one of my public-facing servers, with a customised fail2ban sitting right up there at the top. (I run three strikes and you're out for a couple of hours, and three outs is a one month ban. With a couple of IP address-based exceptions to prevent myself getting totally locked out.)

This is a (cut down) version of my rules.v4 set

-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
...
# Exceptions to allow suitably authorised traffic
...
-A INPUT -j LOG --log-level info --log-prefix "firewall: REJECT "
-A INPUT -j REJECT

Some corresponding packet counts from iptables --line-numbers -nvL INPUT since the beginning of the month

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target            prot opt in     out     source               destination
1    97753   26M f2b-recidive      tcp  --  *      *       0.0.0.0/0            0.0.0.0/0
2    94046   26M f2b-XXXXXXXXXXXX  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0
3    94046   26M f2b-XXXXXXXXXXXX  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0
4    88576   26M f2b-sshd          tcp  --  *      *       0.0.0.0/0            0.0.0.0/0
5     902K  333M ACCEPT            all  --  lo     *       0.0.0.0/0            0.0.0.0/0
6    2463M 2399G ACCEPT            all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
7     1152 52453 DROP              all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate INVALID
...
19    417K   13M ACCEPT            icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 8
20   56921 4276K LOG               all  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 6 prefix "firewall: REJECT "
21   56921 4276K REJECT            all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

As you can see, we get a fair number of packets with invalid data, but mostly it's straightforward TCP/IP probes. And the majority of these trigger the fail2ban rules, just as they should.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.