OpenWRT on GL-AR150 + Guest Wifi over OpenVPN (2023)
Written by pmd - - no comments⚫ Installed last available OpenWRT on AR150
root@192.168.1.1's password:
BusyBox v1.35.0 (2023-04-27 20:28:15 UTC) built-in shell (ash)
_______ ________ __
| |.-----.-----.-----.| | | |.----.| |_
| - || _ | -__| || | | || _|| _|
|_______|| __|_____|__|__||________||__| |____|
|__| W I R E L E S S F R E E D O M
-----------------------------------------------------
OpenWrt 22.03.5, r20134-5f15225c1e
-----------------------------------------------------
#
Source: [OpenWrt Wiki] GL.iNet GL-AR150
⚫ Expected configuration
The router will get access to internet by connecting to a Wifi network available around using wlan0 interface.
The router will spread two independant Wifi network :
- First Wifi will connect users on br-lan interface
br-lan users will have access to internet through wlan0 - Second Wifi will connect users on br-lan2 interface
br-lan2 users will have access to internet exclusively through tun0 interface (VPN)
⚫ Configuring Guest Wifi
Source: Guest Wi-Fi using LuCI (I didn't need to touch anything in Network > Firewall > Traffic Rules)
⚫ Installing OpenVPN and set first configuration
⚪ Installing OpenVPN
# opkg install openvpn-openssl ip-full luci-app-openvpn
Source: OpenWrt setup with NordVPN | NordVPN support
⚪ Configuring NordVPN
Download a NordVPN configuration : Server recommended by NordVPN | NordVPN
Go to VPN > OpenVPN
Under the “OVPN configuration file upload” section name the VPN connection in the “Instance name” field (I named it “nordvpn”.) After that, click on the Browse button, locate the downloaded server file and click Upload.
In the “OpenVPN instances” section, click the Edit button next to the instance you have just created.
Illustration #01 about previous steps
In the lower field, enter your NordVPN service credential username and password into separate lines.
password
Now, copy the path to the credentials file that is given right above the field containing the credentials and paste it next to the “auth-user-pass” line in the “Config file” section above. It should look like this: auth-user-pass /etc/openvpn/nordvpn.auth
Click on the Save button at the bottom.
Illustration #02 about previous steps
Go to Network > Interfaces
Select the Add new interface… button and name it “nordvpntun”.
Click on the “Protocol” dropdown menu and choose “Unmanaged”.
In the “Interface” dropdown, enter the name “tun0” at the bottom -- custom -- field and press the Enter key.
Click the “Create interface” and Save buttons.
Go to Network > Firewall
Click the “Add” button and adjust it as follows:
- Name it “vpnfirewall”;
- Set the “Input” option as “Reject”;
- Leave “Output” as “Accept” and “Forward” as “Reject”;
- Check the “Masquerading” option;
- Check the “MSS clamping” option;
- From the “Covered Networks” dropdown menu choose “nordvpntun”;
- In the “Allow forward from source zones” dropdown menu, choose “lan”;
- Click the “Save” button.
In the “Zones” section, find the zone named “lan”, and click on the “Edit” button.
In the “Allow forward to destination zones” dropdown check the “nordvpntun” entry.
Go to Network > DHCP and DNS
In the “General Settings” tab, find the “DNS forwardings” option and enter DNS addresses there. Addresses could be:
- NordVPN DNS : 103.86.96.100 and 103.86.99.100 | Source 1
- OpenDNS : 208.67.222.222 and 208.67.220.220 | Source 1, 2
- Google DNS : 8.8.8.8 and 8.8.4.4 | Source 1
Go to the “Resolv and Hosts Files” tab, check the “Ignore resolve file” checkbox, and click the “Save & Apply” button.
You can verify which DNS server you are actually requested data to by using ths website : DNS leak test
Go to VPN > OpenVPN
In the “OpenVPN instances” section, check the “Enable” option next to the NordVPN option in the list, and click the “Save & Apply” button.
See Illustration #01 for final setup.
Now all you internet paquets should go through the VPN link.
⚪ Creating route-up.sh to chose which paquets should go through VPN
In your OpenVPN configuration file, you need to add these both lines:
- route-noexec
=> so OpenVPN will not modify main routing table itself - route-up /etc/openvpn/route-up.sh
=> so OpenVPN will execute this file where we will add some rules and routes for vpn routing table
# /etc/openvpn/route-up.sh
# chmod +x /etc/openvpn/route-up.sh
# https://openvpn.net/community-resources/reference-manual-for-openvpn-2-4/#scripting-and-environmental-variables
# This website to know what environmental-variables are available.
# Inspiration :
# https://github.com/soehest/openvpn/blob/master/route-up.sh
# https://medium.com/@ingamedeo/openvpn-splittunneling-on-openwrt-e4302a1a4e12
echo "$dev : $ifconfig_local -> $ifconfig_remote gw: $route_vpn_gateway" | logger
# Checks to see if there is an IP routing table named 'vpn', create if missing
if [ $(cat /etc/iproute2/rt_tables | grep vpn | wc -l) -eq 0 ]; then
echo "100 vpn" >> /etc/iproute2/rt_tables
echo "IP routing table named 'vpn' created" | logger
fi
# Remove any previous rules in the 'vpn' routing table
#/sbin/ip rule | sed -n 's/.*\(from[ \t]*[0-9\.]*\).*vpn/\1/p' | while read RULE
/sbin/ip rule | grep vpn | sed -n 's@.*\(from[ \t]*[0-9\./]*\)@\1@p' | while read RULE
do
echo "remove old rule: /sbin/ip rule del ${RULE}" | logger
/sbin/ip rule del ${RULE}
done
# Remove any previous routes in the 'vpn' routing table
echo "remove old routes: /sbin/ip route flush table vpn" | logger
/sbin/ip route flush table vpn
# Search route for traffic coming from 192.168.2.0/24 in table 'vpn'
# (unicast: This rule type simple causes the kernel to refer to the
# specified routing table in the search for a route.)
echo "adding rule: /sbin/ip rule add from 192.168.2.0/24 table vpn" | logger
/sbin/ip rule add from 192.168.2.0/24 table vpn
# Search route for traffic going to 192.168.2.0/24 in table 'vpn'
echo "adding rule: /sbin/ip rule add to 192.168.2.0/24 table vpn" | logger
/sbin/ip rule add to 192.168.2.0/24 table vpn
# Use 'vpn' table as default for tun0
echo "adding route: /sbin/ip route add table vpn default dev ${dev}" | logger
/sbin/ip route add table vpn default dev ${dev}
# Route traffic from/to 192.168.2.0/24 on br-lan2 using the 'vpn'.
# table. (192.168.2.1 is the source address for outgoing packets)
echo "adding route: /sbin/ip route add 192.168.2.0/24 dev br-lan2 proto kernel scope link src 192.168.2.1 table vpn" | logger
/sbin/ip route add 192.168.2.0/24 dev br-lan2 proto kernel scope link src 192.168.2.1 table vpn
# Logging default rules
echo "/sbin/ip rule -----------" | logger
/sbin/ip rule | logger
# Logging default route table
echo "/sbin/ip route show -----------" | logger
/sbin/ip route show | logger
# Logging vpn route table
echo "/sbin/ip route show table vpn ----------" | logger
/sbin/ip route show table vpn | logger
Thanks to logger, we can check what happened during execution of route-up.sh when OpenVPN connected to the server:
⚫ Updating NordVPN configuration
I made this shell script to easily update the configuration using recommended server by NordVPN :
# chmod +x /etc/openvpn/update_conf.sh
OpenVpnConfFile='/etc/openvpn/nordvpn.ovpn'
# recuperation du serveur recommandé par NordVPN
RecommendedServer=$(curl --silent --interface tun0 'https://nordvpn.com/wp-admin/admin-ajax.php?action=servers_recommendations' | jq --raw-output '.[0].hostname' | awk -F. '{print $1}')
echo "Recommended server by NordVPN:"
echo $RecommendedServer
echo
# récupération de la configuration
echo "Trying to get server configuration https://downloads.nordcdn.com/configs/files/ovpn_udp/servers/$RecommendedServer.nordvpn.com.udp.ovpn ..."
DownloadingServerConfFile=$(curl --silent --interface tun0 --write-out "%{http_code}" -o $OpenVpnConfFile https://downloads.nordcdn.com/configs/files/ovpn_udp/servers/$RecommendedServer.nordvpn.com.udp.ovpn)
if [ $DownloadingServerConfFile -eq 200 ]
then
echo "OK $DownloadingServerConfFile"
echo
else
echo "NOK $DownloadingServerConfFile"
exit
fi
# modification de la configuration pour ajouter password + route no-exec + route-up
echo "Trying to modify $OpenVpnConfFile configuration file..."
echo "$OpenVpnConfFile before modification:"
echo "----------"
echo "[...]"
sed -n '/auth-user-pass/{p;n;p}' $OpenVpnConfFile
echo "[...]"
echo "----------"
echo "Trying to modify $OpenVpnConfFile configuration file..."
sed -i 's@auth-user-pass@auth-user-pass /etc/openvpn/nordvpn.auth\nauth-nocache\nroute-noexec\nroute-up /etc/openvpn/route-up.sh@g' $OpenVpnConfFile
echo "$OpenVpnConfFile after modification:"
echo "----------"
echo "[...]"
sed -n '/auth-user-pass/{p;n;p;n;p;n;p;n;p}' $OpenVpnConfFile
echo "[...]"
echo "----------"
echo
# redemarrage de openvpn
echo "Trying to restart OpenVPN..."
/etc/init.d/openvpn restart
sleep 1
echo -n "Waiting for tun0 interface..."
while [ $(ifconfig | grep -c tun0) == 0 ]
do
echo -n "."
sleep 1
done
echo
t=$(ping -c 10 -I tun0 8.8.8.8 | grep -o -E '[0-9]+ packets r' | grep -o -E '[0-9]+')
if [ $t != 0 ]; then
echo "OK. Done."
echo -n "Public IP: "
curl --interface wlan0 ifconfig.co/
echo -n "VPN IP: "
curl --interface tun0 ifconfig.co/
else
echo "Something went wrong."
fi
echo
echo "Last log:"
echo "----------"
logread | tail -n 30
echo "----------"