1

I have an ubuntu machine with one interface connected to the internet (through mullvad). A RPi box is connected to another ethernet interface on my ubuntu box. Connection works if mullvad is turned off so now I am trying to exclude all traffic from RPi to the internet from mullvad.

I tried to follow this guide but no luck so far. The interface that RPi is connected to has ip 10.0.0.1. RPi receives an ip from ubuntu in 10.0.0.0/8 range. Here's what I have:

table inet excludeTraffic {
 chain allowIncoming {
    type filter hook input priority -100; policy accept;
    ip daddr 10.0.0.1 ct mark set 0x00000f41 meta mark set 0x6d6f6c65;
  }

chain allowOutgoing { type route hook output priority -100; policy accept; ip saddr 10.0.0.1 ct mark set 0x00000f41 meta mark set 0x6d6f6c65; } }

Maybe someone could point me in the right direction. Thanks a lot!

Nhfb9E
  • 11

2 Answers2

0

You need to do that using IPTables. Here is an example script.

#!/bin/bash

Define variables

RPi_IP="10.0.0.2" # Replace with your RPi's IP Primary_Interface="eth0" # Replace with your primary internet-facing interface VPN_Interface="tun0" # Replace with your Mullvad VPN interface Default_Gateway="YOUR_DEFAULT_GATEWAY" # Replace with your default gateway

Create an IP set for excluded IPs

ipset create exclude_ips hash:ip ipset add exclude_ips "$RPi_IP"

Mark outgoing packets from the IP set

iptables -t mangle -A OUTPUT -m set --match-set exclude_ips src -j MARK --set-mark 0x6d6f6c65

Set up routing

ip rule add fwmark 0x6d6f6c65 table 100 ip route add default via "$Default_Gateway" table 100

Configure SNAT to maintain connection

iptables -t nat -A POSTROUTING -o "$Primary_Interface" -j MASQUERADE

Enable IP forwarding

echo "1" > /proc/sys/net/ipv4/ip_forward

Flush existing rules (optional, use with caution)

iptables -F

ipset flush exclude_ips

echo "Excluded traffic from RPi to the internet from the Mullvad VPN."

Turdie
  • 2,945
0

For anyone who's having the same problem, here's the solution I came up with after a full day of reading:

#!/bin/bash

#define some variables Primary_Interface="wlp4s0" # Replace with your primary internet-facing interface Secondary_Interface="enp0s31f6" # Replace with your internal interface Subnet="192.168.9.0/24"

Configure SNAT to maintain connection

nft add rule ip nat POSTROUTING oifname "$Primary_Interface" counter masquerade

nft add rule ip filter FORWARD iifname "$Primary_Interface" oifname "$Secondary_Interface" ct state related,established accept nft add rule ip filter FORWARD iifname "$Secondary_Interface" oifname "$Primary_Interface" accept

add a rule to the mullvad's table to allow forwarding of my subnet's packets

nft insert rule inet mullvad forward ip saddr "$Subnet" accept

set a special mark on packets from and to my subnet for mullvad

nft add rule ip nat PREROUTING ip saddr "$Subnet" ct mark set 0x00000f41 meta mark set 0x6d6f6c65 nft add rule ip nat PREROUTING ip daddr "$Subnet" ct mark set 0x00000f41 meta mark set 0x6d6f6c65

Enable IP forwarding in kernel

#echo "1" > /proc/sys/net/ipv4/ip_forward

naturally, this needs to be executed with sudo.

The problem with the solution based on mullvad's own tutorial that everybody is sharing is that packets forwarded from a subnet never hit the input or output hook, going through prerouting, forward and postrouting instead. Here's a nice diagram that helped me a lot.

I have Ubuntu on my machine so the syntax here is for nftables instead of iptables.

You might want to uncomment the last line if you set this up for the first time. In my case I had ip forwarding already enabled.

Unfortunately anything added to mullvad table would disappear whenever I turn mullvad off and then back on. In this case I need to add the rule again manually (or put it in a separate script). I couldn't find a way to automate it.

Nhfb9E
  • 11