ivpn / desktop-app

Official IVPN Desktop app
https://www.ivpn.net/apps/
GNU General Public License v3.0
367 stars 50 forks source link

IVPN DNS does not work in the Qubes AppVMs -> ProxyVM with the official IVPN client #191

Closed TommyTran732 closed 2 years ago

TommyTran732 commented 2 years ago

Bug report

Describe your environment

Describe the problem

If I install the official IVPN client in a ProxyVM, DNS in the AppVMs based on it will not work. I am aware that I can use a set up similar to https://mullvad.net/en/help/wireguard-on-qubes-os/, however, it is extremely cumbersome and I would like to use the official IVPN client instead.

Steps to reproduce:

  1. Make a standalone Fedora 36 VM on Qubes. Set networking to use sys-firewall. Name this VM `sys-ivpn. (We need to use a standalone VM for the IVPN client here because login session gets lost after a reboot in a normal AppVM setup, and I will make a seperate issue for that later).
  2. Give sys-ivpn the network-manager service and tick the box "Provides Network".
  3. Install the IVPN client on it and log into IVPN.
  4. Make a new AppVM, set networking to use sys-ivpn.

Observed Results:

Observe that DNS is broken regardless of VPN protocol, killswitch and local LAN support settings. The user has to manually set a custom DNS server in /etc/resolv.conf for the AppVM to work.

Expected Results:

DNS is set up properly.

Notes:

This appears to be some issues with some VPN providers and not the other providers. In particular:

I suspect that this has something to do with the integration with NetworkManager. Note that if I do not give the network-manager service to the other VPN providers, they have the exact same issue: DNS is broken, though the packets are still routed through the VPN itself.

stenya commented 2 years ago

Hello @tommytran732

You wrote The user has to manually set a custom DNS server in /etc/resolv.conf for the AppVM to work.. That fact gave me the idea to offer you to try the previous version of the IVPN client (v3.8.20).

In the latest release (v3.9.0), we changed the managing mechanism of DNS configuration. IVPN app is trying not to touch the /etc/resolv.conf directly, but communicate with NetworkManager/systemd-resolved in an appropriate way. The previous version was working with resolv.conf directly.

Can you, please, check if v3.8.20 works for you? (there is also "Custom DNS" functionality if you need to set up a specific DNS configuration)

stenya commented 2 years ago

I am also wondering: is there are any changes if IVPN Firewall is disabled?

Enteee commented 2 years ago

I can report the exact same issue, not changing /etc/resolv.conf breaks Qubes OS support.

v3.8.20 works fine. But not changing /etc/resolv.conf breaks the /usr/lib/qubes/qubes-setup-dnat-to-ns (also see below) script which is central for Qubes DNS functionality to work.

#!/bin/sh
addrule()
{
        if [ "$FIRSTONE" = yes ] ; then
                FIRSTONE=no
                RULE1="-A PR-QBS -d $NS1 -p udp --dport 53 -j DNAT --to $1
-A PR-QBS -d $NS1 -p tcp --dport 53 -j DNAT --to $1"
                RULE2="-A PR-QBS -d $NS2 -p udp --dport 53 -j DNAT --to $1
-A PR-QBS -d $NS2 -p tcp --dport 53 -j DNAT --to $1"
        else
                RULE2="-A PR-QBS -d $NS2 -p udp --dport 53 -j DNAT --to $1
-A PR-QBS -d $NS2 -p tcp --dport 53 -j DNAT --to $1"
        fi
}
export PATH=$PATH:/sbin:/bin
# shellcheck disable=SC1091
. /var/run/qubes/qubes-ns
if [ "X$NS1" = "X" ] ; then exit ; fi
iptables -t nat -F PR-QBS
FIRSTONE=yes
if systemctl -q is-active systemd-resolved && \
        grep -q '^nameserver.*127\.0\.0\.53' /etc/resolv.conf; then
    /usr/lib/qubes/get-dns-from-resolved
else
    grep ^nameserver /etc/resolv.conf
fi | grep -v ":.*:" | head -2 |
        (
        # shellcheck disable=SC2034
        while read -r x y z ; do
                addrule "$y"
        done
        (echo "*nat"; echo "$RULE1"; echo "$RULE2"; echo COMMIT) | iptables-restore -n
        )

Note that /usr/lib/qubes/get-dns-from-resolved would yield the following:

nameserver 10.139.1.1
nameserver 10.139.1.2
nameserver 10.139.1.1
nameserver 10.139.1.2
nameserver 10.56.20.1

which contains the ivpn dns (10.56.20.1). But /usr/lib/qubes/get-dns-from-resolved is not actually called because grep -q '^nameserver.*127\.0\.0\.53' /etc/resolv.conf; exits with 1. But even if the script would use the output from /usr/lib/qubes/get-dns-from-resolved it would not set up the correct dnat rules because of the head -2 which will only set up rules for:

nameserver 10.139.1.1
nameserver 10.139.1.2
stenya commented 2 years ago

Thank you @Enteee Your feedback is very helpful.

It seems, we have to add a configurable option to IVPN settings which will allow switching to the old-style managing of the DNS configuration on Linux (by direct changing /etc.resolve.conf).

This option will be disabled by default since the modern Linux distributives use resolved and warn not to modify /etc.resolve.conf.

stenya commented 2 years ago

@gorkapernas v3.9.20 is ready for testing. An additional option is added to DNS configuration (UI and CLI) image

$ ivpn dns -h
Command usage:
dns DNS_IP           DNS management for VPN connection
                     DNS_IP - optional parameter used to set custom dns value (ignored when AntiTracker enabled)
  -management METHOD - By default IVPN manages DNS resolvers using the 'systemd-resolved' daemon 
                       which is the correct method for systems based on Systemd. 
                       This option enables you to override this behavior and allow the IVPN app 
                       to directly modify the '/etc/resolv.conf' file.   
                       Note: This option is not applicable if there is only one DNS management method supported by the system.
                       Possible values: auto (default); resolvconf
                        Example: 
                         'ivpn dns -management=resolvconf' 
                         'ivpn dns -management=auto'
...

This is the Linux-only option and will not be visible when only one DNS management type is applicable (e.g. in a Snap environment or on systems not based on Systemd)

TommyTran732 commented 2 years ago

I will test it when you have an rpm and let you know

gorkapernas commented 2 years ago

@stenya tested the latest beta 3.9.20 on several Linux distributions, Ubuntu 20.04, Fedora 33, Linux Mint, MX Linux (without systemd), the option to override the default behavior - "manage DNS with systemd-resolved daemon" is present in the UI under the IVPN DNS Settings, if enabled - IVPN modifies /etc/resolve.conf, if disabled - IVPN uses systemd-resolved. On the machine without systemd, the option is not present in the UI as described on https://github.com/ivpn/desktop-app/issues/191#issuecomment-1215119056 Tested the overall DNS configuration and everything seems to work as expected.

stenya commented 2 years ago

@tommytran732 @Enteee Below you can find links to the latest beta version. The new option implemented: https://github.com/ivpn/desktop-app/issues/191#issuecomment-1215119056 I will be grateful to you if you test it and give us feedback. Please, note: It is not an official release!

RPM: base package: https://repo.ivpn.net/beta/ivpn-3.9.21-1.x86_64.rpm UI package: https://repo.ivpn.net/beta/ivpn-ui-3.9.21-1.x86_64.rpm

DEB: base package: https://repo.ivpn.net/beta/ivpn_3.9.21_amd64.deb UI package: https://repo.ivpn.net/beta/ivpn-ui_3.9.21_amd64.deb

Enteee commented 2 years ago

Thank you @stenya , I will try to test the updated version as soon as possible.

Enteee commented 2 years ago

@stenya , I did give this a quick round of testing and so far this looks good. Using ivpn as a Qubes OS netvm does work with this enabled.

Also I do like that you have introduces a config option. :+1:

stenya commented 2 years ago

Thank you @Enteee We will include this change in the next official release for Linux.

stenya commented 2 years ago

Released in v3.9.32