Filtering incoming WireGuard traffic with pf?

From: Wesley Aptekar-Cassels <me_at_wesleyac.com>
Date: Fri, 15 Mar 2024 21:24:37 UTC
Hi all,

I have a WireGuard tunnel between two machines running FreeBSD 14.0-RELEASE-p3.
This works well, but I want to reduce my attack surface by having WireGuard
only decrypt packets from specific source IPs. My expectation is that this
would be done in my pf configuration, but I am having trouble understanding the
relationship between WireGuard and pf.

The relevant section of my /etc/pf.conf is:

```
ext_if = "vtnet0"
wg_lan = "10.10.0.0/24"

set skip on lo
scrub in

nat on $ext_if from $wg_lan to any -> ($ext_if)

block in on $ext_if
pass out
```

My WireGuard configuration sets Address, ListenPort, and PrivateKey for
Interface, and PublicKey, PreSharedKey, AllowedIPs, and Endpoint for Peer. I
can share the full config if needed, but from reading the wg(8) manpage it
seems like there is no configuration knob to restrict source IPs in WireGuard,
so I assume that I need to do something in pf to filter this.

My expectation was that `block in on $ext_if` would block WireGuard traffic and
that I'd need a `pass in on $ext_if proto udp to ($ext_if) port 51820` line in
order to enable it, but my WireGuard tunnel works even without that, which
makes it seem to me that the decapsulation of the WireGuard traffic happens
before it hits pf.

How can I restrict WireGuard traffic to only be accepted from particular source
IPs? Is pf the correct place to do this, or should I be looking elsewhere?

Thanks,

:w