Skip to content

Instantly share code, notes, and snippets.

@jonathanduke
Last active April 21, 2025 16:48
Show Gist options
  • Select an option

  • Save jonathanduke/e76ba70834ccfe9a3326b1f123cc2d2f to your computer and use it in GitHub Desktop.

Select an option

Save jonathanduke/e76ba70834ccfe9a3326b1f123cc2d2f to your computer and use it in GitHub Desktop.
How to route traffic from the public Internet over two routers connected via VPN

VPN Bridge Setup: DD-WRT to Asus (Merlin)

I needed to create a VPN bridge from my network, which has a public IP, to an internal network, which is behind CGNAT and does not have a routable IP. The routers involved were an R6700v3 running DD-WRT and an RT-N66U running the Merlin 380.70 firmware, but the firewall rules should apply for any similar router. While this is not a comprehensive guide, I needed to record the details of the custom steps here in case I have to set up something similar in the future.

1. OpenVPN Setup

Setting up an OpenVPN server on the DD-WRT side and connecting it to the Asus is mostly straightforward using the GUI, but some manual steps were required. I did notice that the Asus had some issues with a few of the OpenVPN parameters, and it had trouble connecting in TCP mode, so I used UDP.

To set up OpenVPN with TLS authentication and X.509 certificates, I used Easy-RSA to generate a certificate authority and required certs:

  1. Initialize a new Public Key Infrastructure:

    easyrsa init-pki
  2. Build the certificate authority:

    easyrsa build-ca
  3. Generate server certificate and key:

    easyrsa gen-req server nopass
    easyrsa sign-req server server
  4. Generate client certificate and key:

    easyrsa gen-req asus_user nopass
    easyrsa sign-req client asus_user
  5. Generate TLS key for extra HMAC security:

    openvpn --genkey --secret ta.key
  6. Copy the following to your DD-WRT configuration:

    • ta.key (TLS Key)
    • pki/ca.crt (CA Certificate)
    • pki/issued/server.crt (Public Server Certificate)
      • do not include the information above -----BEGIN CERTIFICATE----- when copying
    • pki/private/server.key (Private Server Key)
  7. Export the OpenVPN file and upload to the Asus device under the VPN Client GUI:

    • This will automatically contain the certificates in the <tls-auth> and <ca> blocks, but you will need to copy the following into the file manually:
      • pki/issued/asus_user.crt (in the <cert> block)
      • pki/private/asus_user.key (in the <key> block)
    • After uploading to the Asus, you will see a few entries in the "Custom Configuration" section. I did not find any of them to be necessary, but depending on your router configuration, you may need to add the following to prevent its traffic from routing normal Internet traffic over the VPN:
       route-nopull
      

2. CCD File Setup (Client-Specific Configuration)

If you only have one user on your VPN, then you can probably get away with adding this into the configuration in the DD-WRT GUI, but since I had multiple clients with different configurations, I had to make CCD work. On my version of DD-WRT, this was less than trivial because JFFS was not working properly and would not persist my configuration. So, I used a combination of custom nvram entries and a startup script:

  1. Persist the CCD for the Asus user in nvram:

    nvram set ccd_asus_user='ifconfig-push 10.0.0.201 255.255.255.0
    iroute 192.168.2.0 255.255.255.0'
    nvram commit
    • What are these commands doing?
      • The first assigns the Asus router a static address of 10.0.0.201/24 on your VPN network.
      • The second defines the route that allows DD-WRT to access the internal subnet on the Asus router (192.168.2.0/24).
  2. Then make sure DD-WRT recreates this file after each boot in the rc_startup command (Administration > Commands > Startup):

    sleep 20
    mkdir -p /tmp/openvpn/ccd
    printf "%b\n" "$(nvram get ccd_asus_user)" > /tmp/openvpn/ccd/asus_user
    nvram set openvpn_ccdpath="/tmp/openvpn/ccd"
    stopservice openvpn
    startservice openvpn

3. Forwarding Setup (DD-WRT)

This is necessary to allow your DD-WRT subnet to route traffic to devices on the Asus subnet.

  1. In rc_firewall command (Administration > Commands > Firewall), add:

    iptables -t nat -I POSTROUTING -d 192.168.2.0/24 -o tun2 -j MASQUERADE

    Without this, traffic from your local devices will not route back through the VPN tunnel to the internal addresses.

  2. From here, using the GUI for port forwarding (NAT / QoS > Port Forwarding), you can forward traffic from the public Internet to devices across the VPN to internal devices connected to the Asus router, such as forwarding port 8443 to 192.168.2.101:443.

4. Firewall Configuration (Asus)

This is necessary to allow devices from the DD-WRT network to access devices on the Asus network.

  1. You will need JFFS enabled and SSH access so that you can create the a script at /jffs/scripts/nat-start:

    #!/bin/sh
    iptables -I FORWARD -i tun11 -s 10.0.0.0/24 -d 192.168.2.0/24 -j ACCEPT
    iptables -I INPUT -i tun11 -s 10.0.0.0/24 -j ACCEPT
    • This will allow traffic from the 10.0.0.x subnet to access all devices on your 192.168.2.x subnet. Modify as desired to make this rule more restrictive.
  2. Don't forget to make it executable:

    chmod +x /jffs/scripts/nat-start

I also changed the "Firewall" setting under the VPN Client to "Custom" but am not sure whether that was necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment