mullvad / mullvadvpn-app

The Mullvad VPN client app for desktop and mobile
https://mullvad.net/
GNU General Public License v3.0
4.93k stars 336 forks source link

Exclusion by cgroup #3813

Open Oted opened 2 years ago

Oted commented 2 years ago

Issue report

Operating system: Ubuntu 20.04, kernel 5.18.10 App version: 2022.2

Issue description

So I have a scenario where I would like to only have one application using the VPN and all other traffic to be routed normally. My plan was to use cgroups for the purpose and launch this specific application with cgexec. Here are my rules:

table inet exclude_cgroup  {
    chain i {
        type filter hook input priority -100; policy accept;
        meta cgroup!=1234567 ct mark set 0x00000f41 meta mark set 0x6d6f6c65;
    }

    chain o {
        type route hook output priority -100; policy accept;
        meta cgroup!=1234567 ct mark set 0x00000f41 meta mark set 0x6d6f6c65;
    }
}

If i understand things correctly the rules above should cause mullvad to exclude all traffic as long as there is not a cgroup with the id 1234567? However this is not the case, no traffic is excluded and things like ssh breaks for instance (im on a VPS). I have also tested with the example below:

$ netcat -l -p 3300 and connected with $ nc -v -z {VPS_IP} 3300 which also fails.

Am I missing something crucial here or should this works as I planned? Many thanks

dlon commented 2 years ago

What you're doing should work, and did work when I tested it. There are just a couple of potential problems/caveats:

  1. cgroup matching may not be possible for incoming connections, as traffic won't be associated with a process (see https://github.com/mullvad/mullvadvpn-app/issues/2097).
  2. Depending on your custom DNS settings, you may find that DNS lookups will be blocked. That is, unless you allow them to leak into the tunnel:
table inet exclude_cgroup  {
    chain o {
        type route hook output priority -100; policy accept;
                udp dport 53 accept
                tcp dport 53 accept
        meta cgroup!=1234567 ct mark set 0x00000f41 meta mark set 0x6d6f6c65;
    }
}

If neither point explains your issue, I'm not sure what's going on. Does normal split tunneling work on your VPS?

Have you considered just using plain WireGuard and network namespaces (https://www.wireguard.com/netns/#ordinary-containerization)? That's arguably a simpler/cleaner solution until (if ever) the app supports "inverse split tunneling", and it should lack some the quirks of this "hack".

Oted commented 2 years ago

Thank you @dlon. I will give an attempt to solve this with wireguard and namespaces for now.

tombh commented 6 months ago

Just to reference a related project for anybody else researching Mullvad in namespaces, I've been using this project https://github.com/chutz/mullvad-netns