Skip to content

Latest commit

 

History

History
207 lines (158 loc) · 4.32 KB

File metadata and controls

207 lines (158 loc) · 4.32 KB

Split Tunneling

Route only blocked traffic through VPN while keeping Chinese services direct.

Architecture

[Client Request]
       ↓
[iptables/ipset] → Check destination
       ↓
   ┌───┴───┐
   ↓       ↓
[Direct] [VPN]
   ↓       ↓
[5G]    [wireproxy → Mullvad]

Approach 1: IP-based (ipset)

Create IP Sets

# Create set for IPs that should go through VPN
ipset create vpn_ips hash:net

# Add blocked IP ranges (example)
ipset add vpn_ips 8.8.8.0/24      # Google DNS
ipset add vpn_ips 1.1.1.1/32      # Cloudflare DNS
# Add more as needed

iptables Rules

# Mark packets destined for VPN IPs
iptables -t mangle -A PREROUTING -m set --match-set vpn_ips dst -j MARK --set-mark 1

# Redirect marked packets to redsocks
iptables -t nat -A PREROUTING -p tcp -m mark --mark 1 -j REDIRECT --to-ports 12345

Approach 2: Domain-based (dnsmasq + ipset)

Better approach: resolve domains and add IPs to ipset dynamically.

dnsmasq Configuration

# /etc/dnsmasq.d/gfw.conf
# Add resolved IPs to ipset

# Social media
ipset=/twitter.com/vpn_ips
ipset=/facebook.com/vpn_ips
ipset=/instagram.com/vpn_ips

# Google services
ipset=/google.com/vpn_ips
ipset=/youtube.com/vpn_ips
ipset=/googleapis.com/vpn_ips

# Others
ipset=/telegram.org/vpn_ips
ipset=/wikipedia.org/vpn_ips

GFW Domain List

Popular GFW lists:

Convert to dnsmasq format:

# Download and convert gfwlist
curl -L https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt | \
    base64 -d | \
    grep -v '^!' | grep -v '@@' | \
    sed 's/||//g; s/|//g; s|https\?://||g' | \
    sed 's|/.*||' | \
    sort -u | \
    while read domain; do
        echo "ipset=/$domain/vpn_ips"
    done > /etc/dnsmasq.d/gfwlist.conf

Approach 3: PAC-like Routing

For HTTP proxy, you can use a PAC file approach:

Create Routing Rules File

# /mnt/data/vpn/domains-vpn.txt
google.com
youtube.com
twitter.com
facebook.com
instagram.com
telegram.org

Proxy Script with Routing

#!/bin/sh
# /mnt/data/vpn/smart-proxy.sh

VPN_DOMAINS="/mnt/data/vpn/domains-vpn.txt"

check_domain() {
    domain="$1"
    while IFS= read -r vpn_domain; do
        case "$domain" in
            *"$vpn_domain"*) return 0 ;;
        esac
    done < "$VPN_DOMAINS"
    return 1
}

Recommended Setup

For this router, the simplest effective setup:

1. Install dnsmasq (if not present)

The router may use connmand's DNS proxy. Check first:

ps | grep -E 'dnsmasq|connman'

2. Configure Domain-based Routing

# Create blocked domains list
cat > /mnt/data/vpn/blocked-domains.conf << 'EOF'
# Social
ipset=/twitter.com/vpn_ips
ipset=/x.com/vpn_ips
ipset=/facebook.com/vpn_ips
ipset=/instagram.com/vpn_ips
ipset=/threads.net/vpn_ips

# Google
ipset=/google.com/vpn_ips
ipset=/youtube.com/vpn_ips
ipset=/googleapis.com/vpn_ips
ipset=/gstatic.com/vpn_ips
ipset=/googlevideo.com/vpn_ips

# Messaging
ipset=/telegram.org/vpn_ips
ipset=/whatsapp.com/vpn_ips
ipset=/signal.org/vpn_ips

# Other
ipset=/wikipedia.org/vpn_ips
ipset=/reddit.com/vpn_ips
ipset=/medium.com/vpn_ips
ipset=/nytimes.com/vpn_ips
EOF

3. iptables Script

#!/bin/sh
# /mnt/data/vpn/setup-split-tunnel.sh

# Create ipset if not exists
ipset create vpn_ips hash:net 2>/dev/null || ipset flush vpn_ips

# Create NAT chain
iptables -t nat -N REDSOCKS 2>/dev/null || iptables -t nat -F REDSOCKS

# Skip local addresses
for net in 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4; do
    iptables -t nat -A REDSOCKS -d $net -j RETURN
done

# Redirect VPN-destined traffic
iptables -t nat -A REDSOCKS -p tcp -m set --match-set vpn_ips dst -j REDIRECT --to-ports 12345

# Apply to LAN traffic
iptables -t nat -A PREROUTING -i br0 -p tcp -j REDSOCKS

Limitations

  1. UDP traffic: redsocks only handles TCP. UDP (like QUIC) goes direct.
  2. DNS leaks: DNS queries may reveal browsing intent. Use encrypted DNS.
  3. IP changes: Domain IPs can change. ipset entries may become stale.

Testing

# From a client device connected to router WiFi:

# Should go through VPN
curl https://www.google.com
curl https://twitter.com

# Should go direct
curl https://www.baidu.com
curl https://www.taobao.com