VPN-Firewall - enforces that your VPN gets actually used
If you simply add a VPN using common instructions, it generally fails open. That means, if the VPN breaks down, because the connection is interrupted, traffic will be send without the VPN.
It’s much safer when it fails closed, i.e. when the VPN connection breaks down, the whole internet connection must be down as long as the VPN connection isn’t restored.
What does it do
- Forbid outgoing traffic after the VPN / tunnel software broke down for some reason.
- Tight firewall rules, using iptables policy drop.
- Defeat shared VPN/Tor server leak bug.
- Only tested with OpenVPN. Should work with other VPN and tunnel clients such as PPTP in theory, you should test if it does what it claims anyway.
- Only tested on Debian Jessie. Should work in many Linux distribution supporting netfilter-persistent in theory, you should test if it does what it claims.
- Open Source / Free Software
What does it NOT do
- Care about DNS leaks. If you want to ensure that no plaintext nameserver request packets are being leaked over the course of your VPN session then you will need to analyze the packets leaving your hardware NIC.
- Block WebRTC leaks. 
- Defend against IP leaks. If a locally installed application uses trickery to obtain the the users real IP and sends it somewhere though the VPN. 
- Defend against adversaries, which are in position to run code locally, i.e. manipulate the firewall rules.
- Prevent any other kind trickery to circumvent using the VPN.
- Prevent leaks caused by bugs in the VPN software.
- Be compatible with Whonix-Gateway/Workstation. (VPN-Firewall is incompatible with Whonix-Gateway/Workstation’s firewall! Use Whonix documentation and use their built-in features.)
- Manage IPv6 traffic. IPv6 traffic is blocked.
- Install (Open)VPN.
- Configure (Open)VPN.
- Autostart (Open)VPN.
- Anything else not mentioned above in “What does it do”.
 This probably does not apply to VMs / computers behind a VPN-Gateway (when using the #Forwarding feature).
|You should test if VPN-Firewall does what it claims.|
|Use VPN-Firewall outside of Whonix only! (Whonix users should use the built-in VPN_FIREWALL features of Whonix-Gateway and/or Whonix-Workstation, see Tunnels/Introduction and its sub pages for documentation.)|
- 1 Why
- 2 What does it do
- 3 What does it NOT do
- 4 How to use VPN-Firewall
- 4.1 Preparation
- 4.2 Remove old versions of VPN-Firewall
- 4.3 Qubes specific
- 4.4 VPN Setup
- 4.4.1 Introduction
- 4.4.2 Get VPN Certificate
- 4.4.3 VPN Credentials
- 4.4.4 VPN IP Address
- 4.4.5 VPN Configuration File
- 4.4.6 install resolvconf
- 4.4.7 DNS Configuration
- 4.4.8 add user account tunnel
- 4.4.9 Configure Folder Permissions
- 4.4.10 systemd setup
- 4.4.11 resolvconf adjustments
- 4.4.12 Verify DNS Settings
- 4.4.13 Test the VPN
- 4.4.14 Install VPN-Firewall
- 4.4.15 Forwarding
- 4.4.16 Start VPN-Firewall
- 4.4.17 Test VPN-Firewall
- 4.4.18 Qubes specific - Fallback Firewall
- 4.4.19 Done
- 5 Appendix
- 5.1 Troubleshooting
- 5.1.1 ip_unpriv vs ip-unpriv
- 5.1.2 50_openvpn_unpriv.conf vs 50_openvpn-unpriv.conf
- 5.1.3 Cannot ioctl TUNSETIFF
- 5.1.4 Dev tun missmatch
- 5.1.5 /run/openvpn/openvpn.status Permission denied
- 5.1.6 debug start
- 5.1.7 Linux ip link set failed
- 5.1.8 DNS Configuration
- 5.1.9 Terminology for Support Requests
- 5.2 Unload VPN Firewall
- 5.3 Security Discussion
- 5.4 Alternatives
- 5.1 Troubleshooting
- 6 Footnotes
How to use VPN-Firewall
Since setting up OpenVPN including a secure, leak preventing fail closed mechanism is challenging, it is highly recommend to learn how to set up OpenVPN on Debian stable (currently: jessie). Get a Debian stable VM. Install the Debian openvpn package. (sudo apt-get install openvpn) Figure out how to set up your VPN using OpenVPN in the command line. Only proceed if you succeeded setting that up. Do not post support requests regarding these instructions before you succeeded with that basic exercise. You find some help with general VPN setup in the #VPN Setup chapter or on the TestVPN page. There however are ways to get help from various sources for that basic exercise, also your VPN provider may be of assistance.
Existing users who upgrade may remember variable VPN_SERVERS. Don't wonder. That variable was abolished for better security. 
Remove old versions of VPN-Firewall
If you had any installed. Otherwise you can skip this.
sudo update-rc.d vpnfirewall remove sudo update-rc.d vpn-firewall remove sudo rm /usr/local/bin/vpnfirewall sudo rm /usr/bin/vpnfirewall sudo rm /usr/bin/vpn-firewall sudo rm /etc/init.d/vpnfirewall sudo rm /etc/init.d/vpn-firewall
Non-Qubes users can ignore this.
2) Enable netfilter-persistent Qubes qvm-service.
Qubes VM Manager -> right click on VM -> services -> enter (without the single quotes) 'netfilter-persistent' -> click on + -> OK
In the following example we are using the free Riseup VPN, because it is known to support TCP, UDP, SSL. You can use any VPN you like.
Update: Riseup "legacy" VPN may have been discontinued. It did not work anymore for the author of these instructions. The riseup replacement service bitmask has not been tested.
Get VPN Certificate
scurl https://help.riseup.net/security/network-security/riseup-ca/RiseupCA.pem | sudo tee /etc/openvpn/RiseupCA.pem
You need a riseup.net account. You need to know your riseup account name. Go to https://user.riseup.net/users/riseupusername/vpn to obtain your VPN secret. (VPN password) (Replace "riseupusername" with your actual riseup user name.) (Or just got to https://user.riseup.net, login and click on "VPN".)
Open /etc/openvpn/auth.txt in an editor with root rights.
Add. (Add your actual user name and password.)
VPN IP Address
Note, you must use IP addresses. You cannot use DNS hostnames. For example, you could not use vpn.riseup.net. You have to use IP addresses such as for example 220.127.116.11. You find out the IP from your provider or by using nslookup on the host. Example. (You need to use your actual DNS hostname, not vpn.riseup.net.)
VPN Configuration File
Open /etc/openvpn/openvpn.conf in an editor with root rights.
Note: make sure to adjust thevariable in your config (unless you are using as your VPN service). Replace the IP ( ) and port ( ) to match your VPN service.
############################## ## VPN provider specific settings ## ############################## auth-user-pass auth.txt ## using nyc.vpn.riseup.net 80 remote 18.104.22.168 80 ca RiseupCA.pem remote-cert-tls server ############################# ## VPN-Firewall specific settings ## ############################# client dev tun0 persist-tun persist-key script-security 2 up "/etc/openvpn/update-resolv-conf script_type=up dev=tun0" down "/etc/openvpn/update-resolv-conf script_type=down dev=tun0" user tunnel iproute /usr/bin/ip-unpriv
Update package lists.
sudo apt-get update
Install resolvconf. 
sudo apt-get install resolvconf
(If you do not wish to install resolvconf then please see footnotes. )
Open /etc/resolvconf/run/interface/original.resolvconf in an editor with root rights.
Comment everything out by adding a # in front of all entries. Alternatively empty or delete that file. 
add user account tunnel
sudo adduser tunnel
Configure Folder Permissions
Since we will be running OpenVPN under user tunnel, that user requires read access to folder /etc/openvpn.
sudo chown -R tunnel:tunnel /etc/openvpn
sudo chown -R tunnel:tunnel /var/run/openvpn
Create the OpenVPN systemd service file.
sudo cp /lib/systemd/system/openvpn@.service /email@example.com
Enable the OpenVPN systemd service file.
sudo systemctl enable openvpn@openvpn
Start the OpenVPN systemd service.
sudo service openvpn@openvpn start
Check the OpenVPN systemd service status.
sudo service openvpn@openvpn status
Restart resolvconf. 
sudo service resolvconf restart
Verify DNS Settings
See current /etc/resolv.conf settings.
sudo cat /etc/resolv.conf
Should not include your original DNS settings.
Test the VPN
Ping test. Ping some IP. In the example below, we ping google's DNS server. Maybe better use some server of your choice.
Test DNS and output IP address. Remember these results so you can compare it to what you get later after VPN-Firewall is installed and running.
sudo apt-get install debhelper faketime make dpkg-dev devscripts netfilter-persistent git config-package-dev ruby-ronn
git clone https://github.com/adrelanos/vpn-firewall.git
Signed git tags and commits available. TODO: document how to verify, use some wiki template
If you want to forward traffic for virtual machines (or other computers on the LAN), it can be enabled through an option.
|Experimental! (The forwarding feature has not yet been tested for leaks!)|
|The forwarding feature has only been developed and tested in a Qubes ProxyVM. Non-Qubes is unsupported!|
(The forwarding feature was introduced in May 29 2016. You might need to update vpn-firewall.)
Create a new folder.
- Qubes users: run the following command.
- Non-Qubes users: can skip this.
sudo mkdir -p /rw/config/vpn-firewall.d/
Create a new file.
- Qubes users: /rw/config/vpn-firewall.d/50_user.conf
- Non-Qubes users: /etc/vpn-firewall.d/50_user.conf
Qubes users only: create qvm-service netfilter-persistent status file.
sudo touch /var/run/qubes-service/netfilter-persistent
Start VPN-Firewall by restarting netfilter-persistent. 
sudo service netfilter-persistent restart
Check netfilter-persistent status.
sudo service netfilter-persistent status
Should look like the following.
● netfilter-persistent.service - netfilter persistent configuration Loaded: loaded (/lib/systemd/system/netfilter-persistent.service; enabled) Drop-In: /lib/systemd/system/netfilter-persistent.service.d └─30_qubes.conf Active: active (exited) since Wed 2016-05-11 19:21:36 UTC; 2s ago Process: 3950 ExecStop=/usr/sbin/netfilter-persistent stop (code=exited, status=1/FAILURE) Process: 3954 ExecStart=/usr/sbin/netfilter-persistent start (code=exited, status=0/SUCCESS) Main PID: 3954 (code=exited, status=0/SUCCESS) May 11 19:21:36 work netfilter-persistent: run-parts: executing /usr/share/netfilter-persistent/plugins.d/30_vpn-firewall start May 11 19:21:36 work netfilter-persistent: OK: The firewall should not show any messages, May 11 19:21:36 work netfilter-persistent: OK: besides output beginning with prefix OK:... May 11 19:21:36 work netfilter-persistent: OK: VPN firewall loaded. May 11 19:21:36 work systemd: Started netfilter persistent configuration.
(There will only be a 30_qubes.conf drop-in for Qubes users. Non-Qubes users can ignore this.)
At next boot, VPN-Firewall should be automatically starting. It would not hurt to check it really does by checking netfilter-persistent status at next boot.
1) Have VPN-Firewall set up as per above instructions.
2) Test if it works. Check whatismyipaddress.com to see if you your external IP is from the VPN. Check your DNS using dnsleaktest.com as well and compare these results to the results you had earlier. If your nameserver is the same as before or does not match your VPN's DNS then there is a problem and you will need to troubleshoot.
3) Kill the VPN client.
sudo killall openvpn
4) Check if you can still connect to whatismyipaddress.com.
If yes, bad, something is wrong.
If no, good, you won't connect to any remote servers.
Qubes specific - Fallback Firewall
Qubes users only. Non-Qubes users can skip this chapter.
Untested! Please test and leave feedback!
The following is great for users for additional protection from leaks. This fallback is as save as previous ways to firewall VPNs. It however would not defeat the shared VPN/Tor server leak bug. (It however is awful for developers since this would cloak eventual leaks in VPN-Firewall.)
Qubes VM Manager -> sys-vpn -> right click -> VM Settings -> Firewall rules -> choose "deny all network access except..." -> add the IP and port of your VPN server -> OK
You can skip this troubleshooting chapter unless you notice any issues.
ip_unpriv vs ip-unpriv
There are two similar distinct projects. Standalone VPN-FIREWALL and Whonix TUNNEL_FIREWALL. They share a lot similarities, but one difference that you might stumble upon. In chapter #VPN Configuration File there is a difference.
- Whonix TUNNEL_FIREWALL uses ip_unpriv (underscore)
- Standalone VPN-FIREWALL uses ip-unpriv (hyphen)
So make sure you are using the right version of ip unpriv according to the project you are using, VPN-FIREWALL and Whonix TUNNEL_FIREWALL.
50_openvpn_unpriv.conf vs 50_openvpn-unpriv.conf
Similar to above...
- Whonix TUNNEL_FIREWALL uses /usr/lib/tmpfiles.d/50_openvpn_unpriv.conf ip_unpriv (underscore)
- Standalone VPN-FIREWALL uses /usr/lib/tmpfiles.d/50_openvpn-unpriv.conf ip-unpriv (hyphen)
Cannot ioctl TUNSETIFF
ERROR: Cannot ioctl TUNSETIFF tun: Operation not permitted (errno=1)
In openvpn.conf do not use.
Dev tun missmatch
In openvpn.conf do not use.
/run/openvpn/openvpn.status Permission denied
Options error: --status fails with '/run/openvpn/openvpn.status': Permission denied
Do not start openvpn as root. Do not use "sudo openvpn". This would lead to permission issues. Files in /run/openvpn folder owned by root. So they cannot be overwritten by user tunnel.
Debug start in command line.
sudo /usr/sbin/openvpn --rmtun --dev tun0 sudo /usr/sbin/openvpn --mktun --dev tun0 --dev-type tun --user tunnel --group tunnel cd /etc/openvpn/ sudo -u tunnel openvpn /etc/openvpn/openvpn.conf
Linux ip link set failed: external program exited with error status: 2
Use ip_unpriv as documented above.
If you are using resolvconf only...
You may need to manually change permissions on two directories if they are not automatically applied. Check to see if changes are necessary by running the following command:
ls -al /run/resolvconf
If the output lists tunnel as having read/write/execute permissions for both /run/resolvconf and /run/resolvconf/interface then you will not need to modify anything. If tunnel is not listed as group for one or both of these directories then you will need to change the permissions, like so:
sudo chown --recursive root:tunnel /run/resolvconf
then you will need to set the permissions bits
sudo chmod --recursive 775 /run/resolvconf
In /run/resolvconf, resolv.conf may or may not be owned by tunnel depending on whether the systemd service has started already or not. There is no need to modify permissions on this file, as its permissions will change when the service starts.
Terminology for Support Requests
Phrases such as "over Tor" are ambiguous. Please do not prevent your own coining of words. That leads to people talking past each other. Please use the same terms that are consistently used in documentation such as.
- How to connect to a VPN before Tor (User -> VPN -> Tor -> Internet)
- How to connect to Tor before a VPN (User -> Tor -> VPN -> Internet)
Always refer to the connection scheme, User -> VPN -> Tor -> Internet or User -> Tor -> VPN -> Internet etc.
Unload VPN Firewall
How to unload VPN Firewall? If you know what you are doing... Either...
sudo /usr/share/netfilter-persistent/plugins.d/30_vpn-firewall flush
sudo service netfilter-persistent flush
Statement by the creator of VPN-Firewall, Patrick Schleizer.
I don't think I can ever make this standalone VPN-Firewall project as leak proof as Whonix as is. This is because I invented VPN-Firewall alone from scratch - in comparison Whonix was an evolution of existing previous documentation and created by multiple contributors. Also VPN-Firewall is younger, receives less attention by the community, and a lot more difficult to set up than Whonix. All these factors lead to lower popularity and thereby less eyes on the implementation. Specifically the #Forwarding feature should be activated with care, since it is my first project using IP forwarding. If you have any suggestions on how to avoid IP forwarding, please make them.
- One could play with the linux equivalent of the route command.
- Hardening your VPN Setup with iptables
- VPNCheck - No source code. Nice looking user interface.
- VPNetMon - No source code. Windows only. Checks every, let’s say 500 ms, if the VPN IP is still valid, if not, kill a list of applications. This is not very secure, it’s a game if that time period is sufficient to stop a leak and if killing the applications is fast enough. Nice looking user interface.
- OPENVPN Watchdog - No source code. Windows only. Nice looking user interface.
- [VPN Lifeguard](https://sourceforge.net/projects/vpnlife)
This is due to technical limitations. The VPN-Firewall instructions assume to modify a files located in the root image, which by default do not persist in TemplateBasedVMs. So a convenient one time setup and then having it just work including autostart of VPN-Firewall and OpenVPN will not work yet. Help welcome!
In future, perhaps the following instructions could be made to work after some bind-dirs.sh enhancements.
When using a TemplateBasedVM, to persist these changes use the Qubes bind dirs mechanism.
sudo mkdir /rw/config/qubes-bind-dirs.d
Open /rw/config/qubes-bind-dirs.d/50_user.conf in an editor with root rights.
binds+=( '/etc/openvpn' ) binds+=( '/firstname.lastname@example.org' ) binds+=( '/email@example.com' )
TODO: Does not work yet. Files need to exist first.
TODO: umount during run is probably not sane.
TODO: re-running bind-dirs.sh without previous umount does not work yet.
- /etc/openvpn/update-resolv-conf uses resolvconf. You will need to install resolvconf in order for the lines beginning with script-security, up, and down to function properly.
In /etc/openvpn/openvpn.conf file change...
script-security 2 up "/etc/openvpn/update-resolv-conf script_type=up dev=tun0" down "/etc/openvpn/update-resolv-conf script_type=down dev=tun0"
to this (i.e. remove or out comment the lines beginning with "up" and "down" and change the 2 to a 1)
Open /etc/resolv.conf in an editor with root rights.
## Riseup.net OpenVPN DNS server nameserver 172.27.100.1
If you are not using riseup, you need to replace 172.27.100.1 and enter the virtual LAN IP address of your VPN providers DNS server. You might be able to obtain it from your VPN provider. You can also try to infer it after successfully connecting to the VPN from running "sudo route". The first destination default gateway should function as DNS server also.
If you want to be sure, that /etc/resolv.conf does not get overwritten by other packages. (Such as DHCP or resolvconf.)
sudo chattr +i /etc/resolv.conf
If you ever want to remove it, use -i.
Ignore /etc/resolv.conf instructions below.
- This is done to prevent the old DNS server being used. Further discussion: https://github.com/adrelanos/vpn-firewall/issues/16
- So changes in /etc/resolvconf/run/interface/original.resolvconf from chapter #DNS Configuration take effect.
- Debian feature request: add dpkg trigger for /usr/share/netfilter-persistent/plugins.d folder to have newly installed plugins take effect
Impressum | Datenschutz | Haftungsausschluss
Conditions for Contributions to Whonix, then Edit! IP addresses are scrubbed, but editing over Tor is recommended. Edits are held for moderation. Whonix (g+) is a licensee of the Open Invention Network. Unless otherwise noted above, the content of this page is copyrighted and licensed under the same Free (as in speech) license as Whonix itself.