Wireguard with PBR and IPv6

I'm trying to set up my new router to use WireGuard with IPv4 and IPv6, having PBR installed.

I followed these instructions:
https://openwrt.org/docs/guide-user/services/vpn/wireguard/client

And verified it with this video:

I made 2 deviations from the OpenWRT wiki-page. I set the IPv4 and 6 DNS servers provided to me on the interface and I created a firewall-zone called "vpn" and added it to the default forwarder.

I installed PBR and enabled it for IPv6.

The WireGuard interface is coming up just fine and shows the occasional traffic (due to negotiations I'm guessing) but the only traffic that appears to go through the tunnel successfully is DNS traffic (which I can verify by removing the DNS servers and getting no more name resolution). I can only reach IPv6 sites on the Internet and they show my ISP's address so that traffic bypasses the tunnel.

PBR is showing the WireGuard as the default gateway.

Any ideas on how to get this to work or what is going wrong?

Maybe my own notes are helpful, see:

You need the Client Setup guide, better download it as github only show the first 5 pages

IPv6 is covered, some pointers:
Enable Route Allowed IPs and use as allowed IPs ::0/1 and 8000::/1 instead of ::0/0 or disable Source Routing

Well,changing the allowed IP's successfully routes everything over the tunnel now so I have no more connectivity at all. :slight_smile:

Thanks for the notes, it always helps to double-check.

PS You might want to replace the keys in your documents with some random characters. I assume they are no longer valid, but still.

1 Like

If your problem is solved, please consider marking this topic as [Solved]. See How to mark a topic as [Solved] for a short how-to.
Thanks! :slight_smile:

Um, no, I now have no more connectivity at all since all traffic goes over the tunnel. So not solved.

Ah OK I misunderstood, you wrote all traffic goes over the tunnel but you mean the routing is via the tunnel but there is no traffic?

It can help if we can see your configs, please connect to your OpenWRT device using ssh and copy the output of the following commands and post it here using the "Preformatted text </> " button

Remember to redact keys, passwords, MAC addresses and any public IP addresses you may have:

ubus call system board
cat /etc/config/network
cat /etc/config/firewall
ip route show
ip route show table all
ip rule show
wg show
1 Like

One massive post.

config interface 'loopback'
	option device 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config globals 'globals'
	option ula_prefix 'fdd2:3aae:1770::/48'

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'lan1'
	list ports 'lan2'
	list ports 'lan3'
	list ports 'lan4'
	list ports 'lan5'

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option ipaddr '172.25.229.1'
	option netmask '255.255.255.0'
	option ip6assign '60'

config interface 'wan'
	option device 'eth1'
	option proto 'dhcp'

config interface 'wan6'
	option device 'eth1'
	option proto 'dhcpv6'

config interface 'vpn_wg'
	option proto 'wireguard'
	option private_key 'sGtxxxt+TxxxBCmxxxBAsxxxxJKxxxKZdxxxq5cxxxk='
	list addresses '10.88.190.5/32'
	list addresses 'fa7a:76ee:e68f:a993:b38:c7f:56b2:8684/128'
	list dns '10.28.0.1'
	list dns 'fa7a:76ee:e68f:a993::1'
	option mtu '1320'

config wireguard_vpn_wg 'wgserver'
	option public_key 'Rxx9BcqXxxiuuBoxxx1dKxxx8SuxxxclBxxx9bdzHVg='
	option preshared_key '84Bxxx4OixxxcjmxxxNonxxxJW9xxxn/JxxxWFLxxx0='
	option endpoint_host 'nl.ipv6.vpn.org'
	option endpoint_port '1637'
	option persistent_keepalive '15'
	option route_allowed_ips '1'
	option description 'NL'
	list allowed_ips '0.0.0.0/0'
	list allowed_ips '::0/1'
	list allowed_ips '8000::/1'

config defaults
	option syn_flood '1'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'

config zone 'lan'
	option name 'lan'
	list network 'lan'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'

config zone 'wan'
	option name 'wan'
	list network 'wan'
	list network 'wan6'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'

config forwarding 'lan2wan'
	option src 'lan'
	option dest 'wan'

config rule
	option name 'Allow-DHCP-Renew'
	option src 'wan'
	option proto 'udp'
	option dest_port '68'
	option target 'ACCEPT'
	option family 'ipv4'

config rule
	option name 'Allow-Ping'
	option src 'wan'
	option proto 'icmp'
	option icmp_type 'echo-request'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-IGMP'
	option src 'wan'
	option proto 'igmp'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-DHCPv6'
	option src 'wan'
	option proto 'udp'
	option dest_port '546'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-MLD'
	option src 'wan'
	option proto 'icmp'
	option src_ip 'fe80::/10'
	list icmp_type '130/0'
	list icmp_type '131/0'
	list icmp_type '132/0'
	list icmp_type '143/0'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Input'
	option src 'wan'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	list icmp_type 'router-solicitation'
	list icmp_type 'neighbour-solicitation'
	list icmp_type 'router-advertisement'
	list icmp_type 'neighbour-advertisement'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Forward'
	option src 'wan'
	option dest '*'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-IPSec-ESP'
	option src 'wan'
	option dest 'lan'
	option proto 'esp'
	option target 'ACCEPT'

config rule
	option name 'Allow-ISAKMP'
	option src 'wan'
	option dest 'lan'
	option dest_port '500'
	option proto 'udp'
	option target 'ACCEPT'

config include 'pbr'
	option fw4_compatible '1'
	option type 'script'
	option path '/usr/share/pbr/firewall.include'

config zone 'vpn'
	option name 'vpn'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	list network 'vpn_wg'
	list masq '1'
	option masq6 '1'

config forwarding 'lan2vpn'
	option src 'lan'
	option dest 'vpn'


default dev vpn_wg proto static scope link
172.25.229.0/24 dev br-lan proto kernel scope link src 172.25.229.1
192.168.178.0/24 dev eth1 proto kernel scope link src 192.168.178.150
default via 192.168.178.1 dev eth1 table pbr_wan
172.25.229.0/24 dev br-lan table pbr_wan proto kernel scope link src 172.25.229.1
default via 10.188.190.5 dev vpn_wg table pbr_vpn_wg
default dev vpn_wg proto static scope link
172.25.229.0/24 dev br-lan proto kernel scope link src 172.25.229.1
192.168.178.0/24 dev eth1 proto kernel scope link src 192.168.178.150
local 10.88.190.5 dev vpn_wg table local proto kernel scope host src 10.88.190.5
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1
local 172.25.229.1 dev br-lan table local proto kernel scope host src 172.25.229.1
broadcast 172.25.229.255 dev br-lan table local proto kernel scope link src 172.25.229.1
local 192.168.178.150 dev eth1 table local proto kernel scope host src 192.168.178.150
broadcast 192.168.178.255 dev eth1 table local proto kernel scope link src 192.168.178.150
unreachable default dev lo table pbr_wan metric 1024 pref medium
::/1 dev vpn_wg table pbr_vpn_wg proto static metric 1024 pref medium
fa7a:76ee:e68f:a993:b38:c7f:56b2:8684 dev vpn_wg table pbr_vpn_wg proto kernel metric 256 pref medium
8000::/1 dev vpn_wg table pbr_vpn_wg proto static metric 1024 pref medium
default dev vpn_wg table pbr_vpn_wg metric 128 pref medium
default from 2001:1c00:a17:f400:8f7f:5e64:8a93:8278 via fe80::ae22:5ff:fe50:6cc0 dev eth1 proto static metric 384 pref medium
default from 2001:1c00:a17:f400::/64 via fe80::ae22:5ff:fe50:6cc0 dev eth1 proto static metric 384 pref medium
default from 2001:1c00:a17:f410::/60 via fe80::ae22:5ff:fe50:6cc0 dev eth1 proto static metric 384 pref medium
2001:1c00:a17:f400::/64 dev eth1 proto static metric 256 pref medium
2001:1c00:a17:f400::/64 via fe80::ae22:5ff:fe50:6cc0 dev eth1 proto static metric 512 pref medium
unreachable 2001:1c00:a17:f400::/64 dev lo proto static metric 2147483647 pref medium
2001:1c00:a17:f410::/64 dev br-lan proto static metric 1024 pref medium
unreachable 2001:1c00:a17:f410::/60 dev lo proto static metric 2147483647 pref medium
2a00:1678:2470:46:7ad0:3ba6:ba90:6c6b via fe80::ae22:5ff:fe50:6cc0 dev eth1 proto static metric 384 pref medium
::/1 dev vpn_wg proto static metric 1024 pref medium
fa7a:76ee:e68f:a993:b38:c7f:56b2:8684 dev vpn_wg proto kernel metric 256 pref medium
fdd2:3aae:1770::/64 dev br-lan proto static metric 1024 pref medium
unreachable fdd2:3aae:1770::/48 dev lo proto static metric 2147483647 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev br-lan proto kernel metric 256 pref medium
fe80::/64 dev eth1 proto kernel metric 256 pref medium
8000::/1 dev vpn_wg proto static metric 1024 pref medium
local ::1 dev lo table local proto kernel metric 0 pref medium
anycast 2001:1c00:a17:f400:: dev eth1 table local proto kernel metric 0 pref medium
local 2001:1c00:a17:f400:8f7f:5e64:8a93:8278 dev eth1 table local proto kernel metric 0 pref medium
local 2001:1c00:a17:f400:9683:c4ff:fea7:b98f dev eth1 table local proto kernel metric 0 pref medium
anycast 2001:1c00:a17:f410:: dev br-lan table local proto kernel metric 0 pref medium
local 2001:1c00:a17:f410::1 dev br-lan table local proto kernel metric 0 pref medium
local fa7a:76ee:e68f:a993:b38:c7f:56b2:8684 dev vpn_wg table local proto kernel metric 0 pref medium
anycast fdd2:3aae:1770:: dev br-lan table local proto kernel metric 0 pref medium
local fdd2:3aae:1770::1 dev br-lan table local proto kernel metric 0 pref medium
anycast fe80:: dev eth0 table local proto kernel metric 0 pref medium
anycast fe80:: dev br-lan table local proto kernel metric 0 pref medium
anycast fe80:: dev eth1 table local proto kernel metric 0 pref medium
local fe80::9683:c4ff:fea7:b98f dev eth1 table local proto kernel metric 0 pref medium
local fe80::9683:c4ff:fea7:b991 dev eth0 table local proto kernel metric 0 pref medium
local fe80::9683:c4ff:fea7:b991 dev br-lan table local proto kernel metric 0 pref medium
multicast ff00::/8 dev eth0 table local proto kernel metric 256 pref medium
multicast ff00::/8 dev br-lan table local proto kernel metric 256 pref medium
multicast ff00::/8 dev eth1 table local proto kernel metric 256 pref medium
multicast ff00::/8 dev vpn_wg table local proto kernel metric 256 pref medium
0:      from all lookup local
29998:  from all fwmark 0x20000/0xff0000 lookup pbr_vpn_wg
30000:  from all fwmark 0x10000/0xff0000 lookup pbr_wan
32766:  from all lookup main
32767:  from all lookup default
interface: vpn_wg
  public key: Rxx9BcqXxxiuuBoxxx1dKxxx8SuxxxclBxxx9bdzHVg=
  private key: (hidden)
  listening port: 55208

peer: PyxxxAQTxxxM4TxxxsOQxxxUb3xxxfGlxxxApuig+hk=
  preshared key: (hidden)
  endpoint: [2a00:1678:2470:46:7ad0:3ba6:ba90:6c6b]:1637
  allowed ips: 0.0.0.0/0, ::/1, 8000::/1
  latest handshake: 1 minute, 6 seconds ago
  transfer: 132.02 KiB received, 147.13 KiB sent
  persistent keepalive: every 15 seconds

That actually looks quite good, you have a connection/handshake and traffic going over the connection and a default route via the vpn.

One minor detail and not related:
Change list addresses '10.88.190.5/32 to list addresses '10.88.190.5/24 so with a /24 subnet to create local routes

I did noticed you have PBR enabled for testing Disable PBR and reboot.

Test with:

ping 8.8.8.8
ping google.com
ping -6 ipv6.google.com

to see the route taken do

traceroute 8.8.8.8
traceroute google.com
traceroute -6  ipv6.google.com

Interesting. The traceroutes go to the VPN as their first hop and they do reach their destination. But when coming from my PC I get Destination Port Unreachable. So the problem is routing or forwarding to/from my client?

That /32 is directly from the VPN provider's config, should I really change it?

EDIT: Running the traceroute on my PC it shows it's trying to go directly over the ISP's IPv6 address. When using IPv4 the router is the first hop and then state Destination Protocol Unreachable.

I would as that gives you also automatic local routes, but as I said it is a minor detail

Your firewall seems OK, you have forwarding from lan to vpn and Masquerading is enabled for the vpn zone.

Make sure you have disabled PBR.

Otherwise disable the WG interface, restart network (service network restart) or reboot and test your client PC for IPv4 and IPv6 (use ipleak.net and/or whatismyip.com)
Then use the same WireGuard config you are using for the router to setup a WireGuard Client on your PC and test that.

That will make sure the WG config is working and the PC is working

I actually installed PBR because I was not able to reach anything and I figured it would take care of the routing for me. Everything works just fine if I disable the WG interface.

I'll have to figure out how to set it up on my client, there's a reason I'm only setting it up on my router, plus my clients are Windows so I would get the VPN provider's own software.

At least it is not my ISP that's dropping the packets as the traceroutes work from the router. Anybody know if there is a wget-like test I can do on OpenWRT? The busybox wget doesn't really like to.

I guess if all else fails I can try OpenVPN. I need to have it operational by Tuesday.

It is just a simple test to see if the wireguard config works from your PC.
If you want to do that test just download the windows WG client and import the config.
Windows WG client: https://download.wireguard.com/windows-client/

But I understand you want it on your router that is more practical :slight_smile:

Nah, you make a good point, I just really don't like installing stuff on Windows. :slight_smile:

Unfortunately the behavior is something different entirely now. Tunnel comes up but won't complete the handshake. No RX.

EDIT: Hmm... using an IPv4 endpoint gives me a failed handshake. Using an IPv6 endpoint is successful. But, just like on the router, no IPv4 connectivity it seems. Make that strange IPv4 connectivity.

That could point to something in your server side not working.

Can you make a new config with new keys to test?

Or use another provider to test.
With Proton you can make a free account and download a a free WG config to test, but it is IPv4 only but still could be a valuable test.

How to make a proton free account and config is described in my guide

I actually have Proton Unlimited if I'm not mistaken. Forgot about that. I believe VPN is part of that.

1 Like

And I lost all connectivity again. Tunnel is up just fine.

I really think it has something to do with the way OpenWRT has set up my IPv6 address. Something about the way it routes my requests. Like OpenWRT refuses to handle my IPv6 requests because my PC is receiving an IPv6 address directly from the ISP's pool, something like that.

The irony is I never got IPv6 to work with OpenVPN, and I can't get IPv4 to work with WireGuard.

To be honest I would have expected half a dozen responses from people on this forum by now. Very grateful for your help though. Just saying. It is so frustrating that I have only the weekend to make this work.

EDIT: I disabled IPv6 on my Windows to force IPv4 only. No joy. Destination protocol unavailable.
EDIT2: Just to bring out the big guns I connected one of my Linux servers to the new router. It is not happy with the domain and IP switch but it has the same issue. So at least it is not just Windows being Windows.

I think I found it... silly little checkmark next to MSS.

Doesn't really explain a few things though, like how WireGuard on my Windows client doesn't do the IPv4 handshake. But it at least is a change in behavior. Few things in IT troubleshooting are more annoying than consistent behavior. :slight_smile:

I'm going to try the original VPN provider now as well. If I get it all to work I'll reset the whole thing to factory defaults and try again. If it still works, I'll post the uci commands and you can add them to your PDF if you wish.

And if it doesn't work, well... there's still room to grow this thread.

1 Like

Let's hope it is the MSS clamping.

I do have it enabled but usually these MSS/MTU problems give slow or sometimes hanging connections and not completely unreachable.

Keep us posted

That's my experience with MTU, the packets get shredded and slow the whole thing down.

I inserted the WireGuard profile of my VPN provider and it's working great, IPv6 all the way, from endpoint to target. ipleak.net and dnsleaktest.com both come back with the VPN provider's info.

Speedtest results are all over the place though, ranging from 40Mbps to 530Mbps download. So no way to know if it's better than OpenVPN. But since OpenVPN only worked with TCP for me I'm guessing it will be better.

Okay, time for a factory reset and reconfigure from scratch using my ucicmd file. To be continued.

Hmm that is also odd, OpenVPN should work equally well with UDP unless it really is an MTU problem in which case TCP might work and UDP not unless you lower MTU.