1

I am seeing wireguard packets being dropped by the kernel in the output chain yet there is no UID field. How do I enable only the kernel to send udp packets on port 51820. (This is linux 5.8.3). I have a catch all log rule and there is no UID in the output log.

If I don't enable UID checking then any user can send udp packets on this port.

0

2 Answers 2

0

Packets that are not locally emitted by an user process don't have an UID, this includes for example:

  • incoming traffic
  • routed traffic
  • kernel generated traffic (eg: ICMP errors, TCP RST)
  • UDP packets used to tunnel WireGuard (emitted by kernel's WireGuard driver), even if here it concerns only the extra protocol packets rather than all of them (see below).
  • probably a few missing examples

Here's an excerpt from the owner match module:

Forwarded packets do not have any socket associated with them. Packets from kernel threads do have a socket, but usually no owner.

[...]

[!] --uid-owner userid[-userid]

Matches if the packet socket's file structure (if it has one) is owned by the given user. You may also specify a numerical UID, or an UID range.

When there's no UID associated to (the socket associated to) a packet, the reserved invalid uid -1, aka 2^32-1=4294967295 (which is not a valid value to give as parameter) is returned to the owner match module instead of an UID. That's just to explain the meaning of the values. To find a packet not associated with any UID, one has thus to do the inverted query of matching all possible UIDs: ! --uid-owner 0-4294967294.

Now for the specific case of WireGuard at least, it appears that the owner meta properties of the packet in the WireGuard interface (eg wg0) are propagated to the encapsulating packet on the actual interface (eg eth0). So most of the encapsulating UDP traffic will appear with the associated owner having generated it, matching the owner of the traffic inside the wg0 interface. This shouldn't come as granted (I was actually surprised that's the case, using kernel 5.7.x here), and it's possible other kind of tunnels don't behave the same here (they would have an owner inside the interface, but not on the encapsulating packets outside). I expect userland tunnels like OpenVPN to behave like this.

Then there are still all the cases described at the beginning without owner, among them:

  • WireGuard's protocol traffic which periodically revalidates the communication. Usually sent right before or right after some data payload when there was some time without communication. Also sent when persistent keepalive is enabled.
  • tunnelled kernel traffic without owner (such as a TCP RST), thus also without owner on the encapsulating UDP packet.

Those require the inverted match as explained above.

I don't know the actual goal behind the question, but will assume it's to grant access only to some UIDs. For UID 0 and 1000 this would become (could be further factorized):

iptables -I OUTPUT 1 -p udp --dport 51820 -m owner ! --uid-owner 0-4294967294 -j ACCEPT
iptables -I OUTPUT 2 -p udp --dport 51820 -m owner 0 -j ACCEPT
iptables -I OUTPUT 3 -p udp --dport 51820 -m owner 1000 -j ACCEPT
iptables -I OUTPUT 4 -p udp --dport 51820 -j DROP

One can verify the user/kernel property in logs with two rules that could look like this (and that surely require some additional limit match):

iptables -I OUTPUT 1 -p udp --dport 51820 -m owner ! --uid-owner 0-4294967294 -j LOG --log-prefix ' kernel  originated packet: '
iptables -I OUTPUT 2 -p udp --dport 51820 -m owner --uid-owner 0-4294967294 -j LOG --log-prefix 'userland originated packet: ' --log-uid
1
  • Of course usually one uses rules about the actual interface (eg -o wg0) rather than the encapsulating packet (-p udp --dport 51820). If the actual goal behind the question was stated, maybe the answer could be improved.
    – A.B
    Commented Aug 22, 2020 at 19:42
0

Add one rule that blocks all traffic for all users, ie where the UID is not 0 (you can add one for root too if you are paranoid). Then add a rule that allows traffic for the thing that you just blocked but without a UID value.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .