Files
vpn/DEPLOYMENT.md
mguschin f14d4f8f33 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>
2026-02-19 18:02:28 +03:00

10 KiB

Deployment Guide

This guide walks you through deploying the VPN network on your actual servers.

Prerequisites

  • SSH access to both VDS servers
  • Root or sudo privileges
  • Basic familiarity with Linux command line

Infrastructure

Server IP Role
DE VDS 194.31.173.178 Exit node (Debian 13)
RU VDS 176.124.216.197 Gateway (Debian 12)

Step 1: Deploy DE VDS (Exit Node)

1.1 Copy setup script to DE VDS

From your local machine:

scp scripts/setup-de-vds.sh root@194.31.173.178:/root/

1.2 Run setup script

SSH into DE VDS:

ssh root@194.31.173.178

Run the setup:

cd /root
chmod +x setup-de-vds.sh
./setup-de-vds.sh

1.3 Save the DE VDS public key

The script will output the DE VDS public key. Copy it - you'll need it for RU VDS.

Example output:

Your DE VDS public key is:
Xabc123def456ghi789jkl012mno345pqr678stu901vwx234=

Do not start services yet - we need to exchange keys first.


Step 2: Deploy RU VDS (Gateway)

2.1 Copy setup script to RU VDS

From your local machine:

scp scripts/setup-ru-vds.sh root@176.124.216.197:/root/

2.2 Run setup script

SSH into RU VDS:

ssh root@176.124.216.197

Run the setup:

cd /root
chmod +x setup-ru-vds.sh
./setup-ru-vds.sh

2.3 Save the RU VDS keys

