Wireguard VPN setup


security and ability to reuse a VPN for multiple qubes, one may quickly reach device limit


could you explain what you did exactly to try it?

I ran sudo systemctl stop NetworkManager.service inside sys-vpn and than pinged a website in another AppVM that had the NetVM of sys-vpn and it still had network access with the same same ip as the sys-vpn provided.

Thanks for the response. Could you elaborate on the security issues you suspect with using ProtonVPN separately in each AppQube without further configuration?

I don’t reach my device limit so my only concern is security or privacy issues. I’m not too interested in setting up a sys-vpn for every Qube I use, since there are RAM and performance limitations. But I want each Qube to have a separate IP by having its own VPN connection, which is what I have achieved by using ProtonVPN GUI in each connected Qube. What security/privacy issues do you see with this set up?

Thanks for your help. I appreciate your contributions to this forum.

which killswitch did you implement?

you indeed need to run a different vpn for each qube in this setup, so either in a dedicated qube or in the one you use to save some ram

I can only identify the following points with your setup:

  • if the qube get compromised, an attacker may be able to extract data from about your VPN (provider, and that you are using their application)
  • a compromised qube could be allow the attacker to bypass the VPN, but only if you didn’t implement the killswitch using qvm-firewall
  • your VPN account could be stolen

This one

qvm-firewall sys-vpn reset # (1)
qvm-firewall sys-vpn add accept dsthost= # (2)
qvm-firewall sys-vpn del --rule-no 0 # (3)

And this one

nft add rule qubes custom-forward oifname eth0 counter drop
nft add rule ip6 qubes custom-forward oifname eth0 counter drop

I also applied everything in the Hardening and Block all traffic outside VPN using command line Qubes OS Firewall option

what is the output of qvm-firewall sys-vpn?

0   accept  <IP>/32    -         -        -             -         -       -

is the IP i’ve put in from my vpn.

ah, I think I misunderstood your issue. I don’t think stopping network manager is enough to shutdown the tunnel.

the firewall is not tested here because you said the appvm using that sys-vpn qube still use the same sys-vpn public IP, this mean the tunnel is still up.

if you want to disable the tunnel, you can use the network manager icon to stop the VPN, or use nmcli to stop the tunnel. It should also be possible using wg-quick down tunnel_name I think

1 Like

Bringing down the connection via nmcli worked I didn’t have a connection. Thank you for the guide and for your help.

1 Like

Nice :slight_smile:

Just for the record, stopping Network Manager should stop an OpenVPN tunnel, but it does not affect WireGuard tunnels, the protocols work very differently.

WireGuard is done through a kernel component while OpenVPN creates a tun0 interface and an openvpn must be running to make use of it. Network Manager spawns an openvpn client and it will stop it when you stop the service.

1 Like

Hi, a couple questions.

1. Why might you use the Quad9 DNS instead of the VPN’s assigned DNS (DNS = <IP> in the wireguard .conf file) as the dnat target in the Prevent DNS leak hardening step? Context:

Wouldn’t using the VPN’s DNS be strictly better given the VPN sees all your traffic anyway, and this way you aren’t exposing your lookups to another (admittedly benign) third party?

2. What is the security or privacy benefit to interposing a sys-firewall qube between the VPN qube and its client app qubes? Context:

A sys-firewall above the app qubes would, I think, disguise from the VPN qube the number of its clients- so perhaps that is a privacy win in the case the VPN qube becomes compromised. Is that the only benefit? (I’m not challenging the advice, I just want to understand.)

Thanks for the great guide, to all contributing authors, and for answering questions.

With this setup:

sys-vpn <-> sys-firewall <-> personal

When you set Qubes firewall rules for your personal qube, then the rules will be applied in sys-firewall qube.
Now it you have this setup:

sys-vpn <-> personal

The Qubes firewall rules will be applied in sys-vpn and if sys-vpn will be compromised then the malware in sys-vpn can disable the firewall rules for qubes connected to it.

1 Like

That makes sense, thanks :+1:

Another question/observation regarding DNS to add to the one outstanding.

There is a qubes service, disable-dns-server:

    Default: disabled

    Enabling this service will result in an empty /etc/resolv.conf.
    The functionality is implemented in /usr/lib/qubes/setup-ip.

(The systemd service that implements this is qubes-network-uplink@eth0 by way of running /usr/lib/qubes/setup-ip add "eth0", as the qvm-service manpage notes.)

Enabling this qubes service also leaves the dnat-dns chain essentially empty.

Would it not be sensible to enable this service on sys-vpn qubes? I think that would eliminate any actual/perceived competition between Qubes’ DNS-related infrastructure and that of the VPN’s. (A concern noted earlier in the thread in this comment: Wireguard VPN setup - #149 by technopunk)

Seems pretty good, is it documented somewhere? :thinking:

I think only in the qvm-service manpage and the implementing code itself in /usr/lib/qubes/setup-ip, a bash script, not too tricky.

What do you think about the security implications of using many WG configs in the same sys-vpn qube?

I mean, a given VPN provider can have 10 servers in a given country, for example. You’d want to add 10 different configs to NetworkManager so if one server is down, you can quickly switch to another (or just randomize it on Qube start, with some wrapper script). You can go further and also add configs from another country, so if some service you need geo-blocks a whole country, you can quickly switch to another.

One problem is that the Qube-settings firewall allows ALL endpoints at the same time, while ideally it should only allow connection to the one you’re conencting with NM. So the more configs you add, the more rules you allow unnecessarily.

Now imagine your VPN provider loses control over some endpoint (because they rent a different VPS, for example). Theoretically, an attacker who now owns this old IP address can expose something malicious on that same IP:PORT pair that used to be an endpoint for your VPN provider. WG itself won’t be able to connect to it due to there being something different than WG protocol on that port, or even if there is still WG, the public key wouldn’t match. In the case of sys-vpn qube compromise however, some other process than WG’s can connect to that endpoint that IS allowed with the Qube-settings firewall, potentially defeating the killswitch.

So it boils down to the thing: is it possible to dynamically change the Qubes firewall for that qube to contain only one rule for the endpoint you’re connecting to at a given moment, then remove it as soon as you change a connection in NM or disconnect from it? Probably not, it’s on a different level, and would require some script in dom0 that parses text from files or processes output from within the sys-vpn qube, which would be very dangerous for the whole system…

The only workaround I can think of is using different sys-vpn qube for each WG config, but I can’t imagine how cumbersome it would be to then switch between so many net-VMs in other qubes that get network from them. Or maybe NM supports some pre-up hooks that can add a rule with nft, which is not as secure as Qube-settings firewall but better than nothing I guess.

it’s possible to make a qrexec RPC call that would alter the qube firewall, but it’s highly discouraged because you don’t want to qube to modify its own firewall.

I don’t see this being a real issue.

I do not see how the qube would be compromised and how this defeats the killswitch. The WireGuard tunnel won’t be able to establish, and due to the qube firewall it won’t have any internet access as a result.