IPv6 over WireGuard

I have followed this guide to build WireGuard "server" on Ubuntu 22.04 on Vultr.

Vultr provides both IPv4 and IPv6.

Tried to connect to the "server" on my Ubuntu 22.04 computer at home, both IPv4 and IPv6 traffic worked. I have tested with curl -4 https://ifconfig.co and curl -6 https://ifconfig.co to see the IP address.

However, putting the configurations onto OpenWRT 22.03.5 and routing 0.0.0.0/0 and ::/0, only IPv4 worked. IPv6 showed my ISP IP address.

My ISP (HKT4 and HKT6 below) provides /64 IPv6 and /56 IPv6-PD.
Both IPv4 and IPv6 addresses are not permanent. So I use DDNS.

/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 'fdd2:bfa3:612e::/64'

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'eth2'
	list ports 'eth3'
	list ports 'eth4'
	list ports 'eth5'

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option netmask '255.255.255.0'
	option ipaddr '192.168.50.1'
	option ip6assign '64'
	option ip4table '1'
	option ip6table '1'
	list ip6class 'local'

config interface 'HKT4'
	option proto 'dhcp'
	option device 'eth0'
	option ip4table '2'

config interface 'HKT6'
	option proto 'dhcpv6'
	option device 'eth0'
	option sourcefilter '0'
	option delegate '0'
	option reqaddress 'try'
	option ip6table '2'
	option reqprefix 'auto'

config interface 'WireGuard'
	option proto 'wireguard'
	option private_key ''
	option listen_port '51820'
	list addresses '10.0.0.1/24'

config wireguard_WireGuard
	option description 'Xperia1III'
	option public_key ''
	option private_key ''
	list allowed_ips '10.0.0.2/32'

config interface 'HGC4'
	option proto 'dhcp'
	option device 'eth1'
	option metric '10'
	option auto '0'

config interface 'docker'
	option device 'docker0'
	option proto 'none'
	option auto '0'

config device
	option type 'bridge'
	option name 'docker0'

config interface 'zion'
	option proto 'wireguard'
	option private_key ''
	list addresses '10.10.10.2'
	list addresses 'fd78:977c:d34a::2'

config wireguard_zion
	option description 'zion'
	option public_key ''
	option endpoint_port '51820'
	option persistent_keepalive '25'
	option endpoint_host '2001:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'
	list allowed_ips '0.0.0.0/0'
	list allowed_ips '::/0'
	option route_allowed_ips '1'

config rule 'lan_wan'
	option priority '40000'
	option lookup '1'

config rule6 'lan_wan6'
	option lookup '2'
	option priority '40000'

/etc/config/firewall

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

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

config zone
	option name 'wan'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	list network 'HKT4'
	list network 'HKT6'
	list network 'HGC4'
	option masq6 '1'

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 'WireGuard'
	list proto 'udp'
	option src 'wan'
	option dest_port '51820'
	option target 'ACCEPT'

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

config zone
	option name 'WG'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	list network 'WireGuard'

config forwarding
	option src 'WG'
	option dest 'lan'

config forwarding
	option src 'WG'
	option dest 'wan'

config redirect
	option dest 'lan'
	option target 'DNAT'
	list proto 'tcp'
	option src 'wan'
	option dest_ip '192.168.50.3'
	option src_dport '80'
	option dest_port '80'
	option name 'Naive'

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

config redirect
	option dest 'lan'
	option target 'DNAT'
	option name 'Naive'
	option family 'ipv4'
	option src 'wan'
	option src_dport '443'
	option dest_ip '192.168.50.3'
	option dest_port '443'

config redirect
	option dest 'lan'
	option target 'DNAT'
	option name 'Naive'
	option family 'ipv6'
	list proto 'tcp'
	option src 'wan'
	option src_dport '80'
	option dest_ip '2404:c805:3800:6300:a6fc:bdce:d16a:7ea9'
	option dest_port '80'

config redirect
	option dest 'lan'
	option target 'DNAT'
	option name 'Naive'
	option family 'ipv6'
	list proto 'tcp'
	option src 'wan'
	option src_dport '443'
	option dest_ip '2404:c805:3800:6300:a6fc:bdce:d16a:7ea9'
	option dest_port '443'

config zone
	option name 'WGZONE'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	list network 'zion'

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

config forwarding
	option src 'lan'
	option dest 'WG'

config forwarding
	option src 'lan'
	option dest 'WGZONE'

/etc/config/dhcp

config dnsmasq
	option domainneeded '1'
	option localise_queries '1'
	option local '/lan/'
	option domain 'lan'
	option expandhosts '1'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp.leases'
	option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
	option localservice '1'
	option ednspacket_max '1232'
	option cachesize '1000'
	option rebind_protection '0'
	option port '54'
	list server '192.168.50.1'
	list server 'fe80::62be:b4ff:fe0a:2ffe'

config dhcp 'lan'
	option interface 'lan'
	option dhcpv4 'server'
	option start '150'
	option limit '50'
	list dhcp_option '6,192.168.50.1'
	list dhcp_option '3,192.168.50.1'
	option leasetime '1h'
	option ra 'server'
	option dhcpv6 'server'
	list dns 'fe80::62be:b4ff:fe0a:2ffe'

config odhcpd 'odhcpd'
	option maindhcp '0'
	option leasefile '/tmp/hosts/odhcpd'
	option leasetrigger '/usr/sbin/odhcpd-update'
	option loglevel '3'

config dhcp 'HKT6'
	option interface 'HKT6'
	option ignore '1'
	option master '1'
	option ra 'relay'
	option dhcpv6 'relay'
	option ndp 'relay'

I have read this thread and done the commands mentioned on the last post, but not work:

On the first reply on this thread, it was said "Linux, and therefore OpenWrt, will not route traffic from ULA to GUA, global unique address.". But the configuration works on Ubuntu 22.04 but not OpenWRT. I am confused.

And I remembered somewhere pointed out that a real IPv6 address is required, but not like 10.10.10.2/24 in IPv4. What is it needed?

What is the best solution to route both IPv4 and IPv6 via the remote WireGuard server?

Thank you very much.

Sorry I am not good at networking. May you guide me in a little bit more detail please?

Does /56 prefix or not mean will 2404:xxxx:xxxx:xxxx::/56 change from time to time (like router reboot)?

From the link you have shared, it stated:

config interface wan6
        option proto static
        option ip6prefix 2001:db80::/56

Is 2001:db80::/56 arbitrary?

Thanks.

Enable IPv6 masquerading on the VPN zone:

uci set firewall.@zone[-1].masq6="1"
uci commit firewall
/etc/init.d/firewall restart

And apply one of the following workarounds:

I have turned on IPv6 Masquerading on WGZone firewall zone, and uci set dhcp.lan.ra_default="1".

IPv4 shows remote address but IPv6 still shows my ISP address.

May you take a look on my current configurations please?

/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'

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'eth2'
	list ports 'eth3'
	list ports 'eth4'
	list ports 'eth5'

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option netmask '255.255.255.0'
	option ipaddr '192.168.50.1'
	option ip6assign '64'

