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] "
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:
meaning that the packet is associated with no known connection
INVALID
...
[!] --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: TH_CWR| TH_PUSH) ); flags[tcpflags] ) {
nf_log_ packet( pf, 0, skb, NULL, NULL, NULL,
" nf_ct_tcp: invalid TCP flag combination ");
return -NF_ACCEPT;
/* Check TCP flags. */
tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|
if (!tcp_valid_
if (LOG_INVALID(net, IPPROTO_TCP))
Interestingly, the kernel code also has: be_liberal __read_mostly = 0;
/* "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_
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'): netfilter. ip_conntrack_ tcp_be_ liberal= 1
sudo sysctl net.ipv4.
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