Intro
This guide explains how to setup a a VPN with IVPN app on Qubes OS 4.2 using a Fedora template.
IVPN app is open source and they provide repositories for fedora / debian, there is an official documentation but I think it deserves more explanations here: IVPN on Qubes OS - IVPN Help
The App supports OpenVPN and WireGuard tunnels with respectively obfuscation protocols obfsproxy and V2ray.
They seem also a legit service to use as per the trustable source Private VPN Service Recommendations and Comparison, No Sponsors or Ads - Privacy Guides
If you want to set up IVPN using WireGuard without the App, see Wireguard VPN setup
Setup
Qube creation
- Create a dedicated qube for the vpn
- Name it as you want (I will name it
sys-vpn-ivpn-app
) - Choose type “Standalone” with the template fedora-38 (or xfce flavor, minimal flavor should work too)
- Check “provide network access to other qubes” in the Advanced settings tab
- Name it as you want (I will name it
- In the qube settings
- Give it 800 MB of memory minimum
- Add the service
qubes-firewall
Qube configuration
- Start the qube
- Follow the official guide to install IVPN app, which is just:
sudo dnf config-manager --add-repo https://repo.ivpn.net/stable/fedora/generic/ivpn.repo
sudo dnf install ivpn-ui
- Add the following code to
/rw/config/rc.local
this is required to automatically switch the DNS offered by the NetVM to the qubes, in addition this code automatically repatch IVPN code when the program is upgraded
if ! grep "QUBES OS" /opt/ivpn/etc/firewall.sh >/dev/null
then
sudo sed -i '/-set_dns/a\
#QUBES OS - specific operation\
systemctl restart systemd-resolved || echo "Error: systemd-resolved" \
/usr/lib/qubes/qubes-setup-dnat-to-ns || echo "Error: failed to run /usr/lib/qubes/qubes-setup-dnat-to-ns"' /opt/ivpn/etc/firewall.sh
fi
- Reboot the qube
- Proceed to next step
IVPN App
Start the App with /opt/ivpn/ui/bin/ivpn-ui
or add “IVPN” application in the qube menu entry.
The IVPN app should start without issue:
- Enter your credentials
- Connect
- Go in Settings and then Dns
- Enable “Force management of DNS using resolv.conf” ( this is really important)
- Configure the App as you want
Auto start at boot can be enabled in the settings “General”.
Avoid issues with WireGuard
WireGuard tunnels can trigger a MTU issue in the network, in short it could make some websites not working (like duckduckgo) because of too big packet sizes. This is a common issue with WireGuard VPNs.
Add this to /rw/config/qubes-firewall-user-script
nft add rule ip qubes custom-forward tcp flags syn / syn,rst tcp option maxseg size set rt mtu
This will automatically ensure that the qubes network packets will fit in a WireGuard network packet and will make things works©.
Killswitch configuration
You may want to force all qubes traffic to go through the VPN and block non-VPN traffic. IVPN app offers a killswitch but the app could still crash and the killswitch wouldn’t be guaranteed to work.
Add the rules below in /rw/config/qubes-firewall-user-script
in the qube:
# Prevent the qube to forward traffic outside of the VPN
nft add rule qubes custom-forward oifname eth0 counter drop
nft add rule ip6 qubes custom-forward oifname eth0 counter drop
Optional hardening: Avoid DNS leaks
You may also want to force using a defined DNS server (9.9.9.9 in the current example) and blocking all other DNS servers (this avoids dns leaks)
# Redirect all the DNS traffic to the preferred DNS server
DNS=9.9.9.9
nft add chain qubes nat { type nat hook prerouting priority dstnat\; }
nft add rule qubes nat iifname == "vif*" tcp dport 53 dnat "$DNS"
nft add rule qubes nat iifname == "vif*" udp dport 53 dnat "$DNS"
Access local LAN / addresses (Advanced users /!\ )
There is an issue with the App on Qubes OS, the “allow LAN exception doesn’t always work”, it’s not useful for most users though, don’t panic
I created a script /rw/config/bypass-fw
with the content (adapt the IPs in the first variable):
#!/bin/sh
IPS_TO_ALLOW="10.42.42.42 10.42.42.150"
for i in "$IPS_TO_ALLOW"
do
nft insert rule qubes custom-forward ip daddr $i counter accept
nft insert rule filter FORWARD ip daddr $i counter accept
nft insert rule filter FORWARD ip saddr $i counter accept
Make it executable with chmod +x /rw/config/bypass-fw
, make sure to change the script in /rw/config/rc.local
to call /rw/config/bypass-fw
like this:
if ! grep "QUBES OS" /opt/ivpn/etc/firewall.sh >/dev/null
then
sudo sed -i '/-set_dns/a\
#QUBES OS - specific operation\
systemctl restart systemd-resolved || echo "Error: systemd-resolved" # this line is required for Qubes OS 4.2 (tested on Qubes OS 4.2-RC4)\
/usr/lib/qubes/qubes-setup-dnat-to-ns || echo "Error: failed to run /usr/lib/qubes/qubes-setup-dnat-to-ns"' /opt/ivpn/etc/firewall.sh
/rw/config/bypass-fw
fi
Make sure to edit /opt/ivpn/etc/firewall.sh
to add /rw/config/bypass-fw
around where the code above is added within the file.