Files
vpn/README.md

263 lines
8.3 KiB
Markdown
Raw Permalink Normal View History

2026-02-02 20:11:05 +03:00
# VPN Network with Selective Routing
2026-02-02 20:09:57 +03:00
2026-02-02 20:11:05 +03:00
A WireGuard-based VPN network with selective domain routing. Traffic to `.ru` and `.рф` domains goes directly to the internet, all other traffic is routed through an EU exit node.
## Architecture Overview
```
┌─────────────┐ WireGuard ┌─────────────┐ WireGuard ┌─────────────┐
│ Client │─────────────────────▶│ RU VDS │─────────────────────▶│ DE VDS │
│ (Russia) │ 10.10.0.0/24 │ (Gateway) │ 10.20.0.0/24 │ (Exit Node) │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
│ Direct routing │
│ for .ru/.рф ▼
│ ┌───────────┐
└─────────────────────────────▶│ Internet │
└───────────┘
```
## Infrastructure
| Node | Role | IP Address | OS | Specs |
|------|------|------------|-----|-------|
| RU VDS | Gateway + DNS router | 176.124.216.197 | Debian 12 | 1 CPU, 2GB RAM, 20GB NVMe |
| DE VDS | Exit node | 194.31.173.178 | Debian 13 | 1 CPU, 1GB RAM, 15GB NVMe |
| Clients | User devices | Dynamic | Any | WireGuard client |
## Network Design
### IP Addressing
| Network | Range | Purpose |
|---------|-------|---------|
| User VPN | 10.10.0.0/24 | Client ↔ RU VDS tunnel |
| Server VPN | 10.20.0.0/30 | RU VDS ↔ DE VDS tunnel |
### IP Assignments
**User VPN (10.10.0.0/24):**
- 10.10.0.1 - RU VDS (gateway)
- 10.10.0.2 - Client #1
- 10.10.0.3 - Client #2
- ... up to 10.10.0.254
**Server VPN (10.20.0.0/30):**
- 10.20.0.1 - RU VDS
- 10.20.0.2 - DE VDS
### Ports
| Service | Port | Protocol |
|---------|------|----------|
| WireGuard (RU VDS, users) | 51820/udp | WireGuard |
| WireGuard (DE VDS, server) | 51821/udp | WireGuard |
| DNS (RU VDS, internal) | 53/udp | DNS |
## Routing Logic
1. Client connects to RU VDS via WireGuard
2. Client uses RU VDS as DNS server (10.10.0.1)
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
2026-02-02 20:11:05 +03:00
## Components
### RU VDS (Gateway)
- **WireGuard**: Two interfaces
- `wg0` - User-facing (10.10.0.1/24)
- `wg1` - DE VDS tunnel (10.20.0.1/30)
- **dnsmasq**: DNS server for VPN clients
- **nftables**: Firewall, NAT, and packet marking (pure nftables, no iptables)
2026-02-02 20:11:05 +03:00
- **iproute2**: Policy-based routing tables
- **update-direct-routes.sh**: Loads Russian IP ranges from RIPE
2026-02-02 20:11:05 +03:00
### DE VDS (Exit Node)
- **WireGuard**: One interface
- `wg0` - RU VDS tunnel (10.20.0.2/30)
- **nftables**: NAT for outgoing traffic
## Project Structure
```
vpn.git/
├── README.md # Project overview
├── IMPLEMENTATION.md # Step-by-step implementation guide
├── DEPLOYMENT.md # Deployment guide for production
├── configs/ # Configuration files
│ ├── de-vds/ # DE VDS configs
│ │ ├── wg0.conf # WireGuard config
│ │ ├── nftables.conf # Firewall rules
│ │ └── 99-vpn.conf # Sysctl settings
│ ├── ru-vds/ # RU VDS configs
│ │ ├── wg0.conf # User VPN config
│ │ ├── wg1.conf # DE tunnel config
│ │ ├── postup.sh # Routing setup script
│ │ ├── postdown.sh # Routing cleanup script
│ │ ├── nftables.conf # Firewall + packet marking
2026-02-02 20:11:05 +03:00
│ │ ├── 99-vpn.conf # Sysctl settings
│ │ ├── rt_tables # Routing tables
│ │ ├── vpn-routing.conf # dnsmasq config
│ │ └── update-direct-routes.sh # Russian IP loader
2026-02-02 20:11:05 +03:00
│ └── client-templates/ # Client config templates
│ └── example-client.conf
└── scripts/ # Management scripts
├── setup-de-vds.sh # DE VDS automated setup
├── setup-ru-vds.sh # RU VDS automated setup
├── add-client.sh # Add new VPN client
├── remove-client.sh # Remove VPN client
├── disable-client.sh # Disable VPN client
├── enable-client.sh # Enable VPN client
└── list-clients.sh # List all clients
```
## Quick Start
1. **Configure environment:** Copy `.env.example` to `.env` and adjust values
2. **Read the implementation plan:** See [IMPLEMENTATION.md](IMPLEMENTATION.md)
3. **Deploy to servers:** Follow [DEPLOYMENT.md](DEPLOYMENT.md)
4. **Add clients:** Use scripts in `scripts/` directory
## Configuration
All configurable settings are in `.env` file:
```bash
cp .env.example .env
nano .env # Edit values for your environment
```
Key settings:
- `RU_VDS_IP` / `DE_VDS_IP` - Server public IPs
- `WG_CLIENT_PORT` / `WG_TUNNEL_PORT` - WireGuard ports
- `USER_VPN_NETWORK` - Client VPN network (default: 10.10.0.0/24)
- `TUNNEL_*` - Server-to-server tunnel IPs
2026-02-02 20:11:05 +03:00
## Server File Structure
On the servers, files will be organized as:
```
/etc/wireguard/
├── wg0.conf # User VPN interface
├── wg1.conf # Server-to-server tunnel (RU only)
├── postup.sh # Routing setup (RU only)
├── postdown.sh # Routing cleanup (RU only)
├── keys/ # Private/public keys
└── clients/ # Client configs (RU only)
/etc/dnsmasq.d/
└── vpn-routing.conf # Domain-based routing rules (RU only)
/etc/nftables.conf # Firewall and NAT rules
/etc/iproute2/
└── rt_tables # Custom routing tables (RU only)
```
## User Management
Use the provided scripts on RU VDS:
### Add new user
```bash
/root/add-client.sh <client_name>
# Example: /root/add-client.sh phone
```
### List all users
```bash
/root/list-clients.sh
```
### Disable user (temporarily)
```bash
/root/disable-client.sh <client_name>
```
### Enable user
```bash
/root/enable-client.sh <client_name>
```
### Remove user (permanently)
```bash
/root/remove-client.sh <client_name>
```
### Manual management
If you prefer manual commands:
```bash
# Generate keys
wg genkey | tee /etc/wireguard/keys/client_NAME.key | wg pubkey > /etc/wireguard/keys/client_NAME.pub
# Add peer
wg set wg0 peer $(cat /etc/wireguard/keys/client_NAME.pub) allowed-ips 10.10.0.X/32
# Save config
wg-quick save wg0
```
## Security Considerations
- WireGuard keys are stored in `/etc/wireguard/keys/` with 600 permissions
- Only UDP port 51820 is exposed on RU VDS
- Only UDP port 51821 is exposed on DE VDS (and only to RU VDS IP)
- DNS queries are only accepted from VPN clients (10.10.0.0/24)
- IP forwarding is enabled only for necessary interfaces
## Maintenance
### Check status
```bash
# WireGuard status
wg show
# Active connections
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
2026-02-02 20:11:05 +03:00
# Routing tables
ip route show table proxy
ip rule show
2026-02-02 20:11:05 +03:00
```
### View logs
```bash
journalctl -u wg-quick@wg0 -f
journalctl -u dnsmasq -f
```
## References
- [WireGuard Documentation](https://www.wireguard.com/quickstart/)
- [dnsmasq ipset feature](https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html)
- [nftables wiki](https://wiki.nftables.org/)