OpenVPN Chain Configuration on ASUSWRT-Merlin

I had a hard time finding this information, so I’m aggregating it here. What you need:

  • ASUS Router with ASUSWRT-Merlin installed
  • SSH client you can access the router from
  • A device to test your VPN Server (e.g. mobile phone with a data connection)
  • An Upstream VPN service

Step 1: VPN Server

Log in to the router and go the the VPN page, then “VPN Server”. Configure the OpenVPN server, really however you want, just note the IP subnet. I will use 10.8.0.0/24 in this writing as the VPN subnet, just replace it with whatever you use.

Step 2: VPN Client

Go to the VPN Client tab and create a connection to your upstream VPN provider. Use their OpenVPN configuration file, username/password, etc. At the bottom, set the “Force Internet traffic through tunnel” to “Policy Rules”. This enables a table of routing rules. This table is evaluated in order, and items marked for VPN are sent to the VPN Client interface. The default is WAN.

Start with your most specific rules. For example, we need all traffic destined for a VPN client to go over the WAN, otherwise it will be sent through the Upstream VPN, and that means the client won’t see it properly as a response, because it will have a different IP. This rule should go BEFORE any catch-all “Send everything through the VPN” rules. So, you could have a table like the following:

DescSourceDestInterface
VPN Clients10.8.0.0/24WAN
Local192.168.1.0/24VPN
VPN10.8.0.0/24VPN
An example configuration

You can make this more complicated with some devices on your network using the Upstream VPN and some not using it. You can even follow this guide to have rules that make use of port numbers, mac addresses, or any other firewall matching parameters.

Now, if you test this right now, it won’t work. Why? Well the router knows how to route packets, but it doesn’t know to apply NAT. You need to modify the nat table POSTROUTING chain for that, and AFAIK, that can only be done from a script, not the UI.

Enable SSH on your router (Administration->System) and custom scripts (“Enable JFFS custom scripts and configs” : Yes).

Login via SSH. Go to /jffs/scripts and create the file firewall-start. Make it executable. If the script doesn’t exist, you can just run the following in your SSH session:

echo "#!/bin/sh" > /jffs/scripts/firewall-start
echo "iptables -D POSTROUTING -t nat -s $(nvram get vpn_server1_sn)/24 -o tun1+ -j MASQUERADE" >> /jffs/scripts/firewall-start
echo "ptables -I POSTROUTING -t nat -s $(nvram get vpn_server1_sn)/24 -o tun1+ -j MASQUERADE" >> /jffs/scripts/firewall-start

chmod +x /jffs/scripts/firewall-start

Now, you can restart your router to make it use the script, or just run the script now: /jffs/scripts/firewall-start. This will be run anytime the firewall is cleared and re-enabled (reboot or settings change). Look in the system log for messages about it after a reboot if you have issues.

These rules simply tell the router to perform NAT on any outgoing packets from the VPN clients which are destined for the VPN server(s). This way, the VPN server only sees your router as a single client, and nothing gets messed up.

I hope this helps someone. Send me any questions you may have!

Leave a Reply