Wireguard VPN in Qubes 4.2+

I see we now use nfttables exclusively, which breaks backwards compatibility with legacy Qubes iptables scripts.

Here’s the most straightforward configuration I’ve used for a “fail closed” Wireguard tunnel in a proxyVM.

  1. Create a ProxyVM (ensure “provides network” is checked)

  2. /rw/config/rc.local

#!/bin/bash
# Bring up WG
wg-quick up /rw/config/wg0.conf || exit 1

##DNS forwarding

DNS=9.9.9.9 #your DNS server of choice

# Create a NAT table if not already present
nft add table ip qubes

# Add a prerouting chain for destination NAT in that table
nft add chain ip qubes nat { type nat hook prerouting priority dstnat \; }

# Add rules for tcp and udp port 53 redirecting DNS queries to the DNS IP
nft add rule ip qubes nat iifname "vif*" tcp dport 53 dnat to $DNS
nft add rule ip qubes nat iifname "vif*" udp dport 53 dnat to $DNS
  1. Important: in the qubes firewall GUI, set “Limit outgoing connections to…” and enter (UDP) your IP address and port of the Wireguard endpoint

  2. Put your wireguard config in /rw/config/wg0.conf

Would be useful if this were in an FAQ somewhere, or there was a script to install it, or if it was just standalone. Using nm to control wireguard tunnels seems to be a bad idea due to reports of connections dropping. Just call wg-quick directly.

Errata: This script isn’t running at startup for me, which is weird, so I run it manually. Edit: runs at startup as expected with a Debian 13 template. Seems to have been a Fedora/SeLinux issue.

If you’re using Fedora template, then try this:

1 Like

That fix didn’t work but it was enough of a lead to move to Debian minimal template and install wireguard-tools, resolveconf, and the packages suggested for NetVM here Minimal templates — Qubes OS Documentation

And it now works. Thanks!

Using the firewall from the GUI never block ICMP and DNS packets (as explained on that firewall tab), you need to use qvm-firewall in dom0.

2 Likes