WireGuard and Three-Point VPN Gateway

First published — Aug 10, 2023
Last updated — Aug 10, 2023
#wireguard #network #privacy

Three-point VPN Gateway. WireGuard, IPTables/NFTables, DNS, dnsmasq. VPN server and Internet gateway on different machines.

Article Collection

This article is part of the following series:

1. Security

Table of Contents

Introduction

A Virtual Private Network (VPN) is a secure, encrypted data channel connecting two computers or networks. The secure channel is established in software, on top of an existing and usually insecure network such as the Internet.

VPNs can be used to:

  1. Access resources on the other side of the VPN. For example, you connect to a corporate VPN network so that you can access systems and data behind it.

  2. Access Internet anonymously. When you are accessing Internet through a VPN, destinations you connect to can only see the VPN server’s IP address and location, not yours. If you do not transmit nor store any user-identifiable information, e.g. if you browse the public Internet using a disposable environment, this option can protect your identity and location from websites that you visit.

    However, using a VPN without other precautions does not make you unidentifiable; there are numerous ways how users can be tracked across the network, and either immediately or later get linked to their identity. Also, VPN servers are usually located in datacenters (rather than residential areas), and IP addresses of all popular VPN servers are well-known. So when using VPN for anonymity, you are making explicitly visible that a VPN is being used.

  3. Keep Internet use private. When you are accessing Internet through a VPN, your ISP can see that a VPN is being used, but not which websites are being visited or what data is being transferred. That can protect your data and privacy from the service provider and/or other parties who do already know your identity or location.

    However, similarly to previous point, using a VPN without other precautions (primarily, changing the DNS server in this case) does not make your traffic undeterminable, and you are also making it explicitly known that you are using a VPN.

  4. Access Internet from different, random IP addresses. As mentioned, destinations you connect to only see the IP address and location of the VPN server. If you do transmit user-identifiable information, for example if your browser sends cookies or you log in to a social networking site, then this option won’t protect your identity, but will protect location.

    However, similarly to previous point, using a VPN without other precautions does not make your location undeterminable, and you are also making it explicitly known that you are using a VPN.

  5. Access Internet from a specific IP address. In this case you are not seeking anonymity or randomization, but want to appear as accessing the Internet from some specific IP address or geographical location. That location will usually be somewhere in the residential area, but can also be elsewhere, for example at work. Being on the office network may be needed for accessing paid resources like magazine subscriptions that are restricted to office IP ranges, or available only through a second VPN at work.

    When using a VPN for this purpose, it is typically in your interest not to provide evidence that a VPN is being used.

The last mentioned case is best implemented by users themselves. Commercial VPN services are not suitable because they have all the opposite characteristics.

Three best known VPN softwares are WireGuard, OpenVPN, and IPSec. (IPSec is an OSI Layer 2 protocol, lower than the other two).

This article uses WireGuard and explains the necessary configuration for option (5) above. It shows a model where the outgoing (gateway) host is a third machine in the setup. So the outgoing gateway host and the VPN server host are two different machines, having different location and IP address. I call this setup a “three point VPN gateway”. If there exists a different, established name for this setup, please let me know.

An important characteristic of the setup is that only the central VPN server machine needs to be accessible from the Internet. It should also have a static IP, although it is not a strict requirement.

Basic, Unmodified Setup

When you use a commercial VPN service, or when you install a VPN server in a basic configuration yourself, the setup looks like this:

flowchart LR

  1(["1. Your computer"]) -->|"2. connects to"| 2("3. Some VPN server")
  2 -->|"4. and then"| 4[["5. You access the Internet. The\nvisible IP address is that of the\nVPN server, rather than yours."]]

Advanced Three-point Setup

However, an advanced connection setup, described in this article, looks like this:

flowchart LR
	1(["1. Your computer, usually\non a dynamic IP"]) -->|"2. connects to"| 2("3., 6. WireGuard VPN server,\nusually on a static/fixed IP.\nIt can be hosted anywhere.")
	4(["4. Your desired outgoing\n gateway machine,\nusually on a dynamic IP"]) -->|"5. also connects to"| 2

