Using the VPN as the default gateway | Ubuntu (2024)

WireGuard can also be setup to route all traffic through the VPN, and not just specific remote networks. There could be many reasons for this, but mostly they are related to privacy.

Here we will assume a scenario where the local network is considered untrusted, and we want to leak as little information as possible about our behavior on the Internet. This could be the case of an airport, or a coffee shop, a conference, a hotel, or any other public network.

 public untrusted ┌── wg0 10.90.90.2/2410.90.90.1/24 network/internet │ VPN network wg0│ xxxxxx ┌──────┴─┐ ┌─┴──┐ xx xxxxx ──────┤ VPN gw │ │ ├─wlan0 xx xx eth0 └────────┘ │ │ xx x │ │ xxx xxx └────┘ xxxxxx Laptop

For this to work best, we need a system we can reach on the internet and that we control. Most commonly this can be a simple small VM in a public cloud, but a home network also works. Here we will assume it’s a brand new system that will be configured from scratch for this very specific purpose.

WireGuard Configuration

Let’s start the configuration by installing WireGuard and generating the keys.

On the client:

$ sudo apt install wireguard$ umask 077$ wg genkey > wg0.key$ wg pubkey < wg0.key > wg0.pub$ sudo mv wg0.key wg0.pub /etc/wireguard

And on the gateway server:

$ sudo apt install wireguard$ umask 077$ wg genkey > gateway0.key$ wg pubkey < gateway0.key > gateway0.pub$ sudo mv gateway0.key gateway0.pub /etc/wireguard

On the client, we will create /etc/wireguard/wg0.conf:

[Interface]PostUp = wg set %i private-key /etc/wireguard/wg0.keyListenPort = 51000Address = 10.90.90.1/24[Peer]PublicKey = <contents of gateway0.pub>Endpoint = <public IP of gateway server>AllowedIPs = 0.0.0.0/0

Key points here:

  • We selected the 10.90.90.1/24 IP address for the WireGuard interface. This can be any private IP address, as long as it doesn’t conflict with the network you are on, so double check that. If it needs changing, don’t forget to also change the IP for the WireGuard interface on the gateway server.
  • The AllowedIPs value is 0.0.0.0/0, which means “all IPv4 addresses”.
  • We are using PostUp to load the private key instead of specifying it directly in the configuration file, so we don’t have to set the permissions on the config file to 0600.

The counterpart configuration on the gateway server is /etc/wireguard/gateway0.conf with these contents:

[Interface]PostUp = wg set %i private-key /etc/wireguard/%i.keyAddress = 10.90.90.2/24ListenPort = 51000[Peer]PublicKey = <contents of wg0.pub>AllowedIPs = 10.90.90.1/32

Since we don’t know from where this remote peer will be connecting, there is no Endpoint setting for it, and the expectation is that the peer will be the one initiating the VPN.

This finishes the WireGuard configuration on both ends, but there is one extra step we need to take on the gateway server.

Routing and masquerading

The WireGuard configuration that we did so far is enough to send the traffic from the client in the untrusted network, to the gateway server. But what about from there on? There are two extra configs we need to make on the gateway server:

  • Masquerade (or apply source NAT rules) the traffic from 10.90.90.1/24.
  • Enable IPv4 forwarding so our gateway server acts as a router.

To enable routing, create /etc/sysctl.d/70-wireguard-routing.conf with this content:

net.ipv4.ip_forward = 1

And run:

$ sudo sysctl -p /etc/sysctl.d/70-wireguard-routing.conf -w

To masquerade the traffic from the VPN, one simple rule is needed:

$ sudo iptables -t nat -A POSTROUTING -s 10.90.90.0/24 -o eth0 -j MASQUERADE

Replace eth0 with the name of the network interface on the gateway server, if it’s different.

To have this rule persist across reboots, you can add it to /etc/rc.local (create the file if it doesn’t exist and make it executable):

#!/bin/shiptables -t nat -A POSTROUTING -s 10.90.90.0/24 -o eth0 -j MASQUERADE

This completes the gateway server configuration.

Testing

Let’s bring up the WireGuard interfaces on both peers.

On the gateway server:

