Several different places (e.g. http://wiki.wireshark.org/CaptureSetup/NFLOG) recommend using Linux's "NFLOG" firewall module to capture packets generated by a particular UID, like this:
# iptables -A OUTPUT -m owner --uid-owner 1000 -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 uid-1000.pcap
I have not been able to find any documentation for how this works exactly (in particular, netfilter.org
has a whole lot of poorly-written library API documentation and, as far as I can tell, nothing whatsoever on the semantics of the actual kernel-level firewall rules), so I have several questions:
Is there any damn documentation and where is it hiding?
Is the CONNMARK thing actually necessary? That is, would this work just as well?
# iptables -A INPUT -m owner --uid-owner 1000 -j NFLOG --nflog-group 30 # iptables -A OUTPUT -m owner --uid-owner 1000 -j NFLOG --nflog-group 30
Is it necessary to have "ulogd" running for this to work?
Is there a way to tell the kernel to pick an unallocated group number for me and tell me what it is?
Is there a way to tell the kernel that these filter rules should be automatically deleted when process X terminates? (Process X would not be running as uid 1000.)
Presumably the
iptables
command makes some specialioctl
calls or something to configure the firewall. Is there a C library that can be used to do the same from within a program (namely, "process X" from Q4)?
There are examples on the netfilter site which help explain the functionality. Here is a function I wrote in my own code that sets up the netfilter NFLOG.
Here are the examples they provide: http://www.netfilter.org/projects/libnetfilter_log/doxygen/files.html
It is unnecessary.
No -- in fact I dont use it in this application.
Not that I am aware of. In any case this would be useless if you have NFLOG targets setup for HTTP, one to log dropped packets that were FTP and one that was scanning for SMTP strings. In this scenario you cannot determine which rule is bound to which group, and thus which group should be listened upon.
No, but the kernel fills up a buffer only up to a maximum size then will discard data. It does not pose a performance impact in terms of using up too much memory having rules not listened to.
There is no netfilter library I am aware of that helps you manipulate the rules. There is an internally driven library that is used instead though.
IPtables inherits a rather archaic method of speaking to userspace -- you open a SOCK_RAW IP socket to communicate with it. This is totally going to be removed (as it makes no sense) with nftables which will speak over netlink to do the same thing.
Specifically answering this part:
Yes, it is necessary. No, your proposal would not match any incoming packets (perhaps it does match traffic on the local machine, but definitely not external network traffic).
Only local, outgoing packets have an associated owner. Early in the INPUT chain, the owner information is not available since the packet is still being routed. In order to match incoming packets that are related to an outgoing flow, it is necessary to mark the "connection" in the OUTPUT chain which can subsequently be matched on the INPUT chain.
See also the
iptables-extensions
manual page:(The same caveat applies to nftables.)