config interface 'HKT4'
	option proto 'dhcp'
	option device 'eth0'

config interface 'HKT6'
	option proto 'dhcpv6'
	option device 'eth0'
	option sourcefilter '0'
	option reqaddress 'try'
	option reqprefix 'auto'

config interface 'WireGuard'
	option proto 'wireguard'
	option private_key ''
	option listen_port '51820'
	list addresses '10.0.0.1/24'

config wireguard_WireGuard
	option description 'Xperia1III'
	option public_key ''
	option private_key ''
	list allowed_ips '10.0.0.2/32'

config interface 'HGC4'
	option proto 'dhcp'
	option device 'eth1'
	option metric '10'
	option auto '0'

config interface 'docker'
	option device 'docker0'
	option proto 'none'
	option auto '0'

config device
	option type 'bridge'
	option name 'docker0'

config interface 'zion'
	option proto 'wireguard'
	option private_key ''
	list addresses '10.10.10.2'
	list addresses 'fd78:977c:d34a::2'
	option delegate '0'

config wireguard_zion
	option description 'zion'
	option public_key ''
	option endpoint_port '51820'
	option persistent_keepalive '25'
	option endpoint_host '2001:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'
	list allowed_ips '0.0.0.0/0'
	list allowed_ips '::/0'
	option route_allowed_ips '1'

/etc/config/dhcp

config dnsmasq
	option domainneeded '1'
	option localise_queries '1'
	option local '/lan/'
	option domain 'lan'
	option expandhosts '1'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp.leases'
	option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
	option localservice '1'
	option ednspacket_max '1232'
	option cachesize '1000'
	option rebind_protection '0'
	option port '54'
	list server '192.168.50.1'
	list server 'fe80::62be:b4ff:fe0a:2ffe'

config dhcp 'lan'
	option interface 'lan'
	option dhcpv4 'server'
	option start '150'
	option limit '50'
	list dhcp_option '6,192.168.50.1'
	list dhcp_option '3,192.168.50.1'
	option leasetime '1h'
	option ra 'server'
	option dhcpv6 'server'
	list dns 'fe80::62be:b4ff:fe0a:2ffe'
	list ra_flags 'managed-config'
	list ra_flags 'other-config'
	option ra_default '1'

config odhcpd 'odhcpd'
	option maindhcp '0'
	option leasefile '/tmp/hosts/odhcpd'
	option leasetrigger '/usr/sbin/odhcpd-update'
	option loglevel '3'

/etc/config/firewall

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

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

config zone
	option name 'wan'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	list network 'HKT4'
	list network 'HKT6'
	list network 'HGC4'
	option masq6 '1'

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 'WireGuard'
	list proto 'udp'
	option src 'wan'
	option dest_port '51820'
	option target 'ACCEPT'

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

config zone
	option name 'WG'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	list network 'WireGuard'

config forwarding
	option src 'WG'
	option dest 'lan'

config forwarding
	option src 'WG'
	option dest 'wan'

config redirect
	option dest 'lan'
	option target 'DNAT'
	list proto 'tcp'
	option src 'wan'
	option dest_ip '192.168.50.3'
	option src_dport '80'
	option dest_port '80'
	option name 'Naive'

config zone
	option name 'WGZone'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	list network 'zion'
	option masq6 '1'

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

config redirect
	option dest 'lan'
	option target 'DNAT'
	option name 'Naive'
	option family 'ipv4'
	option src 'wan'
	option src_dport '443'
	option dest_ip '192.168.50.3'
	option dest_port '443'

config redirect
	option dest 'lan'
	option target 'DNAT'
	option name 'Naive'
	option family 'ipv6'
	list proto 'tcp'
	option src 'wan'
	option src_dport '80'
	option dest_ip '2404:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'
	option dest_port '80'

config redirect
	option dest 'lan'
	option target 'DNAT'
	option name 'Naive'
	option family 'ipv6'
	list proto 'tcp'
	option src 'wan'
	option src_dport '443'
	option dest_ip '2404:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'
	option dest_port '443'

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

config forwarding
	option src 'lan'
	option dest 'WG'

config zone
	option name 'GuestZone'
	option output 'ACCEPT'
	option forward 'REJECT'
	option input 'REJECT'

config zone
	option name 'IoTZone'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'REJECT'

config forwarding
	option src 'lan'
	option dest 'IoTZone'

config forwarding
	option src 'GuestZone'
	option dest 'wan'

config rule
	option name 'Guest DHCP and DNS'
	option src 'GuestZone'
	option dest_port '53 67 68'
	option target 'ACCEPT'

config forwarding
	option src 'lan'
	option dest 'WGZone'

I have just found out the WAN IPv4 changed but IPv6 did not.
So it could be made use of?

Not sure if it is related to your problem but your WG addresses are missing a netmask/ prefix

Maybe use:
list addresses '10.10.10.2/24'
list addresses 'fd78:977c:d34a::2/64'

Furthermore you seem to have two WG instances which both have the same port number, each tunnel should have each own unique port number.

2 Likes

Just tried adding back /24 and /64, same.

For the two WG instances, one is on the router listening on 51820, while the other is on a remote server. So they won't be conflict.

As far as I can see the second tunnel does not have a listen port and then it might default to 51820?

Check IPv6 ping and traceroute from LAN clients.
Collect and analyze runtime configuration from OpenWrt.

Thank you very much.

# wg show

interface: zion
  public key: xxxxx
  private key: (hidden)
  listening port: 42125

peer: xxxxx
  endpoint: [2001:19f0:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]:51820
  allowed ips: 0.0.0.0/0, ::/0
  latest handshake: 1 minute, 24 seconds ago
  transfer: 71.72 MiB received, 2.49 MiB sent
  persistent keepalive: every 25 seconds
# wg showconf zion

[Interface]
ListenPort = 42125
PrivateKey = xxxxx

[Peer]
PublicKey = xxxxx
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = [2001:19f0:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]:51820
PersistentKeepalive = 25
# ip address show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 60:be:b4:0a:2f:fc brd ff:ff:ff:ff:ff:ff
    inet 218.103.199.110/24 brd 218.103.199.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 2404:c800:9138:1a4:62be:b4ff:fe0a:2ffc/64 scope global dynamic noprefixroute 
       valid_lft 85964sec preferred_lft 3164sec
    inet6 fe80::62be:b4ff:fe0a:2ffc/64 scope link 
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 60:be:b4:0a:2f:fd brd ff:ff:ff:ff:ff:ff
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br-lan state UP group default qlen 1000
    link/ether 60:be:b4:0a:2f:fe brd ff:ff:ff:ff:ff:ff
5: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br-lan state UP group default qlen 1000
    link/ether 60:be:b4:0a:2f:ff brd ff:ff:ff:ff:ff:ff
6: eth4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br-lan state UP group default qlen 1000
    link/ether 60:be:b4:0a:30:00 brd ff:ff:ff:ff:ff:ff
