Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
GNU/Linux UFW VPN kill switch tutorial

GNU/Linux UFW VPN kill switch tutorial

This is a quick guide for setting up a kill switch using UFW (Uncomplicated FireWall). It is assumed you are using OpenVPN and optionally Network-Manager with network-manager-openvpn.

1. (Optional) IP Addresses

Before we can start we're going to need the IP address (or the IP addresses) of your VPN so that we can whitelist those later on, write them down. They are obviously going to be different for every VPN and VPNs with multiple servers, so I'll leave this up to you.

2. Install & Enable UFW

On some systems UFW is installed and enabled by default (Ubuntu, for example). Installation procedure is going to be different for every distribution of GNU/Linux, but once you've got it installed enabling it is easy (assuming you have sudo):

sudo ufw enable

3. Block All Traffic

Block all outgoing traffic:

sudo ufw default deny outgoing

And also block all incoming traffic:

sudo ufw default deny incoming

4. Make an exception for OpenVPN

It is assumed you are using TUN as a network adapter (if you're unsure you most definitely are). Allow outgoing traffic on tun0:

sudo ufw allow out on tun0 from any to any

And optionally allow incoming traffic on tun0 (if you're a seeder, for example):

sudo ufw allow in on tun0 from any to any

Choose 5.A. or 5.B. depending on your VPN situation

5.A. (Optional) Make an exception for your VPN with a static address or range

At this point you're technically done, but with this setup you would need to disable UFW every time OpenVPN needed to connect to your VPN and then re-enable UFW when it has connected. Instead of doing that you could add the IP addresses mentioned earlier as exceptions to UFW.

To add a single IP:

sudo ufw allow out from any to 123.123.123.123

To add a range, use a mask:

sudo ufw allow out from any to 123.123.123.0/24

Go to step 6.

5.B.1 (Optional) Make another exception for OpenVPN

If you didn't follow 5.A, and your VPN service changes/rotates IP addresses you will at least need to allow OpenVPN to somehow communicate to the outside:

sudo ufw allow out 1198/udp
sudo ufw allow in 1198/udp

Here, 1198 is the port number that OpenVPN uses, but be careful as default is actually 1194, you might have to check your VPN configuration files (the line that begins with remote {server} {port} ... or a line with rport {port}) for the actual port number used. Might also need to add the same rules for tcp.

This will allow you to at least disable ufw, connect to your VPN, and then enable ufw again to turn the kill switch back on. You will, however, have to do this every time you want to connect or if you're disconnected, which isn't entirely desirable.

5.B.2 (Optional) Force OpenVPN to use a specific port when authenticating to allow reconnecting

By default, OpenVPN will use a random port when connecting to the VPN. Replace the nobind option from your VPN configuration files with bind to force OpenVPN to use the desired port (1194 by default), and add the desired port (for example port 1198). But beware; this won't work on a system with multiple VPN clients on the same host, e.g. it will only work if you connect to one VPN at a time (unless you specifically bind different ports for different VPNs, of course, but you need to be aware of this).

Example; replace nobind in a /etc/openvpn/client/{name}.conf with:

local 0.0.0.0
lport 1198
bind

The local option is required (trivia: because "the C API" - bind() always takes an address and a port number, so you can't just bind to an address alone.)

There's a high possibility openvpn will try to resolve a host address, in that case add a rule for DNS:

sudo ufw allow out 53
sudo ufw allow in 53

6. Check that it's working

sudo ufw status

And test your internet connection!

7. You're done!

Congratulations, you've configured a VPN Kill switch on your GNU/Linux system!


Thanks to:

@marathone

This comment has been minimized.

Copy link

marathone commented Oct 9, 2018

Thanks for this! The above won't work for me unless I enable outgoing as default. Following your instructions to the 'T' didn't seem to work for me. My rules:
To Action From


Anywhere on tun0 ALLOW Anywhere
Anywhere (v6) on tun0 ALLOW Anywhere (v6)
Anywhere ALLOW OUT Anywhere on tun0
198.144.157.54 ALLOW OUT Anywhere
199.189.26.122 ALLOW OUT Anywhere
159.203.4.110 ALLOW OUT Anywhere
184.75.223.90 ALLOW OUT Anywhere
Anywhere (v6) ALLOW OUT Anywhere (v6) on tun0

@formeroosid

This comment has been minimized.

Copy link

formeroosid commented Feb 4, 2019

You probably need to allow your VPN connections to the outside world. The IP address solution above won't work if your VPN endpoint changes addresses. I would recommend just allowing the ports.

For OpenVPN, you would need the following:
sudo ufw allow out 1198/udp
sudo ufw allow in 1198/udp

@hrvstr

This comment has been minimized.

Copy link

hrvstr commented Feb 26, 2019

Step 5 does not seem to work for me. I have to disable the firewall to reconnect to my VPN.

You probably need to allow your VPN connections to the outside world. The IP address solution above won't work if your VPN endpoint changes addresses. I would recommend just allowing the ports.

For OpenVPN, you would need the following:
sudo ufw allow out 1198/udp
sudo ufw allow in 1198/udp

Also tried this without any luck.

@Necklaces

This comment has been minimized.

Copy link
Owner Author

Necklaces commented Mar 20, 2019

Hey guys, sorry I didn't see this until now, not getting notifications for gists apparently. I've updated the gist a bit, thanks for your input!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.