This post continues from Part 5: DNS

Being able to access your local network from anywhere in the world isn't always necessary, but it can have its benefits. If you're running personal servers on your LAN like a NFS it's nice to have access no matter where you are. By adding a VPN server to your network you can magically teleport yourself to your couch at home and access everything on your local network like you were actually there. Not only does it give you access to local devices, but it can also be used to protect your traffic on insecure networks like coffee shops and airport hotspots.

Now, I'm not going to explain how to setup VPN server. There's already a million tutorials on the internet explaining how to do that. Rather I'm going to focus on the things that all of those tutorials seem to ignore. That is, how to actually connect to your server when you're out of the house and how to make your entire LAN accessible from the VPN so it's as if you are actually there sitting in your living room. From here on, I'll assume you already have an OpenVPN server setup and running on port 1194 of your router with a tunnel device named tun0. If you don't have that, Google knows how you can do it.

Dynamic DNS

To get access from outside your house reliably you'll first have to set up dynamic DNS. This is because the public IP you get from your ISP is not static. They can change it at their will unless you're specifically paying extra to keep it static. If you try to connect to your house and the IP has changed it ain't gonna work. Dynamic DNS is the solution to this problem.

A dynamic DNS record is similar to any other DNS record. It's just a domain name that points to an IP address. The "dynamic" part comes into play when the IP address changes. A dynamic DNS client running on the machine you want the DNS record to point to continually monitors its external IP. When the IP changes it informs the DNS server of the new address and the DNS server updates the record. This means the domain name will always point to the current IP of the machine.

The first step is obviously to own a domain name. I recommend Google's domain registrar https://domains.google.com because its simple and makes setting up dynamic DNS extremely easy. If you're on a different registrar you can either figure out how (or if) they support dynamic DNS or just transfer your domain to Google. Set up a synthetic DNS record on your domain provider for the dynamic domain and they should give you a username and password. If you're using Google's registrar check out their help article on the subject. Once you have the credentials you'll need to install the dynamic DNS client on your router.

Install the ddclient software just like any other package:

$> sudo apt-get install ddclient

And then edit the configuration file /etc/ddclient.conf to look something like this:

# /etc/ddclient.conf
ssl=yes
protocol=dyndns2
use=web
server=domains.google.com
login=yourusername
password='yourpassword'
your.domain.com

Your configuration may differ a bit depending on your provider, but it's pretty straightforward. Use SSL for security, use the dyndns2 DNS updating protocol, use a web request for checking the current IP, and report changes to domains.google.com with your username and password for your.domain.com.

Restart the service and make sure it will run at boot:

$> sudo systemctl restart ddclient
$> sudo systemctl enable ddclient

To test it out make a DNS request with dig to get the IP your domain points to:

$> dig your.domain.com
...
;; ANSWER SECTION:
your.domain.com.  300  IN  A  1.2.3.4
...

And compare that to your current public IP address using the world's best IP checking service icanhazip.com:

$> curl http://icanhazip.com
1.2.3.4

They match! Now whenever your public IP changes ddclient will pick up the change and tell the DNS server to update the record. No matter where you are you can use your.domain.com to get your home's current IP address.

VPN Routing

The next step is to adjust the firewall settings so that you have access to your whole network when you're connected to the VPN. First lets allow incoming connections on the VPN port so you can actually connect to the router from outside:

$> sudo iptables -A INPUT -i eth0 -p tcp --dport 1194 -j ACCEPT

And accept traffic coming from the tunnel interface:

$> sudo iptables -A INPUT -i tun0 -j ACCEPT

With those two rules you should be able to connect to the VPN from outside the local network and access the router. We need a few more rules to forward traffic from the tunnel to the WAN and allow responses from the WAN to the tunnel. This is just like the LAN interface on your router. Allow the tunnel to send any traffic it wants to the WAN:

$> sudo iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT

But only allow WAN traffic to the tunnel if the tunnel initiated the connection:

$> sudo iptables -A FORWARD -i eth0 -o tun0 -m conntrack \
        --ctstate ESTABLISHED,RELATED -j ACCEPT

That should let VPN traffic access the wider internet. To access the LAN interface you need to add forwarding rules between the tunnel and the LAN. One rule is needed for each direction:

$> sudo iptables -A FORWARD -i tun0 -o enx0050b617c34f -j ACCEPT
$> sudo iptables -A FORWARD -i enx0050b617c34f -o tun0 -j ACCEPT

Now there's only one more problem. The LAN devices don't know how to route traffic to your VPN subnet (probably something like 10.8.0.0/24 if you chose the defaults). It's just like how the public internet doesn't know how to route traffic to your LAN subnet in the 192.168.0.0/24 space. To fix it you need to use NAT to translate the tunnel IP to the router's IP before sending the packet out on the LAN and do the reverse before sending packets back through the tunnel. This is just another NAT rule like we did for the WAN:

$> sudo iptables -t nat -A POSTROUTING -i tun0 -o enx0050b617c34f \
       -j MASQUERADE

Make sure everything works and then add all those rules to your /etc/rc.local file. That should do it. Try connecting to your VPN from an external network and test it out. You should be able to access everything on the LAN and reach out to the public internet through the VPN. It's as if you're sitting at home on your own WiFi. Neato.

Next week we'll be discussing caching with Squid as a way to save bandwidth and increase performance on your local network. Stay tuned!

Other Posts in This Series