Alternate SSID just for VPN traffic?

2 Likes

That looks promising, thanks!

I've got some reading to do...

1 Like

Hey, it looks like you are trying the same thing that I want to do. Could you please share parts of your configuration in case you are successfully?

Same here :wink: :joy:

I hoped I could do this withour pbr by separation in different firewall zones without forwarding. I think the issue is, that they still share one routing table. So I tried static routing rules based on interface but that did not work either. I do not know enough about routing stuff to do this by try and error or on my own :frowning: . PBR seems like a big thing to me which is why I ask for configuration examples.

Currently I do have an ugly workaround: I do use two cheap openwrt routers (GL-AR150) in a row. The first one does the ISP uplink and WiFi for this, the second does the wireguard VPN and WiFi for that. I dislike it, but it works for the moment and my limited time :grimacing: . It is not really travel friendly, which is the main reason for me to get this to work.

I think there's enough examples on the wiki covering typical scenarios.
If your problem persists, open a separate topic with your configs.

Success!

I took a bit of a convoluted path with plenty of trial and error but it is up and running now as I wanted. PBR is indeed the key. For the benefit of others who wish to do the same I will attempt to describe the steps I took - the ones that worked - here:

Part 1 - local VPN network with WiFi

  1. Go to the User Guide page on setting up a Guest network:
    https://openwrt.org/docs/guide-user/network/wifi/guestwifi/guest-wlan
    I see no reason why this couldn't be done on the GUI if you know what you're doing, but the guide does it on the command line so might as well go with that.

  2. Follow the steps as given there, substituting 'vpn' for 'guest' anywhere you see it in the code, for example the first line becomes

uci -q delete network.vpn_dev

and the fourth line becomes

uci set network.vpn_dev.name="br-vpn"

...and so forth.

  1. When you get to the ipaddr don't use the one in the guide change it to 192.168.4.1 (or any other range you haven't used elsewhere)

  2. When you get to step 4 - Firewall skip all the lines referencing dns since we don't want dns queries being handled by the local resolver, we want them to go out the VPN pipe along with everything else.

  3. When you have completed this page, test that you can connect to the vpn wifi network, and that you can reach websites by ip address since dns won't be working. As an example ipleak.net is currently resolving to 95.85.16.212 so try that. It should show your traffic is still coming from your ISP - that is okay for the moment - the important part is the new vpn network and the new vpn wifi are able to pass data.

Part 2 - Wireguard

  1. Go to the Wireguard Basics page in the User Guide https://openwrt.org/docs/guide-user/services/vpn/wireguard/basics and follow the process to install the software. Skip step 4 for now - we'll get to that next.

  2. Now we're going to follow the Wireguard Client page https://openwrt.org/docs/guide-user/services/vpn/wireguard/client I tried doing this part in the GUI and my connection didn't work so I had to go back and do it by command line as is shown here. I don't know why it would be any different but that was my experience.

  3. For step 1 - Preparation we are going to have to make some changes to the contents of the variables based on what information your VPN service provider (VSP) has given you, and set up some additional variables that aren't shown in the guide but are used in later steps.

VPN_IF="wg"

calling this interface "vpn" the same as the network we just set up is confusing so I changed mine to "wg" for clarity.

VPN_SERV="the public address your VSP told you to connect to, sometimes called the endpoint"
VPN_PORT="51820"

unless your VSP gave you a different number i.e. 443 use that instead

VPN_ADDR="the interface address given by your VSP"

My VSP did not provide any IPv6 details so I skipped the VPN_ADDR6

VPN_KEY="the *private* key string from your VSP"
VPN_PUB="the *public* key string from your VSP"
VPN_PSK="the *preshared* key string from your VSP"

You can check that you've set the contents of any variable correctly by using, for example

echo $VPN_SERV

  1. Now proceed through steps 2 (maybe not needed? I did it anyway) 3 and begin 4. Note that if your connection to your openWRT device gets interrupted or you get logged out for any reason you will have to repeat the variable settings above as they are not carried over from one user session to the next. Also note that if, like me, your VSP did not supply any IPv6 details you can skip any lines that reference IPADDR6.

  2. When, in step 4, you get to the line

uci set network.wgserver.route_allowed_ips="1"

change it to

uci set network.wgserver.route_allowed_ips="0"

