Migrate to pure nftables routing (remove iptables/ipset)

- Replace hybrid iptables/ipset/nftables approach with pure nftables
- Add nftables native set for Russian IP ranges (populated from RIPE)
- Create update-direct-routes.sh script to load IP ranges from RIPE database
- Remove ipset and iptables dependencies from postup.sh/postdown.sh
- Add automatic weekly cron job for IP range updates
- Update all documentation to reflect the new approach

Benefits:
- More reliable: no iptables/nftables conflicts
- Simpler debugging: single tool for all rules (nft list ruleset)
- Atomic rule loading: prevents partial failures
- IP-based routing is more predictable than DNS-based

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
mguschin
2026-02-19 18:02:28 +03:00
parent b117efc604
commit f14d4f8f33
13 changed files with 461 additions and 264 deletions

View File

@@ -58,12 +58,16 @@ A WireGuard-based VPN network with selective domain routing. Traffic to `.ru` an
1. Client connects to RU VDS via WireGuard
2. Client uses RU VDS as DNS server (10.10.0.1)
3. dnsmasq on RU VDS resolves DNS queries:
- For `.ru` and `.рф` domains → adds resolved IPs to `direct` ipset
- For all other domains → adds resolved IPs to `proxy` ipset
4. nftables routes packets based on ipset membership:
- IPs in `direct` → route via RU VDS default gateway (direct internet)
- IPs in `proxy` → route via DE VDS tunnel (10.20.0.2)
3. Russian IP ranges are loaded into nftables `direct` set (from RIPE database)
4. nftables marks packets based on destination:
- IPs in `direct` set → no mark (routes directly via RU VDS)
- All other IPs → marked with `0x1` (routes via DE VDS tunnel)
5. Policy routing sends marked packets through the DE tunnel
**Why IP-based routing (not DNS-based)?**
- More reliable: works even if DNS is bypassed or cached
- Simpler: no iptables/ipset mixing, pure nftables
- Predictable: based on authoritative RIPE data
## Components
@@ -72,9 +76,10 @@ A WireGuard-based VPN network with selective domain routing. Traffic to `.ru` an
- **WireGuard**: Two interfaces
- `wg0` - User-facing (10.10.0.1/24)
- `wg1` - DE VDS tunnel (10.20.0.1/30)
- **dnsmasq**: DNS server with ipset integration
- **nftables**: Packet marking and routing
- **dnsmasq**: DNS server for VPN clients
- **nftables**: Firewall, NAT, and packet marking (pure nftables, no iptables)
- **iproute2**: Policy-based routing tables
- **update-direct-routes.sh**: Loads Russian IP ranges from RIPE
### DE VDS (Exit Node)
@@ -99,10 +104,11 @@ vpn.git/
│ │ ├── wg1.conf # DE tunnel config
│ │ ├── postup.sh # Routing setup script
│ │ ├── postdown.sh # Routing cleanup script
│ │ ├── nftables.conf # Firewall rules
│ │ ├── nftables.conf # Firewall + packet marking
│ │ ├── 99-vpn.conf # Sysctl settings
│ │ ├── rt_tables # Routing tables
│ │ ── vpn-routing.conf # dnsmasq config
│ │ ── vpn-routing.conf # dnsmasq config
│ │ └── update-direct-routes.sh # Russian IP loader
│ └── client-templates/ # Client config templates
│ └── example-client.conf
└── scripts/ # Management scripts
@@ -215,9 +221,15 @@ wg show wg0 latest-handshakes
# DNS cache stats
kill -USR1 $(pidof dnsmasq) && journalctl -u dnsmasq -n 20
# View nftables rules and sets
nft list ruleset
# Check direct routes set (Russian IPs)
nft list set ip vpn-routing direct
# Routing tables
ip route show table direct
ip route show table proxy
ip rule show
```
### View logs