- Published on
Setting up ProtonVPN on Linux
620 words4 min read
- Authors
Pre-requisites
- Install
openresolv
-apt install openresolv
- Install
iptables
-apt install iptables
Create a Wireguard configuration file
- Install the official WireGuard VPN CLI tool for your distribution
- Sign in to
account.protonvpn.com
, go toDownloads → WireGuard configuration
, and download a WireGuard configuration file. - Download and copy the contents of the new configuration file to your Linux box to the
/etc/wireguard
directory (e.g./etc/wireguard/test-UK-001
) - Confirm it works by running
sudo wg-quick up $configName
(e.g.sudo wg-quick up test-UK-001
) and then runningsudo wg
- Optionally confirm the VPN is running by checking the IP returned by
wget -qO- icanhazip.com
is not your assigned IP address. - End the session by running
sudo wg-quick down $configName
(e.g.sudo wg-quick down test-UK-001
).
Enable and run the Wireguard configuration via systemd
This step ensures that the Wireguard configuration automatically starts on boot
- Run
sudo systemctl enable --now wg-quick@$configName
to create the system service, enable it, and start it immediately (e.g.sudo systemctl enable --now wg-quick@test-UK-001
) - Confirm the service is running with
sudo systemctl status wg-quick@$configName
(e.g. sudo systemctl status wg-quick@test-UK-001`)
Set-up a kill switch
This step uses Wireguards postup
and predown
options to prevent traffic if the VPN interface goes down.
- Edit your confiration under
/etc/wireguard
and add the following under the[Interface]
section. Note: The! -d 192.168.1.0/24
argument excludes the subnet range from the rule, allowing you to still SSH etc. Change this to suit your subnet as appropriate.
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
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
For example:
[Interface]
PrivateKey = abcdefghijklmnopqrstuvwxyz0123456789=
Address = 172.x.y.z/32
DNS = 172.16.0.1
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
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
[Peer]
PublicKey = JPT1veXLmasj2uQDstX24mpR7VWD+GmV8JDkidkz91Q=
Endpoint = us-tx1.wg.ivpn.net:2049
AllowedIPs = 0.0.0.0/0
- Restart the service with
sudo systemctl restart wg-quick@$configName
- Confirm the
iptables
rules have been applied withiptables -L