Setting a 1 here makes the Wireguard interface the default route for the entire device which is not what we want. Setting a 0 ensures that all traffic will continue to go via your ISP except for what we route via Wireguard using PBR.

  1. The notes about race condition and dynamic connection I think are not applicable to this configuration since we haven't changed the default route.

  2. Skip the testing at the end of the page for now since traceroute will go out the default route anyway. To check whether your VPN is up, go to the Status > WireGuard page in the GUI and see if the Latest Handshake field reports a recent date/timestamp. There may also be a small amount of Data Received/Data Transmitted. If your connection appears to be down, go to Network > Interfaces and try clicking Restart on the wg interface. If that doesn't work, you will need to troubleshoot your Wiregard settings.

  3. Optionally, consider going to Edit on wg and unticking the Bring up on boot tickbox. You will have to manually Restart the wg interface if your openWRT device reboots but it seems to do it a whole lot faster for me with this box unticked, and I don't necessarily want to run my VPN connection 24/7/365 either.

  4. (maybe not needed?) Edit your wg interface, on the Advanced Settings tab, and add the dns server your VSP gave you under Use custom DNS servers. If your VSP did not give you a dns server address try entering one of the common public DNS servers such as 1.1.1.1 (cloudflare) or 8.8.8.8 (google)

  5. While in Network > Interfaces, Edit the vpn interface we created in part 1. Go to DHCP Server > Advanced Settings and in the DHCP-Options field add 6,ip of your VSP dns server. Or if they didn't provide one then, as above, use the ip of a public server i.e.

6,1.1.1.1

Not really sure if DHCP is supposed to be distributing the custom DNS server we set in 14. but it doesn't seem to. Setting it as an option here does work, however.

Part 3 - setting up Policy Based Routing and tying it together.

Believe it or not, Part 2 was the hard part. The User Guide page on PBR https://openwrt.org/docs/guide-user/network/routing/pbr mentions a PBR app and PBR with netifd. Initially I wasted a lot of time trying to get netifd working but the setup script in the Guide didn't seem to do much (it did execute - I checked) it turns out the app is the way to go, at least on openWRT v 23.05 and later. If you are trying to do this on an older version I get the feeling it is going to be significantly more complicated for you.

  1. Install the pbr and luci-app-pbr packages, then run
uci set pbr.config.enabled="1"
uci commit pbr
/etc/init.d/pbr restart

To enable PBR, and to activate the GUI log out/log in again. You should get a new Services > Policy Routing menu when it is active.

  1. At the top of the Policy Based Routing - Status page you should see your two gateways: wan/eth0.2/ip from your ISP, with a tick beside it indicating it remains the default route, and wg/ip from your VSP, with no tick beside it.

  2. A little further down the page in the Policies section there are two example policies that are not enabled. Click the green Add button beneath them.

  3. Give you new policy a name like "VPN to WG" set the Local addresses/devices field to the same ip we set on the vpn network way back in step 3 i.e. 192.168.4.1/24, set the Interface field to wg and hit Save.

  4. Join a device to the vpn wifi network and open ipleak.net It should indicate your address is that of your VSP. It should also indicate your DNS address is coming from your VSP, or the public dns server if you configured it that way. At the very least your dns should not be coming from your ISP.

Thassit! Job done!

3 Likes

Bonus Part 4 - wired device connection to VPN

To add wired devices to your vpn network:

  1. Go to Network > Switch and click the green Add VLAN button. Make a note of the number i.e. 3

  2. Set the CPU (eth1) port to tagged on the new VLAN

  3. Choose a LAN port with no link and set it to 'off' on all other VLANS and 'untagged' on your new VLAN

  4. Go to Network > Interfaces > Devices tab and Configure the br-vpn device.

  5. Set Bridge ports to eth1.number of your new VLAN i.e. eth1.3

  6. Connect your wired device to the chosen port, and open ipleak.net to confirm it is connected via your VPN connection.

3 Likes

Thank you for your detailed guide. I will test it tomorrow and will try IPv6 as well as IPv4. I am curious if prefix delegation will work the way I want it to...

I do have some experience with wireguard as server at home and connecting by android into it. I assume you did not restart the device after setting up the wireguard interface by GUI? I experienced that all config did not work before a restart of the router. Even if I hit "save & apply", restarted the wireguard interface and network - I was not able to connect with android. When I restarted the router I was able without any changes in the configuartion. Weird, but ok for me.

I think that might be the reason, why I failed before... Thank you for pointing that out.

I will test it tomorrow and will try IPv6 as well as IPv4. I am curious if prefix delegation will work the way I want it to...

