ProxyVM for OpenVPN with multiple VPN configs

  • Users have occasionally reported openvpn being unable to perform DNS lookups for the VPN provider’s domain. This may be due to the way Qubes passes DNS requests up through various netvm layers on their way to the upstream network. Some workarounds that may improve DNS access are: 1. Populating /etc/resolv.conf with the DNS address of your physical ISP; 2. Installing the resolvconf package; 3. Enabling egress as described in the Firewall notes below.

GitHub - tasket/Qubes-vpn-support: VPN configuration in Qubes OS

My minimal template had these:

gnome-keyring
network-manager
network-manager-openvpn
network-manager-openvpn-gnome
notification-daemon
openvpn
policykit-1
qubes-core-agent-network-manager
qubes-core-agent-networking
qubes-core-agent-passwordless-root

Note that, although installed, network manager was NOT running.

That does sound like a possibility. But everything works flawlessly with my proxy-VM based on debian-11, so I’m not sure if there is point to putting more time and effort.

Yeah, that’s right.
However ‘fail safe’ - whatever you mean about this, is the opposite of multiple VPNs running at the same time.

You can chose the solution you need, but you can’t have it boot at the same time.

Maybe it’s this issue:

Qubes 4.1 - VPN over Tor netvms: ARP request does not get resolved properly · Issue #7123 · QubesOS/qubes-issues · GitHub
VPN over Tor via Proxy-VM will not connect · Issue #7261 · QubesOS/qubes-issues · GitHub

You can configure iptables to drop the connection when not connected to a vpn, thus achieving fail-safe:
(run the following commands as root in your sys-net dvm-template if it’s disposable, or in sys-net if it’s not disposable)

export fw_script="/rw/config/qubes-firewall-user-script"

echo "iptables -I FORWARD -o eth0 -j DROP" >> $fw_script
echo "iptables -I FORWARD -i eth0 -j DROP" >> $fw_script
echo "ip6tables -I FORWARD -o eth0 -j DROP" >> $fw_script
echo "ip6tables -I FORWARD -i eth0 -j DROP" >> $fw_script

chmod +x $fw_script

I read the Qubes community documentation about this.

The first method is Set up a ProxyVM as a VPN gateway using NetworkManager which presumably allows multiple configs since it uses NM. I plan to try it next.

The other method Set up a ProxyVM as a VPN gateway using iptables and CLI scripts seems to be the same as Qubes-vpn-support? So it will not support multiple configs?

Yes.

It won’t support multiple VPNs. If you need to use different VPNs for different qubes connected to ProxyVM then you’ll have to make additional routing as I’ve described in my first reply.

Or, if I am not mistaken, the alternative is what I had planned to try next: Set up ProxyVM as a VPN gateway using NetworkManager.

I’m not sure about NetworkManager as well. I didn’t look into how it can route different interface using different VPNs but you’ll most probably need to specify the qubes virtual interfaces vif* that should use specific VPN configs but there’s a problem with this:

Because these virtual interfaces are not tied to specific qubes persistently. So you’ll need to somehow make the runtime configuration to first determine which interface belongs to which qube and then configure this interface to use specific VPN config.

An ‘easy’ way to do this with Qubes-vpn-support is to keep the various configs in a subdir /rw/config/vpn/my-confs and then have a small script that lets you choose one of the configs.

#!/usr/bin/env sh
selected=$(zenity --file-selection --filename /rw/config/vpn/my-confs/)
cp "$selected" /rw/config/vpn/vpn-client.conf
systemctl restart qubes-vpn-handler

That’s about it, really. Its only the .conf files that go in the my-confs subdir; any other conf-realted files like .pem, .crt etc stay in the parent dir.

If using qubes-tunnel instead, you would only have to change a couple paths + service name…

#!/usr/bin/env sh
selected=$(zenity --file-selection --filename /rw/config/qtunnel/my-confs/)
cp "$selected" /rw/config/qtunnel/qtunnel.conf
systemctl restart qubes-tunnel

You could also put this in a loop with a read at the end so you have to press Return before getting the next file prompt. Or you could call it from a systray tool that run scripts.



Network Manager:

There are good reasons why you probably shouldn’t use NM for VPNs unless the VPN provider has NM-specific instructions. In short, the NM openvpn plugin was designed incorrectly and cannot handle every combination of config options that VPN providers like to use. Its been that way for a loooong time.

I thought I understood the issue you were explaining: Even if everything works with NM, it would still only select one config for all the AppVMs at a time, whereas I wanted different configs running in the ProxyVM simultaneously.

So where does the script run? Can it choose different configs per AppVM simultaneously?

The misunderstanding that there is NO Appvm ↔ VPN config association at all.

If you run multiple VPN, that will be ‘available’ for all the connected AppVMs.
So by design - and by default - the VPN do not know about your AppVMs at all.

That’s can be confusing and ‘dangerous’ for the beginners, but very practical for the one that needs such setup.

And again: NM allows you to run multiple VPNs at the same time.
I’m using this ‘feature’ daily.

OK. So now I have setup up a ProxyVM running NetworkManager with two VPN connecttions.

Then I tried using this to provide the network for an AppVM. Testing the connection showed that the AppVM is using the first VPN connection from NM. So how to do I make the AppVM use the other VPN?

I am guessing that the next step involves qvm-firewall but can I please confirm?

well, the VPN - in general - connecting you with another host or network.
However It can provide you a default route too, which means every connection goes trough that tunnel.

It boot pushing you default route - that’s usually means you do not need more than one VPN at the same time :slight_smile:

Multiple VPNs are only meaningful if you not expecting them to push a default route.
Even tho this simpified sentence not always true, as your client can decide if it accept that route or not, moreover it can also override it.

so in general the (Layer 3) VPN just creates a tunnel, and then it’s all about routing. As you see VPN providers trying to ‘help you’ create the corrent routing… but all depends on your goals.

If you can describe why do you think you need multiple VPN at the same time, I might be able to help you clarify…

I don’t really know what “boot pushing you default route” means? I am using two different configs from the same VPN provider. They have many locations (maybe 50 ~ 100).

But certainly I do need to restrict each VM to use only one of the VPN configs of my choosing. Location spoofing is just one reason.

So unless I can achieve that functionality with this setup it will not be my solution.

You cannot use the same sys-vpn vm to provide different vpn routes to two different qubes. So you have two options:

  • Connect both qubes to the same sys-vpn: they will have the same vpn route;
  • Create a secondary sys-vpn-2 with a different config file, then connect qube 1 to sys-vpn-1 and qube 2 to sys-vpn-2.
1 Like

That answers my question then. The 1st approach does not do what is needed.

The obvious setback of the 2nd approach is that multiple ProxyVMs consume RAM. I’m finding Qubes difficult to use as it is on a 16GB system: VMs frequently become unresponsive as memory gets used up.

I will post the details of my 3rd solution separately. It uses the VPN provider’s app in each AppVM, but this is not straightforward.

so it seems you don’t really need multiple VPNs on a single proxyVM, but you need more RAM :wink: