• How to port forward with a VPN connection

    If you don’t have a public IP address from your ISP, but still want to access your home network from the outside, you may need to set up port forwarding using a VPN connection. With this setup, the VPN server will provide the public IP address you need, and the VPN connection will carry the data in and out of your home network.

    Of course, there are also times that you prefer to do port forwarding from a VPN IP address instead of your ISP IP address.

    If your VPN service supports port forwarding and you have a direct VPN connection from the machine hosting the service you want to expose, then the process is straightforward: just follow the instructions of your VPN service provider.

    If your VPN connection is established on a router, then you also need to set up port forwarding on the router to your internal destination server.

    However, for some routers, port forwarding does not work when the router is connected to a VPN. You can confirm this by following the steps below.

    1. Turn off VPN connection on the router (if it is on).
    2. Configure port forwarding as you normally do. For example, forward external TCP port 18080 to an internal PC’s web server running on port 80.
    3. Test the forwarded port from the Internet. For example, use your smartphone’s mobile connection to access the web server on your PC: http://<your ISP IP address>:18080. The page should load.
    4. Now connect your VPN. Configure port forwarding on your VPN service for the same external port as above.
    5. You should be able to access the forwarded port with your VPN IP address. Continuing with the above example, the URL would be: http://<your VPN IP address>:18080. If this page does not load, your router does not support port forwarding with VPN.
    6. Try the forwarded port on your ISP IP address again. If it works, then your router is doing port forwarding wrong with a VPN connection.

    For the pcWRT router, port forwarding with a VPN connection is exactly the same as port forwarding with an ISP connection.

    Server Side Setup (if you run your own VPN server)

    Sometimes you need to roll your own VPN server. I’m giving an example here on how to do this with WireGuard. The principles remain the same if you choose to use a different VPN protocol such as OpenVPN. You just need some minor modifications.

    1. Enable IP forwarding

      sysctl net.ipv4.ip_forward=1

      Add this line to /etc/sysctl.conf if you want to persist this change over server reboot.

    2. Generate public and private keys for the server and client

      $ wg genkey | tee privatekey | wg pubkey > publickey

    3. Create WireGuard configuration file for the server

      [Interface]
      Address = 10.12.11.1/24
      PrivateKey = 8Bec70Zeb4zGaTCbTqNaIUEh6fCehTu6hZ7AQlqqYWo=
      ListenPort = 51820
      PostUp   = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
      PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
      [Peer]
      PublicKey = +D6zeGuYFD3X/99AuUnwZI6SfJmjdX6e1UQYJOy0qXo=
      AllowedIPs = 10.12.11.10/32
      

      Put the server private key in the Interface section, client public key in the Peer section. The Internet facing network interface is eth0. If on your server it has a different name, you need to change that.

      WireGuard runs the iptables rules on server up/down events. You’ll need to put these rules elsewhere if you use a different protocol.

    4. Save the configuration file as /etc/wirwguard/wg0.conf
    5. Bring up the WireGuard server
      $ sudo wg-quick up wg0

    Client Side Setup (for your self-hosted VPN)

    1. Create client configuration file
      [Interface]
      Address = 10.12.11.10/32
      ListenPort = 64661
      PrivateKey = MA73LJm5cjorXUXV/SKBfcrNQTKoX1xoioVyzJQHU2k=
      
      [Peer]
      PublicKey = XF69enunWI6bbHHwgRbE/jAvuM6plb4kyGcObYKvLVc=
      Endpoint = 100.24.65.223:51820
      AllowedIPs = 0.0.0.0/0
      PersistentKeepalive = 25
      

      The client private key goes to the Interface section. The server public key goes to the Peer section. Endpoint in the Peer section is the VPN server’s public IP address and port.

    2. Save the client configuration file as /etc/wireguard/wg1.conf
    3. Start the WireGuard client. It should successfully connect to the server.
      $ sudo wg-quick up wg1
    4. After the VPN connection is successfully established, test that you have Internet connectivity from the client. Check your public IP address with your browser. It should be that of the VPN server.

    Set up port forwarding on your own VPN server

    Log on to the VPN server, add the iptables rule for port forwarding.

    $ sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.12.11.10:8080
    

    With the above rule, external TCP port 8080 on the VPN server is forwarded to the internal VPN client TCP port 8080. Thus you can access port 8080 on the internal host by using the VPN server’s public IP address.

    Security Considerations

    You are exposing an internal host to the Internet. So make sure that the host/port is secured and the exposed service can’t be used for unintended purposes.

    WireGuard® is a registered trademark of Jason A.Donenfeld.

    Post Tagged with ,

Leave a Reply