PF Wireguard network setup

I'm working on setting up my first wireguard server on FreeBSD 13.3.

The issue: once I start the wireguard service I can't reach the server anymore, the server still can access the internet but nothing can connect to it. The server is in the cloud.
On the same server I'm running an openvpn server, there are no issues there.
Do you have an idea what should I try? What did I miss?

rc.conf
Code:
...
wireguard_enable="YES"
wireguard_interfaces="wg0"

wg0.conf
Code:
[Interface]
Address = 10.9.0.1/32 # address the server will bind to
ListenPort = 51820 # listener port
PrivateKey = ***

[Peer]
AllowedIPs = public-ip-of-the-source/32
PreSharedKey = ***
PublicKey = ***

In pf.conf I have the following wireguard related lines
Code:
ext_if = "em0"
ext_ip = "x.x.x.x"
wg_lan = "10.9.0.0/24"
nat on $ext_if from $wg_lan to any -> $ext_if
pass in on $ext_if inet proto udp from any to ($ext_if) port { 51820 } keep state

Code:
% pfctl -v -s  nat
No ALTQ support in kernel
ALTQ related functions disabled
nat on em0 inet from 10.8.0.0/24 to any -> x.x.x.x
  [ Evaluations: 256       Packets: 1567      Bytes: 101044      States: 3     ]
  [ Inserted: uid 0 pid 44084 State Creations: 21    ]
nat on em0 inet from 10.9.0.0/24 to any -> x.x.x.x
  [ Evaluations: 80        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 44084 State Creations: 0     ]

Code:
% sudo service wireguard restart
[#] ifconfig wg0 destroy
[#] ifconfig wg create name wg0
[#] wg setconf wg0 /dev/stdin
[#] ifconfig wg0 inet 10.9.0.1/32 alias
[#] ifconfig wg0 mtu 1420
[#] ifconfig wg0 up
[#] route -q -n add -inet x.x.x.x/32 -interface wg0
[+]
Backgrounding route

- x.x.x.x - the server's public IP
- 10.8.0.0/24 - openvpn network
- 10.9.0.0/24 - wireguard network
 
I replaced AllowedIPs's with 10.9.0.7/32:
AllowedIPs = 10.9.0.7/32
Now I can still reach the wireguard server when the wireguard service is running but the wireguard client still can't connect :-/

This is the clients configuration file:
Code:
[Interface]
PrivateKey = ***
Address = 10.9.0.7/32

[Peer]
PublicKey = ***
AllowedIPs = 0.0.0.0/0
Endpoint = wireguard-server-address:51820
PersistentKeepalive = 30

pf on the server side looks good and the client can connect to the server, just not on udp/51820
Code:
% pfctl -sr |grep 51820
pass in on em0 inet proto udp from any to (em0) port = 51820 keep state
 
Wait, I do see the client connections, but the VPN itself never connects, see the tcpdump output on the wireguard server
Code:
% sudo tcpdump udp and port 51820
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on em0, link-type EN10MB (Ethernet), capture size 262144 bytes
20:11:42.688862 IP client.host.name.com.50154 > wg-server.51820: UDP, length 148
20:11:42.689801 IP wg-server.51820 > client.host.name.com.50154: UDP, length 92
20:11:48.197842 IP client.host.name.com.50154 > wg-server.51820: UDP, length 148
20:11:48.199064 IP wg-server.51820 > client.host.name.com.50154: UDP, length 92
20:11:53.322173 IP client.host.name.com.50154 > wg-server.51820: UDP, length 148
20:11:53.322905 IP wg-server.51820 > client.host.name.com.50154: UDP, length 92
20:11:59.077790 IP client.host.name.com.50154 > wg-server.51820: UDP, length 148
20:11:59.080433 IP wg-server.51820 > client.host.name.com.50154: UDP, length 92

I can connect to the wireguard server but no new connections can be established from the client. Exiting ones will still work.
 
I tried changing the mask to /24 for [Interface] both on the server ant the client, no luck
 
My configuration is similar to yours, but I found something different in pf.conf:
Code:
### macro name for external interface.
ext_if = "re0"
wg_if="wg0"
wg_clients="10.0.0.0/8"
####
nat on $ext_if from $wg_clients to any -> ($ext_if)
###
pass in on $ext_if proto udp from any to ($ext_if) port = 51820
pass quick on $wg_if

I hope it can help you.
 
I had gateway_enable="YES" already since I use it for openvpn
I added pass quick on $wg_if still the same.

I can connect and receive the IP:

utun8: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1420
options=6460<TSO4,TSO6,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM>
inet 10.9.0.8 --> 10.9.0.8 netmask 0xffffff00
nd6 options=201<PERFORMNUD,DAD>


But I can't reach out from the client:

❯ ping google.com
^C
❯ ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
Request timeout for icmp_seq 4
^C
--- 1.1.1.1 ping statistics ---
6 packets transmitted, 0 packets received, 100.0% packet loss
❯ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
^C
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 0 packets received, 100.0% packet loss


these is my related routing table on the client:

❯ netstat -rn | grep utun
default link#26 UCSg utun8
8.8.8.8 link#26 UHWIig utun8
10.9/24 10.9.0.8 UGSc utun8
10.9.0.8 10.9.0.8 UH utun8
80.80.80.80 link#26 UHW3Ig utun8 !
192.168.8.1 link#26 UHWIig utun8
224.0.0/4 link#26 UmCS utun8
224.0.0.251 link#26 UHmW3I utun8 9
239.255.255.250 link#26 UHmW3I utun8 9
255.255.255.255/32 link#26 UCS utun8


8.8.8.8 is the DNS IP, I'm not sure why is it here, I also don't know why I have a 192.168.8.1 address or 80.80.80.80, odd, my LAN is on 10/24 subnet
 
To summarize it:
pf.conf (just the wireguard related part)
Code:
wg_lan="10.9.0.0/24"
nat on $ext_if inet from $wg_lan to any -> $ext_if
pass in on $ext_if proto udp from any to $ext_if port { 51820 } keep state
pass in on wg0 from any to any

wireguard server: /usr/local/etc/wireguard/wg0.conf:
Code:
[Interface]
Address = 10.9.0.1/24 # address the server will bind to
ListenPort = 51820 # listener port
PrivateKey = ***
[Peer]
AllowedIPs = 10.9.0.7/32
PublicKey = ***
wireguard client:
Code:
[Interface]
Address = 10.9.0.2/24
PrivateKey = ***
DNS = 208.67.222.222,208.67.220.220
[Peer]
AllowedIPs = 0.0.0.0/0
Endpoint = wireguard-server-ip:51820
PersistentKeepalive = 25
PublicKey = ***
wireguard-server-ip = the IP your client(s) can reach the server
You can add PreSharedKey for extra security

I found the missing pf nat bit on this page.
 
Back
Top