ufw

Comment 6 for bug 323950

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

The following lines were put into /etc/ufw/before.rules to address invalid combinations of tcp flags in the first place:
# drop INVALID packets (logs these in loglevel medium and higher)
-A ufw-before-input -m state --state INVALID -j ufw-logging-deny
-A ufw-before-input -m state --state INVALID -j DROP

Due to this bug, I looked into this quite a bit, and in my research and testing I have found that the above rule does block these packets already.

Reading the man page for iptables reveals:
       INVALID
              meaning that the packet is associated with no known connection
...
       [!] --state state
              Where state is a comma separated list of the connection states
              to match. Possible states are INVALID meaning that the packet
              could not be identified for some reason which includes running
              out of memory and ICMP errors which don't correspond to any
              known connection

That man page does not explicitly state that incorrect combinations of tcp flags are marked INVALID, so I looked at the kernel source (netfilter/nf_conntrack_proto_tcp.c), and it has the following:
        /* Check TCP flags. */
        tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR|TH_PUSH));
        if (!tcp_valid_flags[tcpflags]) {
                if (LOG_INVALID(net, IPPROTO_TCP))
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
                                  "nf_ct_tcp: invalid TCP flag combination ");
                return -NF_ACCEPT;

Interestingly, the kernel code also has:
/* "Be conservative in what you do,
    be liberal in what you accept from others."
    If it's non-zero, we mark only out of window RST segments as INVALID. */
static int nf_ct_tcp_be_liberal __read_mostly = 0;

However, it still will mark packets with incorrect combinations of tcp flags as INVALID when using that sysctl value (I didn't look any further into this, because the default on Ubuntu is to have this set to '0'):
sudo sysctl net.ipv4.netfilter.ip_conntrack_tcp_be_liberal=1

The invalid combinations I was most interested in blocking were:
Christmas: ALL FIN,URG,PSH (nmap -sX)
NULL scan: ALL NONE (nmap -sN)
SYN,RST SYN,RST (nmap --scanflags SYNRST)
SYN,FIN SYN,FIN (nmap --scanflags SYNFIN)
ALL FIN (nmap -sF)

and all of the above are blocked in the default ufw configuration. Please remember that ufw sets up a stateful firewall and is not a simple packet filter. From the nmap man page:
...
           The key advantage to these scan types is that they can sneak
           through certain non-stateful firewalls and packet filtering
           routers.
...

Also note, that depending on the version of ufw you are using, the INVALID packets won't be logged unless you are at loglevel medium or higher (but they are always blocked).

If you want to test this yourself, it might be easier to change this line:
-A ufw-before-input -m state --state INVALID -j ufw-logging-deny

to:
-A ufw-before-input -m state --state INVALID -j LOG --log-prefix "[UFW BLOCK INVALID] "

then perform:
sudo ufw reload