Some packets genuinely don't belong to any user, just to the kernel:
- routed packets
- packets generated by the kernel in response to outside events. eg: when receiving an icmp echo-request, the kernel will answer with an icmp echo-reply.
- probably all those iptables' -j REJECT packets.
- ...
Now about the packets you're talking about: from tests made with marking packets with and without owner, they seem to belong to the final ACK
at the end of the FIN
end-of-communication negociation as well as the RST
when the connection is cut more abruptly. My guess is in both cases, the kernel already stopped considering the connection belonged to the user because it is tearing it apart, although this didn't always happen for the ACK
(perhaps when mixed with PSH and final data?).
UPDATE: the answer to "Iptables: matching outgoing traffic with conntrack and owner. Works with strange drops" gives more detailed informations on the issue.
If you don't want to lose those packets and still want to use MARK for the decision, you can still rely on Netfilter's CONNMARK because the last packet, even without owner, is still part of the same connection. For example, testing with these rules adapted from the examples in the link:
#!/bin/sh
iptables -t mangle -N connmark_test
iptables -t mangle -N connmark_log
iptables -t mangle -A connmark_test -j CONNMARK --restore-mark
iptables -t mangle -A connmark_test -m mark ! --mark 0 -j RETURN
iptables -t mangle -A connmark_test -m mark --mark 0 -m owner --uid-owner 0-99999 -p tcp -j MARK --set-mark 1
iptables -t mangle -A connmark_test -m mark --mark 0 -m owner --uid-owner 0-99999 -j MARK --set-mark 2
iptables -t mangle -A connmark_test -m mark --mark 0 -p tcp -j MARK --set-mark 3
iptables -t mangle -A connmark_test -m mark --mark 0 -j MARK --set-mark 4
iptables -t mangle -A connmark_test -j CONNMARK --save-mark
iptables -t mangle -A connmark_log -m owner --uid-owner 0-99999 -j LOG --log-prefix "with_owner "
iptables -t mangle -A connmark_log -m owner ! --uid-owner 0-99999 -j LOG --log-prefix " NO_owner "
iptables -t mangle -A POSTROUTING -j connmark_test
iptables -t mangle -A POSTROUTING -m mark ! --mark 0 -j connmark_log
I could see with curl -s -L https://google.com/ >/dev/null
(which makes two connections) that the final connection's ACK or RST which usually fails at the owner match still got a connmark, since there's MARK=0x1
:
[14668.179780] with_owner IN= OUT=eth0 SRC=10.0.3.66 DST=216.58.209.238 LEN=83 TOS=0x00 PREC=0x00 TTL=64 ID=53193 DF PROTO=TCP SPT=33472 DPT=443 WINDOW=339 RES=0x00 ACK PSH URGP=0 MARK=0x1
[14668.181740] with_owner IN= OUT=eth0 SRC=10.0.3.66 DST=216.58.209.238 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=53194 DF PROTO=TCP SPT=33472 DPT=443 WINDOW=339 RES=0x00 ACK FIN URGP=0 MARK=0x1
[14668.181914] NO_owner IN= OUT=eth0 SRC=10.0.3.66 DST=216.58.209.238 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=53195 DF PROTO=TCP SPT=33472 DPT=443 WINDOW=339 RES=0x00 ACK URGP=0 MARK=0x1
[14668.182667] with_owner IN= OUT=eth0 SRC=10.0.3.66 DST=216.58.198.67 LEN=83 TOS=0x00 PREC=0x00 TTL=64 ID=58460 DF PROTO=TCP SPT=33210 DPT=443 WINDOW=520 RES=0x00 ACK PSH URGP=0 MARK=0x1
[14668.184588] with_owner IN= OUT=eth0 SRC=10.0.3.66 DST=216.58.198.67 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=58461 DF PROTO=TCP SPT=33210 DPT=443 WINDOW=520 RES=0x00 ACK RST URGP=0 MARK=0x1
[14668.201316] NO_owner IN= OUT=eth0 SRC=10.0.3.66 DST=216.58.198.67 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=20784 DF PROTO=TCP SPT=33210 DPT=443 WINDOW=0 RES=0x00 RST URGP=0 MARK=0x1
Last note: don't forget that an user's activity can trigger packets from other user: eg DNS requests to a local DNS server, which will then issue DNS requests with packets owned by the user running the DNS server.