Then:

flowchart LR
  1(["1. From your computer"]) -->|"2. transparently via\nthe VPN network"| 2("3. You use the third\nmachine as your\nInternet gateway")
  2 -->|"4. and"| 4[["5. Access the Internet, with visible\nIP address being that of the gateway,\nrather than yours or VPN server's IP."]]

One vs. Multiple Client Devices

In the setup shown above you could connect your local workstation to the VPN server directly.

However, first, that limits use to a single device. You would need to establish a separate connection to the VPN server from every device you want behind VPN. That complicates hardware and software support, configuration, and management.

Second, the devices must also have direct access to the Internet independently of VPN, or otherwise they could not connect to it. So VPN could be bypassed unexpectedly for a number reasons, such as:

  1. You could mistakenly disable it, or in general make configuration changes that circumvent the VPN
  2. You might not have admin privileges to make network-related changes on the devices themselves (e.g. on company-owned laptops)
  3. Some connections might surprisingly not be routed via VPN. For example, you can install and enable VPN on Android, but any tethered devices you connect to it will silently not be routed via VPN. That’s one of Android’s known limitations
  4. Rogue software with necessary privileges might reconfigure the network to circumvent the VPN

The solution to all those problems is to add one more component – a small, dedicated “jump box” – in front of all your local devices.

Jump Box

On the Internet-facing side, the jump box will have a fixed configuration. It will always connect to the VPN and then unconditionally route all traffic through it.

On the user-facing side, the jump box will offer ethernet ports and/or a WiFi access for your devices. It will also have a DHCP server running and be able to auto-configure network on the devices connecting to it, enabling a complete plug-and-play operation.

The jump box is ultimate in convenience. It simultaneously simplifies device setup, ensures that all traffic is routed via VPN, maximizes compatibility (devices only need to support DHCP), and maximizes transparency (devices will not be aware of VPN).

DNS Resolution

The aim of the described solution is to deprive any monitoring entity of evidence whether you are physically accessing the Internet from the outgoing (gateway) location, or are connecting to it remotely via VPN.

VPN setup described gets us pretty much there, but there is an additional detail.

When computers translate symbolic domain names like “example.com” into IP addresses like “1.2.3.4”, they use a Domain Name System (DNS).

DNS is an enormous, hierarchical, tree-like database. Its records are temporarily cached on millions of computers, to massively distribute the work and achieve best performance. A convention is that every ISP should have their own caching DNS servers for its customers.

DNS servers that a machine should use are typically configured as part of network configuration. If network configuration is done automatically via DHCP, users don’t even see this process – Internet just appears to work. Users only need to choose the WLAN to connect to and enter a password.

Thus, when you physically connect a machine to the Internet in say, Germany, it is practically guaranteed that it will be auto-configured to use DNS servers that are also in Germany. In fact, because DNS servers are very likely ISPs’ own, and ISPs know where their customers are located, the configured servers may be even closer to you geographically than just “Germany”.

When you connect to a VPN, your machine might still remain configured to use ISP’s DNS servers. By looking at their subscriber logs and DNS logs, ISPs could relatively easily determine your VPN IP and also see which hostnames or websites you are accessing. Leaking this information to your local ISP may not be of your primary concern.

However, more importantly, a popular technique in DNS resolution is to resolve hostnames to IP addresses (locations) nearest to users. That reduces global network traffic and increases performance. Users’ location is sometimes determined by their IP, but sometimes simply by which DNS they are asking. Asking a DNS in Germany might return results specific to Germany.

So if you connect to a VPN in say, the US, and then access resources which have location-dependent DNS resolution, you might be routed to an unexpected regional cluster. If this information is being monitored by services you are accessing, your real region and the ISP you are using might be revealed to them.