Ultimately I would like to get IPv6 working as well. Unfortunately my ISP's v6 implementation is horrible and my VSP did not provide any v6 settings at all. I did note that the PBR app only supports v4 by default, you have to turn on v6 support, and I think maybe it can only be configured from the command line (or am I thinking of something else? I have read so many openWRT docs over the last week everything is blurring together...) It seems to be a work in progress. Please post your results I would like to see how (if) it works.

I do have some experience with wireguard as server at home and connecting by android into it. I assume you did not restart the device after setting up the wireguard interface by GUI? I experienced that all config did not work before a restart of the router. Even if I hit "save & apply", restarted the wireguard interface and network - I was not able to connect with android. When I restarted the router I was able without any changes in the configuartion. Weird, but ok for me.

Likewise I found bringing up the tunnel to be quite hairy. I do not recall whether I rebooted the router or not but it's possible I did. However as it actually transpired I found even restarting the network service, which theoretically is all you have to do, got stuck in a loop of stopping/restarting. Fortunately it was a slow enough loop that I was able to get in and stop the wg interface as well as turn off the Bring up on boot setting (step 13) and after that it seemed much better behaved, stable, and possibly quicker. The good news is if you haven't set the tunnel as your default route it doesn't cut off your internet access like it did to me the first time I tried it. It just seems to respond to a manual start so much better but I don't understand why that would be the case. I did implement the race condition fix but it didn't seem to help.

I think that might be the reason, why I failed before... Thank you for pointing that out.

I found that buried in the PBR readme file which is not part of the openWRT User Guide. Worth a read-through. There are links to it on the PBR app GUI page. As it transpired I did not install it that way, I had to install nano and go and manually edit the config file but I think if you set it up like that in the first place it should be a smoother process.

Good luck!

You can try using IPv6 from a tunnel broker:

Yes! I did it! That was quite hard work in try and error mode, because that was new to me. As I promised I want to share the results. My goal was to configure a little travel router smaller than pocket size to be my vpn gateway for WiFi. It should get a wired or wifi connection as upstream to the internet and provide two WiFi access points:

  1. "WiFi-normal": just an access point providing normal lan as if you are connected by wire to the lan port. Useful for dealing with captive portals in hotels.
  2. "WiFi-VPN": basically all of this topic. This one provides WiFi and routes the traffic to a wireguard "client" interface. In my case I have a wireguard server at home.

I wanted to have both: IPv4 and IPv6, as I have some devices running IPv6 only. To cut it short: pbr did not work with IPv6 for me. I had to turn off IPv6 support and use pbr only for IPv4. For IPv6 I had to create an own routing rule. I found this hint: https://docs.openwrt.melmac.net/pbr/#a-word-about-ipv6-routing

So, pbr did not work. Because we set
uci set network.wgserver.route_allowed_ips="0"
there was no IPv6 route and IPv6 failed while IPv4 was working. So set up this route manually for the wireguard interface.

network.@route6[-1]=route6
network.@route6[-1].interface='wg'
network.@route6[1].target='::/0'

After this I ran into the next issue. My ISP at home does not give me a static IPv6 prefix. Instead of this it changes from time to time. Unfortunately, wireguard needs static addresses. To work around this I am using NAT66 and configure wireguard with ULAs instead of GUAs. This was a problem because the DHCPv6 server, which is runnig on "WiFi-VPN", does not set a default gateway in its router advertisements for IPv6 in that case. You need to force it to set a ULA instead of a GUA.
uci set dhcp.vpn.ra_default="1"
It took me hours to realize that because I did not know this. From there on it was easy. I wrote a configuation script based on your work. It will

  • do all of your work above
  • set up both WiFi based on your posts
  • set up DHCP (dnsmasq) for both IPv4 and IPv6
  • set up additional firewall rules for DHCPv6, ICMP and ICMPv6 (look here)
  • set ip6class to both lan and vpn interfaces. This is important. The reason is that vpn will get an IPv6 prefix from wireguard while lan will (possibly) get an IPv6 prefix from wan6. This makes sure both dont mix up and ruin the routing.
  • bonus points for a cronjob, which starts wireguard watchdog. I need this because of the dynamic prefix of my ISP.

Lets say that my wireguard home server has the addresses 192.168.224.1/21 and fdaa:0:0:aab0::1/60. My travel router will get the addresses 192.168.228.1/24 and fdaa:0:0:aab8::1/63. WiFi-VPN will serve 192.168.200.1/24 and fdaa:0:0:aab9::1/64.

