Thanks a lot for your reply. What you’re doing here looks really solid. Unfortunately, with my gear and the current OpenWrt version I’ve had many issues — it was extremely unstable. With better hardware (something that can actually handle this setup properly) I could definitely make use of your work, and your explanation helped me understand the direction you’re taking. In my case, my device simply can’t create proper bridges, and that’s why everything ended up unstable. Anyway, I’ll get better hardware in the future and try again. Thanks a lot for your time.
Στις Τρίτη 3 Μαρτίου 2026 στις 05:09:31 π.μ. EET, ο/η Alexander Gomez mail@forum.openwrt.org έγραψε:
Someone replied to your post.
| Alexander Gomez alexandrglm
March 3 |
Hey, sir,
I know this isn't the exact answer you're after, but I’m actually building a net app to manage multiple WireGuard connections (both client and server) across multiple interfaces (wg-autoconf).
It's still being staged out for the last before submitting a PR to the OpenWrt package sources, and get it publicly available.
That said, I can give you the general gist of how to get your routing sorted, whether you’re using WireGuard or any other VPN that relies on creating an interface:
-
First off, you set the interface and tweak the protocol settings (be it OVPN or WireGuard) until everything's looking solid, right?
-
Then, you bring the interface 'up' and check it’s actually working and reachable (with a traceroute -i [interface] google.com, a ping -I [interface] ..., or curl --interface ...., etc ...).
-
So... finally, you need to route the tunnelled interface to the one you want. This means messing with Firewall/DHCP configs .... going straight through nft (fw3 / fw4) to get your SNAT, chains, rt_tables, forwarding and etc... properly aligned.
The main idea is keeping the dest. as interfaces separate.
E.g.:
If your device has 3 different WLAN cards and you want a different VPN for each SSID, start by creating three separate interfaces, detached from the br-lan (or whatever bridge lan you got).
...
config device
option name 'br-lan'
option type 'bridge'
list ports 'lan1'
list ports 'lan2
config interface 'lan-zone-bridge-or-whatever-you-want''
option device 'br-lan'
option proto 'static'
option ipaddr '192.168.1.50'
option netmask '255.255.255.0'
config interface 'lan3'
option device 'lan3'
option proto 'static'
option ipaddr '192.168.100.1'
...
config interface 'lan4'
option device 'lan4'
option proto 'static'
option ipaddr '192.168.200.1'
....
config interface 'wifi-1'
option device 'phy-ap0'
option proto 'static'
option ipaddr '192.168.2.1'
option netmask '255.255.255.0'
option ip6assign '60'
option type 'bridge'
config interface 'wifi-2'
option device 'phy-ap1'
.....
config interface 'wifi-3'
option device 'phy-ap2
...'
...
In this example, you get LAN1 & LAN2 in a bridge (br-lan) device, then... LAN3, LAN4 and each WLAN interface separated, with its own configuration.
Then, setup and drive up your different VPN clients interfaces.
For each interface that needs DHCP (at least every destination interface), add a section in /etc/config/dhcp and commit it:
...
config dhcp 'wifi-3'
option interface 'wifi-3'
option start '100'
option limit '150'
option leasetime '12h'
option dhcpv4 'server'
config dhcp 'tun0'
option interface 'tun0'
option ignore '1'
...
Lastly, configure your Firewall/DHCP and the post-tweaks for nft/rt_tables (using fw3 for older builds, or fw4 for modern builds). In general terms, this means. E.g:
- Adding FW zones, mandatory forwards and rules by editing and committing
/etc/config/firewall:
..
config zone
option name 'vpn_tun0'
option network 'tun0'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'ACCEPT'
option masq '1'
option mtu_fix '1'
config zone
option name 'wifi3_zone'
option network 'wifi-3'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'ACCEPT'
config forwarding
option src 'wifi3_zone'
option dest 'vpn_tun0'
config forwarding
option src 'vpn_tun0'
option dest 'wifi3_zone'
...
- Adding Route Tables for each VPN-Interface/DEST-Interface pair:
echo "200 vpn_tun0" >> /etc/iproute2/rt_tables
echo "210 _vpn_tun0_wifi3" >> /etc/iproute2/rt_tables
ip rule add from 192.168.4.0/24 to 192.168.4.0/24 lookup main priority 1500
ip rule add from 192.168.4.0/24 lookup _vpn_tun0_wifi3 priority 1501
ip rule add to 192.168.4.0/24 lookup _vpn_tun0_wifi3 priority 1503
ip route add 192.168.4.0/24 dev phy-ap2 table _vpn_tun0_wifi3
ip route add default dev tun0 table _vpn_tun0_wifi3
-
At this point, rt_tables and the 90% of firewall configs are done, but you should add the final nftables "tweaks" to make everything work.
Due to how fw4 (OpenWrt's nftables frontend) handles WireGuard interfaces, you'll likely need to manually add a few rules that fw4 doesn't generate automatically. E.g:
-
Missing jumps in input/output chains for each tun interface/table:
nft add rule inet fw4 input iifname "tun0" jump input_tun0
nft add rule inet fw4 output oifname "tun0" jump output_tun0
-
Counter accepts rules for the rt_table that routes the tun' interface with the dest. interface:
nft add rule inet fw4 accept_from_tun0 counter accept
nft add rule inet fw4 accept_to_tun0 counter accept
-
The srcnat jump's for traffic exiting via the tunneled interface:
nft add rule inet fw4 srcnat oifname "tun0" jump srcnat_tun0
-
Fixes for forward chain ordering (critical for return traffic properly tagged/in the tun0, not the wan):
nft add rule inet fw4 forward_tun0 jump accept_from_tun0
Nftables configs can also be persisted using the automatic include directories, so that every time you run commit or reload the firewall, these last "jump/snat/chain tweaks" are automatically reapplied without manual intervention.