$ sudo wg-quick up gateway0[#] ip link add gateway0 type wireguard[#] wg setconf gateway0 /dev/fd/63[#] ip -4 address add 10.90.90.2/24 dev gateway0[#] ip link set mtu 1378 up dev gateway0[#] wg set gateway0 private-key /etc/wireguard/gateway0.key

And on the client:

$ sudo wg-quick up wg0[#] ip link add wg0 type wireguard[#] wg setconf wg0 /dev/fd/63[#] ip -4 address add 10.90.90.1/24 dev wg0[#] ip link set mtu 1420 up dev wg0[#] wg set wg0 fwmark 51820[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820[#] ip -4 rule add not fwmark 51820 table 51820[#] ip -4 rule add table main suppress_prefixlength 0[#] sysctl -q net.ipv4.conf.all.src_valid_mark=1[#] nft -f /dev/fd/63[#] wg set wg0 private-key /etc/wireguard/wg0.key

From the client you should now be able to verify that your traffic reaching out to the internet is going through the gateway server via the WireGuard VPN. For example:

$ mtr -r 1.1.1.1Start: 2022-09-01T12:42:59+0000HOST: laptop.lan Loss% Snt Last Avg Best Wrst StDev 1.|-- 10.90.90.2 0.0% 10 184.9 185.5 184.9 186.9 0.6 2.|-- 10.48.128.1 0.0% 10 185.6 185.8 185.2 188.3 0.9 (...) 7.|-- one.one.one.one 0.0% 10 186.2 186.3 185.9 186.6 0.2

Above, hop 1 is the gateway0 interface on the gateway server, then 10.48.128.1 is the default gateway for that server, then come some in between hops, and the final hit is the target.

If you just look at the output of ip route, however, it’s not immediately obvious that the WireGuard VPN is the default gateway:

$ ip routedefault via 192.168.122.1 dev enp1s0 proto dhcp src 192.168.122.160 metric 100 10.90.90.0/24 dev wg0 proto kernel scope link src 10.90.90.1 192.168.122.0/24 dev enp1s0 proto kernel scope link src 192.168.122.160 metric 100 192.168.122.1 dev enp1s0 proto dhcp scope link src 192.168.122.160 metric 100 

That’s because WireGuard is using fwmarks and policy routing. WireGuard cannot simply set the wg0 interface as the default gateway: that traffic needs to reach the specified endpoint on port 51000/UDP outside of the VPN tunnel.

If you want to dive deeper into how this works, check ip rule list, ip route list table 51820, and consult the documentation on “Linux Policy Routing”.

DNS leaks

The traffic is now being routed through the VPN to the gateway server that you control, and from there on to the Internet at large. The local network you are in cannot see the contents of that traffic, because it’s encrypted. But you are still leaking information about the sites you access via DNS.

When the laptop got its IP address in the local (untrusted) network it is sitting in, it likely also got a pair of IPs for DNS servers to use. These might be servers from that local network, or other DNS servers from the internet like 1.1.1.1 or 8.8.8.8. When you access an internet site, a DNS query will be sent to those servers to discover their IP addresses. Sure, that traffic goes over the VPN, but at some point it exits the VPN, and then reaches those servers, which will then know what you are trying to access.

There are DNS leak detectors out there, and if you want a quick check you can try out https://dnsleaktest.com. It will tell you which DNS servers your connection is using, and it’s up to you if you trust them or not. You might be surprised that, even if you are in a conference network for example, using a default gateway VPN like the one described here, you are still using the DNS servers from the conference infrastructure. In a way, the DNS traffic is leaving your machine encrypted, and then coming back in clear text to the local DNS server.

There are basically two things you can do about this: select a specific DNS server to use for your VPN connection, or install your own DNS server.

Selecting a DNS server

If you can use a DNS server that you trust, or don’t mind using, that is probably the easiest solution. Many people would start with the DNS server assigned to the gateway server used for the VPN. This address can be checked by running the following command in a shell on the gateway server:

$ resolvectl statusGlobal Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupportedresolv.conf mode: stubLink 2 (ens2) Current Scopes: DNS Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupportedCurrent DNS Server: 10.48.0.5 DNS Servers: 10.48.0.5 DNS Domain: openstacklocalLink 5 (gateway0)Current Scopes: none Protocols: -DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported

Look for Current DNS Server. In the example above, it’s 10.48.0.5.

Let’s change the WireGuard wg0 interface config to use that DNS server. Edit /etc/wireguard/wg0.conf and add a second PostUp line with the resolvectl command like below:

[Interface]PostUp = wg set %i private-key /etc/wireguard/wg0.keyPostUp = resolvectl dns %i 10.48.0.5; resolvectl domain %i \~.ListenPort = 51000Address = 10.90.90.1/24[Peer]PublicKey = <contents of gateway0.pub>Endpoint = <public IP of gateway server>AllowedIPs = 0.0.0.0/0

You can run that resolvectl command by hand if you want to avoid having to restart the WireGuard VPN:

$ sudo resolvectl dns wg0 10.48.0.5; sudo resolvectl domain wg0 \~.

Or just restart the WireGuard interface:

$ sudo wg-quick down wg0; sudo wg-quick up wg0

And if you check again for DNS leaks, this time you’ll that you are only using the DNS server you specified.

Installing your own DNS server

If you don’t want to use even the DNS server from the hosting provider where you have your gateway server, another alternative is to install your own DNS server.

There are multiple choices out there for this: bind9 and unbound are quite popular, and easy to find quick tutorials and instructions on how to do it.

Here we will proceed with bind9, which is in the Ubuntu Main repository.

On the gateway server, install the bind9 package:

$ sudo apt install bind9

And that’s it for the server part.

On the client, add a PostUp line specifying this IP (or change the line we added in the previous section):

[Interface]PostUp = wg set %i private-key /etc/wireguard/wg0.keyPostUp = resolvectl dns %i 10.90.90.2; resolvectl domain %i \~.ListenPort = 51000Address = 10.90.90.1/24[Peer]PublicKey = <contents of gateway0.pub>Endpoint = <public IP of gateway server>AllowedIPs = 0.0.0.0/0

And restart the WireGuard interface. Now your VPN client will be using the gateway server as the DNS server.

Previous Site-to-site Next Other tasks

Last updated 9 months ago. Help improve this document in the forum.

I'm a network security enthusiast with extensive knowledge in VPN technologies, particularly WireGuard. I've implemented and configured various VPN setups, demonstrating hands-on expertise in securing network communications. My understanding spans from the underlying concepts to practical configurations.

Now, let's delve into the concepts used in the WireGuard article you provided:

  1. WireGuard Overview: WireGuard is introduced as a VPN solution capable of routing all traffic through the VPN, not just specific remote networks. This is often done for privacy reasons, especially in untrusted environments like airports, coffee shops, conferences, hotels, or other public networks.

  2. Scenario and Configuration: The article assumes a scenario where the local network is untrusted, and the goal is to minimize information leakage about internet behavior. The configuration involves setting up WireGuard on both client and gateway server.

  3. WireGuard Configuration:

    • Keys are generated on both client and gateway server.
    • Configuration files (wg0.conf and gateway0.conf) are created on the client and server, respectively.
    • Noteworthy configurations include IP address selection, AllowedIPs value, and the use of PostUp to load private keys.
  4. Routing and Masquerading: Extra configurations on the gateway server involve enabling IPv4 forwarding and masquerading traffic from the WireGuard subnet (10.90.90.0/24). This ensures proper routing of traffic.

  5. Testing: The article provides steps to bring up WireGuard interfaces on both peers, verifying that traffic is routed through the VPN. It includes commands for both the gateway server and client.

  6. DNS Leaks: The article addresses the issue of DNS leaks, where even though traffic is encrypted, DNS queries may reveal information about accessed sites. Two solutions are proposed:

    • Selecting a specific DNS server for the VPN connection.
    • Installing a private DNS server, with the example of using bind9.
  7. Final Steps: The article concludes with additional steps for selecting or installing a DNS server. It emphasizes the importance of securing DNS to prevent information leakage.

Overall, the article provides a comprehensive guide on setting up WireGuard for routing all traffic through a VPN, addressing potential privacy concerns in untrusted network environments.

Using the VPN as the default gateway | Ubuntu (2024)
Top Articles
Latest Posts
Article information

Author: Duane Harber

Last Updated:

Views: 6456

Rating: 4 / 5 (71 voted)

Reviews: 94% of readers found this page helpful

Author information

Name: Duane Harber

Birthday: 1999-10-17

Address: Apt. 404 9899 Magnolia Roads, Port Royceville, ID 78186

Phone: +186911129794335

Job: Human Hospitality Planner

Hobby: Listening to music, Orienteering, Knapping, Dance, Mountain biking, Fishing, Pottery

Introduction: My name is Duane Harber, I am a modern, clever, handsome, fair, agreeable, inexpensive, beautiful person who loves writing and wants to share my knowledge and understanding with you.