7: eth5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br-lan state UP group default qlen 1000
    link/ether 60:be:b4:0a:30:01 brd ff:ff:ff:ff:ff:ff
8: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 60:be:b4:0a:2f:fe brd ff:ff:ff:ff:ff:ff
    inet6 fe80::62be:b4ff:fe0a:2ffe/64 scope link 
       valid_lft forever preferred_lft forever
9: br-lan.7@br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 60:be:b4:0a:2f:fe brd ff:ff:ff:ff:ff:ff
    inet 192.168.50.1/24 brd 192.168.50.255 scope global br-lan.7
       valid_lft forever preferred_lft forever
    inet6 2404:c805:3800:6b00::1/64 scope global dynamic noprefixroute 
       valid_lft 1143sec preferred_lft 1143sec
    inet6 fe80::62be:b4ff:fe0a:2ffe/64 scope link 
       valid_lft forever preferred_lft forever
10: br-lan.8@br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 60:be:b4:0a:2f:fe brd ff:ff:ff:ff:ff:ff
    inet 192.168.58.1/24 brd 192.168.58.255 scope global br-lan.8
       valid_lft forever preferred_lft forever
    inet6 fe80::62be:b4ff:fe0a:2ffe/64 scope link 
       valid_lft forever preferred_lft forever
11: br-lan.9@br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 60:be:b4:0a:2f:fe brd ff:ff:ff:ff:ff:ff
    inet 192.168.59.1/24 brd 192.168.59.255 scope global br-lan.9
       valid_lft forever preferred_lft forever
    inet6 fe80::62be:b4ff:fe0a:2ffe/64 scope link 
       valid_lft forever preferred_lft forever
13: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:ff:ff:4f:76 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:ffff:feff:4f76/64 scope link 
       valid_lft forever preferred_lft forever
22: WireGuard: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none 
    inet 10.0.0.1/24 brd 10.0.0.255 scope global WireGuard
       valid_lft forever preferred_lft forever
26: zion: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none 
    inet 10.10.10.2/32 brd 255.255.255.255 scope global zion
       valid_lft forever preferred_lft forever
    inet6 fd78:977c:d34a::2/128 scope global 
       valid_lft forever preferred_lft forever
# ip route show table all

default via 218.103.199.252 dev eth0 proto static src 218.103.199.110 
10.0.0.0/24 dev WireGuard proto kernel scope link src 10.0.0.1 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown 
192.168.50.0/24 dev br-lan.7 proto kernel scope link src 192.168.50.1 
192.168.58.0/24 dev br-lan.8 proto kernel scope link src 192.168.58.1 
192.168.59.0/24 dev br-lan.9 proto kernel scope link src 192.168.59.1 
218.103.199.0/24 dev eth0 proto kernel scope link src 218.103.199.110 
broadcast 10.0.0.0 dev WireGuard table local proto kernel scope link src 10.0.0.1 
local 10.0.0.1 dev WireGuard table local proto kernel scope host src 10.0.0.1 
broadcast 10.0.0.255 dev WireGuard table local proto kernel scope link src 10.0.0.1 
local 10.10.10.2 dev zion table local proto kernel scope host src 10.10.10.2 
broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.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 
broadcast 172.17.0.0 dev docker0 table local proto kernel scope link src 172.17.0.1 linkdown 
local 172.17.0.1 dev docker0 table local proto kernel scope host src 172.17.0.1 
broadcast 172.17.255.255 dev docker0 table local proto kernel scope link src 172.17.0.1 linkdown 
broadcast 192.168.50.0 dev br-lan.7 table local proto kernel scope link src 192.168.50.1 
local 192.168.50.1 dev br-lan.7 table local proto kernel scope host src 192.168.50.1 
broadcast 192.168.50.255 dev br-lan.7 table local proto kernel scope link src 192.168.50.1 
broadcast 192.168.58.0 dev br-lan.8 table local proto kernel scope link src 192.168.58.1 
local 192.168.58.1 dev br-lan.8 table local proto kernel scope host src 192.168.58.1 
broadcast 192.168.58.255 dev br-lan.8 table local proto kernel scope link src 192.168.58.1 
broadcast 192.168.59.0 dev br-lan.9 table local proto kernel scope link src 192.168.59.1 
local 192.168.59.1 dev br-lan.9 table local proto kernel scope host src 192.168.59.1 
broadcast 192.168.59.255 dev br-lan.9 table local proto kernel scope link src 192.168.59.1 
broadcast 218.103.199.0 dev eth0 table local proto kernel scope link src 218.103.199.110 
local 218.103.199.110 dev eth0 table local proto kernel scope host src 218.103.199.110 
broadcast 218.103.199.255 dev eth0 table local proto kernel scope link src 218.103.199.110 
default from 2404:c800:9138:1a4::/64 via fe80::ff:fe02:202 dev eth0 table 272 proto static metric 512 pref medium
default from 2404:c805:3800:6b00::/56 via fe80::ff:fe02:202 dev eth0 table 272 proto static metric 512 pref medium
2001:19f0:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx via fe80::ff:fe02:202 dev eth0 table 272 proto static metric 512 pref medium
2404:c800:9138:1a4::/64 dev eth0 table 272 proto static metric 256 pref medium
fe80::/64 dev eth0 table 272 proto kernel metric 256 pref medium
unreachable default dev lo table 273 metric 1024 pref medium
fd78:977c:d34a::2 dev zion table 274 proto kernel metric 256 pref medium
unreachable default dev lo table 274 metric 1024 pref medium
default from 2404:c800:9138:1a4::/64 via fe80::ff:fe02:202 dev eth0 proto static metric 512 pref medium
default from 2404:c805:3800:6b00::/56 via fe80::ff:fe02:202 dev eth0 proto static metric 512 pref medium
2001:19f0:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx via fe80::ff:fe02:202 dev eth0 proto static metric 512 pref medium
2404:c800:9138:1a4::/64 dev eth0 proto static metric 256 pref medium
unreachable 2404:c800:9138:1a4::/64 dev lo proto static metric 2147483647 pref medium
2404:c805:3800:6b00::/64 dev br-lan.7 proto kernel metric 256 expires 796sec pref medium
2404:c805:3800:6b00::/64 dev br-lan.7 proto static metric 1024 pref medium
unreachable 2404:c805:3800:6b00::/56 dev lo proto static metric 2147483647 pref medium
fd78:977c:d34a::2 dev zion proto kernel metric 256 pref medium
fe80::/64 dev br-lan proto kernel metric 256 pref medium
fe80::/64 dev br-lan.7 proto kernel metric 256 pref medium
fe80::/64 dev br-lan.8 proto kernel metric 256 pref medium
fe80::/64 dev br-lan.9 proto kernel metric 256 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev docker0 proto kernel metric 256 linkdown pref medium
local ::1 dev lo table local proto kernel metric 0 pref medium
anycast 2404:c800:9138:1a4:: dev eth0 table local proto kernel metric 0 pref medium
local 2404:c800:9138:1a4:62be:b4ff:fe0a:2ffc dev eth0 table local proto kernel metric 0 pref medium
anycast 2404:c805:3800:6b00:: dev br-lan.7 table local proto kernel metric 0 pref medium
local 2404:c805:3800:6b00::1 dev br-lan.7 table local proto kernel metric 0 pref medium
local fd78:977c:d34a::2 dev zion table local proto kernel metric 0 pref medium
anycast fe80:: dev br-lan.7 table local proto kernel metric 0 pref medium
anycast fe80:: dev br-lan table local proto kernel metric 0 pref medium
anycast fe80:: dev br-lan.8 table local proto kernel metric 0 pref medium
anycast fe80:: dev br-lan.9 table local proto kernel metric 0 pref medium
anycast fe80:: dev eth0 table local proto kernel metric 0 pref medium
anycast fe80:: dev docker0 table local proto kernel metric 0 pref medium
local fe80::42:ffff:feff:4f76 dev docker0 table local proto kernel metric 0 pref medium
local fe80::62be:b4ff:fe0a:2ffc dev eth0 table local proto kernel metric 0 pref medium
local fe80::62be:b4ff:fe0a:2ffe dev br-lan.7 table local proto kernel metric 0 pref medium
local fe80::62be:b4ff:fe0a:2ffe dev br-lan table local proto kernel metric 0 pref medium
local fe80::62be:b4ff:fe0a:2ffe dev br-lan.8 table local proto kernel metric 0 pref medium
local fe80::62be:b4ff:fe0a:2ffe dev br-lan.9 table local proto kernel metric 0 pref medium
multicast ff00::/8 dev br-lan table local proto kernel metric 256 pref medium
multicast ff00::/8 dev br-lan.7 table local proto kernel metric 256 pref medium
multicast ff00::/8 dev br-lan.8 table local proto kernel metric 256 pref medium
multicast ff00::/8 dev br-lan.9 table local proto kernel metric 256 pref medium
multicast ff00::/8 dev eth0 table local proto kernel metric 256 pref medium
multicast ff00::/8 dev docker0 table local proto kernel metric 256 linkdown pref medium
multicast ff00::/8 dev WireGuard table local proto kernel metric 256 pref medium
multicast ff00::/8 dev zion table local proto kernel metric 256 pref medium
# ip rule show