configuration script
#--- WiFi ---
uci -q delete network.vpn_dev
uci set network.vpn_dev="device"
uci set network.vpn_dev.type="bridge"
uci set network.vpn_dev.name="br-vpn"
uci -q delete network.vpn
uci set network.vpn="interface"
uci set network.vpn.proto="static"
uci set network.vpn.device="br-vpn"
uci set network.vpn.ipaddr="192.168.200.1"
uci set network.vpn.netmask="255.255.255.0"
uci set network.vpn.ip6assign="64"
uci set network.vpn.peerdns="0"
uci set network.vpn.dns="'192.168.224.1' 'fdaa:0:0:aab0::1'" # DNS server
uci set network.vpn.ip6class="wg"

uci set network.lan.ip6class="wan6"
uci commit network
/etc/init.d/network restart

WIFI_PSK1="INSERT_PASSWORD_HERE_FOR_WIFI_VPN"
WIFI_PSK2="INSERT_PASSWORD_HERE_FOR_WIFI_NORMAL"
WIFI_DEV="$(uci get wireless.@wifi-iface[0].device)"
[ -z "$WIFI_DEV" ] && WIFI_DEV="radio0"
uci set wireless.${WIFI_DEV}.disabled="0"
uci -q delete wireless.vpn
uci set wireless.vpn="wifi-iface"
uci set wireless.vpn.device="${WIFI_DEV}"
uci set wireless.vpn.mode="ap"
uci set wireless.vpn.network="vpn"
uci set wireless.vpn.ssid="Bergwerk"
uci set wireless.vpn.encryption="psk2"
uci set wireless.vpn.key="${WIFI_PSK1}"
uci set wireless.vpn.disabled="0"

uci -q delete wireless.lan
uci set wireless.lan="wifi-iface"
uci set wireless.lan.device="${WIFI_DEV}"
uci set wireless.lan.mode="ap"
uci set wireless.lan.network="lan"
uci set wireless.lan.ssid="Tagebau"
uci set wireless.lan.encryption="psk2"
uci set wireless.lan.key="${WIFI_PSK2}"
uci set wireless.lan.disabled="0"

uci commit wireless
wifi reload

uci -q delete dhcp.vpn
#uci del_list dhcp.@dnsmasq[0].interface=br-vpn
#uci add_list dhcp.@dnsmasq[0].interface=br-vpn
uci set dhcp.vpn="dhcp"
uci set dhcp.vpn.interface="vpn"
uci set dhcp.vpn.start="100"
uci set dhcp.vpn.limit="150"
uci set dhcp.vpn.leasetime="1h"
uci set dhcp.vpn.netmask="255.255.255.0"
uci set dhcp.vpn.dhcpv6="server"
uci set dhcp.vpn.ra="server"
uci set dhcp.vpn.dhcp_option='6,192.168.224.1'
uci set dhcp.vpn.dns='fdaa:0:0:aab0::1'
uci set dhcp.vpn.ra_default="1"
uci commit dhcp
/etc/init.d/dnsmasq restart

uci -q delete firewall.vpn
uci set firewall.vpn="zone"
uci set firewall.vpn.name="vpn"
uci set firewall.vpn.network="vpn"
uci set firewall.vpn.input="REJECT"
uci set firewall.vpn.output="ACCEPT"
uci set firewall.vpn.forward="REJECT"
uci -q delete firewall.vpn_wan
uci set firewall.vpn_wan="forwarding"
uci set firewall.vpn_wan.src="vpn"
uci set firewall.vpn_wan.dest="wan"
uci -q delete firewall.vpn_dhcp
uci set firewall.vpn_dhcp="rule"
uci set firewall.vpn_dhcp.name="Allow-DHCP-VPN"
uci set firewall.vpn_dhcp.src="vpn"
uci set firewall.vpn_dhcp.dest_port="67"
uci set firewall.vpn_dhcp.proto="udp"
uci set firewall.vpn_dhcp.family="ipv4"
uci set firewall.vpn_dhcp.target="ACCEPT"
uci -q delete firewall.vpn_dhcp6
uci set firewall.vpn_dhcp6="rule"
uci set firewall.vpn_dhcp6.name="Allow-DHCPv6-VPN"
uci set firewall.vpn_dhcp6.src="vpn"
uci set firewall.vpn_dhcp6.dest_port="547"
uci set firewall.vpn_dhcp6.proto="udp"
uci set firewall.vpn_dhcp6.family="ipv6"
uci set firewall.vpn_dhcp6.target="ACCEPT"

uci rename firewall.@rule[1]="icmp"
uci rename firewall.@rule[5]="icmp6"
uci set firewall.icmp.src="*"
uci set firewall.icmp6.src="*"

