OpenWrt 22.03 VPN setup per Wifi Channel

I've 2 VPN accounts running in openwrt which I want to make available via 2 different wifi channels (named so it is clear which country is selected). I followed the manual of the VPN provider (proton), but my requirement/setup is different :wink:

The VPN accounts work and are configured, but I can use some help with the setup how to forward a connected wifi device to the correct VPN country. (Device is connected to Wifi_US which needs to be forwarded to the VPN US connection.

Any idea if this is possible ?

You need to do Policy Based Routing and you have 3 options:

  1. mwan3 package
  2. pbr package
  3. a set of rules/routes for each internet connection.

The pbr would be the simplest way.

Thanks for the help so far. Need to dive into this much more.

I think I can overcome the service errors, because this device is configured as 192.168.1.253.
But I still need to look into how I can forward a connected wifi device through this particular VPN tunnel.
For the moment I just want to forward any traffic connected to a wifi-channel

My best guess for the moment is that under Interface Configuration, Network some things have to change also...

Any end-user guide some where ?

Create one network per SSID. Then use the PBR to drive the packets ingress the interface to the appropriate vpn.

I think I did the 1st step SSID->newly created network vpn_us. No idea how to proceed because I can't find these networks in BPR but the same also applies to the 2 up-and running VPN connections..

Errors are in red rectangle. So I do not know, whether it is NFT problem.

Are there default gateways from the VPNs? If they are using non-standard names, you can define them with list supported_interface 'Proton1'

Had some other Linux activities on the agenda. Back to the topic. Thanks for the help again. What in the heck is a NFT problem :wink: ?

I also use Proton VPN for one of my VPN providers too.

After setting up the wireguard interface and verifying the handshake, I made a new firewall zone for it and literally mimicked it with the wan zone settings I had and checked both masquerading and mss clamping.

Then, I setup a new network interface (in this case it is my guest network interface) with its own ip subnet. I use pbr and assign the guest network to the proton vpn interface.

After that, I setup a new ssid for the guest network and VOILA! Magic happens! Any guest that is on my guest network is automatically tunneled thru the Proton VPN.

EDIT: I failed to mention, the guest network has its own firewall zone and I allowed forward to destination zone to WAN and the Proton VPN zones. I set input as reject, allow as accept, and forward as reject. I kept masquerading and mss clamping unchecked.

EDIT2: To secure the network, I added a firewall traffic rule that rejects any attempt to access the router and my modem.

1 Like

I should mention, that I was getting DNS leaks using Proton VPN, so I installed stubby package and kept its default settings. Stubby works excellent right out of the box and uses Cloudflare’s DNS servers.

Thanks for the feedback so far.. I see some challenges ahead because I'm new in these details of network configuration...

As far as pbr is concerned, you have to type out the name of the network interface you want on the left, include it’s full ip subnet in the next field (e.g. 192.168.1.1/24) and then select which gateway you want to assign it to on the right, in which case, choose the name of your wireguard interface.

Everything I mentioned can be done in luci.

Good luck!

EDIT: which reminds me - make sure to uncheck “use default gateway” in your network interface settings that you’re assigning to the VPN. This can conflict with your route assignment in pbr. YMMV obviously and you won’t need to create a firewall traffic rule to prohibit access to your router and modem or install stubby. It is recommended to do a dns leak test when on a VPN irregardless to ensure its security.

Should be 192.168.1.0/24

PBR uses its own routing tables, so it won't conflict. What you can do is use different metric for the gateway in all interfaces which connect to the internet. Use a low value, e.g 10, for the wan and 20, 30, ... for the VPN interfaces.

1 Like

After reading all your help, I'm wondering if I miss something while setting this up. My ProtonVPN uses the openvpn package (and I don't have a wireguard interface installed).

100% sure that Proton VPN is working because I did an IP check via the cmdline and my openwrt box had an foreign IP. (I did not check any routing at that time).

I collected some details of my configs

openwrt 22.03

#/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 'fd83:****:****::/48'

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

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option netmask '255.255.255.0'
	option ip6assign '60'
	option ipaddr '192.168.1.253'
	option gateway '192.168.1.1'
	list dns '192.168.1.1'

