Sniffing using iptables

School project

For one of my subject to school I had to work on project using netlink sockets.

I decided to work with netfilter subsystem, and one of possible use of netfilter is to get packets logged by the kernel packet filter (ULOG/NFLOG target).

Result of project:
Libpcap patch: already commited: cc8520ff5294900d93509eaf843684c51af102a9
Patch for dumpcap (no longer needed, it's enough to have patched libpcap)

Why to bother with NFLOG? I can BPF!

When you capture from network interfaces you can use BPF to filter traffic.
But BPF is stateless and can only filter only from frame data.

In contrast iptables can not only match data from packet, but it can get information from tcp/ip stack, and you can use many extensions of iptables or write your own.

IMHO one of most interesting use cases is sniffing using netfilter owner module.
(which can be used to filter packets generated for example by suspicious user or malware).
man 8 iptables list these options:

--uid-owner userid
    Matches if the packet was created by a process with the given effective user id.
--gid-owner groupid
    Matches if the packet was created by a process with the given effective group id.
--pid-owner processid
    Matches if the packet was created by a process with the given process id.
--sid-owner sessionid
    Matches if the packet was created by a process in the given session group.
--cmd-owner name
    Matches if the packet was created by a process with the given command name.
    (this option is present only if iptables was compiled under a kernel supporting this feature)
*** NOTE: pid, sid and command matching are broken on SMP ***

Unfortunetly on my Linux- SMP system it's possible only to use three: -- uid-owner, --gid-owner and --socket-exists.
But it's still good!

You can also put NFLOG as last target of your firewall and filter data which passed firewall.
(wireshark see packets which should be dropped by iptables)

It can be also used by people who finds BPF syntax hard, and prefers to grep/gawk output of tcpdump ;)


  • Capture packets generated by user nobody to file user-nobody.pcap
  • # iptables -A OUTPUT -m owner --uid-owner nobody -j CONNMARK --set-mark 1
    # iptables -A INPUT -m connmark --mark 1 -j NFLOG --nflog-group 30
    # iptables -A OUTPUT -m connmark --mark 1 -j NFLOG --nflog-group 30
    # dumpcap -i nflog:30 -w user-nobody.pcap

  • Capture tcp packets from/to port 80
  • # iptables -A INPUT -p tcp -m tcp --sport 80 -j NFLOG --nflog-group 40
    # iptables -A OUTPUT -p tcp -m tcp --dport 80 -j NFLOG --nflog-group 40
    # dumpcap -i nflog:40 -w port-80.pcap

Future work

Project was handed, I got A ;-) but after GSoC I might work on:

  • Adding support for -j NFQUEUE
    NFQUEUE is another possible target which forwards data to userspace program.
    But unlikely NFLOG it's last target (like -j ACCEPT/DROP) and userspace program must decide whether this packet should be accepted (NF_ACCEPT) or dropped (NF_DROP).
    When sniffing we're not really interested in dropping packets, but netfilter will NOT pass (read: DROP) packet when userspace program will not handle it. It's good when we haven't run dumpcap yet.

    NFQUEUE is also used by DAQ (Snort IDS library)

  • Write something similar for other (not-Linux) systems
Patch for dumpcap17.12 KB