The script will output two public keys:

  1. Server key - for clients (you'll use this later when adding clients)
  2. DE tunnel key - for DE VDS

Example output:

Server key (for clients):
Yabc123def456ghi789jkl012mno345pqr678stu901vwx234=

DE tunnel key (for DE VDS):
Zabc123def456ghi789jkl012mno345pqr678stu901vwx234=

Copy both keys and keep them safe.

Do not start services yet - we need to configure keys first.


Step 3: Exchange Keys

3.1 Configure DE VDS with RU key

SSH into DE VDS:

ssh root@194.31.173.178

Edit WireGuard config:

nano /etc/wireguard/wg0.conf

Replace __RU_DE_TUNNEL_PUBLIC_KEY__ with the RU DE tunnel key (the second key from RU VDS).

Save and exit (Ctrl+X, Y, Enter).

3.2 Configure RU VDS with DE key

SSH into RU VDS:

ssh root@176.124.216.197

Edit WireGuard config:

nano /etc/wireguard/wg1.conf

Replace __DE_SERVER_PUBLIC_KEY__ with the DE VDS public key.

Save and exit (Ctrl+X, Y, Enter).


Step 4: Start Services

4.1 Start DE VDS services

SSH into DE VDS:

ssh root@194.31.173.178

Start services:

systemctl start nftables
systemctl start wg-quick@wg0

Check status:

systemctl status wg-quick@wg0
wg show

You should see:

  • wg0 interface with IP 10.20.0.2/30
  • No handshake yet (RU VDS not connected)

4.2 Start RU VDS services

SSH into RU VDS:

ssh root@176.124.216.197

Start services:

systemctl start dnsmasq
systemctl start wg-quick@wg1
systemctl start wg-quick@wg0

Check status:

systemctl status wg-quick@wg1
systemctl status wg-quick@wg0
systemctl status dnsmasq

Step 5: Verify Tunnel

5.1 Test from RU VDS

# Ping DE VDS through tunnel
ping -c 4 10.20.0.2

# Check WireGuard handshake
wg show wg1

You should see:

  • Successful ping responses
  • Recent handshake timestamp
  • Transfer data counters

5.2 Test from DE VDS

# Check WireGuard handshake
wg show wg0

# You should see recent handshake from RU VDS

5.3 Check routing on RU VDS

# Check routing table
ip route show table proxy

# Check nftables set (will be empty until IP ranges are loaded)
nft list set ip vpn-routing direct

# Check policy routing rules
ip rule show

Expected output:

  • Routing table proxy should have default route via 10.20.0.2
  • nftables set direct should exist
  • Policy routing rule for 10.10.0.0/24 with fwmark 0x1

5.4 Load Russian IP ranges

# Load Russian IP ranges into nftables (takes 1-2 minutes)
/etc/wireguard/update-direct-routes.sh

# Verify ranges were loaded
nft list set ip vpn-routing direct | head -20

Step 6: Add First Client

6.1 Copy client management scripts to RU VDS

From your local machine:

scp scripts/add-client.sh root@176.124.216.197:/root/
scp scripts/list-clients.sh root@176.124.216.197:/root/
scp scripts/disable-client.sh root@176.124.216.197:/root/
scp scripts/enable-client.sh root@176.124.216.197:/root/
scp scripts/remove-client.sh root@176.124.216.197:/root/

6.2 Add a client

SSH into RU VDS:

ssh root@176.124.216.197

Add client (replace "phone" with your device name):

chmod +x /root/*.sh
/root/add-client.sh phone

The script will:

  1. Generate client keys
  2. Assign IP address (starting from 10.10.0.2)
  3. Add peer to WireGuard
  4. Create client config file
  5. Display QR code for mobile devices

6.3 Transfer configuration to client

For mobile devices:

  • Scan the QR code with WireGuard app

For desktop/laptop:

  • Copy the configuration file from RU VDS:
    cat /etc/wireguard/clients/phone.conf
    
  • Save it locally as phone.conf
  • Import into WireGuard client

Step 7: Test Client Connection

7.1 Connect from client

  1. Open WireGuard app/client
  2. Import/scan the configuration
  3. Connect

7.2 Test basic connectivity

From the client device:

# Test VPN gateway
ping 10.10.0.1

# Test DNS
nslookup google.com
nslookup yandex.ru

7.3 Test routing

From the client device:

# Check external IP (should show DE VDS IP: 194.31.173.178)
curl ifconfig.me

# Visit a Russian site, then check ipset on RU VDS

On RU VDS:

# Check that Russian IP ranges are loaded
nft list set ip vpn-routing direct | wc -l

# Should show many IP ranges (thousands)

7.4 Advanced testing

Test that Russian IPs go direct:

# From client - visit some Russian sites
curl -I https://yandex.ru
curl -I https://mail.ru

# These should be fast (direct routing)

Test that other domains go through DE:

# From client
traceroute google.com
# Should show hop through 10.20.0.x

traceroute yandex.ru
# Should NOT show 10.20.0.x hop (goes direct)

Step 8: Client Management

List all clients

/root/list-clients.sh

Add another client

/root/add-client.sh laptop

Disable a client temporarily

/root/disable-client.sh phone

Enable a disabled client

/root/enable-client.sh phone

Permanently remove a client

/root/remove-client.sh phone

Troubleshooting

Tunnel not working

Check WireGuard status:

# On both servers
wg show
systemctl status wg-quick@wg0
systemctl status wg-quick@wg1  # RU only

Check if ports are open:

# On DE VDS
ss -ulnp | grep 51821

# On RU VDS
ss -ulnp | grep 51820

Check firewall:

nft list ruleset

DNS not working

Check dnsmasq:

# On RU VDS
systemctl status dnsmasq
journalctl -u dnsmasq -n 50

Test DNS locally:

dig @127.0.0.1 google.com
dig @10.10.0.1 yandex.ru

Routing not working

Check routing tables:

# On RU VDS
ip route show table proxy
ip rule show

Check nftables set:

nft list set ip vpn-routing direct | head -20

Check nftables rules:

nft list chain ip vpn-routing prerouting

Client can't connect

Check client config:

  • Correct server IP (176.124.216.197)
  • Correct port (51820)
  • Correct DNS (10.10.0.1)

Check server logs:

# On RU VDS
journalctl -u wg-quick@wg0 -f

Check if peer is added:

wg show wg0

Maintenance

View logs

# WireGuard
journalctl -u wg-quick@wg0 -f
journalctl -u wg-quick@wg1 -f

# dnsmasq
journalctl -u dnsmasq -f

# System
dmesg | grep -i wireguard

Restart services

# RU VDS
systemctl restart wg-quick@wg0
systemctl restart wg-quick@wg1
systemctl restart dnsmasq

# DE VDS
systemctl restart wg-quick@wg0

Update system packages

apt update && apt upgrade -y

Backup configurations

# On both servers
tar -czf wireguard-backup-$(date +%Y%m%d).tar.gz /etc/wireguard/

Security Best Practices

  1. Change SSH port from default 22
  2. Use SSH keys instead of passwords
  3. Enable automatic security updates:
    apt install unattended-upgrades
    dpkg-reconfigure -plow unattended-upgrades
    
  4. Monitor logs regularly
  5. Keep WireGuard keys secure - never share them
  6. Rotate client keys periodically
  7. Remove unused clients promptly

Performance Optimization

If experiencing slow speeds:

  1. Check MTU settings:

    # Add to WireGuard config
    MTU = 1420
    
  2. Enable BBR congestion control:

    echo "net.core.default_qdisc=fq" >> /etc/sysctl.d/99-vpn.conf
    echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.d/99-vpn.conf
    sysctl -p /etc/sysctl.d/99-vpn.conf
    
  3. Increase UDP buffer sizes:

    echo "net.core.rmem_max=2500000" >> /etc/sysctl.d/99-vpn.conf
    echo "net.core.wmem_max=2500000" >> /etc/sysctl.d/99-vpn.conf
    sysctl -p /etc/sysctl.d/99-vpn.conf
    

Next Steps

  • Deploy to production servers
  • Add first client
  • Test routing for .ru domains
  • Test routing for international domains
  • Set up monitoring (optional)
  • Document server access credentials securely
  • Schedule regular backups

Quick Reference

Key Files

DE VDS:

  • /etc/wireguard/wg0.conf - WireGuard config
  • /etc/nftables.conf - Firewall rules
  • /etc/wireguard/keys/ - WireGuard keys

RU VDS:

  • /etc/wireguard/wg0.conf - User VPN config
  • /etc/wireguard/wg1.conf - DE tunnel config
  • /etc/wireguard/postup.sh - Routing setup
  • /etc/wireguard/postdown.sh - Routing cleanup
  • /etc/dnsmasq.d/vpn-routing.conf - DNS config
  • /etc/nftables.conf - Firewall rules
  • /etc/wireguard/clients/ - Client configs

Common Commands

# Check WireGuard status
wg show

# List clients
/root/list-clients.sh

# Add client
/root/add-client.sh <name>

# View logs
journalctl -u wg-quick@wg0 -f

# Test tunnel
ping 10.20.0.2

# Check routing
ip route show table proxy
nft list set ip vpn-routing direct | head -20

# Update Russian IP ranges
/etc/wireguard/update-direct-routes.sh