config device
	option name 'wan'
	option macaddr '5c:02:14:31:**:**'

config interface 'wan'
	option device 'wan'
	option proto 'dhcp'
	option type 'bridge'

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

config device
	option name 'ztyouu2ouh'

#/etc/config/openvpn

config openvpn 'custom_config'
	option config '/etc/openvpn/my-vpn.conf'

config openvpn 'sample_server'
	option port '1194'
	option proto 'udp'
	option dev 'tun'
	option ca '/etc/openvpn/ca.crt'
	option cert '/etc/openvpn/server.crt'
	option key '/etc/openvpn/server.key'
	option dh '/etc/openvpn/dh2048.pem'
	option server '10.8.0.0 255.255.255.0'
	option ifconfig_pool_persist '/tmp/ipp.txt'
	option keepalive '10 120'
	option persist_key '1'
	option persist_tun '1'
	option user 'nobody'
	option status '/tmp/openvpn-status.log'
	option verb '3'

config openvpn 'sample_client'
	option client '1'
	option dev 'tun'
	option proto 'udp'
	list remote 'my_server_1 1194'
	option resolv_retry 'infinite'
	option nobind '1'
	option persist_key '1'
	option persist_tun '1'
	option user 'nobody'
	option ca '/etc/openvpn/ca.crt'
	option cert '/etc/openvpn/client.crt'
	option key '/etc/openvpn/client.key'
	option verb '3'

config openvpn 'ProtonNL'
	option config '/etc/openvpn/ProtonNL.ovpn'

config openvpn 'ProtonUS'
	option config '/etc/openvpn/ProtonUS.ovpn'
	option enabled '1'

#/etc/openvpn/ProtonUS.ovpn

client
dev tun
proto udp

remote 45.89.173.194 5060
remote 45.89.173.194 80
remote 45.89.173.194 51820
remote 45.89.173.194 1194
remote 45.89.173.194 4569

remote-random
resolv-retry infinite
nobind



auth SHA512
verb 3

setenv CLIENT_CERT 0
tun-mtu 1500
tun-mtu-extra 32
mssfix 1450
persist-key
persist-tun

reneg-sec 0

remote-cert-tls server
auth-user-pass /etc/openvpn/ProtonUS.auth
pull
fast-io


<ca>
-----BEGIN CERTIFICATE-----
MIIFozCCA4ugAwIBAgIBATANBgkqhkiG9w0BAQ0FADBAMQswCQYDVQQGEwJDSDEV

DK/yPwECUcPgHIeXiRjHnJt0Zcm23O2Q3RphpU+1SO3XixsXpOVOYP6rJIXW9bMZ
A1gTTlpi7A==
-----END CERTIFICATE-----
</ca>

key-direction 1
<tls-auth>
# 2048 bit OpenVPN static key
-----BEGIN OpenVPN Static key V1-----
6acef03f62675b4b1bbd03e53b187727

16672ea16c012664f8a9f11255518deb
-----END OpenVPN Static key V1-----
</tls-auth>

Still wondering about which part is missing here (missing default gateways from the VPNs?) before making a next step in routing.

Please run the following commands (copy-paste the whole block) and paste the output here, using the "Preformatted text </> " button:
grafik
Remember to redact passwords, MAC addresses and any public IP addresses you may have

