Question about Wireguard on Linux set up via terminal. Please help & clarify!

I asked this question in the chat but got no response so making a post about it to try my luck again:

If Wireguard is set up on Linux via the terminal with a conf file and wg-quick - is the killswitch auto enabled with it or does killswitch not apply/work if a VPN is set up this way. I am on Linux Mint.

ProtonVPN app randomly and suddenly stopped working for me on Mint so I decided to learn this way. It works now and I have set it up and also enabled auto start on system startup but I need clarification on killswitch.

I appreciate any insight anyone may have. Thanks!

WireGuard doesn’t have a built-in kill switch by default, but you can create one using firewall rules to block all traffic if the VPN disconnects.

There are two ways to do this:

Option 1: Use PostUp and PreDown in the WireGuard config (Recommended)

This method automates the process and makes it easier to switch the VPN on and off without manually adjusting firewall rules.
Add these lines in the [Interface] section of your WireGuard config:

PostUp = iptables -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 -j REJECT

Here’s a breakdown of what those PostUp and PreDown commands do:

  • PostUp: This command is executed when the WireGuard interface is brought up (i.e., when the VPN is connected, sudo wg-quick up wg0).

    • iptables -I OUTPUT: This inserts a new rule into the OUTPUT chain, which controls outgoing traffic.
    • ! -o %i: %i is a placeholder for the interface name (e.g., wg0). This rule matches any traffic not going through the WireGuard interface.
    • -m mark ! --mark $(wg show %i fwmark): This ensures the rule doesn’t apply to traffic that is already marked by WireGuard, preventing conflicts with marked packets.
    • -m addrtype ! --dst-type LOCAL: This excludes local traffic (such as to your own machine), ensuring that local connections aren’t blocked.
    • -j REJECT: This rejects any other outgoing traffic not going through the VPN.
  • PreDown: This command is executed when the WireGuard interface is brought down (i.e., when the VPN is disconnected, sudo wg-quick down wg0).

    • iptables -D OUTPUT: This deletes the rule that was added when the interface was brought up, removing the restriction on outgoing traffic.
    • The rest of the command is the same as PostUp, but instead of inserting the rule, it removes it.

Option 2: Set up firewall rules manually with iptables

  1. First, find your WireGuard interface name (e.g., wg0, wg1) and your default network interface name (e.g., eth0, wlan0).
  2. Then, add the following firewall rules using iptables to block traffic unless WireGuard is active:
# Allow traffic through the WireGuard interface
sudo iptables -A OUTPUT -o wg0 -j ACCEPT
sudo iptables -A INPUT -i wg0 -j ACCEPT

# Allow established connections
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Block all other outgoing traffic (replace eth0 with your default interface)
sudo iptables -A OUTPUT -o eth0 -j DROP

Make sure to save these rules so they persist after a reboot using iptables-save and iptables-restore. One downside of this method is that you’d need to manually adjust the firewall rules every time you want to stop using the VPN.

2 Likes

Wow thanks for the detailed info!

I am not sure I am this tech savvy to understand all of this and implement this on my end. I was only able to set up wireguard via terminal following simple step by step guidelines from the support pages from Proton and Mullvad.

That said, I will definitely try to implement this but I also don’t want to break/brick/mess with networking too much or to a point where I make a mistake and I have no internet at all. I do want to learn!

Follow up questions:

  1. Do you mean, I should add this in the config file that’s in the etc and wireguard folder?

  2. Do I add this in the end or the beginning of the interface section?

  3. Do I simply copy-paste your code and save the file or do I have to make any changes to what you have in your comment? Correct me if I’m wrong but this is the same as what I see on the Mullvad’s support page?

  4. Will I simply and still be able to disconnect from the VPN with the sudo wg-quick down command after doing this?

  5. Is killswitch for a VPN set up with wireguard via the terminal even needed? I do want to ensure all traffic goes through my VPN but I don’t know under what circumstances traffic will go outside of it if one doesn’t have killswitch enabled.

  6. Do these instructions apply for Fedora too? I’m guessing these wireguard instructions are not distro specific.

Once you clarify again - I’ll try this with confidence. Thanks again for your help!

Edit: Mullvad has an extra line for each in addition to what you have:

PostUp  =  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
PreDown = 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

Which one should I follow? I do have a ProtonVPN confid file but wireguard should work the same no matter the VPN so I’m guessing it should be okay - please clarify.

Okay, I jumped the gun and made the change and tried it. It works. I mean, I have no issues anymore so I the killswitch is indeed turned on.

Thank you again!

Yes, you need to add this to your WireGuard configuration file, typically located in /etc/wireguard/ (e.g., wg0.conf). It doesn’t really matter where you place it within the [Interface] section, but for readability, I recommend adding it at the end, like this:

[Interface]
PrivateKey = YOUR_PRIVATE_KEY
Address = 10.0.0.1/24
ListenPort = 51820

PostUp  = 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
PreDown = 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

[Peer]
PublicKey = PEER_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32

The only difference betwen my command and the Mullvad command is that Mullvad adds rules to both iptables (for IPv4) and ip6tables (for IPv6). This ensures the kill switch works for both types of traffic. Even if you only use IPv4, it won’t hurt to leave the IPv6 rule in place.
So just use the Mullvad command and you don’t need to change anything.

Yes, running sudo wg-quick down wg0 will still work. When the VPN is disconnected, it will run the PreDown command to remove the firewall rules, allowing your normal internet connection to resume.

Without a kill switch, there are several situations where your traffic could bypass the VPN.

  • VPN Disconnection: If the VPN drops due to network instability or server issues, your device could switch back to using your regular internet, exposing your data.
  • Network Changes: Switching between Wi-Fi and mobile data might cause leaks if the VPN doesn’t reconnect properly.
  • Application Behavior: Some applications may not respect the VPN connection and could attempt to connect directly to the internet.
  • Misconfigurations: Incorrect VPN settings could lead to traffic leaks.
  • DNS Leaks: Even if your traffic is routed through the VPN, DNS queries might still go through your ISP.

Yes, these instructions are distro-independent. This should work on Fedora, Mint and any other Linux distribution since WireGuard and iptables are not specific to any particular OS.

1 Like

Ok, good to know.
I’ve still posted my reply, so all of your questions should be addressed.

1 Like

Yes! I learned a lot. Thanks again.