Yet another set of VPN qube DNS configuration settings

I’m posting this here in case this is useful to someone. I spent quite some time to find a working solution for DNS with a VPN gateway qube.

Please note:

  • I have verified that these work in practice, but my knowledge of linux network is still limited, so use these at your own risk and do your research to make sure that you stay safe
  • I’m using OpenVPN, things may or may not be different with Wireguard and other protocols

Background: I have a VPN gateway qube (sys-vpn) which provides network for qubes which I want to route through a VPN tunnel. I don’t use any VPN apps but only openvpn official software with command line. Using Mullvad VPN service was easy as it hijacks and redirects DNS traffic, but other services don’t so I ended up with DNS issues.

First leak protection in case the VPN tunnel breaks - I put this into /rw/config/qubes-firewall-user-script:

iptables -I FORWARD -o eth0 -j DROP
iptables -I FORWARD -i eth0 -j DROP

Then setting up DNS and starting VPN with a script, let’s call it “start_vpn.sh”, run it as root:

#!/bin/bash

#cp /etc/resolv.conf /root/resolv.conf.backup
#cp resolv.conf.vpn /etc/resolv.conf
#chattr +i /etc/resolv.conf

q_dns1=10.139.1.1
q_dns2=10.139.1.2
v_dns=10.8.0.1

iptables -t nat -F PREROUTING

iptables -t nat -A PREROUTING -d $q_dns1 -p udp --dport 53 -j DNAT --to-destination $v_dns
iptables -t nat -A PREROUTING -d $q_dns1 -p tcp --dport 53 -j DNAT --to-destination $v_dns
iptables -t nat -A PREROUTING -d $q_dns2 -p udp --dport 53 -j DNAT --to-destination $v_dns
iptables -t nat -A PREROUTING -d $q_dns2 -p tcp --dport 53 -j DNAT --to-destination $v_dns

iptables -t nat -A PREROUTING -p udp --dport 53 -j LOG --log-prefix 'should not happen: '
iptables -t nat -A PREROUTING -p udp --dport 53 -j DNAT --to-destination $v_dns
iptables -t nat -A PREROUTING -p tcp --dport 53 -j LOG --log-prefix 'should not happen: '
iptables -t nat -A PREROUTING -p tcp --dport 53 -j DNAT --to-destination $v_dns

#RUN OpenVPN
openvpn --config vpn_service_config.conf

#chattr -i /etc/resolv.conf
#mv /root/resolv.conf.backup /etc/resolv.conf

iptables -t nat -F PREROUTING

Rationale:

  • All qubes use 10.139.1.{1,2} as their DNS address, it’s the Qubes virtual DNS address. However, when the VPN gateway is in use, DNS queries go through the VPN into these addresses which doesn’t work of course.
  • Exception is Mullvad VPN which hijacks and redirects all DNS traffic on their servers, that’s why I didn’t even notice any problems until I tried another VPN service.
  • So here the iptables rules are used to redirect DNS queries into the VPN service DNS address, in this case I’m using Mullvad VPN as the example, their address is 10.8.0.1. Change it to whatever address is used by your service.
  • The resolv.conf changes are used to configure DNS in the gateway qube, but it’s probably not needed (hence commented out) since no applications should be used in the gateway qube
  • I verified with wireshark that no traffic happens outside the VPN tunnel when this solution is used… but use at your own risk anyway.
  • If you do not want to run openvpn as root, there was a way to run it as a limited user that had privilege to do network configurations that normally require root… but I’m not sure if that method works anymore. I can post details if someone wants. Since openvpn is isolated in the gateway qube anyway there is less risk in running it as root in my opinion…
1 Like

@throwed343 Qubes 4.2 and 4.3 do not support iptables anymore, from debian 12 upwards the default is nftables. you should port your rules to nftables I’m afraid.

1 Like