VPN-Firewall: Enforce use of a VPN
Instructions on how to use VPN-Firewall. A Fail Closed Mechanism for VPNs. Prevent leaks when using VPNs. Force all connections through VPNs. Prevents shared VPN/Tor server leak bug.
Why[edit]
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[edit]
- 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 bookworm. 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[edit]
- 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. [1]
- 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. [1]
- 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”.
[1] This probably does not apply to VMs / computers behind a VPN-Gateway (when using the #Forwarding feature).
How to use VPN-Firewall[edit]
Preparation[edit]
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: bookworm). Get a Debian stable VM. Install the Debian openvpn package. (sudo apt 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 Tunnels/Examples 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. [1]
Remove old versions of VPN-Firewall[edit]
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
Qubes specific[edit]
Non-Qubes users can ignore this.
1) If you are using Qubes OS as your host operating system, it is recommended to use a StandaloneVM for this. For more information, see footnote. [2]
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
VPN Setup[edit]
Introduction[edit]
Get VPN Certificate[edit]
- Inspect the Riseup Certificate Authority page and download (right-click) the Riseup CA certificate. [3]
- Advanced users can optionally verify the Riseup CA certificate before storing it. [4]
- Store the certificate in
/etc/openvpn/RiseupCA.pem
:
curl --tlsv1.3 https://help.riseup.net/security/network-security/riseup-ca/RiseupCA.pem | sudo tee /etc/openvpn/RiseupCA.pem
VPN Credentials[edit]
For this example, for this step, a Riseup account is required. Unfortunately, the former free VPN service is no longer available. [5] This means to create an account you will need an "invite code" from a current Riseup user.
- If you have one:
- 1. Navigate to the account creation page in Tor Browser.
- 2. Enter the invite code.
- 3. Choose a username unrelated to your real identity.
- 4. Enter a strong password.
- If you do not have an invite code:
- Please do not ask Whonix developers or forums for an invite code because none will be available.
- Instead tailor the instructions in this section to work with any other OpenVPN provider.
1. Open file /etc/openvpn/auth.txt
in an editor with root rights.
Qubes-Whonix™
NOTES:
- When using Qubes-Whonix, this needs to be done inside the Template.
sudoedit /etc/openvpn/auth.txt
- After applying this change, shutdown the Template.
- All App Qubes based on the Template need to be restarted if they were already running.
- This is a general procedure required for Qubes and unspecific to Qubes-Whonix™.
Others and Alternatives
- This is just an example. Other tools could achieve the same goal.
- If this example does not work for you or if you are not using Whonix, please refer to this link.
sudoedit /etc/openvpn/auth.txt
2. Add.
Note: Replace riseupusername
with the actual Riseup user name and replace vpnsecret
with the actual user name and password or just go to account.riseup.net, log in and click on "VPN".
riseupusername vpnsecret
3 . Save and exit.
VPN IP Address[edit]
When editing the VPN configuration file the use of DNS hostnames is not supported. This means IP address(s) of the VPN must be used. [6] Therefore, vpn.riseup.net
cannot be used, but an IP address such as 198.252.153.226 should be used instead. To discover the IP address, check with the VPN provider or use nslookup on the host operating system (OS) (outside any virtual machine (VM)). For example, to verify the actual IP address of the vpn.riseup.net
DNS server, run.
nslookup vpn.riseup.net
VPN Configuration File[edit]
Open file /etc/openvpn/openvpn.conf
in an editor with root rights.
Qubes-Whonix™
NOTES:
- When using Qubes-Whonix, this needs to be done inside the Template.
sudoedit /etc/openvpn/openvpn.conf
- After applying this change, shutdown the Template.
- All App Qubes based on the Template need to be restarted if they were already running.
- This is a general procedure required for Qubes and unspecific to Qubes-Whonix™.
Others and Alternatives
- This is just an example. Other tools could achieve the same goal.
- If this example does not work for you or if you are not using Whonix, please refer to this link.
sudoedit /etc/openvpn/openvpn.conf
Add.
Note: make sure to adjust the remote 198.252.153.226 80 variable in your config (unless you are using nyc.vpn.riseup.net as your VPN service). Replace the IP (198.252.153.226) and port (80) to match your VPN service.
############################## ## VPN provider specific settings ## ############################## auth-user-pass auth.txt ## using nyc.vpn.riseup.net 80 remote 198.252.153.226 80 ca RiseupCA.pem remote-cert-tls server keysize 256 auth SHA256 cipher AES-256-CBC ############################# ## 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"
Save.
install resolvconf[edit]
Update the package lists.
sudo apt update
Install resolvconf
. [7]
sudo apt install resolvconf
Users preferring not to install resolvconf should read the footnotes. [8]
DNS Configuration[edit]
Open file /etc/resolvconf/run/interface/original.resolvconf
in an editor with root rights.
Non-Qubes-Whonix™
This box uses sudoedit
for better security.
sudoedit /etc/resolvconf/run/interface/original.resolvconf
Qubes-Whonix™
NOTES:
- When using Qubes-Whonix, this needs to be done inside the Template.
sudoedit /etc/resolvconf/run/interface/original.resolvconf
- After applying this change, shutdown the Template.
- All App Qubes based on the Template need to be restarted if they were already running.
- This is a general procedure required for Qubes and unspecific to Qubes-Whonix™.
Others and Alternatives
- This is just an example. Other tools could achieve the same goal.
- If this example does not work for you or if you are not using Whonix, please refer to this link.
sudoedit /etc/resolvconf/run/interface/original.resolvconf
Comment everything out by adding a # in front of all entries. Alternatively, empty or delete that file. [9]
Save and exit.
add user account tunnel[edit]
sudo adduser tunnel
Configure Folder Permissions[edit]
Since OpenVPN will be run under user tunnel
, that user requires read access to the folder /etc/openvpn
.
sudo chown -R tunnel:tunnel /etc/openvpn
sudo chown -R tunnel:tunnel /run/openvpn
systemd setup[edit]
1. Create the OpenVPN systemd service file.
sudo cp /lib/systemd/system/openvpn@.service /lib/systemd/system/openvpn@openvpn.service
2. Enable the OpenVPN systemd service file.
sudo systemctl enable openvpn@openvpn
3. Start the OpenVPN systemd service.
sudo systemctl start openvpn@openvpn
4.Check the OpenVPN systemd service status.
sudo systemctl status openvpn@openvpn
resolvconf adjustments[edit]
Restart resolvconf
. [10]
sudo service resolvconf restart
Verify DNS Settings[edit]
See current /etc/resolv.conf settings.
sudo cat /etc/resolv.conf
Should not include your original DNS settings.
Test the VPN[edit]
Ping test. Ping some IP. In the example below, we ping google's DNS server. Maybe better use some server of your choice.
ping 8.8.8.8
Test TCP.
TODO
DNS Test.
nslookup google.com
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.
scurl --remote-name myip.is
Or manually run curl with these parameters. [11]
curl --tlsv1.3 --remote-name myip.is
Install VPN-Firewall[edit]
sudo apt install debhelper faketime make dpkg-dev devscripts netfilter-persistent git config-package-dev ruby-ronn
git clone https://github.com/adrelanos/vpn-firewall.git
cd vpn-firewall
Signed git tags and commits available. TODO: document how to verify, use some wiki template
make deb-icup
Forwarding[edit]
If you want to forward traffic for virtual machines (or other computers on the LAN), it can be enabled through an option.
(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
Add.
FORWARDING=true
Save.
Start VPN-Firewall[edit]
Qubes users only: create qvm-service netfilter-persistent status file.
sudo touch /run/qubes-service/netfilter-persistent
Start VPN-Firewall by restarting netfilter-persistent. [12]
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[3954]: run-parts: executing /usr/share/netfilter-persistent/plugins.d/30_vpn-firewall start May 11 19:21:36 work netfilter-persistent[3954]: OK: The firewall should not show any messages, May 11 19:21:36 work netfilter-persistent[3954]: OK: besides output beginning with prefix OK:... May 11 19:21:36 work netfilter-persistent[3954]: OK: VPN firewall loaded. May 11 19:21:36 work systemd[1]: 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.
Test VPN-Firewall[edit]
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.
Example OpenVPN:
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[edit]
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 safe 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
Done[edit]
Done.
Appendix[edit]
Troubleshooting[edit]
You can skip this troubleshooting chapter unless any difficulties are encountered.
ip_unpriv vs ip-unpriv[edit]
There are two similar, yet distinct projects: standalone VPN-FIREWALL and Whonix TUNNEL_FIREWALL. Although both are alike, there is one difference that might be encountered. For instance, in the VPN Configuration File section:
- Whonix TUNNEL_FIREWALL uses ip_unpriv (underscore)
- Standalone VPN-FIREWALL uses ip-unpriv (hyphen)
Be sure to use the right version of ip unpriv depending on whether VPN-FIREWALL or Whonix TUNNEL_FIREWALL is in use.
50_openvpn_unpriv.conf vs 50_openvpn-unpriv.conf[edit]
Like the example 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[edit]
ERROR: Cannot ioctl TUNSETIFF tun: Operation not permitted (errno=1)
In openvpn.conf
do not use.
dev tun
Use.
dev tun0
Dev tun Mismatch[edit]
In openvpn.conf
do not use.
dev tun
Use.
dev tun0
/run/openvpn/openvpn.status Permission denied[edit]
Options error: --status fails with '/run/openvpn/openvpn.status': Permission denied
To avoid permission issues, do not:
- start OpenVPN as root; or
- use
sudo openvpn
.
Files in the /run/openvpn
folder are owned by root, so they cannot be overwritten by the user tunnel
.
debug start[edit]
To start debug, run the following commands successively.
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[edit]
Linux ip link set failed: external program exited with error status: 2
Use ip_unpriv as documented above.
Connectivity Test[edit]
1. Check if TCP is functional.
- without DNS:
- The following command uses an IP address
116.202.120.181
. - UWT_DEV_PASSTHROUGH=1 curl --tlsv1.3 --proto =https -H 'Host: check.torproject.org' -k https://116.202.120.181/api/ip
- The following command uses an IP address
2. Check if DNS + TCP is functional.
- with DNS:
- The following command uses a hostname
check.torproject.org
. - UWT_DEV_PASSTHROUGH=1 curl --tlsv1.3 --proto =https https://check.torproject.org/api/ip
- The following command uses a hostname
DNS Configuration[edit]
This only applies if resolvconf
is in use.
Permissions on two directories may need to be manually changed if they are not automatically applied. Check if changes are necessary with the following command.
ls -la /run/resolvconf
If the output lists tunnel
as having read / write / execute permissions for both /run/resolvconf
and /run/resolvconf/interface
, then nothing needs modification. If tunnel
is not listed as a group for one or both directories, then permissions need to be changed. In that case, run.
sudo chown --recursive root:tunnel /run/resolvconf
Then set the necessary permissions.
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 already started. There is no need to modify permissions on this file, as the permissions will change when the service starts.
Terminology for Support Requests[edit]
Phrases such as "over Tor" are ambiguous. Please do not coin idiosyncratic words or phrases, otherwise this leads to confusion. Please use the same terms that are consistently referenced in documentation, such as:
- Connect to a VPN Before Tor (
User
→VPN
→Tor
→Internet
). - Connect to Tor Before a VPN (
User
→Tor
→VPN
→Internet
). - And so on.
Always refer to the connection scheme when requesting support, such as:
User
→VPN
→Tor
→Internet
, orUser
→Tor
→VPN
→Internet
.
Unload VPN Firewall[edit]
How to unload VPN Firewall? If you know what you are doing... Either...
sudo /usr/share/netfilter-persistent/plugins.d/30_vpn-firewall flush
Or...
sudo service netfilter-persistent flush
Security Discussion[edit]
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.
Alternatives[edit]
- 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
- Windows firewall. Windows only.
- IP Security Policies. Windows only.
Footnotes[edit]
- ↑ https://phabricator.whonix.org/T460
- ↑
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 file
/rw/config/qubes-bind-dirs.d/50_user.conf
in an editor with root rights.Non-Qubes-Whonix™
This box uses
sudoedit
for better security.sudoedit /rw/config/qubes-bind-dirs.d/50_user.conf
Qubes-Whonix™
NOTES:
- When using Qubes-Whonix, this needs to be done inside the Template.
sudoedit /rw/config/qubes-bind-dirs.d/50_user.conf
- After applying this change, shutdown the Template.
- All App Qubes based on the Template need to be restarted if they were already running.
- This is a general procedure required for Qubes and unspecific to Qubes-Whonix™.
Others and Alternatives
- This is just an example. Other tools could achieve the same goal.
- If this example does not work for you or if you are not using Whonix, please refer to this link.
sudoedit /rw/config/qubes-bind-dirs.d/50_user.conf
binds+=( '/etc/openvpn' ) binds+=( '/lib/systemd/system/openvpn@openvpn.service' ) binds+=( '/etc/systemd/system/multi-user.target.wants/openvpn@openvpn.service' )
TODO: Does not work yet. Files need to exist first.
TODO: umount during run is probably not sane.
/usr/lib/qubes/bind-dirs.sh umount
TODO: re-running bind-dirs.sh without previous umount does not work yet.
/usr/lib/qubes/bind-dirs.sh
- ↑ Riseup notes:
Every CA (certificate authority) has a file that is distributed publicly. This file, called a “CA certificate”, is used by your local program to confirm the identity of servers you connect with.
- ↑ If verification is not performed, then it is impossible to know the correct certificate was downloaded and that connections are secure.
- ↑ Previously a VPN secret (VPN password) and username could be registered.
- ↑ Many VPN service providers include DNS hostnames in their configuration files. The hostnames typically include the providers name followed by (.net, .com, .ch, .pw).
- ↑
/etc/openvpn/update-resolv-conf
usesresolvconf
.resolvconf
needs to be installed for the lines beginning with script-security, up, and down to function properly. - ↑
1. In the
/etc/openvpn/openvpn.conf
file, change the following text.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 the following. Remove or comment out the lines beginning with "up" and "down", and change the 2 to a 1.
script-security 1
2. Open file
/etc/resolv.conf
in an editor with root rights.Qubes-Whonix™
NOTES:
- When using Qubes-Whonix, this needs to be done inside the Template.
sudoedit /etc/resolv.conf
- After applying this change, shutdown the Template.
- All App Qubes based on the Template need to be restarted if they were already running.
- This is a general procedure required for Qubes and unspecific to Qubes-Whonix™.
Others and Alternatives
- This is just an example. Other tools could achieve the same goal.
- If this example does not work for you or if you are not using Whonix, please refer to this link.
sudoedit /etc/resolv.conf
3. Comment out the nameserver.
#nameserver 10.152.152.10
4. Add the VPN provider's DNS server.
## Riseup.net OpenVPN DNS server nameserver 172.27.100.1
If Riseup is not in use, replace 172.27.100.1 with the virtual LAN IP address of the VPN provider's DNS server. If unsure, the VPN provider might provide it. To try to infer it, run
sudo route
after successfully connecting to the VPN. The first destination default gateway should also function as a DNS server.5. Save and exit.
6. Optional: Prevent
/etc/resolv.conf
being overwritten by other packages like DHCP orresolvconf
.Run.
sudo chattr +i /etc/resolv.conf
In order to revert this change, use -i.
Ignore the
/etc/resolv.conf
instructions below. - ↑ This is done to prevent the old DNS server being used. For further discussion of this issue, see: https://github.com/adrelanos/vpn-firewall/issues/16
- ↑
This ensures changes in
/etc/resolvconf/run/interface/original.resolvconf
from the DNS Configuration section take effect. - ↑ This has the same effect as the scurl command above.
- ↑ Debian feature request: add dpkg trigger for /usr/share/netfilter-persistent/plugins.d folder to have newly installed plugins take effect
We believe security software like Whonix needs to remain open source and independent. Would you help sustain and grow the project? Learn more about our 12 year success story and maybe DONATE!