uci commit firewall
/etc/init.d/firewall restart

#--- Wireguard ---

VPN_IF="wg"
VPN_SERV="" # address or IP of wireguard remote server
VPN_PORT="" # port of wireguard remote server
VPN_ADDR="192.168.228.1/24"
VPN_ADDR6="fdaa:0:0:aab8::1/64"
VPN_ADDR6_PREFIX="fdaa:0:0:aab9::/64"
VPN_DNS="'192.168.224.1' 'fdaa:0:0:aab0::1'"

#### CHANGE THAT
VPN_KEY="" #client/local private key
VPN_PSK="" #preshared key
VPN_PUB="" #server/remote public key
#### CHANGE THAT

uci rename firewall.@zone[0]="lan"
uci rename firewall.@zone[1]="wan"
uci del_list firewall.wan.network="${VPN_IF}"
uci add_list firewall.wan.network="${VPN_IF}"
uci commit firewall
/etc/init.d/firewall restart

uci -q delete network.${VPN_IF}
uci set network.${VPN_IF}="interface"
uci set network.${VPN_IF}.proto="wireguard"
uci set network.${VPN_IF}.private_key="${VPN_KEY}"
uci set network.${VPN_IF}.dns="${VPN_DNS}"
uci set network.${VPN_IF}.ip6prefix="${VPN_ADDR6_PREFIX}"
uci add_list network.${VPN_IF}.addresses="${VPN_ADDR}"
uci add_list network.${VPN_IF}.addresses="${VPN_ADDR6}"
 
# Add VPN peers
uci -q delete network.wgserver
uci set network.wgserver="wireguard_${VPN_IF}"
uci set network.wgserver.public_key="${VPN_PUB}"
uci set network.wgserver.preshared_key="${VPN_PSK}"
uci set network.wgserver.endpoint_host="${VPN_SERV}"
uci set network.wgserver.endpoint_port="${VPN_PORT}"
uci set network.wgserver.route_allowed_ips="0"
uci set network.wgserver.persistent_keepalive="25"
uci add_list network.wgserver.allowed_ips="0.0.0.0/0"
uci add_list network.wgserver.allowed_ips="::/0"
uci commit network
/etc/init.d/network restart

#--- pbr ---

uci set pbr.config.enabled="1"
uci commit pbr
/etc/init.d/pbr restart
uci set pbr.config.ipv6_enabled='0'
uci set pbr.@policy[-1]=policy
uci set pbr.@policy[-1].name='VPN to WG'
uci set pbr.@policy[-1].src_addr='192.168.200.1/24'
uci set pbr.@policy[-1].interface='wg'
uci commit pbr
/etc/init.d/pbr restart

network.@route6[-1]=route6
network.@route6[-1].interface='wg'
network.@route6[1].target='::/0'

#--- bonus, watchdog for dynamic connections ---

cat << "EOF" >> /etc/crontabs/root
45 7 * * 1 sleep 130 && touch /etc/banner && reboot
* * * * * /usr/bin/wireguard_watchdog
EOF
uci set system.@system[0].cronloglevel="9"
uci commit system
/etc/init.d/cron restart

I apologize, that I do explain everything in the same detailed way you did. I am too tired and it took me way too long to get this working. However, I would like to answer questions if you have any.

Thanks again!

2 Likes

That's fantastic! Glad I was able to help. Does your configuration route all IPv6 traffic over the wg interface? It sort of looks like that to my limited understanding.

The routing rule does apply to the wg interface, not globally. So all interfaces which are allowed to forward to wg will route ipv6 through the wireguard VPN. Currently, only interfaces in the VPN firewall zone can do that. All others cannot.

We don't have a forwarding for lan, so all wired connections or clients of WiFi-normal cannot use this route. However, the router might get an GUA (global IPv6) and a prefix bigger than /64 (lets say /56) from wan6, the normal internet upstream. In this case he can delegate a prefix to lan (lets say /60). Now lan does have its own global route and can access the internet with IPv6, but different than the VPN.

Because we set ip6class

the vpn interface cannot obtain an additional IPv6 from the main upstream and it's forced to use the configured one and route though wireguard. Elseweise it could have two IPv6 and decide randomly which one it works use. We certainly don't want that.

See here:

@squeeze2 : I played a little with routes & rules, based on some hints of vgaetera . It turned out that the package pbr is an overkill for our situation. Just one route and one rule are enough for a policy based routing configuration which does the same. Two routes/rules for IP4 & IP6 and two more rules for an additional kill switch:

