Iptables – How to pass to NFQUEUE only the initial connection packets

iptables

I am developing an application on top of NFQUEUE that is supposed to drop specific HTTP connections based on the host name. For performance reasons, I would like to tell netfilter to send my application packets until a verdict (pass or drop) is reached. When that happens my NFQUEUE-based application will set the mark using nfq_set_verdict2(). Unfortunately netfilter sends to NFQUEUE packets even after they have been marked, and from userspace I see that incoming packets have always a mark 0 even though if previous connection packets were marked properly to a non zero value.

This is my configuration:

iptables -A OUTPUT -t mangle -j CONNMARK --restore-mark
iptables -A OUTPUT -t mangle -m mark --mark 1 -j ACCEPT
iptables -A OUTPUT -t mangle -m mark --mark 2 -j DROP
iptables -A OUTPUT -t mangle -m mark --mark 0 -p tcp --destination-port 80 -j NFQUEUE --queue-num 0
iptables -A OUTPUT -t mangle -j CONNMARK --save-mark

What am I doing wrong?

Best Answer

NFQUEUE is terminal so packet leave OUTPUT chain when you issue nfq_set_verdict. So packet don't reach the save mark. Common solution is to save the mark in POSTROUTING mangle.

iptables -A OUTPUT -t mangle -j CONNMARK --restore-mark
iptables -A OUTPUT -m mark --mark 1 -j ACCEPT
iptables -A OUTPUT -m mark --mark 2 -j DROP
iptables -A OUTPUT -m mark --mark 0 -p tcp --destination-port 80 -j NFQUEUE --queue-num 0
iptables -A POSTROUTING -t mangle -j CONNMARK --save-mark
Related Topic