0:	from all lookup local
32766:	from all lookup main
32767:	from all lookup default
# ip -6 rule show

0:	from all lookup local
30000:	from all fwmark 0x10000/0xff0000 lookup 272
30001:	from all fwmark 0x20000/0xff0000 lookup 273
30002:	from all fwmark 0x30000/0xff0000 lookup 274
32766:	from all lookup main
4200000000:	from 2404:c805:3800:6b00::1/64 iif br-lan.7 unreachable
# nft list ruleset
table inet fw4 {
	chain input {
		type filter hook input priority filter; policy accept;
		iifname "lo" accept comment "!fw4: Accept traffic from loopback"
		ct state established,related accept comment "!fw4: Allow inbound established and related flows"
		tcp flags syn / fin,syn,rst,ack jump syn_flood comment "!fw4: Rate limit TCP syn packets"
		iifname "br-lan.7" jump input_lan comment "!fw4: Handle lan IPv4/IPv6 input traffic"
		iifname "WireGuard" jump input_WG comment "!fw4: Handle WG IPv4/IPv6 input traffic"
		iifname "br-lan.8" jump input_IoTZone comment "!fw4: Handle IoTZone IPv4/IPv6 input traffic"
		iifname "br-lan.9" jump input_GuestZone comment "!fw4: Handle GuestZone IPv4/IPv6 input traffic"
		iifname "zion" jump input_WGZone comment "!fw4: Handle WGZone IPv4/IPv6 input traffic"
		iifname { "eth0", "eth1" } jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic"
		iifname "docker0" jump input_docker comment "!fw4: Handle docker IPv4/IPv6 input traffic"
	}

	chain forward {
		type filter hook forward priority filter; policy drop;
		ct state established,related accept comment "!fw4: Allow forwarded established and related flows"
		iifname "br-lan.7" jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic"
		iifname "WireGuard" jump forward_WG comment "!fw4: Handle WG IPv4/IPv6 forward traffic"
		iifname "br-lan.8" jump forward_IoTZone comment "!fw4: Handle IoTZone IPv4/IPv6 forward traffic"
		iifname "br-lan.9" jump forward_GuestZone comment "!fw4: Handle GuestZone IPv4/IPv6 forward traffic"
		iifname "zion" jump forward_WGZone comment "!fw4: Handle WGZone IPv4/IPv6 forward traffic"
		iifname { "eth0", "eth1" } jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic"
		iifname "docker0" jump forward_docker comment "!fw4: Handle docker IPv4/IPv6 forward traffic"
		jump handle_reject
	}

	chain output {
		type filter hook output priority filter; policy accept;
		oifname "lo" accept comment "!fw4: Accept traffic towards loopback"
		ct state established,related accept comment "!fw4: Allow outbound established and related flows"
		oifname "br-lan.7" jump output_lan comment "!fw4: Handle lan IPv4/IPv6 output traffic"
		oifname "WireGuard" jump output_WG comment "!fw4: Handle WG IPv4/IPv6 output traffic"
		oifname "br-lan.8" jump output_IoTZone comment "!fw4: Handle IoTZone IPv4/IPv6 output traffic"
		oifname "br-lan.9" jump output_GuestZone comment "!fw4: Handle GuestZone IPv4/IPv6 output traffic"
		oifname "zion" jump output_WGZone comment "!fw4: Handle WGZone IPv4/IPv6 output traffic"
		oifname { "eth0", "eth1" } jump output_wan comment "!fw4: Handle wan IPv4/IPv6 output traffic"
		oifname "docker0" jump output_docker comment "!fw4: Handle docker IPv4/IPv6 output traffic"
	}

	chain prerouting {
		type filter hook prerouting priority filter; policy accept;
		iifname "br-lan.7" jump helper_lan comment "!fw4: Handle lan IPv4/IPv6 helper assignment"
		iifname "WireGuard" jump helper_WG comment "!fw4: Handle WG IPv4/IPv6 helper assignment"
		iifname "br-lan.8" jump helper_IoTZone comment "!fw4: Handle IoTZone IPv4/IPv6 helper assignment"
		iifname "br-lan.9" jump helper_GuestZone comment "!fw4: Handle GuestZone IPv4/IPv6 helper assignment"
		iifname "docker0" jump helper_docker comment "!fw4: Handle docker IPv4/IPv6 helper assignment"
	}

	chain handle_reject {
		meta l4proto tcp reject with tcp reset comment "!fw4: Reject TCP traffic"
		reject comment "!fw4: Reject any other traffic"
	}

	chain syn_flood {
		limit rate 25/second burst 50 packets return comment "!fw4: Accept SYN packets below rate-limit"
		drop comment "!fw4: Drop excess packets"
	}

	chain input_lan {
		jump accept_from_lan
	}

	chain output_lan {
		jump accept_to_lan
	}

	chain forward_lan {
		jump accept_to_wan comment "!fw4: Accept lan to wan forwarding"
		jump accept_to_WG comment "!fw4: Accept lan to WG forwarding"
		jump accept_to_IoTZone comment "!fw4: Accept lan to IoTZone forwarding"
		jump accept_to_WGZone comment "!fw4: Accept lan to WGZone forwarding"
		jump accept_to_lan
	}

	chain helper_lan {
	}

	chain accept_from_lan {
		iifname "br-lan.7" counter packets 3150 bytes 231251 accept comment "!fw4: accept lan IPv4/IPv6 traffic"
	}

	chain accept_to_lan {
		oifname "br-lan.7" counter packets 434 bytes 36576 accept comment "!fw4: accept lan IPv4/IPv6 traffic"
	}

	chain input_wan {
		meta nfproto ipv4 udp dport 68 counter packets 0 bytes 0 accept comment "!fw4: Allow-DHCP-Renew"
		icmp type echo-request counter packets 1 bytes 40 accept comment "!fw4: Allow-Ping"
		meta nfproto ipv4 meta l4proto igmp counter packets 0 bytes 0 accept comment "!fw4: Allow-IGMP"
		meta nfproto ipv6 udp dport 546 counter packets 1 bytes 161 accept comment "!fw4: Allow-DHCPv6"
		ip6 saddr fe80::/10 icmpv6 type . icmpv6 code { mld-listener-query . no-route, mld-listener-report . no-route, mld-listener-done . no-route, mld2-listener-report . no-route } counter packets 0 bytes 0 accept comment "!fw4: Allow-MLD"
		icmpv6 type { destination-unreachable, time-exceeded, echo-request, echo-reply, nd-router-solicit, nd-router-advert } limit rate 1000/second counter packets 2 bytes 272 accept comment "!fw4: Allow-ICMPv6-Input"
		icmpv6 type . icmpv6 code { packet-too-big . no-route, parameter-problem . no-route, nd-neighbor-solicit . no-route, nd-neighbor-advert . no-route, parameter-problem . admin-prohibited } limit rate 1000/second counter packets 45 bytes 3240 accept comment "!fw4: Allow-ICMPv6-Input"
		udp dport 51820 counter packets 0 bytes 0 accept comment "!fw4: WireGuard"
		jump reject_from_wan
	}

	chain output_wan {
		jump accept_to_wan
	}

	chain forward_wan {
		icmpv6 type { destination-unreachable, time-exceeded, echo-request, echo-reply } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Forward"
		icmpv6 type . icmpv6 code { packet-too-big . no-route, parameter-problem . no-route, parameter-problem . admin-prohibited } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Forward"
		meta l4proto esp counter packets 0 bytes 0 jump accept_to_lan comment "!fw4: Allow-IPSec-ESP"
		udp dport 500 counter packets 0 bytes 0 jump accept_to_lan comment "!fw4: Allow-ISAKMP"
		jump reject_to_wan
	}

	chain accept_to_wan {
		oifname { "eth0", "eth1" } counter packets 2101 bytes 233947 accept comment "!fw4: accept wan IPv4/IPv6 traffic"
	}

	chain reject_from_wan {
		iifname { "eth0", "eth1" } counter packets 645 bytes 25841 jump handle_reject comment "!fw4: reject wan IPv4/IPv6 traffic"
	}

	chain reject_to_wan {
		oifname { "eth0", "eth1" } counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject wan IPv4/IPv6 traffic"
	}

	chain input_WG {
		jump accept_from_WG
	}

	chain output_WG {
		jump accept_to_WG
	}

	chain forward_WG {
		jump accept_to_lan comment "!fw4: Accept WG to lan forwarding"
		jump accept_to_wan comment "!fw4: Accept WG to wan forwarding"
		jump accept_to_IoTZone comment "!fw4: Accept WG to IoTZone forwarding"
		jump accept_to_WG
	}

	chain helper_WG {
	}

	chain accept_from_WG {
		iifname "WireGuard" counter packets 0 bytes 0 accept comment "!fw4: accept WG IPv4/IPv6 traffic"
	}

	chain accept_to_WG {
		oifname "WireGuard" counter packets 0 bytes 0 accept comment "!fw4: accept WG IPv4/IPv6 traffic"
	}

	chain input_WGZone {
		jump drop_from_WGZone
	}

	chain output_WGZone {
		jump accept_to_WGZone
	}

	chain forward_WGZone {
		jump accept_to_wan comment "!fw4: Accept WGZone to wan forwarding"
		jump drop_to_WGZone
	}

	chain accept_to_WGZone {
		oifname "zion" counter packets 922 bytes 66180 accept comment "!fw4: accept WGZone IPv4/IPv6 traffic"
	}

	chain drop_from_WGZone {
		iifname "zion" counter packets 721 bytes 103924 drop comment "!fw4: drop WGZone IPv4/IPv6 traffic"
	}

	chain drop_to_WGZone {
		oifname "zion" counter packets 0 bytes 0 drop comment "!fw4: drop WGZone IPv4/IPv6 traffic"
	}

	chain input_docker {
		jump accept_from_docker
	}

	chain output_docker {
		jump accept_to_docker
	}

	chain forward_docker {
		jump accept_to_docker
	}

	chain helper_docker {
	}

	chain accept_from_docker {
		iifname "docker0" counter packets 0 bytes 0 accept comment "!fw4: accept docker IPv4/IPv6 traffic"
	}

	chain accept_to_docker {
		oifname "docker0" counter packets 0 bytes 0 accept comment "!fw4: accept docker IPv4/IPv6 traffic"
	}

	chain input_GuestZone {
		tcp dport { 53, 54, 67, 68 } counter packets 0 bytes 0 accept comment "!fw4: Guest DHCP and DNS"
		udp dport { 53, 54, 67, 68 } counter packets 0 bytes 0 accept comment "!fw4: Guest DHCP and DNS"
		jump accept_from_GuestZone
	}

	chain output_GuestZone {
		jump accept_to_GuestZone
	}

	chain forward_GuestZone {
		jump accept_to_wan comment "!fw4: Accept GuestZone to wan forwarding"
		jump accept_to_GuestZone
	}

	chain helper_GuestZone {
	}

	chain accept_from_GuestZone {
		iifname "br-lan.9" counter packets 0 bytes 0 accept comment "!fw4: accept GuestZone IPv4/IPv6 traffic"
	}

	chain accept_to_GuestZone {
		oifname "br-lan.9" counter packets 0 bytes 0 accept comment "!fw4: accept GuestZone IPv4/IPv6 traffic"
	}

	chain input_IoTZone {
		tcp dport { 53, 54, 67, 68 } counter packets 0 bytes 0 accept comment "!fw4: IoT DHCP and DNS"
		udp dport { 53, 54, 67, 68 } counter packets 0 bytes 0 accept comment "!fw4: IoT DHCP and DNS"
		jump accept_from_IoTZone
	}

	chain output_IoTZone {
		jump accept_to_IoTZone
	}

	chain forward_IoTZone {
		jump reject_to_IoTZone
	}

	chain helper_IoTZone {
	}

	chain accept_from_IoTZone {
		iifname "br-lan.8" counter packets 0 bytes 0 accept comment "!fw4: accept IoTZone IPv4/IPv6 traffic"
	}

	chain accept_to_IoTZone {
		oifname "br-lan.8" counter packets 0 bytes 0 accept comment "!fw4: accept IoTZone IPv4/IPv6 traffic"
	}

	chain reject_to_IoTZone {
		oifname "br-lan.8" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject IoTZone IPv4/IPv6 traffic"
	}

	chain dstnat {
		type nat hook prerouting priority dstnat; policy accept;
	}

	chain srcnat {
		type nat hook postrouting priority srcnat; policy accept;
		oifname "zion" jump srcnat_WGZone comment "!fw4: Handle WGZone IPv4/IPv6 srcnat traffic"
		oifname { "eth0", "eth1" } jump srcnat_wan comment "!fw4: Handle wan IPv4/IPv6 srcnat traffic"
	}

	chain dstnat_lan {
	}

	chain srcnat_lan {
	}

	chain dstnat_wan {
	}

	chain srcnat_wan {
		meta nfproto ipv4 masquerade comment "!fw4: Masquerade IPv4 wan traffic"
		meta nfproto ipv6 masquerade comment "!fw4: Masquerade IPv6 wan traffic"
	}

	chain srcnat_WGZone {
		meta nfproto ipv4 masquerade comment "!fw4: Masquerade IPv4 WGZone traffic"
		meta nfproto ipv6 masquerade comment "!fw4: Masquerade IPv6 WGZone traffic"
	}

	chain raw_prerouting {
		type filter hook prerouting priority raw; policy accept;
	}

	chain raw_output {
		type filter hook output priority raw; policy accept;
	}

	chain mangle_prerouting {
		type filter hook prerouting priority mangle; policy accept;
		jump pbr_prerouting comment "Jump into pbr prerouting chain"
	}

	chain mangle_postrouting {
		type filter hook postrouting priority mangle; policy accept;
		jump pbr_postrouting comment "Jump into pbr postrouting chain"
	}

	chain mangle_input {
		type filter hook input priority mangle; policy accept;
		jump pbr_input comment "Jump into pbr input chain"
	}

	chain mangle_output {
		type route hook output priority mangle; policy accept;
		jump pbr_output comment "Jump into pbr output chain"
	}

	chain mangle_forward {
		type filter hook forward priority mangle; policy accept;
		iifname "zion" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone WGZone IPv4/IPv6 ingress MTU fixing"
		oifname "zion" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone WGZone IPv4/IPv6 egress MTU fixing"
		iifname { "eth0", "eth1" } tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 ingress MTU fixing"
		oifname { "eth0", "eth1" } tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 egress MTU fixing"
		jump pbr_forward comment "Jump into pbr forward chain"
	}

	chain pbr_forward {
	}

	chain pbr_input {
	}

	chain pbr_output {
	}

	chain pbr_prerouting {
	}

	chain pbr_postrouting {
	}
}
table ip nat {
	chain DOCKER {
		iifname "docker0" counter packets 0 bytes 0 return
	}

	chain POSTROUTING {
		type nat hook postrouting priority srcnat; policy accept;
		oifname != "docker0" ip saddr 172.17.0.0/16 counter packets 0 bytes 0 # xt_MASQUERADE
	}

	chain PREROUTING {
		type nat hook prerouting priority dstnat; policy accept;
		# xt_addrtype counter packets 157914 bytes 11248104 jump DOCKER
	}

	chain OUTPUT {
		type nat hook output priority -100; policy accept;
		ip daddr != 127.0.0.0/8 # xt_addrtype counter packets 28047 bytes 2039326 jump DOCKER
	}
}
table ip filter {
	chain DOCKER {
	}

	chain DOCKER-ISOLATION-STAGE-1 {
		iifname "docker0" oifname != "docker0" counter packets 0 bytes 0 jump DOCKER-ISOLATION-STAGE-2
		counter packets 5689199 bytes 9582061123 return
	}

	chain DOCKER-ISOLATION-STAGE-2 {
		oifname "docker0" counter packets 0 bytes 0 drop
		counter packets 0 bytes 0 return
	}

	chain FORWARD {
		type filter hook forward priority filter; policy accept;
		counter packets 5689192 bytes 9582060464 jump DOCKER-USER
		counter packets 5689194 bytes 9582060646 jump DOCKER-ISOLATION-STAGE-1
		oifname "docker0" # xt_conntrack counter packets 0 bytes 0 accept
		oifname "docker0" counter packets 0 bytes 0 jump DOCKER
		iifname "docker0" oifname != "docker0" counter packets 0 bytes 0 accept
		iifname "docker0" oifname "docker0" counter packets 0 bytes 0 accept
	}

	chain DOCKER-USER {
		counter packets 5689192 bytes 9582060464 return
	}
}
# uci show network
network.loopback=interface
network.loopback.device='lo'
network.loopback.proto='static'
network.loopback.ipaddr='127.0.0.1'
network.loopback.netmask='255.0.0.0'
network.globals=globals
network.@device[0]=device
network.@device[0].name='br-lan'
network.@device[0].type='bridge'
network.@device[0].ports='eth2' 'eth3' 'eth4' 'eth5'
network.lan=interface
network.lan.proto='static'
network.lan.netmask='255.255.255.0'
network.lan.ipaddr='192.168.50.1'
network.lan.ip6assign='64'
network.lan.ip6ifaceid='::1'
network.lan.device='br-lan.7'
network.HKT4=interface
network.HKT4.proto='dhcp'
network.HKT4.device='eth0'
network.HKT6=interface
network.HKT6.proto='dhcpv6'
network.HKT6.device='eth0'
network.HKT6.reqaddress='try'
network.HKT6.reqprefix='auto'
network.WireGuard=interface
network.WireGuard.proto='wireguard'
network.WireGuard.private_key=''
network.WireGuard.listen_port='51820'
network.WireGuard.addresses='10.0.0.1/24'
network.@wireguard_WireGuard[0]=wireguard_WireGuard
network.@wireguard_WireGuard[0].description='Xperia1III'
network.@wireguard_WireGuard[0].public_key=''
network.@wireguard_WireGuard[0].private_key=''
network.@wireguard_WireGuard[0].allowed_ips='10.0.0.2/32'
network.@wireguard_WireGuard[1]=wireguard_WireGuard
network.@wireguard_WireGuard[1].description='deskmini@office'
network.@wireguard_WireGuard[1].public_key=''
network.@wireguard_WireGuard[1].private_key=''
network.@wireguard_WireGuard[1].allowed_ips='10.0.0.3/32'
network.HGC4=interface
network.HGC4.proto='dhcp'
network.HGC4.device='eth1'
network.HGC4.metric='10'
network.HGC4.auto='0'
network.@wireguard_WireGuard[2]=wireguard_WireGuard
network.@wireguard_WireGuard[2].description='odyssey@office'
network.@wireguard_WireGuard[2].public_key=''
network.@wireguard_WireGuard[2].private_key=''
network.@wireguard_WireGuard[2].allowed_ips='10.0.0.4/32'
network.docker=interface
network.docker.device='docker0'
network.docker.proto='none'
network.docker.auto='0'
network.@device[1]=device
network.@device[1].type='bridge'
network.@device[1].name='docker0'
network.zion=interface
network.zion.proto='wireguard'
network.zion.private_key=''
network.zion.addresses='10.10.10.2' 'fd78:977c:d34a::2'
network.zion.delegate='0'
network.zion.dns='10.10.10.1' 'fd78:977c:d34a::1'
network.@wireguard_zion[0]=wireguard_zion
network.@wireguard_zion[0].description='zion'
network.@wireguard_zion[0].public_key=''
network.@wireguard_zion[0].endpoint_port='51820'
network.@wireguard_zion[0].persistent_keepalive='25'
network.@wireguard_zion[0].endpoint_host='2001:19f0:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'
network.@wireguard_zion[0].allowed_ips='0.0.0.0/0' '::/0'
network.@bridge-vlan[0]=bridge-vlan
network.@bridge-vlan[0].device='br-lan'
network.@bridge-vlan[0].vlan='7'
network.@bridge-vlan[0].ports='eth2:u*' 'eth3:t' 'eth4:u*' 'eth5:u*'
network.@bridge-vlan[1]=bridge-vlan
network.@bridge-vlan[1].device='br-lan'
network.@bridge-vlan[1].vlan='8'
network.@bridge-vlan[1].ports='eth2:t' 'eth3:t'
network.@bridge-vlan[2]=bridge-vlan
network.@bridge-vlan[2].device='br-lan'
network.@bridge-vlan[2].vlan='9'
network.@bridge-vlan[2].ports='eth2:t' 'eth3:t'
network.IoT=interface
network.IoT.proto='static'
network.IoT.device='br-lan.8'
network.IoT.ipaddr='192.168.58.1'
network.IoT.netmask='255.255.255.0'
network.Guest=interface
network.Guest.proto='static'
network.Guest.device='br-lan.9'
network.Guest.ipaddr='192.168.59.1'
network.Guest.netmask='255.255.255.0'
# uci show firewall
firewall.@defaults[0]=defaults
firewall.@defaults[0].input='ACCEPT'
firewall.@defaults[0].output='ACCEPT'
firewall.@defaults[0].forward='REJECT'
firewall.@defaults[0].synflood_protect='1'
firewall.@zone[0]=zone
firewall.@zone[0].name='lan'
firewall.@zone[0].input='ACCEPT'
firewall.@zone[0].output='ACCEPT'
firewall.@zone[0].forward='ACCEPT'
firewall.@zone[0].network='lan'
firewall.@rule[0]=rule
firewall.@rule[0].name='Allow-DHCP-Renew'
firewall.@rule[0].src='wan'
firewall.@rule[0].proto='udp'
firewall.@rule[0].dest_port='68'
firewall.@rule[0].target='ACCEPT'
firewall.@rule[0].family='ipv4'
firewall.@rule[1]=rule
firewall.@rule[1].name='Allow-Ping'
firewall.@rule[1].src='wan'
firewall.@rule[1].proto='icmp'
firewall.@rule[1].icmp_type='echo-request'
firewall.@rule[1].family='ipv4'
firewall.@rule[1].target='ACCEPT'
firewall.@rule[2]=rule
firewall.@rule[2].name='Allow-IGMP'
firewall.@rule[2].src='wan'
firewall.@rule[2].proto='igmp'
firewall.@rule[2].family='ipv4'
firewall.@rule[2].target='ACCEPT'
firewall.@rule[3]=rule
firewall.@rule[3].name='Allow-DHCPv6'
firewall.@rule[3].src='wan'
firewall.@rule[3].proto='udp'
firewall.@rule[3].dest_port='546'
firewall.@rule[3].family='ipv6'
firewall.@rule[3].target='ACCEPT'
firewall.@rule[4]=rule
firewall.@rule[4].name='Allow-MLD'
firewall.@rule[4].src='wan'
firewall.@rule[4].proto='icmp'
firewall.@rule[4].src_ip='fe80::/10'
firewall.@rule[4].icmp_type='130/0' '131/0' '132/0' '143/0'
firewall.@rule[4].family='ipv6'
firewall.@rule[4].target='ACCEPT'
firewall.@rule[5]=rule
firewall.@rule[5].name='Allow-ICMPv6-Input'
firewall.@rule[5].src='wan'
firewall.@rule[5].proto='icmp'
firewall.@rule[5].icmp_type='echo-request' 'echo-reply' 'destination-unreachable' 'packet-too-big' 'time-exceeded' 'bad-header' 'unknown-header-type' 'router-solicitation' 'neighbour-solicitation' 'router-advertisement' 'neighbour-advertisement'
firewall.@rule[5].limit='1000/sec'
firewall.@rule[5].family='ipv6'
firewall.@rule[5].target='ACCEPT'
firewall.@rule[6]=rule
firewall.@rule[6].name='Allow-ICMPv6-Forward'
firewall.@rule[6].src='wan'
firewall.@rule[6].dest='*'
firewall.@rule[6].proto='icmp'
firewall.@rule[6].icmp_type='echo-request' 'echo-reply' 'destination-unreachable' 'packet-too-big' 'time-exceeded' 'bad-header' 'unknown-header-type'
firewall.@rule[6].limit='1000/sec'
firewall.@rule[6].family='ipv6'
firewall.@rule[6].target='ACCEPT'
firewall.@rule[7]=rule
firewall.@rule[7].name='Allow-IPSec-ESP'
firewall.@rule[7].src='wan'
firewall.@rule[7].dest='lan'
firewall.@rule[7].proto='esp'
firewall.@rule[7].target='ACCEPT'
firewall.@rule[8]=rule
firewall.@rule[8].name='Allow-ISAKMP'
firewall.@rule[8].src='wan'
firewall.@rule[8].dest='lan'
firewall.@rule[8].dest_port='500'
firewall.@rule[8].proto='udp'
firewall.@rule[8].target='ACCEPT'
firewall.@rule[9]=rule
firewall.@rule[9].name='WireGuard'
firewall.@rule[9].proto='udp'
firewall.@rule[9].src='wan'
firewall.@rule[9].dest_port='51820'
firewall.@rule[9].target='ACCEPT'
firewall.pbr=include
firewall.pbr.fw4_compatible='1'
firewall.pbr.type='script'
firewall.pbr.path='/usr/share/pbr/pbr.firewall.include'
firewall.@zone[1]=zone
firewall.@zone[1].name='WG'
firewall.@zone[1].input='ACCEPT'
firewall.@zone[1].output='ACCEPT'
firewall.@zone[1].forward='ACCEPT'
firewall.@zone[1].network='WireGuard'
firewall.@zone[2]=zone
firewall.@zone[2].name='IoTZone'
firewall.@zone[2].input='ACCEPT'
firewall.@zone[2].output='ACCEPT'
firewall.@zone[2].forward='REJECT'
firewall.@zone[2].network='IoT'
firewall.@zone[3]=zone
firewall.@zone[3].name='GuestZone'
firewall.@zone[3].output='ACCEPT'
firewall.@zone[3].network='Guest'
firewall.@zone[3].input='ACCEPT'
firewall.@zone[3].forward='ACCEPT'
firewall.@forwarding[0]=forwarding
firewall.@forwarding[0].src='WG'
firewall.@forwarding[0].dest='lan'
firewall.@forwarding[1]=forwarding
firewall.@forwarding[1].src='WG'
firewall.@forwarding[1].dest='wan'
firewall.@zone[4]=zone
firewall.@zone[4].name='WGZone'
firewall.@zone[4].output='ACCEPT'
firewall.@zone[4].masq='1'
firewall.@zone[4].mtu_fix='1'
firewall.@zone[4].masq6='1'
firewall.@zone[4].input='DROP'
firewall.@zone[4].forward='DROP'
firewall.@zone[4].network='zion'
firewall.@zone[5]=zone
firewall.@zone[5].name='wan'
firewall.@zone[5].input='REJECT'
firewall.@zone[5].output='ACCEPT'
firewall.@zone[5].forward='REJECT'
firewall.@zone[5].masq='1'
firewall.@zone[5].mtu_fix='1'
firewall.@zone[5].masq6='1'
firewall.@zone[5].network='HKT4' 'HKT6' 'HGC4'
firewall.docker=zone
firewall.docker.input='ACCEPT'
firewall.docker.output='ACCEPT'
firewall.docker.forward='ACCEPT'
firewall.docker.name='docker'
firewall.docker.network='docker'
firewall.@forwarding[2]=forwarding
firewall.@forwarding[2].src='lan'
firewall.@forwarding[2].dest='wan'
firewall.@forwarding[3]=forwarding
firewall.@forwarding[3].src='lan'
firewall.@forwarding[3].dest='WG'
firewall.@forwarding[4]=forwarding
firewall.@forwarding[4].src='lan'
firewall.@forwarding[4].dest='IoTZone'
firewall.@forwarding[5]=forwarding
firewall.@forwarding[5].src='GuestZone'
firewall.@forwarding[5].dest='wan'
firewall.@rule[10]=rule
firewall.@rule[10].name='Guest DHCP and DNS'
firewall.@rule[10].src='GuestZone'
firewall.@rule[10].target='ACCEPT'
firewall.@rule[10].dest_port='53 54 67 68'
firewall.@forwarding[6]=forwarding
firewall.@forwarding[6].src='lan'
firewall.@forwarding[6].dest='WGZone'
firewall.@forwarding[7]=forwarding
firewall.@forwarding[7].src='WGZone'
firewall.@forwarding[7].dest='wan'
firewall.@rule[11]=rule
firewall.@rule[11].name='IoT DHCP and DNS'
firewall.@rule[11].src='IoTZone'
firewall.@rule[11].target='ACCEPT'
firewall.@rule[11].dest_port='53 54 67 68'
firewall.@forwarding[8]=forwarding
firewall.@forwarding[8].src='WG'
firewall.@forwarding[8].dest='IoTZone'

