TL/DR:
- Subscribe to Mullvad VPN if you haven't already or set up a self-hosted WireGuard server.
- Use the vanilla WireGuard client.
- Export a server configuration from Mullvad.
- Update the
AllowedIPs
property to exclude LAN IP ranges.
- Add your corporate intranet DNS server to the
DNS
property.
- Update the
InterfaceMetric
of your connections.
0. Subscribe to Mullvad VPN if you haven't already or set up a self-hosted WireGuard server
Mullvad VPN: https://mullvad.net/en
Setting up a self-hosted WireGuard VPN server is wa-a-ay out of scope of this guide. But I was able to do it using this tutorial:
https://www.digitalocean.com/community/tutorials/how-to-set-up-wireguard-on-ubuntu-22-04
1. Use the vanilla WireGuard client
The Mullvad VPN client does not allow configuring AllowedIPS
or DNS
. Their tech support recommend using the vanilla WireGuard client, but they refuse to assist configuring it. Don't worry, we got you covered!
Download the vanilla WireGuard client here:
https://www.wireguard.com/install/
2. Export a server configuration from Mullvad and import it to the WireGuard client
Visit this link for instructions:
https://mullvad.net/en/help/wireguard-app-windows/
After log in, configuration exporting is available here:
https://mullvad.net/en/account/#/wireguard-config/?platform=windows
Please note that you don't have to export all servers as the manual suggests. Pick just one server for starters, the one that the Mullvad client chooses by default (hopefully it's one of the fastest for you).
Import the configuration to the WireGuard client.
3. Update the AllowedIPs
property to exclude LAN IP ranges.
This is the tricky part.
The AllowedIPs
configuration property name is misleading. What it actually does is defines which IP ranges should be routed through the WireGuard VPN connection. Ranges that are not covered will work directly, outside the VPN.
The problem is that you don't want to allow ranges, you want to exclude ranges! Specifically, you need to exclude all the LAN subnets such as 10.x.x.x
, 172.16.x.x
and 192.168.x.x
.
In order to do that, you need to specify all ranges between and around those LAN ranges, which is not a trivial task at all.
Luckily, there exist online calclators that do this for you. I googled up this one:
https://www.procustodibus.com/blog/2021/03/wireguard-allowedips-calculator/
I input the following ranges:
- Allowed IPs:
0.0.0.0/0
- Disallowed IPs:
10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
And press Calculate. The result is:
AllowedIPs = 0.0.0.0/5, 8.0.0.0/7, 11.0.0.0/8, 12.0.0.0/6, 16.0.0.0/4, 32.0.0.0/3, 64.0.0.0/2, 128.0.0.0/3, 160.0.0.0/5, 168.0.0.0/6, 172.0.0.0/12, 172.32.0.0/11, 172.64.0.0/10, 172.128.0.0/9, 173.0.0.0/8, 174.0.0.0/7, 176.0.0.0/4, 192.0.0.0/9, 192.128.0.0/11, 192.160.0.0/13, 192.169.0.0/16, 192.170.0.0/15, 192.172.0.0/14, 192.176.0.0/12, 192.192.0.0/10, 193.0.0.0/8, 194.0.0.0/7, 196.0.0.0/6, 200.0.0.0/5, 208.0.0.0/4, 224.0.0.0/3
This is the range of all IPs except LAN subnets.
Edit your server ("tunnel") in the WireGuard app and put this line into the [Peer]
section.
Note that you can use the calculator to exclude more IP addresses from the VPN to access them directly.
4. Add your corporate intranet DNS server to the DNS
property.
You need to know which DNS server the corporate intranet is using.
To find it out with a working corporate connection (ask your colleague?), use the follwing while the corporate VPN is connected and intranet resources are accessible.
On Windows:
nslookup <corporate.resource.local>
The output will look like this:
❯ nslookup coroprate.resource.local
Server: ip-10-2-0-2.eu-central-1.compute.internal
Address: 10.2.0.2
Non-authoritative answer:
Name: internal-blah-blah.eu-west-3.elb.amazonaws.com
Addresses: 10.2.3.4 > 10.3.4.5
Aliases: corporate.resource.local
On POSIX (in case your colleague uses MacOS or Linux):
dig <coroprate.resource.local>
❯ dig coroprate.resource.local
; <<>> DiG 9.16.1-Ubuntu <<>> coroprate.resource.local
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32760
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;coroprate.resource.local. IN A
;; ANSWER SECTION:
coroprate.resource.local. 49 IN CNAME internal-garble-garble.eu-west-3.elb.amazonaws.com.
internal-garble-garble.eu-west-3.elb.amazonaws.com. 36 IN A 10.34.9.140
internal-garble-garble.eu-west-3.elb.amazonaws.com. 36 IN A 10.34.8.128
;; Query time: 50 msec
;; SERVER: 10.2.0.2#53(10.2.0.2)
;; WHEN: Wed Apr 05 11:53:23 MSK 2023
;; MSG SIZE rcvd: 156
Copy the IP address of the intranet DNS server (it's in bold in above examples) and paste it into the WireGuard server (tunnel) configuration, into the DNS
proeprty under the [Interface]
section, prepending the existing DNS IP address, separated by a space:
DNS = 10.2.0.2 10.64.0.1
Note: if you're using WSL, it will not use the corporate DNS server. Follow this QA to figure it out:
How do I change the DNS settings for WSL2?
5. Update the InterfaceMetric
of your connections.
Finally, the priority of your corporate VPN interface must be higher than that of WireGuard. To achieve that, you need to make the corporate InterfaceMetric
smaller than that of WireGuard.
You can edit the InterfaceMetric
in the Advanced settings of the TCP/IP stack of your VPN interface:
But I prefer to do it in the terminal.
Start PowerShell as an administrator and run this command:
Get-NetIPInterface | Sort-Object Interfacemetric
In the output, find your corporate VPN interface and WireGuard and compare their InterfaceMetric
(fragment shown):
> Get-NetIPInterface | Sort-Object Interfacemetric
ifIndex InterfaceAlias AddressFamily NlMtu(Bytes) InterfaceMetric Dhcp ConnectionState PolicyStore
------- -------------- ------------- ------------ --------------- ---- --------------- -----------
27 VPN - VPN Client IPv4 1500 1 Enabled Disconnected ActiveStore
54 Pritunl 1 IPv6 1500 25 Enabled Disconnected ActiveStore
53 se-sto-wg-011 IPv4 1420 10 Disabled Connected ActiveStore
There may be duplicate entries, don't worry about that.
The InterfaceMetric
of the coroprate VPN interface must be lower than that of WireGuard.
If it's not, use this command to update InterfaceMetric
s:
Set-NetIPInterface -InterfaceIndex <ifIndex> -InterfaceMetric <value>
I set the corporate value to 3 and WireGuard to 5.
Success! 😸
You're done! Connect WireGuard first, then the corporate VPN. You should have access now.