ubus call system board; \
uci export network; uci export wireless; \
uci export dhcp; uci export firewall; uci export pbr; \
ip -4 addr ; ip -4 ro li tab all ; ip -4 ru; \
ls -l  /etc/resolv.* /tmp/resolv.* /tmp/resolv.*/* ; head -n -0 /etc/resolv.* /tmp/resolv.* /tmp/resolv.*/*
root@OpenWrt_AX3200_1:~# ubus call system board; \
> uci export network; uci export wireless; \
> uci export dhcp; uci export firewall; uci export pbr; \
ip -4 addr ; ip -4 ro li tab all ; ip -4 ru; \
> ip -4 addr ; ip -4 ro li tab all ; ip -4 ru; \
> ls -l  /etc/resolv.* /tmp/resolv.* /tmp/resolv.*/* ; head -n -0 /etc/resolv.* /tmp/resolv.* /tmp/resolv.*/*
{
        "kernel": "5.10.134",
        "hostname": "OpenWrt_AX3200_1",
        "system": "ARMv8 Processor rev 4",
        "model": "Xiaomi Redmi Router AX6S",
        "board_name": "xiaomi,redmi-router-ax6s",
        "rootfs_type": "squashfs",
        "release": {
                "distribution": "OpenWrt",
                "version": "22.03.0-rc6",
                "revision": "r19590-042d558536",
                "target": "mediatek/mt7622",
                "description": "OpenWrt 22.03.0-rc6 r19590-042d558536"
        }
}
package 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 'fd83:****:****::/48'

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

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option netmask '255.255.255.0'
        option ip6assign '60'
        option ipaddr '192.168.1.253'
        option gateway '192.168.1.1'
        list dns '192.168.1.1'

config device
        option name 'wan'
        option macaddr '**:02:**:31:d0:**'

config interface 'wan'
        option device 'wan'
        option proto 'dhcp'
        option type 'bridge'

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

config device
        option name 'ztyouu2ouh'

package wireless

config wifi-device 'radio0'
        option type 'mac80211'
        option path 'platform/18000000.wmac'
        option band '2g'
        option cell_density '0'
        option channel '10'
        option country 'BE'
        option htmode 'HT20'
        option txpower '17'
        option disabled '1'

config wifi-iface 'default_radio0'
        option device 'radio0'
        option mode 'ap'
        option key 'blaablaa'
        option encryption 'sae-mixed'
        option ssid 'Wifi Home US2'
        option disabled '1'

config wifi-device 'radio1'
        option type 'mac80211'
        option path '1a143000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0'
        option band '5g'
        option cell_density '0'
        option channel '48'
        option txpower '17'
        option disabled '1'

config wifi-iface 'default_radio1'
        option device 'radio1'
        option mode 'ap'
        option encryption 'sae-mixed'
        option ssid 'Wifi Home US'
        option key 'blaablaa'
        option disabled '1'

package dhcp

config dnsmasq
        option domainneeded '1'
        option boguspriv '1'
        option filterwin2k '0'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local '/lan/'
        option domain 'lan'
        option expandhosts '1'
        option nonegcache '0'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
        option nonwildcard '1'
        option localservice '1'
        option ednspacket_max '1232'

config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv4 'server'
        option ignore '1'

config dhcp 'wan'
        option interface 'wan'
        option ignore '1'

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

package 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'
        list network 'wan'

config zone
        option name 'wan'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option masq '1'
        option mtu_fix '1'
        list network 'wan6'
        list device 'br-lan'
        list device 'wlan0'

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'

package pbr

config pbr 'config'
        option verbosity '2'
        option strict_enforcement '1'
        option resolver_set 'none'
        option ipv6_enabled '0'
        list ignored_interface 'vpnserver'
        list ignored_interface 'wgserver'
        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'
        option enabled '1'

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

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

config policy
        option name 'Plex/Emby Local Server'
        option src_port '8096 8920 32400'
        option enabled '0'
        option interface 'lan'

config policy
        option name 'Plex/Emby Remote Servers'
        option dest_addr 'plex.tv my.plexapp.com emby.media app.emby.media tv.emby.media'
        option enabled '0'
        option interface 'lan'

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
23: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    inet 192.168.1.253/24 brd 192.168.1.255 scope global br-lan
       valid_lft forever preferred_lft forever
183: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
    inet 10.20.0.5/16 scope global tun0
       valid_lft forever preferred_lft forever