In this snippet I have used your IPv4 suggestion, it is at the end of /etc/config/network

config route
	option interface 'wg'
	option target '0.0.0.0/0'
	option table '1'
	option metric '5'

config route6
	option interface 'wg'
	option target '::/0'
	option table '1'
	option metric '5'

config rule
	option in 'vpn'
	option src '192.168.4.1/24'
	option lookup '1'

config rule6
	option in 'vpn'
	option src 'ddaa:0:0:aab4::/63'
	option lookup '1'

config rule
	option in 'vpn'
	option action 'prohibit'
	option priority '32000'

config rule6
	option in 'vpn'
	option action 'prohibit'
	option priority '32000'

I also debuged my config script. Now it is tested and works for me to set up everything from an untouched freshly installed router. It is here, this time I used my IP address plan:

New config script
WIFI_VPN_NAME="WIFI-VPN"
WIFI_VPN_NORMAL="WIFI-ISP"
WIFI_PSK="WIFI-PASSWORD"
WIFI_IP="192.168.200.1"
WIFI_IP_SUBNET="/24"
WIFI_IP_NETMASK=$(ipcalc.sh "${WIFI_IP}${WIFI_IP_SUBNET}" | grep -i "netmask" | sed -En 's/^[^=]*=([0-9.]+)$/\1/p')
[ -z "$WIFI_IP_NETMASK" ] && WIFI_IP_NETMASK="255.255.255.0"
VPN_KEY="" #client/local private key
VPN_PSK="" #preshared key
VPN_PUB="" #server/remote public key
VPN_DNS_IPV4="192.168.224.1"
VPN_DNS_IPV6="ddaa:0:0:aab0::1"
VPN_SERV="" # address or IP of wireguard remote server
VPN_PORT="" # port of wireguard remote server
VPN_ADDR="192.168.224.1/24"
VPN_ADDR6="ddaa:0:0:aab2::1/64"
VPN_ADDR6_PREFIX="ddaa:0:0:aab3::/64"


#--- system ---
uci set system.@system[0].hostname="Ar150Van"
uci set system.@system[0].zonename="Europe/Berlin"
uci set system.@system[0].timezone="CET-1CEST,M3.5.0,M10.5.0/3"
uci commit system
ntpd -q -p openwrt.pool.ntp.org

#--- WiFi ---
uci -q delete network.vpn_dev
uci set network.vpn_dev="device"
uci set network.vpn_dev.type="bridge"
uci set network.vpn_dev.name="br-vpn"
uci -q delete network.vpn
uci set network.vpn="interface"
uci set network.vpn.proto="static"
uci set network.vpn.device="br-vpn"
uci set network.vpn.ipaddr="${WIFI_IP}"
uci set network.vpn.netmask="${WIFI_IP_NETMASK}"
uci set network.vpn.ip6assign="64"
uci set network.vpn.peerdns="0"
uci add_list network.vpn.dns="${VPN_DNS_IPV4}"
uci add_list network.vpn.dns="${VPN_DNS_IPV6}"
uci set network.vpn.ip6class="wg"

uci set network.lan.ip6class="wan6"
uci commit network
/etc/init.d/network restart

WIFI_DEV="$(uci get wireless.@wifi-iface[0].device)"
[ -z "$WIFI_DEV" ] && WIFI_DEV="radio0"
uci set wireless.${WIFI_DEV}.disabled="0"
uci -q delete wireless.vpn
uci set wireless.vpn="wifi-iface"
uci set wireless.vpn.device="${WIFI_DEV}"
uci set wireless.vpn.mode="ap"
uci set wireless.vpn.network="vpn"
uci set wireless.vpn.ssid="${WIFI_VPN_NAME}"
uci set wireless.vpn.encryption="psk2"
uci set wireless.vpn.key="${WIFI_PSK}"
uci set wireless.vpn.disabled="0"

uci -q delete wireless.lan
uci set wireless.lan="wifi-iface"
uci set wireless.lan.device="${WIFI_DEV}"
uci set wireless.lan.mode="ap"
uci set wireless.lan.network="lan"
uci set wireless.lan.ssid="${WIFI_VPN_NORMAL}"
uci set wireless.lan.encryption="psk2"
uci set wireless.lan.key="${WIFI_PSK}"
uci set wireless.lan.disabled="0"

uci commit wireless
wifi reload
uci -q delete wireless.default_radio0
uci commit wireless
wifi reload


