VPN Gateway Server for your LAN

This tutorial is about creating a VPN Gateway for your LAN. If you change the gateway address for any of your systems to be that of the VPN Gateway server, the system will use the Public VPN gateway to route all of your traffic.

This project is based upon work done to solve the ipTables routing issues in the Ubuntu forum published in 2018 here:

https://ubuntuforums.org/showthread.php?t=2399250

In our example we use NordVPN, but other VPN services should work just as well as long as they are UDP connections and not TCP connections. In addition, since the routing table only passes UDP port 1194, if the VPN connection fails, no traffic is routed to the WAN effectively creating a kill switch.

The advantage of this is that this VPN Gateway has one connection to a NordVPN server and multiple systems on your LAN can route through it. This allows systems on your network to use your VPN service that do not have OpenVPN configured. It also allows nodes like Roku devices that can’t run a VPN client to be able to connect through a VPN.

This project is built on a Virtual Machine instance of Ubuntu Server 18.04 configured with 2vcpu, 2GB of memory, and 25GB of storage.

Install dependencies:

sudo apt install openvpn openssh-server unzip

Move to configuration directory:

cd /etc/openvpn

Download NordVPN configuration files:

sudo wget https://downloads.nordcdn.com/configs/archives/servers/ovpn.zip

Unzip files:

sudo unzip ovpn.zip

Create connection script:

sudo nano /etc/openvpn/connect.sh

sudo openvpn --config “/etc/openvpn/ovpn_udp/us9144.nordvpn.com.udp.ovpn” --auth-user-pass /etc/openvpn/auth.txt

Save the file

Create the login credentials file:

sudo nano /etc/openvpn/auth.txt

username@email.com
password

Save the file

Create the ip tables routing file:

sudo nano /etc/openvpn/iptables.sh

#!/bin/bash

Flush

iptables -t nat -F
iptables -t mangle -F
iptables -F
iptables -X

Block All

iptables -P OUTPUT DROP
iptables -P INPUT DROP
iptables -P FORWARD DROP

allow Localhost

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

Make sure you can communicate with any DHCP server

iptables -A OUTPUT -d 255.255.255.255 -j ACCEPT
iptables -A INPUT -s 255.255.255.255 -j ACCEPT

Make sure that you can communicate within your own network

iptables -A INPUT -s 172.16.0.0/16 -d 172.16.0.0/16 -j ACCEPT
iptables -A OUTPUT -s 172.16.0.0/16 -d 172.16.0.0/16 -j ACCEPT

Allow established sessions to receive traffic:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Allow TUN

iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -o tun+ -j ACCEPT
iptables -t nat -A POSTROUTING -o tun+ -j MASQUERADE
iptables -A OUTPUT -o tun+ -j ACCEPT

allow VPN connection

iptables -I OUTPUT 1 -p udp --destination-port 1194 -m comment --comment “Allow VPN connection” -j ACCEPT

Block All

iptables -A OUTPUT -j DROP
iptables -A INPUT -j DROP
iptables -A FORWARD -j DROP

Log all dropped packages, debug only.

iptables -N logging
iptables -A INPUT -j logging
iptables -A OUTPUT -j logging
iptables -A logging -m limit --limit 2/min -j LOG --log-prefix "IPTables general: " --log-level 7
iptables -A logging -j DROP

echo “saving”
iptables-save > /etc/iptables.rules
echo “done”
#echo ‘openVPN - Rules successfully applied, we start “watch” to verify IPtables in realtime (you can cancel it as usual CTRL + c)’
#sleep 3
#watch -n 0 “sudo iptables -nvL”

Save the File after editing the four 172.16.0.0/16 entries above to match your network. Example 192.168.1.0/24.

Enable IP Forwarding:

sudo sh -c “echo 1 > /proc/sys/net/ipv4/ip_forward”

TO TEST
sudo bash /etc/openvpn/iptables.sh
sudo bash /etc/openvpn/connect.sh

Point another device’s default gateway at your VPN Gateway server address:

curl ifconfig.me

The above command should return the NordVPN server address.

Create rc.local service so that the connection is made when the VM boots:

sudo nano /etc/systemd/system/rc-local.service

[Unit]
Description=/etc/rc.local Compatibility
ConditionPathExists=/etc/rc.local

[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
StandardOutput=tty
RemainAfterExit=yes
SysVStartPriority=99

[Install]
WantedBy=multi-user.target

Save the File

Create rc.local script to launch our service:

sudo /etc/rc.local

#!/bin/sh -e
sudo bash /etc/openvpn/iptables.sh &
sleep 10
sudo sh -c “echo 1 > /proc/sys/net/ipv4/ip_forward”
sudo bash /etc/openvpn/connect.sh &
exit 0

Save the File

Finally, Enable/Start rc.local service

sudo systemctl enable rc-local
sudo systemctl start rc-local

Finally, reboot your virtual machine.

If you change the default gateway of any machine on your network LAN to be the address of the VPN-Gateway virtual machine, that machine will be communicating through the public VPN server.