0.0.0.0/1 via 10.20.0.1 dev tun0 table pbr_lan
default via 192.168.1.1 dev br-lan table pbr_lan
10.20.0.0/16 dev tun0 table pbr_lan proto kernel scope link src 10.20.0.5
45.89.173.194 via 192.168.1.1 dev br-lan table pbr_lan
128.0.0.0/1 via 10.20.0.1 dev tun0 table pbr_lan
192.168.1.0/24 dev br-lan table pbr_lan proto kernel scope link src 192.168.1.253
0.0.0.0/1 via 10.20.0.1 dev tun0 table pbr_wan
unreachable default table pbr_wan
10.20.0.0/16 dev tun0 table pbr_wan proto kernel scope link src 10.20.0.5
45.89.173.194 via 192.168.1.1 dev br-lan table pbr_wan
128.0.0.0/1 via 10.20.0.1 dev tun0 table pbr_wan
192.168.1.0/24 dev br-lan table pbr_wan proto kernel scope link src 192.168.1.253
0.0.0.0/1 via 10.20.0.1 dev tun0
default via 192.168.1.1 dev br-lan proto static
10.20.0.0/16 dev tun0 proto kernel scope link src 10.20.0.5
45.89.173.194 via 192.168.1.1 dev br-lan
128.0.0.0/1 via 10.20.0.1 dev tun0
192.168.1.0/24 dev br-lan proto kernel scope link src 192.168.1.253
broadcast 10.20.0.0 dev tun0 table local proto kernel scope link src 10.20.0.5
local 10.20.0.5 dev tun0 table local proto kernel scope host src 10.20.0.5
broadcast 10.20.255.255 dev tun0 table local proto kernel scope link src 10.20.0.5
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 192.168.1.0 dev br-lan table local proto kernel scope link src 192.168.1.253
local 192.168.1.253 dev br-lan table local proto kernel scope host src 192.168.1.253
broadcast 192.168.1.255 dev br-lan table local proto kernel scope link src 192.168.1.253
0:      from all lookup local
30000:  from all fwmark 0x10000/0xff0000 lookup pbr_lan
30001:  from all fwmark 0x20000/0xff0000 lookup pbr_wan
32766:  from all lookup main
32767:  from all lookup default
lrwxrwxrwx    1 root     root            16 Jul 31 17:12 /etc/resolv.conf -> /tmp/resolv.conf
-rw-r--r--    1 root     root            47 Dec  8 13:57 /tmp/resolv.conf
-rw-r--r--    1 root     root            39 Dec  8 13:56 /tmp/resolv.conf.d/resolv.conf.auto

/tmp/resolv.conf.d:
-rw-r--r--    1 root     root            39 Dec  8 13:56 resolv.conf.auto
==> /etc/resolv.conf <==
search lan
nameserver 127.0.0.1
nameserver ::1

==> /tmp/resolv.conf <==
search lan
nameserver 127.0.0.1
nameserver ::1

==> /tmp/resolv.conf.d <==
head: /tmp/resolv.conf.d: I/O error

==> /tmp/resolv.conf.d/resolv.conf.auto <==
# Interface lan
nameserver 192.168.1.1
root@OpenWrt_AX3200_1:~#

Upgrade to stable version.

There is no other interface except lan to serve customer traffic.
You need to create the additional interfaces and connect them to the wifi SSID. Then you can configure it on the PBR to use a VPN as uplink.

Upgraded to Firmware Version OpenWrt 22.03.1 r19777-2853b6d652 / LuCI openwrt-22.03 branch git-22.339.35241-4ca7a8d. Updated all packages also. No clue how to create additional interfaces in Openwrt but will start looking into it. Always nice to learn something new

Network - Interfaces - Scroll to the bottom of the page "Add new Interface"
image

Give it a name and leave the others as you see. Then fill in the IP address and the mask.
Then go to Network - Wireless, add a new wifi and assign it to the new interface.

Ok, I managed to set up an interface with this help, linked it to a wifi adapter and even managed to set op a dhcp server to assign addresses to connecting clients. IP has been set to another subnet 192.168.2.1.
When connecting to wifi with a phone an 192.168.2.x ip address is assigned and a connection is there. Due to the lack of routing, there is no internet or vpn yet.

Trying to setup PBR (192.168.2.x - BPR - VPN) but run into issues and it doesn't work yet. Will continue to read more

1 Like