The Problem #
As rising concern on the privacy issue recently, I started to use VPN service to protect my network. Setting up VPN client on top of the Wireguard server plus DDNS in DD-WRT hits lots of issues but didn’t find related article. After spending several hours digging into iptables and OpenVPN config, they are all working as expected.
Enable OpenVPN Client #
There should be a setup guide of DD-WRT from the VPN service provider. In my case, I am using Mullvad so follow their guide and then the OpenVPN client should be working.
Settings should look like:
VPN should work when you see an IP at the page Status > OpenVPN.
Setup Wireguard Server #
Brief steps:
- Go to Setup > Tunnels.
- Enable tunnel and select Wireguard for Protocol Type.
- Enter IP Address other than the router IP, says
10.10.0.1
- Add Peer
- Enter the Peer Tunnel IP within the oet1 interface IP range, says
10.10.0.11
. - Enter the Peer Tunnel DNS, which may be 8.8.8.8, or the router IP if you want to have local hostnames resolving.
- Enter allowed IPs as
10.10.0.11/32
. - Click Save then the QR-Code button.
- Go to Services > Services > Dnsmasq, add
interface=oet1
for Wireguard internet access.
Remark:
- Repeats step 4-8 to add more peers.
- Enable
Local DNS
and disableNo DNS Rebind
in Dnsmasq if you want local hostname resolving.
Fix wireguard traffic #
With VPN active, wireguard traffic always send to VPN interface which block wireguard outgoing traffic. To fix it, go to Administration > Commands.
Save Startup
ip rule add fwmark 1234 table 7
Save Firewall
wg set oet1 fwmark 1234
ip route add default via $(nvram get wan_gateway) table 7
DDNS #
- Add A+Dynamic DNS record at your DNS control panel.
- Setup DDNS on the router follow the guide provided by your DNS service provider.
Fix IP Check #
With OpenVPN active, your external IP is always same with the VPN IP. Setting Use external IP check
to No does not fix the update in my case. I fixed it by whitelisting the IP of DDNS server by adding line
route {IP of DDNS server} 255.255.255.255 net_gateway
to OpenVPN client > Additional Config.
Port forwarding #
Port forwarding faces the same routing issue as wireguard. Additional firewall rules are needed in order to make it works.
Save Startup
ip rule add fwmark 1 table 100
Save Firewall
ip route add default via $(nvram get wan_gateway) table 100
# For DD-WRT remote access with HTTPS.
# Change 192.168.1.0/24 according to your netmask.
iptables -t mangle -I OUTPUT -p tcp --sport 443 -d ! 192.168.1.0/24 -j MARK --set-mark 1
# Define a CHAIN to exclude the traffic from LAN and Wireguard.
# Finally, MARK with fwmark 1.
#
# Remark:
# Change 192.168.1.0/24 and 10.10.0.0/24 according to the settings of LAN
# and Wireguard respectively.
iptables -t mangle -N BYPASS_VPN
iptables -t mangle -A BYPASS_VPN -p tcp -d 192.168.1.0/24 -j RETURN
iptables -t mangle -A BYPASS_VPN -p tcp -d 10.10.0.0/24 -j RETURN
iptables -t mangle -A BYPASS_VPN -p tcp -j MARK --set-mark 1
# Port forwarding for SSH.
# For example, marks the traffic to 192.168.1.100:22 to bypass VPN.
iptables -t mangle -A PREROUTING -p tcp -s 192.168.1.100 --sport 22 -j BYPASS_VPN
Troubleshooting #
Actually I met numerous issues when setting up the OpenVPN client. I would suggest to reset the router to factory default before getting start.