mullvad / mullvadvpn-app

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

How to exclude a container's traffic (static local ip) from tunneled traffic in Linux? #4814

Open FeryET opened 1 year ago

FeryET commented 1 year ago

Issue report

Operating system: Ubuntu 23.04, 64bit.

App version:

$ mullvad version
Current version      : 2023.3
Is supported         : true
Suggested upgrade    : none
Latest stable version: 2023.3

Issue description

I am trying to exclude a specific local ip from the tunneled traffic. This ip is bound to a container (via a virtual bridge network created by docker with gateway of 10.10.5.1) which is acting as a non-tunneled proxy for websites that are only accessible without VPN. (country specific issue)

I've tried using this guide and this is my nftables config at the moment:

define EXCLUDED_IPS = {
   # Local Proxy Subnet
   10.10.5.0/24,
}

table inet excludeTraffic {
  chain excludeOutgoing {
    type route hook output priority 0; policy accept;
    ip daddr $EXCLUDED_IPS ct mark set 0x00000f41 meta mark set 0x6d6f6c65;
  }
}

I want to use the ip 10.10.5.1 as my proxy IP (the ip of the gateway of the network), without Mullvad routing its outgoing traffic via its tunnel.

I am confused by nftables configuration, thought about asking it here.

pinkisemils commented 1 year ago

This would be easier with rootless docker or podman, where mullvad-exclude podman run ... would just work.

As forthe nftables rule, your current rule matches traffic that's destined for 10.10.5.0/24, but it doesn't mark traffic originating there. So, instead, you may want to change the ip daddr $EXCLUDED_IPS to ip saddr $EXCLUDED_IPS. However, I have not tested whether this would be the only thing you should change to make it work.

I can recommend adding a counter to each of the rules you're trying to add, this helps immensely with debugging these things.

FeryET commented 1 year ago

I had tried saddr before, but I think generally the routing/forwarding thing that is happening in the network bridge in the container is not working for whatever reason.

nitramiz commented 11 months ago

Looking for a solution for a similar problem. Mullvad is always enabled (Wireguard only) and I also have a second Wireguard work tunnel, which provides access to.. things.

If Mullvad is enabled, I can't reach the public IPs in the AllowedIPs list in the work WG VPN. If it's disabled, no issues connecting. I tried adding an nft rule to the mullvad table's input and output chains to allow in/outgoing traffic to the certain IPs, but started getting timeouts instead of refused connections.

nitramiz commented 11 months ago

Ok, please disregard the above... I was able to find exactly what I was looking for in the Advanced Linux docs.

https://mullvad.net/en/help/split-tunneling-with-linux-advanced/#allow-ip

nicholasngai commented 3 months ago

@FeryET I’m a bit late to this, but to answer the original question, I was trying to figure out how to do the same thing, and it looks like a mark-based accept rule was to the forward chain (which is used by the container stuff) added back in August in https://github.com/mullvad/mullvadvpn-app/commit/3e86de27b220371ca8e10d22f46b86862b731739! This allows you to exclude forwarded/routed traffic from the firewall with a rule that looks like this:

table inet excludeTraffic {
  chain excludeOutgoing {
    type route hook output priority -150; policy accept;
    ip daddr 10.10.5.0/24 ct mark set 0x00000f41 meta mark set 0x6d6f6c65;
  }

  chain excludeForwarding {
    type filter hook prerouting priority -150; policy accept;
    ip saddr 10.10.5.0/24 ct mark set 0x00000f41 meta mark set 0x6d6f6c65;
  }
}

Does that work for you?

FeryET commented 3 months ago

@FeryET I’m a bit late to this, but to answer the original question, I was trying to figure out how to do the same thing, and it looks like a mark-based accept rule was to the forward chain (which is used by the container stuff) added back in August in https://github.com/mullvad/mullvadvpn-app/commit/3e86de27b220371ca8e10d22f46b86862b731739! This allows you to exclude forwarded/routed traffic from the firewall with a rule that looks like this:

table inet excludeTraffic {
  chain excludeOutgoing {
    type route hook output priority -150; policy accept;
    ip daddr 10.10.5.0/24 ct mark set 0x00000f41 meta mark set 0x6d6f6c65;
  }

  chain excludeForwarding {
    type filter hook prerouting priority -150; policy accept;
    ip saddr 10.10.5.0/24 ct mark set 0x00000f41 meta mark set 0x6d6f6c65;
  }
}

Does that work for you?

Thanks. I will give this a try and will ping you.