uci -q delete dhcp.vpn
#uci del_list dhcp.@dnsmasq[0].interface=br-vpn
#uci add_list dhcp.@dnsmasq[0].interface=br-vpn
uci set dhcp.vpn="dhcp"
uci set dhcp.vpn.interface="vpn"
uci set dhcp.vpn.start="100"
uci set dhcp.vpn.limit="150"
uci set dhcp.vpn.leasetime="1h"
uci set dhcp.vpn.netmask="255.255.255.0"
uci set dhcp.vpn.dhcpv6="server"
uci set dhcp.vpn.ra="server"
uci add_list dhcp.vpn.dhcp_option="6,${VPN_DNS_IPV4}"
uci add_list dhcp.vpn.dns="${VPN_DNS_IPV6}"
uci set dhcp.vpn.ra_default="1"
uci commit dhcp
/etc/init.d/dnsmasq restart

uci -q delete firewall.vpn
uci set firewall.vpn="zone"
uci set firewall.vpn.name="vpn"
uci set firewall.vpn.network="vpn"
uci set firewall.vpn.input="REJECT"
uci set firewall.vpn.output="ACCEPT"
uci set firewall.vpn.forward="REJECT"
uci -q delete firewall.vpn_wan
uci set firewall.vpn_wan="forwarding"
uci set firewall.vpn_wan.src="vpn"
uci set firewall.vpn_wan.dest="wan"
uci -q delete firewall.vpn_dhcp
uci set firewall.vpn_dhcp="rule"
uci set firewall.vpn_dhcp.name="Allow-DHCP-VPN"
uci set firewall.vpn_dhcp.src="vpn"
uci set firewall.vpn_dhcp.dest_port="67"
uci set firewall.vpn_dhcp.proto="udp"
uci set firewall.vpn_dhcp.family="ipv4"
uci set firewall.vpn_dhcp.target="ACCEPT"
uci -q delete firewall.vpn_dhcp6
uci set firewall.vpn_dhcp6="rule"
uci set firewall.vpn_dhcp6.name="Allow-DHCPv6-VPN"
uci set firewall.vpn_dhcp6.src="vpn"
uci set firewall.vpn_dhcp6.dest_port="547"
uci set firewall.vpn_dhcp6.proto="udp"
uci set firewall.vpn_dhcp6.family="ipv6"
uci set firewall.vpn_dhcp6.target="ACCEPT"

uci rename firewall.@rule[1]="icmp"
uci rename firewall.@rule[5]="icmp6"
uci set firewall.icmp.src="*"
uci set firewall.icmp6.src="*"

uci commit firewall
/etc/init.d/firewall restart

#--- Wireguard ---

VPN_IF="wg"
VPN_DNS="'${VPN_DNS_IPV4}' '${VPN_DNS_IPV6}'"

uci rename firewall.@zone[0]="lan"
uci rename firewall.@zone[1]="wan"
uci del_list firewall.wan.network="${VPN_IF}"
uci add_list firewall.wan.network="${VPN_IF}"
uci commit firewall
/etc/init.d/firewall restart

uci -q delete network.${VPN_IF}
uci set network.${VPN_IF}="interface"
uci set network.${VPN_IF}.proto="wireguard"
uci set network.${VPN_IF}.private_key="${VPN_KEY}"
uci set network.${VPN_IF}.dns="${VPN_DNS}"
uci set network.${VPN_IF}.ip6prefix="${VPN_ADDR6_PREFIX}"
uci add_list network.${VPN_IF}.addresses="${VPN_ADDR}"
uci add_list network.${VPN_IF}.addresses="${VPN_ADDR6}"
 
# Add VPN peers
uci -q delete network.wgserver
uci set network.wgserver="wireguard_${VPN_IF}"
uci set network.wgserver.public_key="${VPN_PUB}"
uci set network.wgserver.preshared_key="${VPN_PSK}"
uci set network.wgserver.endpoint_host="${VPN_SERV}"
uci set network.wgserver.endpoint_port="${VPN_PORT}"
uci set network.wgserver.route_allowed_ips="0"
uci set network.wgserver.persistent_keepalive="25"
uci add_list network.wgserver.allowed_ips="0.0.0.0/0"
uci add_list network.wgserver.allowed_ips="::/0"
uci commit network
/etc/init.d/network restart

#--- rules & routes based pbr