Or, in any case, you could be using non-optimal routes and experience slower service than necessary.

Thus, it is important to use DNS servers that are native to the outgoing gateway’s host. This is most conveniently done by installing a DNS proxy on the gateway machine itself. The solution explained in this article takes it into account.

Local Network Information

When you are physically present at the location of your Internet gateway, you can connect devices directly to the local router. VPN does not make a difference there and will only make Internet slower. (Slower because it would route traffic to the VPN server and back to itself before going out to the Internet.)

After connecting to the router, devices will typically receive network settings via the DHCP protocol.

As part of it, devices will see the router’s hardware MAC address. Also, while information such as devices’ local IP address is private, it may still be leaked to Internet, most commonly when using web browsers and WebRTC. (WebRTC can be fully disabled in Firefox, but not in Chrome-based browsers.)

The jump box will surely have a MAC address different than the router’s, and the network information will also probably be different.

So when you connect devices to the jump box, they could in theory make note of the difference in address and settings of the DHCP server. And/or a different local IP will be visible in WebRTC data that will leak. Or you might have to explicitly configure devices for two networks – one router’s, and one jump boxes’, and the information about multiple networks will remain stored in devices’ memory.

So for minimizing identifiable differences between setups, and also for minimizing total work required, you could configure all your routers, access points, and jump boxes with the same settings and even the same hardware MAC address. That will make it increasingly hard for devices to even passively notice any changes.

Complete Diagram

A generalized diagram, taking into account everything described above, now looks like this:

flowchart LR
	3(["5. The outgoing gateway\nmachine"]) --> 4[["6. Through which your traffic\ngoes out to the Internet."]]
	1(["1. All your devices\n('All your base')"]) -->|"2. connect to"| 2("3. The local jump box and get\nDHCP IP address from DHCP\nserver on it.\n\n(Jump box itself gets its address\nfrom the ISP's router or modem,\nwhere it acts as a DHCP client.)")
	2 -->|"4. The jump box is permanently\nconnected, via the VPN server, to"| 3

Note: “All your base” above is a reference to All your base are belong to us.

Configuration

VPN Server Host

Let’s start by setting up WireGuard on the VPN server machine. It is the central component of the system.

By convention, we always configure a WireGuard client device as wg0, so our WireGuard server device will be wg1.

/etc/wireguard/wg1.conf

# Run this file with: qg-quick up wg1

[Interface] # Configuration for the Wg server itself
Address = 10.0.0.1/24
#MTU = 1420
SaveConfig = false
ListenPort = 51820
#FwMark = 0xca6c
PrivateKey = OPyMtq..........

Table = off
PostUp = ip -4 route add default dev %i table 51820
PostUp = ip -4 rule add from 10.0.0.0/24 table 51820
PostUp = ip -4 rule add table main suppress_prefixlength 0
PostUp = iptables -I FORWARD -i %i ! -o %i -j REJECT
PostUp = iptables -A FORWARD -i %i -o %i -j ACCEPT
PreDown = ip -4 route del default dev %i table 51820
PreDown = ip -4 rule del from 10.0.0.0/24 table 51820
PreDown = ip -4 rule del table main suppress_prefixlength 0
PreDown = iptables -D FORWARD -i %i ! -o %i -j REJECT
PreDown = iptables -D FORWARD -i %i -o %i -j ACCEPT

[Peer] # Jump Box
PublicKey = QStNCC..........
AllowedIPs = 10.0.0.2/32
PersistentKeepalive = 25

[Peer] # Gateway Server
PublicKey = 1wKjA3..........
AllowedIPs = 0.0.0.0/0 # Only use 0.0.0.0 appropriate FW rules in [Interface]
#AllowedIPs = 10.0.0.4/32 # Only use with appropriate FW rules in [Interface]
PersistentKeepalive = 25

Internet Gateway Host

Then we configure the Internet gateway machine, which will serve as our outgoing node.

Install Software Packages

apt install dnsmasq wireguard

