cmc/cleberg.net
My personal web garden & blog.
clone: git clone https://gitbay.org/cmc/cleberg.net.git
main: content/blog/2023-07-12-wireguard-lan.org · raw
1#+date: [2023-07-12 Wed 00:00:00]
2#+title: Mullvad WireGuard with LAN Access
3#+description: Modifying Mullvad WireGuard configs to allow LAN access while connected.
4#+slug: wireguard-lan
5#+filetags: :security:self-hosting:
6
7* Download Configuration Files from Mullvad
8
9To begin, you'll need
10[[https://mullvad.net/account/wireguard-config][Wireguard configuration
11files from Mullvad]]. You can choose any of the options as you download
12them. For example, I enabled the kill switch, selected all countries,
13and selected a few content filters.
14
15Once downloaded, unzip the files and move them to the Wireguard folder
16on your system.
17
18#+begin_src sh
19cd ~/Downloads
20unzip mullvad_wireguard_linux_all_all.zip
21doas mv *.conf /etc/wireguard/
22#+end_src
23
24** Configuration File Layout
25
26The default configuration files will look something like this:
27
28#+begin_src conf
29[Interface]
30# Device: <redacted>
31PrivateKey = <redacted>
32Address = <redacted>
33DNS = <redacted>
34PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT && ip6tables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
35PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT && ip6tables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
36
37[Peer]
38PublicKey = <redacted>
39AllowedIPs = <redacted>
40Endpoint = <redacted>
41#+end_src
42
43#+begin_quote
44Note: If you didn't select the kill switch option, you won't see the
45=PostUp= and =PreDown= lines. In this case, you'll need to modify the
46script below to simply append those lines to the =[Interface]= block.
47#+end_quote
48
49* Editing the Configuration Files
50
51Once you have the files, you'll need to edit them and replace the
52=PostUp= and =PreDown= lines to enable LAN access.
53
54I recommend that you do this process as root, since you'll need to be
55able to access files in =/etc/wireguard=, which are generally owned by
56root. You can also try using =sudo= or =doas=, but I didn't test that
57scenario so you may need to adjust, as necessary.
58
59#+begin_src sh
60su
61#+end_src
62
63Create the Python file that we'll be using to update the Wireguard
64configuration files.
65
66#+begin_src sh
67nano replace.py
68#+end_src
69
70Within the Python file, copy and paste the logic below. This script will
71open a directory, loop through every configuration file within the
72directory, and replace the =PostUp= and =PreDown= lines with the new
73LAN-enabled iptables commands.
74
75#+begin_quote
76Note: If your LAN is on a subnet other than =192.168.1.0/24=, you'll
77need to update the Python script below appropriately.
78#+end_quote
79
80#+begin_src python
81import os
82import fileinput
83
84print("--- starting ---")
85
86dir = "/etc/wireguard/"
87
88for file in os.listdir(dir):
89 print(os.path.join(dir, file))
90 for line in fileinput.input(os.path.join(dir, file), inplace=True):
91 if "PostUp" in line:
92 print("PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL ! -d 192.168.1.0/24 -j REJECT && ip6tables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT")
93 elif "PreDown" in line:
94 print("PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL ! -d 192.168.1.0/24 -j REJECT && ip6tables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT")
95 else:
96 print(line, end="")
97
98print("--- done ---")
99#+end_src
100
101Once you're done, save and close the file. You can now run the Python
102script and watch as each file is updated.
103
104#+begin_src sh
105python3 replace.py
106#+end_src
107
108To confirm it worked, you can =cat= one of the configuration files to
109inspect the new logic and connect to one to test it out.
110
111#+begin_src sh
112cat /etc/wireguard/us-chi-wg-001.conf
113#+end_src
114
115The configuration files should now look like this:
116
117#+begin_src conf
118[Interface]
119# Device: <redacted>
120PrivateKey = <redacted>
121Address = <redacted>
122DNS = <redacted>
123PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL ! -d 192.168.1.0/24 -j REJECT && ip6tables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
124PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL ! -d 192.168.1.0/24 -j REJECT && ip6tables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
125
126[Peer]
127PublicKey = <redacted>
128AllowedIPs = <redacted>
129Endpoint = <redacted>
130#+end_src
131
132If you connect to a Wireguard interface, such as =us-chi-wg-001=, you
133can test your SSH functionality and see that it works even while on the
134VPN.
135
136#+begin_src sh
137wg-quick up us-chi-wg-001
138ssh user@lan-host
139#+end_src
140
141To confirm your VPN connection, you can curl Mullvad's connection API:
142
143#+begin_src sh
144curl https://am.i.mullvad.net/connected
145# You are connected to Mullvad (server us-chi-wg-001). Your IP address is <redacted>
146#+end_src