Files
vpn/README.md
mguschin b117efc604 Init
2026-02-02 20:11:05 +03:00

7.4 KiB

VPN Network with Selective Routing

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. 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)

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 with ipset integration
  • nftables: Packet marking and routing
  • iproute2: Policy-based routing tables

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 rules
│   │   ├── 99-vpn.conf       # Sysctl settings
│   │   ├── rt_tables         # Routing tables
│   │   └── vpn-routing.conf  # dnsmasq config
│   └── 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. Read the implementation plan: See IMPLEMENTATION.md
  2. Deploy to servers: Follow DEPLOYMENT.md
  3. Add clients: Use scripts in scripts/ directory

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

/root/add-client.sh <client_name>
# Example: /root/add-client.sh phone

List all users

/root/list-clients.sh

Disable user (temporarily)

/root/disable-client.sh <client_name>

Enable user

/root/enable-client.sh <client_name>

Remove user (permanently)

/root/remove-client.sh <client_name>

Manual management

If you prefer manual commands:

# 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

# WireGuard status
wg show

# Active connections
wg show wg0 latest-handshakes

# DNS cache stats
kill -USR1 $(pidof dnsmasq) && journalctl -u dnsmasq -n 20

# Routing tables
ip route show table direct
ip route show table proxy

View logs

journalctl -u wg-quick@wg0 -f
journalctl -u dnsmasq -f

References