"Bidirectional" wireguard pbr setup

Hello everybody, I have two openwrt routers in two different apartments, communicating via a wireguard VPN. What I would like to have is some clients in the first apartment (let's call it AP1) to be routed via the wireguard channel and use the public IP address of the second apartment (AP2); in addition some clients of the second apartment should be routed via the same channel and use the public IP address of the first apartment.

I'm failing to do this and the only solution I've found is to establish two mirror wireguard VPNs (in which AP1 is server for the first one and client for the second one, and the opposite for AP2) and the PBR package takes care of the rest. Having two VPNs sounds redundant to me, and this should be possible with just one VPN.

My setup is the following:

AP1                           AP2
WGserver wg0 192.168.123.1 <- WGclient wg1 192.168.123.2
WGclient wg1 192.168.126.2 -> WGserver wg0 192.168.126.1
AP1
config interface 'wg0'
	option proto 'wireguard'
	option private_key 'CENSORED'
	option listen_port 'CENSORED'
	list addresses '192.168.123.1/24'

config wireguard_wg0 'wg_client'
	option public_key 'CENSORED'
	list allowed_ips '192.168.123.2/32'

config interface 'wg1'
	option proto 'wireguard'
	option private_key 'CENSORED'
	list addresses '192.168.126.2/32'

config wireguard_wg1 'wgserver'
	option public_key 'CENSORED'
	option endpoint_host 'CENSORED'
	option endpoint_port 'CENSORED'
	option persistent_keepalive '25'
	list allowed_ips '0.0.0.0/0'
	list allowed_ips '::/0'


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

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

The configuration for AP2 is the same.

Is there any way to achieve what I want with just one wireguard connection (let's say AP1 192.168.123.x)?

Thanks in advance

This can absolutely be done with a single tunnel.

Let's see the full network and firewall config files from each side.

2 Likes

Great! So, here's the configuration for AP1:

network

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 'fdd6:fd3e:cd39::/48'

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

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option ipaddr '192.168.124.1'
	option netmask '255.255.255.0'
	option ip6assign '60'
	list ip6class 'local'

config interface 'wan'
	option device 'wan'
	option proto 'dhcp'
	option peerdns '0'
	list dns '94.140.15.15'

config interface 'wan6'
	option device 'wan'
	option proto 'dhcpv6'
	list dns '2a00:5a60::ad2:0ff'
	option peerdns '0'

config interface 'wg0'
	option proto 'wireguard'
	option private_key 'CENSORED'
	option listen_port 'CENSORED'
	list addresses '192.168.123.1/24'

config wireguard_wg0 'wg_client'
	option public_key 'CENSORED'
	list allowed_ips '192.168.123.2/32'

config interface 'wg1'
	option proto 'wireguard'
	option private_key 'CENSORED'
	list addresses '192.168.126.2/32'

config wireguard_wg1 'wgserver'
	option public_key 'CENSORED'
	option endpoint_host 'AP2'
	option endpoint_port 'CENSORED'
	option persistent_keepalive '25'
	list allowed_ips '0.0.0.0/0'
	list allowed_ips '::/0'

firewall

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

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

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

config forwarding
	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 redirect
	option target 'DNAT'
	option name 'ssh'
	list proto 'tcp'
	option src 'wan'
	option src_dport '22'
	option dest 'lan'
	option dest_ip '192.168.124.1'
	option dest_port '22'

config redirect
	option target 'DNAT'
	option name 'wireguard'
	list proto 'udp'
	option src 'wan'
	option src_dport '31415'
	option dest 'lan'
	option dest_ip '192.168.124.1'
	option dest_port '31415'

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

And here's the one for AP2:

network

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 'fd66:fa99:3514::/48'

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

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option ipaddr '192.168.125.1'
	option netmask '255.255.255.0'
	option ip6assign '60'
	list ip6class 'local'

config interface 'wan'
	option device 'wan'
	option proto 'dhcp'
	option peerdns '0'
	list dns '94.140.15.15'

config interface 'wan6'
	option device 'wan'
	option proto 'dhcpv6'
	list dns '2a00:5a60::ad2:0ff'
	option peerdns '0'

config interface 'wg0'
	option proto 'wireguard'
	option private_key 'CENSORED'
	option listen_port '31415'
	list addresses '192.168.126.1/24'

config wireguard_wg0 'wg_client'
	option public_key 'CENSORED'
	list allowed_ips '192.168.126.2/32'

config interface 'wg1'
	option proto 'wireguard'
	option private_key 'CENSORED'
	list addresses '192.168.123.2/32'

config wireguard_wg1 'wgserver'
	option public_key 'CENSORED'
	option endpoint_host 'AP1'
	option endpoint_port 'CENSORED'
	option persistent_keepalive '25'
	list allowed_ips '0.0.0.0/0'
	list allowed_ips '::/0'

firewall

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

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

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

config forwarding
	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/pbr.firewall.include'

config redirect
	option dest 'lan'
	option target 'DNAT'
	list proto 'udp'
	option src 'wan'
	option src_dport '31415'
	option dest_ip '192.168.125.1'
	option dest_port '31415'
	option name 'wireguard'

Thanks for the configs...

So, AP1 has a lan subnet of 192.168.124.0/24 and AP2's is 192.168.125.0/24. We can use the single WG tunnel, so let's use 192.168.126.0/24 for that (wg1 from AP1).

So, first thing we're going to do is remove wg0 from AP1. Delete all of this:

We can add the listen port to wg1's interface:

config interface 'wg1'
	option proto 'wireguard'
	option private_key 'CENSORED'
	option listen_port 'CENSORED'
	list addresses '192.168.126.2/32'

Next, we'll modify the wg1 peer on AP1 to specify the AP2 network and wireguard address, removing the all-IPs (0's) from the allowed IPs. We'll also add the route_allowed_ips option. That is to say, we will start with this:

And we will edit it so that it looks like this:

config wireguard_wg1 'wgserver'
	option public_key 'CENSORED'
	option endpoint_host 'AP2'
	option endpoint_port 'CENSORED'
	option persistent_keepalive '25'
	list allowed_ips '192.168.126.1/32'
	list allowed_ips '192.168.125.0/24'
	option route_allowed_ips '1'

We'll move onto AP1's firewall... Delete this, and replace it with a traffic rule:

The replacement rule will be:

config rule
	option name 'Allow-Wireguard'
	option src 'wan'
	option dest_port '31415'
	option proto 'udp'
	option target 'ACCEPT'

Next, we can move onto AP2.

We'll remove all of wg1:

We'll similarly edit wg0's peer config so that it allows the AP1 network, endpoint host + port, and route_allowed_ips.

config wireguard_wg0 'wg_client'
	option public_key 'CENSORED'
	option endpoint_host 'AP1'
	option endpoint_port 'CENSORED'
	option persistent_keepalive '25'
	list allowed_ips '192.168.124.0/24'
	list allowed_ips '192.168.126.2/32'
	option route_allowed_ips '1'

We'll make the same fix to the firewall rule on AP2. But, I do see that you have the same port in use on both sides. It's probably best to use a different port on each side -- be sure to adjust the configs appropriately. So delete this:

And replace it with this:

config rule
	option name 'Allow-Wireguard'
	option src 'wan'
	option dest_port '31415'
	option proto 'udp'
	option target 'ACCEPT'

There are a lot of moving parts here, so there's a chance you might end up with key mismatches or the wrong ports, etc... so make sure you have access to both devices via an alternate method in the event that it doesn't "just work". You appear to have a rule to allow ssh on AP1 from the wan. I would recommend removing that when you're done here, but in the meantime, it does provide you with a means of accessing ap1 if you are at the location with ap2.

Report back with the status once you make these changes... and feel free to post the updated configs for review as soon as they're ready.

And one last thing -- you probably don't need PBR anymore if it is specifically for this purpose. Be sure to remove the related routes between the two routers, as we're now letting Wireguard handle all that with the route allowed IPs option.

1 Like

Wow, thanks! That's a huge simplification of what I had! I am going to attempt this in a few hours and I'll let you know!

If PBR is not required anymore, how do I choose which clients in AP1 should be routed to AP2 and viceversa?

There might be some miscommunication going on?

I interpret the above that you have some LAN clients on your LAN in apartment A you want to have the public IP address of apartment B and the other way around.

That is technically possible with one tunnel but easier to do with two.
With one tunnel you make a site-to-site setup basically both sides are setup as server and have as allowed IPS 0.0.0.0/0, the subnet of the other side and the IP address of the WG peer.
Now comes the hacking part, you do enable Route allowed IPs but you do not want to have a default route via the tunnel so you also Disable Default routing on the WG interface. So in the end you only have a route to the other subnet via the tunnel (and a route to the WG peer).
The routing of the respective subnets via the tunnel is important for the return traffic.
You then use PBR for your designated lan clients to use the tunnel.

1 Like

@egc raises a good point. The recipe I have provided assumes a different goal than was described by @egc .

Specifically, my interpretation of the desired result was to enable the two lans to communicate with each other as a site-to-site. This will allow devices at each location to make connections to each other via the tunnel, but it will not redirect regular internet traffic. The regular internet traffic will still egress through the wan at each location.

If the description above is what you intend, then please use my earlier suggestions. If you have a different goal, it would be best to stop and detail the desired end result so that we can give you the right functional solution.

3 Likes

Ah, I see.

What I would like to achieve is that only some clients in the AP1 network should be routed to AP2 (and having AP2's public IP) and only some of the clients in the AP2 network should be routed to AP1 (with AP1's public IP).

Thanks for the clarification.

You will need PBR to make this work. But it should still be possible to do this with a single tunnel. You'll set the allowed IPs on both sides to 0.0.0.0/0, but do not set option route_allowed_ips '1' on either side. Instead, use PBR to set the route via the WG tunnel for the specific hosts in question (on each side, of course).

1 Like

It seems that PBR doesn't allow to route via WG interfaces where listen_port is specified (is_wg function checks if the property is set and this function is used by is_tunnel which, in turn, is used by is_supported_interface) and, as far as I understood, the only wg interface set on each side should look like the following

config interface 'wg0'
	option proto 'wireguard'
	option private_key 'CENSORED'
	option listen_port 'CENSORED'
	list addresses '192.168.126.2/32'

Am I doing something wrong?

The peer that waits for a connection must have listen_port set. Peers that initiate a connection (typically road warriors, or home sites behind NAT) would not have a listen_port specified.

The wg tunnel interface address should be a /24 so it automatically installs a route which covers the other peer(s) tunnel IPs.

1 Like

But then, if I cannot set a wg interface with listen_port as interface for a PBR policy, this means that I always need to setup two symmetrical wg connections if I want to do PBR on both ends.

You have to set the WG interfaces as supported interfaces in the PBR GUI.

If there is a listen port set it assumes it is a server and will discard the interface but in this case it is needed so add it as supported interface.

But as noted use a /24 address for the interface

Thank you, egc.

In my old configuration, I used to have

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

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

where wg0 was the server and wg1 the client of the two symmetric wg connections. If wg0 is the only one expected to remain, how should I configure the wan zone?

It is a bidirectional setup so both sides can inititated traffic and both sides must be setup like a WG server i.e. WG interface in the LAN zone and open WG UDP port in the firewall.

Allowed IPs set to 0.0.0.0/0 and the subnet of the other side
Enable Route Allowed IPs (this is for the route to the other side) but, and this is important, Disable default routing on the WG interface (Advanced tab).

You now have the setup where you can reach the other side by IP address (both sides and the WG subnet must be different of course) but the default route is via the WAN.

Now enter PBR first add the WG interfaces as supported interfaces so that those can be used in PBR route your designated LAN clients.

If it does not work pleas show us the configs of both sides:
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
cat /etc/config/pbr
service pbr status
cat /var/run/pbr.nft

I followed the instruction and, although I feel closer to the solution, I still cannot get the client in the AP1 network to be routed via AP2.

As a recap, here's the scenario:
AP1
local IP 192.168.124.1/24
wg IP 192.168.123.1/24

AP2
local IP 192.168.125.1/24
wg IP 192.168.123.2/24

On AP1 openwrt, I can ping 192.168.125.1 (but I can't do it from a client in the AP1 network). On AP2 openwrt, I cannot ping 192.168.124.1 though.
When I enable the PBR on AP1, I get not internet connection from the client configured in the PBR rule.
Maybe there's still some mess in "allowed_ips" on both ends?

AP1 config

root@OpenWrt:~# ubus call system board
{
	"kernel": "5.15.167",
	"hostname": "OpenWrt",
	"system": "ARMv7 Processor rev 5 (v7l)",
	"model": "GL.iNet GL-A1300",
	"board_name": "glinet,gl-a1300",
	"rootfs_type": "squashfs",
	"release": {
		"distribution": "OpenWrt",
		"version": "23.05.5",
		"revision": "r24106-10cc5fcd00",
		"target": "ipq40xx/generic",
		"description": "OpenWrt 23.05.5 r24106-10cc5fcd00"
	}
}

root@OpenWrt:~# cat /etc/config/network
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 'fdd6:fd3e:cd39::/48'

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

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option ipaddr '192.168.124.1'
	option netmask '255.255.255.0'
	option ip6assign '60'
	list ip6class 'local'

config interface 'wan'
	option device 'wan'
	option proto 'dhcp'
	option peerdns '0'
	list dns '94.140.15.15'

config interface 'wan6'
	option device 'wan'
	option proto 'dhcpv6'
	list dns '2a00:5a60::ad2:0ff'
	option peerdns '0'

config interface 'wg0'
	option proto 'wireguard'
	option private_key 'AP1_PRIV_KEY'
	option listen_port '31415'
	list addresses '192.168.123.1/24'
	option defaultroute '0'

config wireguard_wg0 'wg_aldo'
	option public_key 'AP2_PUB_KEY'
	list allowed_ips '192.168.125.1/24'
	list allowed_ips '0.0.0.0/0'
	list allowed_ips '::/0'
	option route_allowed_ips '1'
	option persistent_keepalive '25'

root@OpenWrt:~# cat /etc/config/firewall
config defaults
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option synflood_protect '1'

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

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

config forwarding
	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 rule
	option name 'Allow-Wireguard'
	option src 'wan'
	option dest_port '31415'
	option proto 'udp'
	option target 'ACCEPT'

config redirect
	option target 'DNAT'
	option name 'ssh'
	list proto 'tcp'
	option src 'wan'
	option src_dport '22'
	option dest 'lan'
	option dest_ip '192.168.124.1'
	option dest_port '22'

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

root@OpenWrt:~# ip route show
default via 192.168.1.1 dev wan proto static src 192.168.1.2 
192.168.1.0/24 dev wan proto kernel scope link src 192.168.1.2 
192.168.123.0/24 dev wg0 proto kernel scope link src 192.168.123.1 
192.168.124.0/24 dev br-lan proto kernel scope link src 192.168.124.1 
192.168.125.0/24 dev wg0 proto static scope link

root@OpenWrt:~# ip route show
default via 192.168.1.1 dev wan proto static src 192.168.1.2 
192.168.1.0/24 dev wan proto kernel scope link src 192.168.1.2 
192.168.123.0/24 dev wg0 proto kernel scope link src 192.168.123.1 
192.168.124.0/24 dev br-lan proto kernel scope link src 192.168.124.1 
192.168.125.0/24 dev wg0 proto static scope link 
root@OpenWrt:~# ip route show table all
default via 192.168.1.1 dev wan table pbr_wan 
192.168.124.0/24 dev br-lan table pbr_wan proto kernel scope link src 192.168.124.1 
default via 192.168.123.1 dev wg0 table pbr_wg0 
192.168.124.0/24 dev br-lan table pbr_wg0 proto kernel scope link src 192.168.124.1 
default via 192.168.1.1 dev wan proto static src 192.168.1.2 
192.168.1.0/24 dev wan proto kernel scope link src 192.168.1.2 
192.168.123.0/24 dev wg0 proto kernel scope link src 192.168.123.1 
192.168.124.0/24 dev br-lan proto kernel scope link src 192.168.124.1 
192.168.125.0/24 dev wg0 proto static scope link 
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 192.168.1.2 dev wan table local proto kernel scope host src 192.168.1.2 
broadcast 192.168.1.255 dev wan table local proto kernel scope link src 192.168.1.2 
local 192.168.123.1 dev wg0 table local proto kernel scope host src 192.168.123.1 
broadcast 192.168.123.255 dev wg0 table local proto kernel scope link src 192.168.123.1 
local 192.168.124.1 dev br-lan table local proto kernel scope host src 192.168.124.1 
broadcast 192.168.124.255 dev br-lan table local proto kernel scope link src 192.168.124.1 
fdd6:fd3e:cd39::/64 dev br-lan proto static metric 1024 pref medium
unreachable fdd6:fd3e:cd39::/48 dev lo proto static metric 2147483647 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev wan proto kernel metric 256 pref medium
fe80::/64 dev phy0-ap0 proto kernel metric 256 pref medium
fe80::/64 dev br-lan proto kernel metric 256 pref medium
fe80::/64 dev phy1-ap0 proto kernel metric 256 pref medium
local ::1 dev lo table local proto kernel metric 0 pref medium
anycast fdd6:fd3e:cd39:: dev br-lan table local proto kernel metric 0 pref medium
local fdd6:fd3e:cd39::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 wan table local proto kernel metric 0 pref medium
anycast fe80:: dev br-lan table local proto kernel metric 0 pref medium
anycast fe80:: dev phy0-ap0 table local proto kernel metric 0 pref medium
anycast fe80:: dev phy1-ap0 table local proto kernel metric 0 pref medium
local fe80::9683:c4ff:fe36:5f1 dev eth0 table local proto kernel metric 0 pref medium
local fe80::9683:c4ff:fe36:5f1 dev br-lan table local proto kernel metric 0 pref medium
local fe80::9683:c4ff:fe36:5f2 dev wan table local proto kernel metric 0 pref medium
local fe80::9683:c4ff:fe36:5f3 dev phy0-ap0 table local proto kernel metric 0 pref medium
local fe80::9683:c4ff:fe36:5f4 dev phy1-ap0 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 wg0 table local proto kernel metric 256 pref medium
multicast ff00::/8 dev wan table local proto kernel metric 256 pref medium
multicast ff00::/8 dev phy0-ap0 table local proto kernel metric 256 pref medium
multicast ff00::/8 dev phy1-ap0 table local proto kernel metric 256 pref medium

root@OpenWrt:~# ip rule show
0:	from all lookup local
29998:	from all fwmark 0x20000/0xff0000 lookup pbr_wg0
30000:	from all fwmark 0x10000/0xff0000 lookup pbr_wan
32766:	from all lookup main
32767:	from all lookup default

root@OpenWrt:~# wg show
interface: wg0
  public key: AP1_PUB_KEY
  private key: (hidden)
  listening port: 31415

peer: AP2_PUB_KEY
  endpoint: 2.15.236.155:52249
  allowed ips: 192.168.125.0/24, 0.0.0.0/0, ::/0
  latest handshake: 1 minute, 8 seconds ago
  transfer: 1.06 MiB received, 1.20 MiB sent
  persistent keepalive: every 25 seconds

root@OpenWrt:~# cat /etc/config/pbr
config pbr 'config'
	option enabled '1'
	option verbosity '2'
	option strict_enforcement '1'
	option resolver_set 'dnsmasq.nftset'
	option ipv6_enabled '0'
	option boot_timeout '30'
	option rule_create_option 'add'
	option procd_reload_delay '1'
	option webui_show_ignore_target '0'
	list webui_supported_protocol 'all'
	list webui_supported_protocol 'tcp'
	list webui_supported_protocol 'udp'
	list webui_supported_protocol 'tcp udp'
	list webui_supported_protocol 'icmp'
	list supported_interface 'wg0'

config include
	option path '/usr/share/pbr/pbr.user.aws'
	option enabled '0'

config include
	option path '/usr/share/pbr/pbr.user.netflix'
	option enabled '0'

config policy
	option name 'test'
	option src_addr 'AP1_CLIENT_MAC'
	option interface 'wg0'

root@OpenWrt:~# service pbr status

pbr - environment
pbr 1.1.6-20 running on OpenWrt 23.05.5.

Dnsmasq version 2.90  Copyright (c) 2000-2024 Simon Kelley
Compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP conntrack ipset nftset auth cryptohash DNSSEC no-ID loop-detect inotify dumpfile

pbr fw4 nft file: /usr/share/nftables.d/ruleset-post/30-pbr.nft
add chain inet fw4 pbr_mark_0x010000
add rule inet fw4 pbr_mark_0x010000  mark set mark and 0xff00ffff xor 0x010000
add rule inet fw4 pbr_mark_0x010000 return
add chain inet fw4 pbr_mark_0x020000
add rule inet fw4 pbr_mark_0x020000  mark set mark and 0xff00ffff xor 0x020000
add rule inet fw4 pbr_mark_0x020000 return
add rule inet fw4 pbr_prerouting ether saddr { AP1_CLIENT_MAC }  goto pbr_mark_0x020000 comment "test"

pbr chains - policies
	chain pbr_forward { # handle 33
	}
	chain pbr_input { # handle 34
	}
	chain pbr_output { # handle 35
	}
	chain pbr_postrouting { # handle 37
	}
	chain pbr_prerouting { # handle 36
		ether saddr AP1_CLIENT_MAC goto pbr_mark_0x020000 comment "test" # handle 5557
	}
	chain pbr_dstnat_lan { # handle 32
	}

pbr chains - marking
	chain pbr_mark_0x010000 { # handle 5551
		meta mark set meta mark & 0xff01ffff | 0x00010000 # handle 5552
		return # handle 5553
	}
	chain pbr_mark_0x020000 { # handle 5554
		meta mark set meta mark & 0xff02ffff | 0x00020000 # handle 5555
		return # handle 5556
	}

pbr nft sets

IPv4 table 256 route: default via 192.168.1.1 dev wan 
IPv4 table 256 rule(s):
30000:	from all fwmark 0x10000/0xff0000 lookup pbr_wan
IPv4 table 257 route: default via 192.168.123.1 dev wg0 
IPv4 table 257 rule(s):
29998:	from all fwmark 0x20000/0xff0000 lookup pbr_wg0

root@OpenWrt:~# cat /var/run/pbr.nft
#!/usr/sbin/nft -f

add chain inet fw4 pbr_mark_0x010000
add rule inet fw4 pbr_mark_0x010000  mark set mark and 0xff00ffff xor 0x010000
add rule inet fw4 pbr_mark_0x010000 return
add chain inet fw4 pbr_mark_0x020000
add rule inet fw4 pbr_mark_0x020000  mark set mark and 0xff00ffff xor 0x020000
add rule inet fw4 pbr_mark_0x020000 return
add rule inet fw4 pbr_prerouting ether saddr { AP1_CLIENT_MAC }  goto pbr_mark_0x020000 comment "test"

AP2 config

root@OpenWrt:~# ubus call system board
{
	"kernel": "5.15.134",
	"hostname": "OpenWrt",
	"system": "ARMv7 Processor rev 5 (v7l)",
	"model": "GL.iNet GL-A1300",
	"board_name": "glinet,gl-a1300",
	"rootfs_type": "squashfs",
	"release": {
		"distribution": "OpenWrt",
		"version": "23.05.0",
		"revision": "r23497-6637af95aa",
		"target": "ipq40xx/generic",
		"description": "OpenWrt 23.05.0 r23497-6637af95aa"
	}
}

root@OpenWrt:~# cat /etc/config/network
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 'fd66:fa99:3514::/48'

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

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option ipaddr '192.168.125.1'
	option netmask '255.255.255.0'
	option ip6assign '60'
	list ip6class 'local'

config interface 'wan'
	option device 'wan'
	option proto 'dhcp'
	option peerdns '0'
	list dns '94.140.15.15'

config interface 'wan6'
	option device 'wan'
	option proto 'dhcpv6'
	list dns '2a00:5a60::ad2:0ff'
	option peerdns '0'

config interface 'wg0'
	option proto 'wireguard'
	option private_key 'AP2_PRIV_KEY'
	list addresses '192.168.123.2/24'
	option defaultroute '0'

config wireguard_wg0 'wg_server'
	option public_key 'AP1_PUB_KEY'
	list allowed_ips '192.168.124.1/24'
	list allowed_ips '0.0.0.0/0'
	list allowed_ips '::/0'
	option route_allowed_ips '1'
	option endpoint_host 'AP1_PUB_IP'
	option endpoint_port '31415'
	option persistent_keepalive '25'

root@OpenWrt:~# cat /etc/config/firewall
config defaults
	option syn_flood '1'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'

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

config zone
	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
	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 rule
	option name 'Allow-Wireguard'
	option src 'wan'
	option dest_port '31415'
	option proto 'udp'
	option target 'ACCEPT'

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

config redirect
	option dest 'lan'
	option target 'DNAT'
	option name 'ssh'
	list proto 'tcp'
	option src 'wan'
	option src_dport '22'
	option dest_ip '192.168.125.2'
	option dest_port '22'

root@OpenWrt:~# ip route show
default via 192.168.1.1 dev wan proto static src 192.168.1.2 
151.45.111.42 via 192.168.1.1 dev wan proto static 
192.168.1.0/24 dev wan proto kernel scope link src 192.168.1.2 
192.168.123.0/24 dev wg0 proto kernel scope link src 192.168.123.2 
192.168.125.0/24 dev br-lan proto kernel scope link src 192.168.125.1

root@OpenWrt:~# ip route show table all
default via 192.168.1.1 dev wan table pbr_wan 
192.168.125.0/24 dev br-lan table pbr_wan proto kernel scope link src 192.168.125.1 
default via 192.168.123.2 dev wg0 table pbr_wg0 
192.168.125.0/24 dev br-lan table pbr_wg0 proto kernel scope link src 192.168.125.1 
default via 192.168.1.1 dev wan proto static src 192.168.1.2 
151.45.111.42 via 192.168.1.1 dev wan proto static 
192.168.1.0/24 dev wan proto kernel scope link src 192.168.1.2 
192.168.123.0/24 dev wg0 proto kernel scope link src 192.168.123.2 
192.168.125.0/24 dev br-lan proto kernel scope link src 192.168.125.1 
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 192.168.1.2 dev wan table local proto kernel scope host src 192.168.1.2 
broadcast 192.168.1.255 dev wan table local proto kernel scope link src 192.168.1.2 
local 192.168.123.2 dev wg0 table local proto kernel scope host src 192.168.123.2 
broadcast 192.168.123.255 dev wg0 table local proto kernel scope link src 192.168.123.2 
local 192.168.125.1 dev br-lan table local proto kernel scope host src 192.168.125.1 
broadcast 192.168.125.255 dev br-lan table local proto kernel scope link src 192.168.125.1 
default from 2a01:cb1d:db:2d00::/64 via fe80::6a3f:7dff:fe1c:d350 dev wan proto static metric 384 pref medium
default from 2a01:cb1d:db:2df1::/64 via fe80::6a3f:7dff:fe1c:d350 dev wan proto static metric 384 pref medium
2a01:cb1d:db:2d00::/64 dev wan proto static metric 256 pref medium
unreachable 2a01:cb1d:db:2d00::/64 dev lo proto static metric 2147483647 pref medium
unreachable 2a01:cb1d:db:2df1::/64 dev lo proto static metric 2147483647 pref medium
fd66:fa99:3514::/64 dev br-lan proto static metric 1024 pref medium
unreachable fd66:fa99:3514::/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 wan proto kernel metric 256 pref medium
fe80::/64 dev phy0-ap0 proto kernel metric 256 pref medium
fe80::/64 dev phy1-ap0 proto kernel metric 256 pref medium
local ::1 dev lo table local proto kernel metric 0 pref medium
anycast 2a01:cb1d:db:2d00:: dev wan table local proto kernel metric 0 pref medium
local 2a01:cb1d:db:2d00:9683:c4ff:fe30:c4b7 dev wan table local proto kernel metric 0 pref medium
anycast fd66:fa99:3514:: dev br-lan table local proto kernel metric 0 pref medium
local fd66:fa99:3514::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 wan table local proto kernel metric 0 pref medium
anycast fe80:: dev phy0-ap0 table local proto kernel metric 0 pref medium
anycast fe80:: dev br-lan table local proto kernel metric 0 pref medium
anycast fe80:: dev phy1-ap0 table local proto kernel metric 0 pref medium
local fe80::9683:c4ff:fe30:c4b6 dev eth0 table local proto kernel metric 0 pref medium
local fe80::9683:c4ff:fe30:c4b6 dev br-lan table local proto kernel metric 0 pref medium
local fe80::9683:c4ff:fe30:c4b7 dev wan table local proto kernel metric 0 pref medium
local fe80::9683:c4ff:fe30:c4b8 dev phy0-ap0 table local proto kernel metric 0 pref medium
local fe80::9683:c4ff:fe30:c4b9 dev phy1-ap0 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 wan table local proto kernel metric 256 pref medium
multicast ff00::/8 dev phy0-ap0 table local proto kernel metric 256 pref medium
multicast ff00::/8 dev phy1-ap0 table local proto kernel metric 256 pref medium
multicast ff00::/8 dev wg0 table local proto kernel metric 256 pref medium

root@OpenWrt:~# ip rule show
0:	from all lookup local
30000:	from all fwmark 0x10000/0xff0000 lookup pbr_wan
30001:	from all fwmark 0x20000/0xff0000 lookup pbr_wg0
32766:	from all lookup main
32767:	from all lookup default

root@OpenWrt:~# wg show
interface: wg0
  public key: AP2_PUB_KEY
  private key: (hidden)
  listening port: 52249

peer: AP1_PUB_KEY
  endpoint: 151.45.111.42:31415
  allowed ips: 192.168.124.0/24, 0.0.0.0/0, ::/0
  latest handshake: 46 seconds ago
  transfer: 1.65 MiB received, 1.32 MiB sent
  persistent keepalive: every 25 seconds

root@OpenWrt:~# cat /etc/config/pbr
config pbr 'config'
	option enabled '1'
	option verbosity '2'
	option strict_enforcement '1'
	option resolver_set 'dnsmasq.nftset'
	option ipv6_enabled '0'
	list ignored_interface 'wg_server'
	option boot_timeout '30'
	option rule_create_option 'add'
	option procd_reload_delay '1'
	option webui_show_ignore_target '0'
	list webui_supported_protocol 'all'
	list webui_supported_protocol 'tcp'
	list webui_supported_protocol 'udp'
	list webui_supported_protocol 'tcp udp'
	list webui_supported_protocol 'icmp'

config include
	option path '/usr/share/pbr/pbr.user.aws'
	option enabled '0'

config include
	option path '/usr/share/pbr/pbr.user.netflix'
	option enabled '0'

config policy
	option name 'mediacenter'
	option interface 'wg0'
	option src_addr 'AP2_CLIENT_MAC'

root@OpenWrt:~# service pbr status
============================================================
pbr - environment
pbr 1.1.1-7 running on OpenWrt 23.05.0. WAN (IPv4): wan/wan/192.168.1.1.
============================================================
Dnsmasq version 2.89  Copyright (c) 2000-2022 Simon Kelley
Compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP conntrack ipset nftset auth cryptohash DNSSEC no-ID loop-detect inotify dumpfile
============================================================
pbr chains - policies
	chain pbr_forward { # handle 32
	}
	chain pbr_input { # handle 33
	}
	chain pbr_output { # handle 34
	}
	chain pbr_prerouting { # handle 35
		ether saddr @pbr_wg0_4_src_mac_cfg046ff5 goto pbr_mark_0x020000 comment "mediacenter" # handle 4977
	}
	chain pbr_postrouting { # handle 36
	}
============================================================
pbr chains - marking
	chain pbr_mark_0x010000 { # handle 4970
		counter packets 0 bytes 0 meta mark set meta mark & 0xff01ffff | 0x00010000 # handle 4971
		return # handle 4972
	}
	chain pbr_mark_0x020000 { # handle 4973
		counter packets 10255 bytes 943337 meta mark set meta mark & 0xff02ffff | 0x00020000 # handle 4974
		return # handle 4975
	}
============================================================
pbr nft sets
	set pbr_wg0_4_src_mac_cfg046ff5 { # handle 4976
		type ether_addr
		flags interval
		counter
		auto-merge
		comment "mediacenter"
		elements = { AP2_CLIENT_MAC counter packets 10255 bytes 943337 }
	}
============================================================
IPv4 table 256 route: default via 192.168.1.1 dev wan 
IPv4 table 256 rule(s):
30000:	from all fwmark 0x10000/0xff0000 lookup pbr_wan
IPv4 table 257 route: default via 192.168.123.2 dev wg0 
IPv4 table 257 rule(s):
30001:	from all fwmark 0x20000/0xff0000 lookup pbr_wg0

root@OpenWrt:~# cat /var/run/pbr.nft
cat: can't open '/var/run/pbr.nft': No such file or directory

There is no route to the other side because the allowed IPs are off, you should use the whole network while routing

On AP1:

On AP 2:

Reboot both routers and test with ip route show and you should see a route to the other side via the WG tunnel and should be able to get to the other side.
Note that individual LAN clients can have their own firewall and might only allow traffic from their own subnet.

You are running a rather old PBR version and might need to update:

Great! It seems to work!! Well, at least the PBR from AP1 to AP2 (AP2 is far away and I'll be able to test the reverse only in a few days).

But, hey, it works! Thank you very much!

Now, what if I were to add an AP3, and add a PBR for a client in AP1 to go to AP3? I tried to replicate the same wg rule, but it AP1 -> AP2 doesn't work anymore.
This is what I'm trying now on AP1:

config interface 'wg0'         
        option proto 'wireguard'
        option private_key 'AP1_PRIV_KEY'
        option listen_port '31415'
        list addresses '192.168.123.1/24'
        option defaultroute '0'      
                          
config wireguard_wg0 'wg_ap2'
        option public_key 'AP2_PUB_KEY'
        list allowed_ips '192.168.125.0/24'
        list allowed_ips '0.0.0.0/0'                                     
        list allowed_ips '::/0'
        option route_allowed_ips '1'
        option persistent_keepalive '25'
                              
config wireguard_wg0 'wg_ap3'                                       
        option public_key 'AP3_PUB_KEY'
        list allowed_ips '192.168.122.0/24'
        list allowed_ips '0.0.0.0/0'
        list allowed_ips '::/0'
        option route_allowed_ips '1'    
        option persistent_keepalive '25'

but wg show shows the following

root@OpenWrt:~# wg show
interface: wg0
  public key: AP1_PRIV_KEY
  private key: (hidden)
  listening port: 31415

peer: AP3_PUB_KEY
  endpoint: AP3_IP:46302
  allowed ips: 192.168.122.0/24, 0.0.0.0/0, ::/0
  latest handshake: 1 minute, 11 seconds ago
  transfer: 2.23 KiB received, 1.16 KiB sent
  persistent keepalive: every 25 seconds

peer: AP2_PUB_KEY
  endpoint: AP2_IP:53633
  allowed ips: 192.168.125.0/24
  latest handshake: 2 minutes, 1 second ago
  transfer: 924.50 KiB received, 848.36 KiB sent
  persistent keepalive: every 25 seconds

Having 0.0.0.0/0 and ::/0 in both clients, leads them to be set only in one (which I guess makes sense). But, what if I wanted to have an additional AP?

Great to hear it is working.

Indeed you are correct this can only work with two connected servers.

You can add additional peers but not with 0.0.0.0/0, you can add the subnet of the other side and connect to that peer but it cannot be used as internet gateway like you are now doing.

The only solution is to setup a second tunnel just like this one.

Make sure all subnets are unique

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:

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.