I have just tried running the commands mentioned on the last reply of this thread:

And it suddenly works...

This seems to be getting way too complicated. I have done this with a Linode VPS without loading multiple routing tables or poking around in iptables/nftables.

First, forget ULAs. Take a /64 out from your Vultr /56 and assign it (prefix::1/64) to your local LAN. In the VPS make this /64 an allowed_ip for your house peer so that it routes back into the Wireguard tunnel.

It's probably important to assign link-locals to the Wireguard tunnel ends. Wireguard does not do this automatically. Use one of the machine MACs to form them. It certainly helps in testing to be able to ping through the tunnel using the link-local.

Thanks for your suggestion.

May you instruct me how to "take a /64 and assign it to my LAN" please?
This is the IPv6 from Vultr:

Thanks.

Looking further it looks like Vultr only gives customers a single /64. Which really isn't very useful if you want to set up a VPN server with IPv6 support. As I said I use Linode and they will issue /56 or /48 on request.

Now setting 0.0.0.0/0 and ::/0 with "route allowed IPs" on WireGuard interface works.
However, unchecked "route allowed IPs" on the WireGuard interface, but managed with PBR does not work.
0.0.0.0/0 routes via WireGuard server, but ::/0 does not.

I have just created an instance on Linode, but it is also /64

$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.104.85.6  netmask 255.255.255.0  broadcast 172.104.85.255
        inet6 2400:8902::f03c:93ff:fed6:b0a6  prefixlen 64  scopeid 0x0<global>
        inet6 fe80::f03c:93ff:fed6:b0a6  prefixlen 64  scopeid 0x20<link>
        ether f2:3c:93:d6:b0:a6  txqueuelen 1000  (Ethernet)
        RX packets 6410  bytes 67071404 (67.0 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5069  bytes 807698 (807.6 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Isn't /64 enough?

I have asked Vultr they said they cannot provide an extra /56.

I have just created a new instance on Linode, added an extra /56 on web interface, and installed OpenWRT 22.03.5 on the instance.

There is only a /64 address on the WAN6 (DHCPv6). How to configure it so as to get the /56 identified?

Thanks.

ifstatus wan6 should show the prefix (picked up by dhcpv6). Then you can create a wireguard instance and assign part of the prefix to it, and it will forward to your client(s) based on further dividing it into allowed_ips. That needs to be done manually.

The point of a prefix from a separate range is that the router itself won't hold any IPs on that prefix. It forwards them from routers downstream.

it seems to be no /56:

root@OpenWrt:~# ifstatus wan6
{
	"up": true,
	"pending": false,
	"available": true,
	"autostart": true,
	"dynamic": false,
	"uptime": 840,
	"l3_device": "eth0",
	"proto": "dhcpv6",
	"device": "eth0",
	"metric": 0,
	"dns_metric": 0,
	"delegation": true,
	"ipv4-address": [
		
	],
	"ipv6-address": [
		{
			"address": "2400:8902::f03c:93ff:fea3:d613",
			"mask": 64,
			"preferred": 27,
			"valid": 87
		}
	],
	"ipv6-prefix": [
		
	],
	"ipv6-prefix-assignment": [
		
	],
	"route": [
		{
			"target": "::",
			"mask": 0,
			"nexthop": "fe80::1",
			"metric": 512,
			"valid": 60,
			"source": "2400:8902::f03c:93ff:fea3:d613/64"
		}
	],
	"dns-server": [
		
	],
	"dns-search": [
		
	],
	"neighbors": [
		
	],
	"inactive": {
		"ipv4-address": [
			
		],
		"ipv6-address": [
			
		],
		"route": [
			
		],
		"dns-server": [
			
		],
		"dns-search": [
			
		],
		"neighbors": [
			
		]
	},
	"data": {
		
	}
}