/etc/wireguard/wg0.conf

[Interface]
Address = 10.0.0.4/24
# SaveConfig = true
#ListenPort = 51820

#PostUp = iptables -t nat -A POSTROUTING -o enp3s0 -j MASQUERADE
#PostUp = ip6tables -t nat -A POSTROUTING -o enp3s0 -j MASQUERADE
#PreDown = iptables -t nat -D POSTROUTING -o enp3s0 -j MASQUERADE
#PreDown = ip6tables -t nat -D POSTROUTING -o enp3s0 -j MASQUERADE
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o enp3s0 -j MASQUERADE
PreDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o enp3s0 -j MASQUERADE

PrivateKey = 2LLt9E..........

[Peer]
AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 25
Endpoint = SERVER_IP:51820
PublicKey = 4xViFQ..........

Jump Box Host

And finally we configure the “jump box”, which will sit in front of our devices.

apt get install wireguard resolvconf isc-dhcp-server

/etc/default/isc-dhcp-server

# Defaults for isc-dhcp-server (sourced by /etc/init.d/isc-dhcp-server)

# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf).
#DHCPDv4_CONF=/etc/dhcp/dhcpd.conf
#DHCPDv6_CONF=/etc/dhcp/dhcpd6.conf

# Path to dhcpd's PID file (default: /var/run/dhcpd.pid).
#DHCPDv4_PID=/var/run/dhcpd.pid
#DHCPDv6_PID=/var/run/dhcpd6.pid

# Additional options to start dhcpd with.
#       Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead
#OPTIONS=""

# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
#       Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACESv4="eth1"
INTERFACESv6=""

/etc/dhcp/dhcpd.conf

option domain-name "local.net";
option domain-name-servers 192.168.8.1;

default-lease-time 600;
max-lease-time 7200;

ddns-update-style none;

authoritative;

subnet 192.168.5.0 netmask 255.255.255.0 {
}

subnet 192.168.8.0 netmask 255.255.255.0 {
  range 192.168.8.25 192.168.8.65;
  option routers 192.168.8.1;
}

/etc/default/dnsmasq

ENABLED=1
CONFIG_DIR=/etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new
IGNORE_RESOLVCONF=yes

/etc/dnsmasq.conf

resolv-file=/etc/resolv.wg

/etc/resolv.wg

nameserver 10.0.0.4
search local.net Home

/etc/wireguard/wg0.conf

[Interface]
PrivateKey = 2CqLXL...
Address =  10.0.0.2/24
DNS = 10.0.0.4
MTU = 1280

PostUp = ip route del default; ip route add default via 10.0.0.4
PostUp = ip route add SERVER_IP/32 via 192.168.5.1
PostUp = iptables -A FORWARD -i wg1 -m state --state RELATED,ESTABLISHED -j ACCEPT
PostUp = iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
PostUp = iptables -A FORWARD -i eth1 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o wg1 -j MASQUERADE

PostDown = ip route add default via 192.168.5.1;
PostDown = ip route del SERVER_IP/32 via 192.168.5.1;
PostDown = iptables -D FORWARD -i wg1 -m state --state RELATED,ESTABLISHED -j ACCEPT
PostDown = iptables -D FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
PostDown = iptables -D FORWARD -i eth1 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o wg1 -j MASQUERADE


[Peer]
PublicKey = 4xViFQ...
Endpoint= SERVER_IP:51820
AllowedIPs = 0.0.0.0/0

Article Collection

This article is part of the following series:

1. Security

Automatic Links

The following links appear in the article:

1. All Your Base Are Belong to Us - https://en.wikipedia.org/wiki/All_your_base_are_belong_to_us
2. DHCP - https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol
3. MAC Address - https://en.wikipedia.org/wiki/MAC_address
4. OSI Layer 2 - https://en.wikipedia.org/wiki/OSI_layer_2
5. WebRTC - https://en.wikipedia.org/wiki/WebRTC