1

I am trying to route all traffic from one specific user on the machine over vpn. I do it by creating an iptables rule with "-m owner --uid-owner" to mark the packets from the user and then use a routing table from this packet. To make sure everything is redirected, I also have a "-m owner ! --uid-owner 0-99999 -j DROP" to drop all "anonymous" network packages just in case.

In most cases it works well, however I get some packets with no uid, although clearly originating from the user; observed it happening seldom for some SSL connections. Meaning I am doing "wget https://google.com" and I see in the log that the packet to the google's IP gets dropped because it is issued without uid.

My understanding is that kernel might sometimes for some reason "queue" the request and then process it asynchronously, without setting the uid for the packet. Is it possible to track the real source of this packets in this case? I can't forward all the "anonymous" packets through vpn, as I assume it also happens for other users.

Thanks.

1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.