uci -q delete network.vpn4_tunnel_route
uci set network.vpn4_tunnel_route="route"
uci set network.vpn4_tunnel_route.interface="wg"
uci set network.vpn4_tunnel_route.target="0.0.0.0/0"
uci set network.vpn4_tunnel_route.table="1"
uci set network.vpn4_tunnel_route.metric="5"
uci -q delete network.vpn6_tunnel_route
uci set network.vpn6_tunnel_route="route6"
uci set network.vpn6_tunnel_route.interface="wg"
uci set network.vpn6_tunnel_route.target="::/0"
uci set network.vpn6_tunnel_route.table="1"
uci set network.vpn6_tunnel_route.metric="5"

uci -q delete network.vpn4_tunnel_rule
uci set network.vpn4_tunnel_rule="rule"
uci set network.vpn4_tunnel_rule.in="vpn"
uci set network.vpn4_tunnel_rule.src="${WIFI_IP}${WIFI_IP_SUBNET}"
uci set network.vpn4_tunnel_rule.lookup="1"
uci -q delete network.vpn6_tunnel_rule
uci set network.vpn6_tunnel_rule="rule6"
uci set network.vpn6_tunnel_rule.in="vpn"
HELPER_VAR="${VPN_ADDR6::-2}$((${VPN_ADDR6:(-2)}-1))" #make "ddaa:0:0:aab8::1/64" --> "ddaa:0:0:aab8::1/63"
uci set network.vpn6_tunnel_rule.src="${HELPER_VAR}"
uci set network.vpn6_tunnel_rule.lookup="1"

for IPV in 4 6
do
uci set network.vpn.ip${IPV}table="1"
uci -q delete network.vpn_ks${IPV%4}
uci set network.vpn_ks${IPV%4}="rule${IPV%4}"
uci set network.vpn_ks${IPV%4}.in="vpn"
uci set network.vpn_ks${IPV%4}.action="prohibit"
uci set network.vpn_ks${IPV%4}.priority="32000"
done

uci commit network
/etc/init.d/network restart

#--- bonus, watchdog for dynamic connections ---

cat << "EOF" >> /etc/crontabs/root
#0 7 * * * sleep 130 && touch /etc/banner && reboot
0,10,20,30,40,50 * * * * /usr/bin/wireguard_watchdog

EOF
uci set system.@system[0].cronloglevel="9"
uci commit system
/etc/init.d/cron restart

Keep in mind that extra default routes and custom metrics are redundant.
A better way to implement PBR is assigning interfaces to separate routing tables:
https://openwrt.org/docs/guide-user/network/routing/pbr_netifd

I think I did this in the script at the very end in the same loop I do set the kill switch:

for IPV in 4 6
do
uci set network.vpn.ip${IPV}table="1"
uci -q delete network.vpn_ks${IPV%4}
uci set network.vpn_ks${IPV%4}="rule${IPV%4}"
uci set network.vpn_ks${IPV%4}.in="vpn"
uci set network.vpn_ks${IPV%4}.action="prohibit"
uci set network.vpn_ks${IPV%4}.priority="32000"
done

That way, I can delete something else? Metrics?

uci set network.wgserver.route_allowed_ips="1"
for IPV in 4 6
do
uci set network.lan.ip${IPV}table="1"
uci set network.vpn.ip${IPV}table="2"
uci set network.wg.ip${IPV}table="3"
uci set network.vpn${IPV}_tunnel_rule.lookup="3"
uci set network.vpn${IPV}_tunnel_rule.priority="30000"
uci -q delete network.vpn${IPV}_tunnel_route
done
uci commit network
/etc/init.d/network restart
1 Like

Ok, thank you very much. For now that leaves me with some headache. I thought I understood everything. Routing tables and their correct usage are quite new to me...

That sets new default routes, so wan isn't default anymore. Right? I prefer to keep it the default beause it avoids race contitions with the wireguard tunnel. I am just asking because we do not give wan a own table.

That implies we keep the rules network.vpn${IPV}_tunnel_rule and therefore also the routes? I have used table 1 in those. And Why do we need uci set network.wgserver.route_allowed_ips="1" then? The main goal is to route all traffic of vpn thought the wg interface. lan should stay untouched and route to wan.

Puh. I think I need some sleep and some testing the next days.

Yes.

No, the routes are redundant, remove them.

It creates the routes automatically in the custom table.

Yes, I understand that.

It is default, except for custom rules overriding the main table.
Assuming that we keep the WAN in the main table.

The routes for tunnel endpoints are always created in the main table.
You can move WAN to a separate table, but it requires a default routing rule.
It must be prioritized after the main table due to the tunnel endpoints.

Ok, I think I got it. Thank you for the explanation.

That saved me a lot of time trying to figure it out all by myself!

1 Like

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