IP-based Split Tunneling on Raspberry Pi VPN Gateway

In a previous article, we discussed the process of turning a Raspberry Pi into a router, and also configured it as a VPN gateway. For users in China, if you’re using a Raspberry Pi as a gateway router with an OpenConnect VPN (HK server), the most robust approach is:

  • Default route → HK VPN
  • China mainland IP ranges → direct WAN
  • LAN clients automatically benefit from the split tunnel.

This is called policy-based routing (PBR).

Architecture

LAN clients
      │
      ▼
┌──────────────────┐
│ Raspberry Pi     │
│                  │
│ eth0  ←→  ISP    │
│ eth1 ←→   LAN    │
│ tun0  ←→  HK VPN │
└──────────────────┘
      │
      ▼
Internet

Default route → tun0 (HK VPN)
China IPs     → ISP directly

Step 1. Install packages

Debian/Raspberry Pi OS:

sudo apt install dnsmasq ipset nftables

Step 2. Create an ipset for China

Using nftables:

sudo nft add table inet pbr

sudo nft add set inet pbr china '{ type ipv4_addr; flags interval; }'

Step 3. Download China IP ranges

The most commonly used source is CHNRoute.

wget https://ispip.clang.cn/all_cn.txt

Import:

while read net; do
sudo nft add element inet pbr china { $net }
done < all_cn.txt

Check the ipset.

sudo nft list set inet pbr china

You should see lots of IP addresses in the IP set.


Step 4. Create an alternate routing table

Edit:

sudo mkdir /etc/iproute2/
echo "100 direct" | sudo tee /etc/iproute2/rt_tables

Step 5. Populate the direct table

Assuming:

WAN gateway: 192.168.1.1
WAN interface: eth0
VPN interface: tun0

Add:

sudo ip route add 192.168.1.0/24 dev eth0 table direct

sudo ip route add default via 192.168.1.1 dev eth0 table direct

Check the direct routing table.

ip route show table direct

Output:

default via 192.168.1.1 dev eth0
192.168.1.0/24 dev eth0 scope link

Step 6. Mark China traffic

sudo nft add chain inet pbr prerouting \
'{ type filter hook prerouting priority mangle; }'
 sudo nft add rule inet pbr prerouting \ ip daddr @china meta mark set 0x1

Step 7. Create policy routing rule

sudo ip rule add fwmark 0x1 lookup direct

Verify:

ip rule

You should see:

32765: from all fwmark 0x1 lookup direct

Step 8. Make VPN the default route

When OpenConnect connects:

sudo ip route replace default dev tun0

Check:

ip route

Expected:

default dev tun0
192.168.1.0/24 dev eth0

Now my XIAOMI TV can stream China channels smoothly. I also use it to watch YouTube via the SmartTube app.

Rate this tutorial
[Total: 0 Average: 0]

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community (https://community.linuxbabe.com) for questions unrelated to this article.
  • I don't have time to answer every question. Making a donation would incentivize me to spend more time answering questions.

The maximum upload file size: 2 MB. You can upload: image. Links to YouTube, Facebook, Twitter and other services inserted in the comment text will be automatically embedded. Drop file here