This commit is contained in:
mguschin
2026-02-02 20:11:05 +03:00
parent 49f778a61b
commit b117efc604
26 changed files with 3544 additions and 1 deletions

616
DEPLOYMENT.md Normal file
View File

@@ -0,0 +1,616 @@
# 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:
```bash
scp scripts/setup-de-vds.sh root@194.31.173.178:/root/
```
### 1.2 Run setup script
SSH into DE VDS:
```bash
ssh root@194.31.173.178
```
Run the setup:
```bash
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:
```bash
scp scripts/setup-ru-vds.sh root@176.124.216.197:/root/
```
### 2.2 Run setup script
SSH into RU VDS:
```bash
ssh root@176.124.216.197
```
Run the setup:
```bash
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:
```bash
ssh root@194.31.173.178
```
Edit WireGuard config:
```bash
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:
```bash
ssh root@176.124.216.197
```
Edit WireGuard config:
```bash
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:
```bash
ssh root@194.31.173.178
```
Start services:
```bash
systemctl start nftables
systemctl start wg-quick@wg0
```
Check status:
```bash
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:
```bash
ssh root@176.124.216.197
```
Start services:
```bash
systemctl start dnsmasq
systemctl start wg-quick@wg1
systemctl start wg-quick@wg0
```
Check status:
```bash
systemctl status wg-quick@wg1
systemctl status wg-quick@wg0
systemctl status dnsmasq
```
---
## Step 5: Verify Tunnel
### 5.1 Test from RU VDS
```bash
# 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
```bash
# Check WireGuard handshake
wg show wg0
# You should see recent handshake from RU VDS
```
### 5.3 Check routing on RU VDS
```bash
# Check routing table
ip route show table proxy
# Check ipset
ipset list direct
# Check policy routing rules
ip rule show
```
Expected output:
- Routing table `proxy` should have default route via `10.20.0.2`
- ipset `direct` should exist (empty initially)
- Policy routing rule for `10.10.0.0/24` with fwmark `0x1`
---
## Step 6: Add First Client
### 6.1 Copy client management scripts to RU VDS
From your local machine:
```bash
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:
```bash
ssh root@176.124.216.197
```
Add client (replace "phone" with your device name):
```bash
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:
```bash
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:
```bash
# Test VPN gateway
ping 10.10.0.1
# Test DNS
nslookup google.com
nslookup yandex.ru
```
### 7.3 Test routing
From the client device:
```bash
# 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:
```bash
# After client visits .ru domains, check direct ipset
ipset list direct
# Should show Russian IPs
```
### 7.4 Advanced testing
Test that `.ru` domains go direct:
```bash
# From client - visit some Russian sites
curl -I https://yandex.ru
curl -I https://mail.ru
# Then on RU VDS - check ipset
ipset list direct
```
Test that other domains go through DE:
```bash
# 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
```bash
/root/list-clients.sh
```
### Add another client
```bash
/root/add-client.sh laptop
```
### Disable a client temporarily
```bash
/root/disable-client.sh phone
```
### Enable a disabled client
```bash
/root/enable-client.sh phone
```
### Permanently remove a client
```bash
/root/remove-client.sh phone
```
---
## Troubleshooting
### Tunnel not working
**Check WireGuard status:**
```bash
# On both servers
wg show
systemctl status wg-quick@wg0
systemctl status wg-quick@wg1 # RU only
```
**Check if ports are open:**
```bash
# On DE VDS
ss -ulnp | grep 51821
# On RU VDS
ss -ulnp | grep 51820
```
**Check firewall:**
```bash
nft list ruleset
```
### DNS not working
**Check dnsmasq:**
```bash
# On RU VDS
systemctl status dnsmasq
journalctl -u dnsmasq -n 50
```
**Test DNS locally:**
```bash
dig @127.0.0.1 google.com
dig @10.10.0.1 yandex.ru
```
### Routing not working
**Check routing tables:**
```bash
# On RU VDS
ip route show table proxy
ip rule show
```
**Check ipset:**
```bash
ipset list direct
```
**Check iptables mangle:**
```bash
iptables -t mangle -L -v
```
### 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:**
```bash
# On RU VDS
journalctl -u wg-quick@wg0 -f
```
**Check if peer is added:**
```bash
wg show wg0
```
---
## Maintenance
### View logs
```bash
# 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
```bash
# 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
```bash
apt update && apt upgrade -y
```
### Backup configurations
```bash
# 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:**
```bash
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:**
```bash
# Add to WireGuard config
MTU = 1420
```
2. **Enable BBR congestion control:**
```bash
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:**
```bash
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
```bash
# 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
ipset list direct
```

684
IMPLEMENTATION.md Normal file
View File

@@ -0,0 +1,684 @@
# Implementation Plan
## Prerequisites
- SSH access to both VDS servers (RU: 176.124.216.197, DE: 194.31.173.178)
- Root or sudo privileges on both servers
- Basic firewall rules allowing SSH access
---
## Phase 1: DE VDS Setup (Exit Node)
The simpler node - just accepts traffic from RU VDS and NATs it to the internet.
### Step 1.1: Install packages
```bash
apt update && apt install -y wireguard nftables
```
### Step 1.2: Enable IP forwarding
```bash
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.d/99-vpn.conf
sysctl -p /etc/sysctl.d/99-vpn.conf
```
### Step 1.3: Generate WireGuard keys
```bash
mkdir -p /etc/wireguard/keys
chmod 700 /etc/wireguard/keys
wg genkey | tee /etc/wireguard/keys/server.key | wg pubkey > /etc/wireguard/keys/server.pub
chmod 600 /etc/wireguard/keys/*
```
### Step 1.4: Create WireGuard config
Create `/etc/wireguard/wg0.conf`:
```ini
[Interface]
Address = 10.20.0.2/30
ListenPort = 51821
PrivateKey = <DE_SERVER_PRIVATE_KEY>
PostUp = nft -f /etc/nftables.conf
PostDown = nft flush ruleset
[Peer]
# RU VDS
PublicKey = <RU_SERVER_PUBLIC_KEY>
AllowedIPs = 10.20.0.1/32, 10.10.0.0/24
```
### Step 1.5: Configure nftables
Create `/etc/nftables.conf`:
```nft
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Allow established connections
ct state established,related accept
# Allow loopback
iif lo accept
# Allow SSH (adjust port if needed)
tcp dport 22 accept
# Allow WireGuard from RU VDS only
ip saddr 176.124.216.197 udp dport 51821 accept
# Allow ICMP
icmp type echo-request accept
}
chain forward {
type filter hook forward priority 0; policy drop;
# Allow forwarding from VPN
iifname "wg0" accept
# Allow established connections back
ct state established,related accept
}
chain output {
type filter hook output priority 0; policy accept;
}
}
table inet nat {
chain postrouting {
type nat hook postrouting priority 100;
# NAT traffic from VPN to internet
oifname != "wg0" ip saddr { 10.10.0.0/24, 10.20.0.0/30 } masquerade
}
}
```
### Step 1.6: Enable and start services
```bash
systemctl enable --now nftables
systemctl enable --now wg-quick@wg0
```
### Step 1.7: Verify
```bash
wg show
ip addr show wg0
```
---
## Phase 2: RU VDS Setup (Gateway)
The main node - handles user connections, DNS-based routing decisions.
### Step 2.1: Install packages
```bash
apt update && apt install -y wireguard dnsmasq nftables ipset
```
### Step 2.2: Enable IP forwarding
```bash
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.d/99-vpn.conf
sysctl -p /etc/sysctl.d/99-vpn.conf
```
### Step 2.3: Generate WireGuard keys
```bash
mkdir -p /etc/wireguard/keys
chmod 700 /etc/wireguard/keys
# Server key for user-facing interface
wg genkey | tee /etc/wireguard/keys/server.key | wg pubkey > /etc/wireguard/keys/server.pub
# Key for DE tunnel
wg genkey | tee /etc/wireguard/keys/de-tunnel.key | wg pubkey > /etc/wireguard/keys/de-tunnel.pub
chmod 600 /etc/wireguard/keys/*
```
### Step 2.4: Create routing tables
Add to `/etc/iproute2/rt_tables`:
```
200 proxy
```
### Step 2.5: Create WireGuard configs
Create `/etc/wireguard/wg0.conf` (user-facing):
```ini
[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = <RU_SERVER_PRIVATE_KEY>
PostUp = /etc/wireguard/postup.sh
PostDown = /etc/wireguard/postdown.sh
# Users will be added here as [Peer] sections
```
Create `/etc/wireguard/wg1.conf` (DE tunnel):
```ini
[Interface]
Address = 10.20.0.1/30
PrivateKey = <RU_DE_TUNNEL_PRIVATE_KEY>
[Peer]
# DE VDS
PublicKey = <DE_SERVER_PUBLIC_KEY>
Endpoint = 194.31.173.178:51821
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
```
### Step 2.6: Create PostUp script
Create `/etc/wireguard/postup.sh`:
```bash
#!/bin/bash
# Create ipsets for routing decisions
ipset create direct hash:net -exist
ipset create proxy hash:net -exist
# Add default route via DE tunnel for 'proxy' table
ip route add default via 10.20.0.2 table proxy
# Load nftables rules
nft -f /etc/nftables.conf
```
Make executable:
```bash
chmod +x /etc/wireguard/postup.sh
```
### Step 2.7: Create PostDown script
Create `/etc/wireguard/postdown.sh`:
```bash
#!/bin/bash
# Flush routing table
ip route flush table proxy
# Destroy ipsets
ipset destroy direct 2>/dev/null
ipset destroy proxy 2>/dev/null
# Flush nftables
nft flush ruleset
```
Make executable:
```bash
chmod +x /etc/wireguard/postdown.sh
```
### Step 2.8: Configure nftables
Create `/etc/nftables.conf`:
```nft
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Allow established
ct state established,related accept
# Allow loopback
iif lo accept
# Allow SSH
tcp dport 22 accept
# Allow WireGuard from anywhere (user connections)
udp dport 51820 accept
# Allow DNS from VPN clients only
iifname "wg0" udp dport 53 accept
iifname "wg0" tcp dport 53 accept
# Allow ICMP
icmp type echo-request accept
}
chain forward {
type filter hook forward priority 0; policy drop;
# Allow forwarding from user VPN
iifname "wg0" accept
# Allow forwarding from DE tunnel
iifname "wg1" accept
# Allow established
ct state established,related accept
}
chain output {
type filter hook output priority 0; policy accept;
}
}
table inet nat {
chain postrouting {
type nat hook postrouting priority 100;
# NAT direct traffic (going out main interface)
oifname != "wg0" oifname != "wg1" ip saddr 10.10.0.0/24 masquerade
}
}
table inet mangle {
chain prerouting {
type filter hook prerouting priority -150;
# Mark packets destined for 'proxy' ipset
ip daddr @proxy meta mark set 0x1
}
}
```
**Note:** nftables native sets will be used instead of ipset. See Step 2.10 for updated approach.
### Step 2.9: Configure dnsmasq
Disable systemd-resolved if running:
```bash
systemctl disable --now systemd-resolved
rm /etc/resolv.conf
echo "nameserver 8.8.8.8" > /etc/resolv.conf
```
Create `/etc/dnsmasq.d/vpn-routing.conf`:
```conf
# Listen only on VPN interface
interface=wg0
bind-interfaces
# Upstream DNS
server=8.8.8.8
server=8.8.4.4
# Don't read /etc/resolv.conf
no-resolv
# Cache size
cache-size=10000
# Log queries (optional, disable in production)
# log-queries
# Russian TLDs - route directly (add to 'direct' ipset)
ipset=/ru/direct
ipset=/рф/direct
ipset=/su/direct
# Everything else goes to proxy (default)
# This is handled by routing table, not ipset
```
**Important:** dnsmasq's ipset feature requires ipset, not nftables sets. We'll use a hybrid approach.
### Step 2.10: Updated routing approach (hybrid ipset + nftables)
Since dnsmasq works with ipset, we'll use ipset for the sets and nftables for the rules.
Update `/etc/nftables.conf`:
```nft
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif lo accept
tcp dport 22 accept
udp dport 51820 accept
iifname "wg0" udp dport 53 accept
iifname "wg0" tcp dport 53 accept
icmp type echo-request accept
}
chain forward {
type filter hook forward priority 0; policy drop;
iifname "wg0" accept
iifname "wg1" accept
ct state established,related accept
}
chain output {
type filter hook output priority 0; policy accept;
}
}
table inet nat {
chain postrouting {
type nat hook postrouting priority 100;
# NAT direct traffic going out main interface
oifname != "wg0" oifname != "wg1" ip saddr 10.10.0.0/24 masquerade
}
}
```
Update `/etc/wireguard/postup.sh`:
```bash
#!/bin/bash
# Create ipsets
ipset create direct hash:net -exist
ipset flush direct
# Add default route via DE tunnel for 'proxy' table
ip route add default via 10.20.0.2 table proxy 2>/dev/null || true
# Policy routing: packets NOT going to 'direct' ipset use 'proxy' table
ip rule add from 10.10.0.0/24 fwmark 0x1 table proxy priority 100 2>/dev/null || true
# Load nftables
nft -f /etc/nftables.conf
# Add iptables rule for fwmark (nftables mangle is complex with ipset)
iptables -t mangle -A PREROUTING -m set ! --match-set direct dst -s 10.10.0.0/24 -j MARK --set-mark 0x1
```
Update `/etc/wireguard/postdown.sh`:
```bash
#!/bin/bash
ip rule del from 10.10.0.0/24 fwmark 0x1 table proxy priority 100 2>/dev/null || true
ip route flush table proxy 2>/dev/null || true
iptables -t mangle -F PREROUTING 2>/dev/null || true
ipset destroy direct 2>/dev/null || true
nft flush ruleset
```
### Step 2.11: Enable and start services
```bash
systemctl enable --now dnsmasq
systemctl enable --now wg-quick@wg0
systemctl enable --now wg-quick@wg1
```
### Step 2.12: Verify
```bash
wg show
ip route show table proxy
ipset list direct
```
---
## Phase 3: Key Exchange
After generating keys on both servers, exchange public keys:
### On DE VDS:
```bash
cat /etc/wireguard/keys/server.pub
# Copy this value
```
### On RU VDS:
```bash
cat /etc/wireguard/keys/server.pub
cat /etc/wireguard/keys/de-tunnel.pub
# Copy these values
```
### Update configs:
1. **DE VDS** `/etc/wireguard/wg0.conf`: Replace `<RU_SERVER_PUBLIC_KEY>` with RU's `de-tunnel.pub`
2. **RU VDS** `/etc/wireguard/wg1.conf`: Replace `<DE_SERVER_PUBLIC_KEY>` with DE's `server.pub`
### Restart WireGuard:
```bash
# On DE VDS
systemctl restart wg-quick@wg0
# On RU VDS
systemctl restart wg-quick@wg1
```
### Verify tunnel:
```bash
# On RU VDS
ping 10.20.0.2
wg show wg1
```
---
## Phase 4: Add First Client
### Step 4.1: Generate client keys (on RU VDS)
```bash
CLIENT_NAME="phone"
wg genkey | tee /etc/wireguard/keys/client_${CLIENT_NAME}.key | wg pubkey > /etc/wireguard/keys/client_${CLIENT_NAME}.pub
chmod 600 /etc/wireguard/keys/client_${CLIENT_NAME}.*
```
### Step 4.2: Add peer to server
```bash
CLIENT_IP="10.10.0.2"
CLIENT_PUBKEY=$(cat /etc/wireguard/keys/client_${CLIENT_NAME}.pub)
wg set wg0 peer ${CLIENT_PUBKEY} allowed-ips ${CLIENT_IP}/32
wg-quick save wg0
```
### Step 4.3: Create client config
```bash
CLIENT_NAME="phone"
CLIENT_IP="10.10.0.2"
SERVER_PUBKEY=$(cat /etc/wireguard/keys/server.pub)
CLIENT_PRIVKEY=$(cat /etc/wireguard/keys/client_${CLIENT_NAME}.key)
cat > /etc/wireguard/clients/${CLIENT_NAME}.conf << EOF
[Interface]
PrivateKey = ${CLIENT_PRIVKEY}
Address = ${CLIENT_IP}/32
DNS = 10.10.0.1
[Peer]
PublicKey = ${SERVER_PUBKEY}
Endpoint = 176.124.216.197:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF
mkdir -p /etc/wireguard/clients
chmod 600 /etc/wireguard/clients/${CLIENT_NAME}.conf
```
### Step 4.4: Transfer to client
Display as QR code (for mobile):
```bash
apt install -y qrencode
qrencode -t ansiutf8 < /etc/wireguard/clients/${CLIENT_NAME}.conf
```
Or copy the file contents manually.
---
## Phase 5: Testing
### Test 1: Basic connectivity
```bash
# From client
ping 10.10.0.1 # Should work - RU VDS
ping 10.20.0.2 # Should work - DE VDS
```
### Test 2: DNS resolution
```bash
# From client
nslookup google.com 10.10.0.1
nslookup yandex.ru 10.10.0.1
```
### Test 3: Routing verification
```bash
# On RU VDS - check ipset after client visits some .ru sites
ipset list direct
# From client - check external IP
curl ifconfig.me # Should show DE VDS IP (194.31.173.178)
curl ifconfig.me --resolve ifconfig.me:80:$(dig +short yandex.ru | head -1) # Won't work, but...
# Better test - check where traffic goes
curl https://2ip.ru # Russian service, should go direct, show RU VDS IP
curl https://ifconfig.me # Should show DE VDS IP
```
### Test 4: Check that .ru domains go direct
```bash
# From client
traceroute yandex.ru # Should not go through DE
traceroute google.com # Should go through DE (you'll see 10.20.0.x hop)
```
---
## Troubleshooting
### WireGuard not connecting
```bash
# Check if service is running
systemctl status wg-quick@wg0
# Check for errors
journalctl -u wg-quick@wg0 -e
# Verify port is open
ss -ulnp | grep 51820
```
### DNS not working
```bash
# Check dnsmasq
systemctl status dnsmasq
journalctl -u dnsmasq -e
# Test locally
dig @127.0.0.1 google.com
```
### Routing not working
```bash
# Check ipset
ipset list direct
# Check routing table
ip route show table proxy
ip rule show
# Check marks
iptables -t mangle -L -v
# Test marking
ping -c 1 8.8.8.8
conntrack -L | grep 8.8.8.8
```
### Traffic not NATed
```bash
# Check nftables
nft list ruleset
# Check forwarding
cat /proc/sys/net/ipv4/ip_forward
```
---
## Summary Checklist
- [ ] **DE VDS**
- [ ] WireGuard installed
- [ ] IP forwarding enabled
- [ ] Keys generated
- [ ] wg0.conf configured
- [ ] nftables configured
- [ ] Services enabled and started
- [ ] **RU VDS**
- [ ] WireGuard installed
- [ ] dnsmasq installed
- [ ] ipset installed
- [ ] IP forwarding enabled
- [ ] Keys generated
- [ ] Routing table 'proxy' added
- [ ] wg0.conf configured (users)
- [ ] wg1.conf configured (DE tunnel)
- [ ] postup.sh / postdown.sh created
- [ ] nftables configured
- [ ] dnsmasq configured
- [ ] Services enabled and started
- [ ] **Key Exchange**
- [ ] DE public key → RU wg1.conf
- [ ] RU de-tunnel public key → DE wg0.conf
- [ ] Tunnel verified (ping 10.20.0.2 from RU)
- [ ] **First Client**
- [ ] Keys generated
- [ ] Peer added to wg0
- [ ] Client config created
- [ ] Connection tested
- [ ] Routing verified

262
PRE_DEPLOYMENT_CHECKLIST.md Normal file
View File

@@ -0,0 +1,262 @@
# Pre-Deployment Checklist
Complete this checklist before deploying to production servers.
## Infrastructure Verification
### RU VDS (176.124.216.197)
- [ ] Can SSH into server: `ssh root@176.124.216.197`
- [ ] Have root access: `sudo -i` or logged in as root
- [ ] Server is Debian 12 (or compatible): `cat /etc/debian_version`
- [ ] Adequate resources:
- [ ] At least 1GB RAM: `free -h`
- [ ] At least 5GB free disk: `df -h`
- [ ] CPU is reasonable: `lscpu`
- [ ] Internet connectivity: `ping -c 4 8.8.8.8`
- [ ] Can resolve DNS: `nslookup google.com`
- [ ] Port 51820/udp not in use: `ss -ulnp | grep 51820` (should be empty)
- [ ] Port 53 not in use by another service: `ss -ulnp | grep :53` (or just systemd-resolved)
### DE VDS (194.31.173.178)
- [ ] Can SSH into server: `ssh root@194.31.173.178`
- [ ] Have root access: `sudo -i` or logged in as root
- [ ] Server is Debian 13 (or compatible): `cat /etc/debian_version`
- [ ] Adequate resources:
- [ ] At least 512MB RAM: `free -h`
- [ ] At least 5GB free disk: `df -h`
- [ ] CPU is reasonable: `lscpu`
- [ ] Internet connectivity: `ping -c 4 8.8.8.8`
- [ ] Can resolve DNS: `nslookup google.com`
- [ ] Port 51821/udp not in use: `ss -ulnp | grep 51821` (should be empty)
### Network Connectivity
- [ ] RU VDS can reach DE VDS: `ping -c 4 194.31.173.178` (from RU VDS)
- [ ] DE VDS can reach RU VDS: `ping -c 4 176.124.216.197` (from DE VDS)
- [ ] No firewall blocking UDP between servers (if any external firewall exists)
## Security Preparation
### SSH Access
- [ ] Have backup SSH access method (console access, VNC, etc.)
- [ ] Know how to access server if SSH breaks
- [ ] Current SSH session is stable
- [ ] Consider opening second SSH session before making changes
### Firewall Considerations
- [ ] Understand current firewall setup (if any): `iptables -L -n` or `nft list ruleset`
- [ ] Have documented how to disable firewall if something goes wrong
- [ ] Won't lock yourself out when applying new firewall rules
### Backup Current State
- [ ] Backup current network config: `cp /etc/network/interfaces /root/interfaces.backup` (if applicable)
- [ ] Backup current SSH config: `cp /etc/ssh/sshd_config /root/sshd_config.backup`
- [ ] Know how to rollback changes if needed
## Client Device Preparation
- [ ] Have at least one device to test VPN client
- [ ] WireGuard app installed on test device:
- iOS/Android: WireGuard app from App Store/Play Store
- Windows: WireGuard from wireguard.com
- macOS: WireGuard from App Store or wireguard.com
- Linux: `apt install wireguard-tools`
- [ ] Device can scan QR codes (for mobile) or can copy/paste config text
## Tools and Access
### Local Machine
- [ ] Have SSH access from local machine to both servers
- [ ] Can copy files via SCP: `scp test.txt root@176.124.216.197:/tmp/` works
- [ ] Have text editor ready for editing configs
- [ ] Have terminal with multiple tabs/windows open
### Required Information
- [ ] DE VDS IP: 194.31.173.178 (confirmed)
- [ ] RU VDS IP: 176.124.216.197 (confirmed)
- [ ] Root password or SSH keys for both servers
- [ ] Know which local device will be first test client
## Time and Planning
- [ ] Have allocated 1-2 hours for deployment
- [ ] Not during critical business hours (in case of issues)
- [ ] Have time for troubleshooting if needed
- [ ] Not in a rush
## Documentation Review
- [ ] Read QUICKSTART.md overview
- [ ] Reviewed DEPLOYMENT.md deployment steps
- [ ] Know where to find troubleshooting info (DEPLOYMENT.md)
- [ ] Have TESTING.md ready for post-deployment tests
## Script Verification
### Check scripts are ready
```bash
cd /home/mish/vpn.git
ls -la scripts/
```
Should see:
- [ ] setup-de-vds.sh (executable)
- [ ] setup-ru-vds.sh (executable)
- [ ] add-client.sh (executable)
- [ ] disable-client.sh (executable)
- [ ] enable-client.sh (executable)
- [ ] remove-client.sh (executable)
- [ ] list-clients.sh (executable)
## Configuration Files Check
```bash
cd /home/mish/vpn.git
ls -la configs/de-vds/
ls -la configs/ru-vds/
```
Should see all required config files.
## Risk Assessment
### Understand the risks
- [ ] Understand that changes will be made to network configuration
- [ ] Understand that firewall rules will be modified
- [ ] Understand that new services will be installed
- [ ] Have rollback plan if things go wrong
- [ ] Won't lose access to servers (have console/recovery access)
### Rollback Plan
If something goes wrong:
**DE VDS:**
```bash
# Stop services
systemctl stop wg-quick@wg0
systemctl stop nftables
# Flush firewall
nft flush ruleset
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
# Default accept
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
```
**RU VDS:**
```bash
# Stop services
systemctl stop wg-quick@wg0
systemctl stop wg-quick@wg1
systemctl stop dnsmasq
# Start systemd-resolved if it was stopped
systemctl start systemd-resolved
# Flush firewall (same as above)
nft flush ruleset
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
```
## Post-Deployment Preparation
- [ ] Have notepad ready to save:
- DE VDS public key
- RU VDS server public key
- RU VDS DE tunnel public key
- [ ] Ready to run tests from TESTING.md
- [ ] Have client device ready for connection test
## Final Verification
- [ ] All above items checked
- [ ] Confident to proceed
- [ ] Have time allocated
- [ ] No critical dependencies on servers right now
- [ ] Ready to start deployment
---
## Ready to Deploy?
If all items are checked, proceed to:
1. **QUICKSTART.md** - For rapid deployment
2. **DEPLOYMENT.md** - For detailed deployment guide
## Need More Info?
- Architecture details → README.md
- Implementation steps → IMPLEMENTATION.md
- Testing procedures → TESTING.md
---
## Deployment Day Checklist
### Morning of deployment
- [ ] Verify servers are accessible
- [ ] Verify servers are up-to-date: `apt update && apt list --upgradable`
- [ ] Create snapshot/backup if available from hosting provider
- [ ] Notify anyone who might be affected
### During deployment
- [ ] Follow DEPLOYMENT.md step by step
- [ ] Don't skip verification steps
- [ ] Test after each major phase
- [ ] Document any issues or deviations
### After deployment
- [ ] Complete all tests from TESTING.md
- [ ] Verify client can connect
- [ ] Verify routing is correct
- [ ] Document any configuration changes made
- [ ] Save all keys securely
---
## Emergency Contacts
Document here:
- VDS provider support: _______________________
- Backup admin contact: _______________________
- Your remote access method: _______________________
---
**Date completed:** _______________
**Completed by:** _______________
**Ready to proceed:** ☐ Yes ☐ No
**If No, blockers:**
_________________________________
_________________________________
_________________________________

279
PROJECT_SUMMARY.md Normal file
View File

@@ -0,0 +1,279 @@
# Project Summary
## Overview
This project implements a split-tunnel VPN network for bypassing internet restrictions in Russia while maintaining optimal performance for domestic traffic.
## Architecture
**3-node setup:**
- Client devices (users in Russia)
- RU VDS (176.124.216.197) - Gateway with selective routing
- DE VDS (194.31.173.178) - Exit node in Germany
**Key feature:** DNS-based domain routing
- `.ru`, `.рф`, `.su` domains → Direct routing (fast, no proxy)
- All other domains → Routed through Germany (bypass blocks)
## Technology Stack
| Component | Purpose |
|-----------|---------|
| WireGuard | VPN tunnels (lightweight, fast) |
| dnsmasq | DNS server with ipset integration |
| nftables | Firewall and NAT |
| ipset | IP address sets for routing decisions |
| iproute2 | Policy-based routing |
## What's Included
### Documentation (5 files)
1. **README.md** - Architecture overview and reference
2. **QUICKSTART.md** - 30-minute setup guide
3. **IMPLEMENTATION.md** - Detailed step-by-step implementation
4. **DEPLOYMENT.md** - Production deployment guide
5. **TESTING.md** - Comprehensive testing checklist
### Configuration Files (11 files)
**DE VDS configs:**
- `wg0.conf` - WireGuard interface config
- `nftables.conf` - Firewall rules (NAT)
- `99-vpn.conf` - Kernel parameters (IP forwarding)
**RU VDS configs:**
- `wg0.conf` - User-facing VPN interface
- `wg1.conf` - DE tunnel interface
- `postup.sh` - Routing setup script
- `postdown.sh` - Routing cleanup script
- `nftables.conf` - Firewall rules
- `vpn-routing.conf` - dnsmasq domain routing
- `rt_tables` - Custom routing table definitions
- `99-vpn.conf` - Kernel parameters
**Client template:**
- `example-client.conf` - Template for client configs
### Management Scripts (7 files)
**Setup:**
- `setup-de-vds.sh` - Automated DE VDS setup
- `setup-ru-vds.sh` - Automated RU VDS setup
**Client management:**
- `add-client.sh` - Add new VPN client (with QR code)
- `remove-client.sh` - Permanently remove client
- `disable-client.sh` - Temporarily disable client
- `enable-client.sh` - Re-enable disabled client
- `list-clients.sh` - List all clients with status
## Key Features
### Automated Setup
- One-command server deployment
- Automatic key generation
- Automatic package installation
- Automatic service configuration
### Easy Client Management
- Simple CLI commands
- Automatic IP assignment
- QR code generation for mobile
- Enable/disable without key regeneration
### Smart Routing
- Automatic domain-based routing
- No manual IP list maintenance
- DNS-driven routing decisions
- Optimal performance for local traffic
### Security
- WireGuard modern cryptography
- Restricted firewall rules
- Key-based authentication
- Isolated VPN network
### Scalability
- Support for 253 concurrent clients
- Low resource usage
- Efficient packet routing
- No bottlenecks
## Network Topology
```
Internet
┌───────────────┼───────────────┐
│ │ │
│ Direct (fast) │
│ .ru/.рф domains │
│ │
┌──────────┐ │ ┌──────────────┐ │ ┌──────────┐
│ Client │◄───┼───►│ RU VDS │◄─────────┼───►│ DE VDS │
│ Device │ │ │ Gateway │ │ │Exit Node │
└──────────┘ │ └──────────────┘ │ └──────────┘
│ │ │
│ │ │
│ ▼ │
│ Routing Decision │
│ (dnsmasq + ipset) │
│ │
│ WireGuard tunnel │
│ (all other domains) │
└───────────────────────────────┘
```
## IP Addressing
- **User VPN:** 10.10.0.0/24 (clients ↔ RU VDS)
- 10.10.0.1 - RU VDS gateway
- 10.10.0.2-254 - Client IPs
- **Server VPN:** 10.20.0.0/30 (RU ↔ DE tunnel)
- 10.20.0.1 - RU VDS
- 10.20.0.2 - DE VDS
## Deployment Workflow
1. **Prepare** (5 min)
- Verify server access
- Copy setup scripts
2. **Deploy DE VDS** (5 min)
- Run setup script
- Save public key
3. **Deploy RU VDS** (5 min)
- Run setup script
- Save public keys
4. **Exchange Keys** (3 min)
- Update DE config with RU key
- Update RU config with DE key
5. **Start Services** (2 min)
- Start DE services
- Start RU services
6. **Verify** (5 min)
- Test tunnel connectivity
- Check routing tables
7. **Add Clients** (5 min each)
- Run add-client script
- Transfer config to device
**Total time: ~30-40 minutes**
## Testing Coverage
Comprehensive testing checklist covers:
- Pre-deployment verification
- Post-setup validation
- Tunnel connectivity
- DNS resolution
- Routing logic
- Client management
- Performance benchmarks
- Security verification
- Failure recovery
## Maintenance
### Regular Tasks
- Monitor logs for errors
- Check client list for inactive users
- Review bandwidth usage
- Update system packages
### Backup Strategy
- Backup `/etc/wireguard/` directory
- Store keys securely offline
- Document client assignments
### Monitoring
- WireGuard handshake status
- DNS query logs (optional)
- System resource usage
- Network traffic patterns
## Troubleshooting Quick Reference
| Issue | Check | Fix |
|-------|-------|-----|
| Tunnel down | `wg show` | Restart wg-quick services |
| DNS not working | `systemctl status dnsmasq` | Restart dnsmasq |
| Routing wrong | `ipset list direct` | Check dnsmasq config |
| Client can't connect | `wg show wg0 peers` | Verify peer added |
| Slow performance | `ping` tests | Check MTU settings |
## Security Considerations
- Keys stored with 600 permissions
- Firewall restricts access by IP
- DNS only accessible from VPN clients
- Separate interfaces for users/tunnel
- No logging of DNS queries (configurable)
## Future Enhancements (Optional)
Potential additions:
- Web UI for client management
- Prometheus metrics export
- Automated key rotation
- Fail-over to secondary DE server
- IPv6 support
- Traffic statistics dashboard
## Repository Structure
```
vpn.git/
├── README.md # Architecture and reference
├── QUICKSTART.md # Fast setup guide
├── IMPLEMENTATION.md # Detailed implementation
├── DEPLOYMENT.md # Production deployment
├── TESTING.md # Testing checklist
├── PROJECT_SUMMARY.md # This file
├── .gitignore # Git ignore rules
├── configs/ # All configuration files
│ ├── de-vds/ # DE VDS configs
│ ├── ru-vds/ # RU VDS configs
│ └── client-templates/ # Client config templates
└── scripts/ # Management scripts
├── setup-*.sh # Server setup
└── *-client.sh # Client management
```
## Success Metrics
After deployment, you should have:
- ✓ Stable VPN tunnel between RU and DE
- ✓ Working client connections
- ✓ Correct routing for .ru vs other domains
- ✓ Simple client management via CLI
- ✓ No errors in service logs
- ✓ Acceptable performance (latency, bandwidth)
## Support and Documentation
All information needed is in this repository:
- Architecture → README.md
- Quick setup → QUICKSTART.md
- Detailed steps → IMPLEMENTATION.md
- Deployment → DEPLOYMENT.md
- Testing → TESTING.md
## License
This is a personal project. Use at your own discretion.
## Credits
Built with:
- WireGuard - Jason A. Donenfeld
- dnsmasq - Simon Kelley
- nftables - Netfilter Project

207
QUICKSTART.md Normal file
View File

@@ -0,0 +1,207 @@
# Quick Start Guide
Get your VPN network up and running in 30 minutes.
## What You'll Get
A VPN network where:
- `.ru` and `.рф` domains go directly to the internet (fast, no proxy)
- All other domains route through Germany (bypass blocks)
- Easy client management via command-line scripts
- Support for multiple users (up to 253 devices)
## Prerequisites
- 2 VDS servers (already have: RU + DE)
- SSH access with root privileges
- 30 minutes of time
## Deployment Steps
### Step 1: Setup DE VDS (5 min)
```bash
# From your computer
scp scripts/setup-de-vds.sh root@194.31.173.178:/root/
# SSH into DE VDS
ssh root@194.31.173.178
# Run setup
chmod +x /root/setup-de-vds.sh
/root/setup-de-vds.sh
# Copy the public key that appears (save it for step 3)
```
### Step 2: Setup RU VDS (5 min)
```bash
# From your computer
scp scripts/setup-ru-vds.sh root@176.124.216.197:/root/
# SSH into RU VDS
ssh root@176.124.216.197
# Run setup
chmod +x /root/setup-ru-vds.sh
/root/setup-ru-vds.sh
# Copy both public keys that appear (save for step 3)
```
### Step 3: Exchange Keys (3 min)
**On DE VDS:**
```bash
nano /etc/wireguard/wg0.conf
# Replace __RU_DE_TUNNEL_PUBLIC_KEY__ with RU's "DE tunnel key"
# Save and exit (Ctrl+X, Y, Enter)
```
**On RU VDS:**
```bash
nano /etc/wireguard/wg1.conf
# Replace __DE_SERVER_PUBLIC_KEY__ with DE's public key
# Save and exit (Ctrl+X, Y, Enter)
```
### Step 4: Start Services (2 min)
**On DE VDS:**
```bash
systemctl start nftables
systemctl start wg-quick@wg0
```
**On RU VDS:**
```bash
systemctl start dnsmasq
systemctl start wg-quick@wg1
systemctl start wg-quick@wg0
```
### Step 5: Verify Tunnel (2 min)
**On RU VDS:**
```bash
ping -c 4 10.20.0.2
wg show wg1
# Should see successful ping and recent handshake
```
### Step 6: Add First Client (5 min)
**Copy client scripts to RU VDS:**
```bash
# From your computer
scp scripts/*.sh root@176.124.216.197:/root/
```
**On RU VDS:**
```bash
chmod +x /root/*.sh
/root/add-client.sh phone
# Scan the QR code with WireGuard app or copy the config
```
### Step 7: Test (5 min)
**On your client device:**
1. Install WireGuard app
2. Scan QR code or import config
3. Connect to VPN
**Test it works:**
```bash
# Should show DE VDS IP (194.31.173.178)
curl ifconfig.me
# Should resolve through VPN DNS
nslookup google.com
```
**Test routing:**
- Visit google.com → routed through Germany
- Visit yandex.ru → routed directly (faster)
## Done!
Your VPN is now operational.
## Common Commands
```bash
# List all clients
/root/list-clients.sh
# Add new client
/root/add-client.sh laptop
# Disable client temporarily
/root/disable-client.sh phone
# Re-enable client
/root/enable-client.sh phone
# Remove client permanently
/root/remove-client.sh phone
# Check VPN status
wg show
# View logs
journalctl -u wg-quick@wg0 -f
```
## Need Help?
- Full implementation details: [IMPLEMENTATION.md](IMPLEMENTATION.md)
- Deployment guide: [DEPLOYMENT.md](DEPLOYMENT.md)
- Architecture overview: [README.md](README.md)
## Troubleshooting
**Tunnel not connecting?**
```bash
# Check WireGuard status
wg show
systemctl status wg-quick@wg0
# Check if ports are open
ss -ulnp | grep 51820 # RU VDS
ss -ulnp | grep 51821 # DE VDS
```
**DNS not working?**
```bash
# Check dnsmasq
systemctl status dnsmasq
journalctl -u dnsmasq -n 50
```
**Routing not working?**
```bash
# Check ipset after visiting .ru sites
ipset list direct
# Check routing table
ip route show table proxy
ip rule show
```
## Security Notes
- Keep WireGuard keys secure (never share them)
- Change SSH port from default 22
- Use SSH keys instead of passwords
- Remove unused clients promptly
- Monitor logs regularly
## Next Steps
- Add more clients as needed
- Set up automatic security updates
- Configure backups for `/etc/wireguard/`
- Monitor server resources
- Consider setting up monitoring/alerting

234
README.md
View File

@@ -1,2 +1,234 @@
# vpn
# 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](IMPLEMENTATION.md)
2. **Deploy to servers:** Follow [DEPLOYMENT.md](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
```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
# Routing tables
ip route show table direct
ip route show table proxy
```
### 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/)

305
TESTING.md Normal file
View File

@@ -0,0 +1,305 @@
# Testing Checklist
Use this checklist to verify your VPN network is working correctly.
## Pre-Deployment Tests
### DE VDS
- [ ] SSH access working
- [ ] System updated (`apt update && apt upgrade`)
- [ ] Adequate disk space (`df -h`)
- [ ] No port conflicts on 51821 (`ss -ulnp | grep 51821`)
### RU VDS
- [ ] SSH access working
- [ ] System updated (`apt update && apt upgrade`)
- [ ] Adequate disk space (`df -h`)
- [ ] No port conflicts on 51820 (`ss -ulnp | grep 51820`)
- [ ] No DNS conflicts on port 53 (`ss -ulnp | grep :53`)
## Post-Setup Tests
### DE VDS
- [ ] WireGuard installed (`wg version`)
- [ ] IP forwarding enabled (`cat /proc/sys/net/ipv4/ip_forward` = 1)
- [ ] WireGuard keys generated (`ls /etc/wireguard/keys/`)
- [ ] nftables config exists (`ls /etc/nftables.conf`)
- [ ] Services enabled (not yet started)
### RU VDS
- [ ] WireGuard installed (`wg version`)
- [ ] dnsmasq installed (`dnsmasq -v`)
- [ ] ipset installed (`ipset -v`)
- [ ] IP forwarding enabled (`cat /proc/sys/net/ipv4/ip_forward` = 1)
- [ ] WireGuard keys generated (`ls /etc/wireguard/keys/`)
- [ ] Routing table added (`grep proxy /etc/iproute2/rt_tables`)
- [ ] All configs in place
- [ ] Services enabled (not yet started)
## Post-Configuration Tests (After Key Exchange)
### DE VDS
- [ ] wg0.conf contains RU public key (no `__RU_DE_TUNNEL_PUBLIC_KEY__` placeholder)
- [ ] nftables service started (`systemctl status nftables`)
- [ ] wg-quick@wg0 started (`systemctl status wg-quick@wg0`)
- [ ] wg0 interface exists (`ip addr show wg0`)
- [ ] wg0 has correct IP (`ip addr show wg0 | grep 10.20.0.2`)
### RU VDS
- [ ] wg1.conf contains DE public key (no `__DE_SERVER_PUBLIC_KEY__` placeholder)
- [ ] dnsmasq started (`systemctl status dnsmasq`)
- [ ] wg-quick@wg1 started (`systemctl status wg-quick@wg1`)
- [ ] wg-quick@wg0 started (`systemctl status wg-quick@wg0`)
- [ ] wg1 interface exists (`ip addr show wg1`)
- [ ] wg0 interface exists (`ip addr show wg0`)
- [ ] wg1 has correct IP (`ip addr show wg1 | grep 10.20.0.1`)
- [ ] wg0 has correct IP (`ip addr show wg0 | grep 10.10.0.1`)
## Tunnel Tests
### From RU VDS
- [ ] Can ping DE VDS: `ping -c 4 10.20.0.2`
- [ ] WireGuard handshake established: `wg show wg1 | grep "latest handshake"`
- [ ] Transfer counters incrementing: `wg show wg1 | grep transfer`
### From DE VDS
- [ ] WireGuard handshake established: `wg show wg0 | grep "latest handshake"`
- [ ] Shows RU VDS as peer: `wg show wg0 peers`
- [ ] Transfer counters incrementing: `wg show wg0 | grep transfer`
## Routing Tests (Before Client Connection)
### RU VDS
- [ ] Proxy routing table exists: `ip route show table proxy`
- [ ] Default route via DE: `ip route show table proxy | grep "default via 10.20.0.2"`
- [ ] Policy routing rule exists: `ip rule show | grep proxy`
- [ ] ipset 'direct' exists: `ipset list direct`
- [ ] iptables mangle rule exists: `iptables -t mangle -L PREROUTING | grep direct`
## Client Connection Tests
### First Client Addition
- [ ] Client added successfully: `/root/add-client.sh testclient`
- [ ] Client keys generated: `ls /etc/wireguard/keys/client_testclient.*`
- [ ] Client config created: `ls /etc/wireguard/clients/testclient.conf`
- [ ] QR code generated successfully
- [ ] Peer added to wg0: `wg show wg0 peers | grep -f /etc/wireguard/keys/client_testclient.pub`
### Client Connection (From Client Device)
- [ ] WireGuard app installed
- [ ] Config imported successfully
- [ ] Connection established
- [ ] No connection errors in app
### Basic Connectivity (From Client)
- [ ] Can ping VPN gateway: `ping 10.10.0.1`
- [ ] Can ping DE VDS: `ping 10.20.0.2`
- [ ] DNS resolution works: `nslookup google.com`
- [ ] DNS uses correct server: `nslookup google.com 10.10.0.1`
### Routing Verification (From Client)
- [ ] External IP shows DE VDS: `curl ifconfig.me` (should be 194.31.173.178)
- [ ] Can access international sites: `curl -I https://google.com`
- [ ] Can access Russian sites: `curl -I https://yandex.ru`
### DNS-Based Routing (From Client)
Visit some Russian sites first, then check on RU VDS:
- [ ] Visit `https://yandex.ru` from client
- [ ] Visit `https://mail.ru` from client
- [ ] Check ipset on RU VDS: `ipset list direct`
- [ ] ipset contains Russian IPs
- [ ] Visit `https://google.com` from client
- [ ] Check that google IPs NOT in direct ipset
### Advanced Routing Tests
From client, check routing paths:
- [ ] Traceroute to Russian site shows no DE hop
```bash
traceroute yandex.ru
# Should NOT show 10.20.0.x
```
- [ ] Traceroute to international site shows DE hop
```bash
traceroute google.com
# Should show 10.20.0.x in path
```
## Performance Tests
### Latency (From Client)
- [ ] Latency to VPN gateway: `ping -c 10 10.10.0.1`
- Expected: < 50ms (depends on your location)
- [ ] Latency through tunnel: `ping -c 10 8.8.8.8`
- Expected: 50-150ms (via DE)
### Bandwidth (From Client)
- [ ] Download speed test: `curl -o /dev/null https://speed.cloudflare.com/__down?bytes=100000000`
- [ ] Should get reasonable speeds (depends on VDS specs)
## Client Management Tests
### List Clients
- [ ] List shows active client: `/root/list-clients.sh`
- [ ] Shows correct IP assignment
- [ ] Shows latest handshake
### Disable Client
- [ ] Disable client: `/root/disable-client.sh testclient`
- [ ] Client no longer in wg show: `wg show wg0 peers`
- [ ] Client cannot connect
- [ ] Keys still exist: `ls /etc/wireguard/keys/client_testclient.*`
### Enable Client
- [ ] Enable client: `/root/enable-client.sh testclient`
- [ ] Client appears in wg show: `wg show wg0 peers`
- [ ] Client can connect again
### Add Multiple Clients
- [ ] Add 2nd client: `/root/add-client.sh client2`
- [ ] Gets different IP (10.10.0.3)
- [ ] Both clients can connect simultaneously
- [ ] Both clients in list: `/root/list-clients.sh`
### Remove Client
- [ ] Remove client: `/root/remove-client.sh testclient`
- [ ] Client not in wg show
- [ ] Keys deleted: `ls /etc/wireguard/keys/client_testclient.* 2>&1 | grep "No such file"`
- [ ] Config deleted: `ls /etc/wireguard/clients/testclient.conf 2>&1 | grep "No such file"`
## Stress Tests
### Multiple Concurrent Clients
- [ ] Add 5 clients
- [ ] All connect simultaneously
- [ ] All can browse internet
- [ ] Check server load: `top` (CPU should be low)
- [ ] Check memory: `free -h` (should have free memory)
### Continuous Traffic
- [ ] Stream video through VPN for 10 minutes
- [ ] No disconnections
- [ ] Stable speed
- [ ] Check for errors: `journalctl -u wg-quick@wg0 -n 50`
## Security Tests
### Firewall Rules (DE VDS)
- [ ] Port 51821 only accepts from RU IP:
```bash
# From another host (should fail)
nc -u 194.31.173.178 51821
```
- [ ] SSH still accessible (if configured)
- [ ] Other ports closed
### Firewall Rules (RU VDS)
- [ ] Port 51820 accepts WireGuard connections
- [ ] DNS only from VPN clients:
```bash
# From outside (should fail)
dig @176.124.216.197 google.com
```
- [ ] SSH still accessible
- [ ] Other ports closed
### DNS Leak Test (From Client)
- [ ] Check DNS server used: visit https://dnsleaktest.com/
- [ ] Should show RU VDS or your VPN as DNS server
- [ ] Should NOT show your ISP's DNS
## Failure Recovery Tests
### Restart Services
- [ ] Restart wg-quick@wg0 on RU VDS
- [ ] Clients reconnect automatically
- [ ] No connection loss > 30 seconds
### Reboot Tests
- [ ] Reboot DE VDS: `reboot`
- [ ] Services auto-start after boot
- [ ] Tunnel re-establishes
- [ ] Reboot RU VDS: `reboot`
- [ ] Services auto-start after boot
- [ ] Clients can reconnect
## Logs Check
### No Errors in Logs
- [ ] DE VDS WireGuard: `journalctl -u wg-quick@wg0 -n 50 --no-pager`
- [ ] RU VDS WireGuard wg0: `journalctl -u wg-quick@wg0 -n 50 --no-pager`
- [ ] RU VDS WireGuard wg1: `journalctl -u wg-quick@wg1 -n 50 --no-pager`
- [ ] RU VDS dnsmasq: `journalctl -u dnsmasq -n 50 --no-pager`
## Final Verification
- [ ] All clients can connect
- [ ] Russian domains route directly (fast)
- [ ] International domains route through DE (working)
- [ ] DNS resolution working
- [ ] No errors in logs
- [ ] Services set to auto-start
- [ ] Documentation updated with actual client names
- [ ] Backup of /etc/wireguard/ created
## Troubleshooting References
If any tests fail, refer to:
- [DEPLOYMENT.md](DEPLOYMENT.md) - Troubleshooting section
- [IMPLEMENTATION.md](IMPLEMENTATION.md) - Detailed implementation steps
## Test Results Template
```
Date: ____________________
Tester: __________________
Pre-Deployment: ☐ Pass ☐ Fail
Post-Setup: ☐ Pass ☐ Fail
Tunnel Tests: ☐ Pass ☐ Fail
Routing Tests: ☐ Pass ☐ Fail
Client Tests: ☐ Pass ☐ Fail
Performance: ☐ Pass ☐ Fail
Security: ☐ Pass ☐ Fail
Recovery: ☐ Pass ☐ Fail
Notes:
_____________________________________
_____________________________________
_____________________________________
```

View File

@@ -0,0 +1,10 @@
[Interface]
PrivateKey = <CLIENT_PRIVATE_KEY>
Address = 10.10.0.X/32
DNS = 10.10.0.1
[Peer]
PublicKey = <RU_SERVER_PUBLIC_KEY>
Endpoint = 176.124.216.197:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

View File

@@ -0,0 +1,2 @@
# Enable IP forwarding for VPN
net.ipv4.ip_forward = 1

View File

@@ -0,0 +1,47 @@
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Allow established connections
ct state established,related accept
# Allow loopback
iif lo accept
# Allow SSH (adjust port if needed)
tcp dport 22 accept
# Allow WireGuard from RU VDS only
ip saddr 176.124.216.197 udp dport 51821 accept
# Allow ICMP
icmp type echo-request accept
}
chain forward {
type filter hook forward priority 0; policy drop;
# Allow forwarding from VPN
iifname "wg0" accept
# Allow established connections back
ct state established,related accept
}
chain output {
type filter hook output priority 0; policy accept;
}
}
table inet nat {
chain postrouting {
type nat hook postrouting priority 100;
# NAT traffic from VPN to internet
oifname != "wg0" ip saddr { 10.10.0.0/24, 10.20.0.0/30 } masquerade
}
}

11
configs/de-vds/wg0.conf Normal file
View File

@@ -0,0 +1,11 @@
[Interface]
Address = 10.20.0.2/30
ListenPort = 51821
PrivateKey = __DE_SERVER_PRIVATE_KEY__
PostUp = nft -f /etc/nftables.conf
PostDown = nft flush ruleset
[Peer]
# RU VDS (server tunnel)
PublicKey = __RU_DE_TUNNEL_PUBLIC_KEY__
AllowedIPs = 10.20.0.1/32, 10.10.0.0/24

View File

@@ -0,0 +1,2 @@
# Enable IP forwarding for VPN
net.ipv4.ip_forward = 1

View File

@@ -0,0 +1,55 @@
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Allow established connections
ct state established,related accept
# Allow loopback
iif lo accept
# Allow SSH (adjust port if needed)
tcp dport 22 accept
# Allow WireGuard from anywhere (user connections)
udp dport 51820 accept
# Allow DNS from VPN clients only
iifname "wg0" udp dport 53 accept
iifname "wg0" tcp dport 53 accept
# Allow ICMP
icmp type echo-request accept
}
chain forward {
type filter hook forward priority 0; policy drop;
# Allow forwarding from user VPN
iifname "wg0" accept
# Allow forwarding from DE tunnel
iifname "wg1" accept
# Allow established connections
ct state established,related accept
}
chain output {
type filter hook output priority 0; policy accept;
}
}
table inet nat {
chain postrouting {
type nat hook postrouting priority 100;
# NAT direct traffic going out main interface
# Traffic going through wg1 doesn't need NAT (DE VDS will NAT it)
oifname != "wg0" oifname != "wg1" ip saddr 10.10.0.0/24 masquerade
}
}

View File

@@ -0,0 +1,18 @@
#!/bin/bash
# Remove policy routing rule
ip rule del from 10.10.0.0/24 fwmark 0x1 table proxy priority 100 2>/dev/null || true
# Flush routing table
ip route flush table proxy 2>/dev/null || true
# Remove iptables mangle rule
iptables -t mangle -F PREROUTING 2>/dev/null || true
# Destroy ipsets
ipset destroy direct 2>/dev/null || true
# Flush nftables (if not managed by other services)
# nft flush ruleset
echo "PostDown script completed"

21
configs/ru-vds/postup.sh Normal file
View File

@@ -0,0 +1,21 @@
#!/bin/bash
set -e
# Create ipsets for routing decisions
ipset create direct hash:net -exist
ipset flush direct
# Add default route via DE tunnel for 'proxy' table
ip route add default via 10.20.0.2 dev wg1 table proxy 2>/dev/null || true
# Policy routing: packets with fwmark 0x1 use 'proxy' table
ip rule add from 10.10.0.0/24 fwmark 0x1 table proxy priority 100 2>/dev/null || true
# Load nftables rules
nft -f /etc/nftables.conf
# Mark packets NOT going to 'direct' ipset with fwmark 0x1
# This is needed because nftables + ipset integration is complex
iptables -t mangle -I PREROUTING -m set ! --match-set direct dst -s 10.10.0.0/24 -j MARK --set-mark 0x1
echo "PostUp script completed successfully"

10
configs/ru-vds/rt_tables Normal file
View File

@@ -0,0 +1,10 @@
# Reserved values
#
255 local
254 main
253 default
0 unspec
#
# Local routing tables
#
200 proxy

View File

@@ -0,0 +1,30 @@
# Listen only on VPN interface
interface=wg0
bind-interfaces
# Upstream DNS servers
server=8.8.8.8
server=8.8.4.4
server=1.1.1.1
# Don't read /etc/resolv.conf
no-resolv
# Cache settings
cache-size=10000
# Log queries (optional, comment out in production for performance)
# log-queries
# Russian TLDs - add resolved IPs to 'direct' ipset
# These domains will be routed directly, not through DE VDS
ipset=/ru/direct
ipset=/рф/direct
ipset=/su/direct
# Additional Russian domains (optional, can be extended)
# ipset=/yandex.ru/direct
# ipset=/mail.ru/direct
# ipset=/vk.com/direct
# All other domains will go through proxy (default routing)

9
configs/ru-vds/wg0.conf Normal file
View File

@@ -0,0 +1,9 @@
[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = __RU_SERVER_PRIVATE_KEY__
PostUp = /etc/wireguard/postup.sh
PostDown = /etc/wireguard/postdown.sh
# Client peers will be added below
# Use scripts/add-client.sh to add new clients

10
configs/ru-vds/wg1.conf Normal file
View File

@@ -0,0 +1,10 @@
[Interface]
Address = 10.20.0.1/30
PrivateKey = __RU_DE_TUNNEL_PRIVATE_KEY__
[Peer]
# DE VDS (exit node)
PublicKey = __DE_SERVER_PUBLIC_KEY__
Endpoint = 194.31.173.178:51821
AllowedIPs = 10.10.0.0/24
PersistentKeepalive = 25

97
scripts/add-client.sh Executable file
View File

@@ -0,0 +1,97 @@
#!/bin/bash
set -e
# Script to add a new VPN client
# Usage: ./add-client.sh <client_name>
if [ "$EUID" -ne 0 ]; then
echo "ERROR: Please run as root"
exit 1
fi
if [ -z "$1" ]; then
echo "Usage: $0 <client_name>"
echo "Example: $0 phone"
exit 1
fi
CLIENT_NAME="$1"
KEYS_DIR="/etc/wireguard/keys"
CLIENTS_DIR="/etc/wireguard/clients"
WG_INTERFACE="wg0"
# Check if client already exists
if [ -f "${KEYS_DIR}/client_${CLIENT_NAME}.key" ]; then
echo "ERROR: Client '${CLIENT_NAME}' already exists"
exit 1
fi
echo "Adding new VPN client: ${CLIENT_NAME}"
echo ""
# Find next available IP
USED_IPS=$(wg show ${WG_INTERFACE} allowed-ips 2>/dev/null | grep -oP '10\.10\.0\.\K[0-9]+' | sort -n)
NEXT_IP=2
for ip in $USED_IPS; do
if [ $ip -ge $NEXT_IP ]; then
NEXT_IP=$((ip + 1))
fi
done
if [ $NEXT_IP -gt 254 ]; then
echo "ERROR: No available IPs in 10.10.0.0/24 range"
exit 1
fi
CLIENT_IP="10.10.0.${NEXT_IP}"
echo "[1/5] Generating client keys..."
wg genkey | tee "${KEYS_DIR}/client_${CLIENT_NAME}.key" | wg pubkey > "${KEYS_DIR}/client_${CLIENT_NAME}.pub"
chmod 600 "${KEYS_DIR}/client_${CLIENT_NAME}."*
CLIENT_PRIVATE_KEY=$(cat "${KEYS_DIR}/client_${CLIENT_NAME}.key")
CLIENT_PUBLIC_KEY=$(cat "${KEYS_DIR}/client_${CLIENT_NAME}.pub")
SERVER_PUBLIC_KEY=$(cat "${KEYS_DIR}/server.pub")
echo "[2/5] Adding peer to WireGuard interface..."
wg set ${WG_INTERFACE} peer ${CLIENT_PUBLIC_KEY} allowed-ips ${CLIENT_IP}/32
echo "[3/5] Saving WireGuard configuration..."
wg-quick save ${WG_INTERFACE}
echo "[4/5] Creating client configuration file..."
mkdir -p ${CLIENTS_DIR}
cat > "${CLIENTS_DIR}/${CLIENT_NAME}.conf" << EOF
[Interface]
PrivateKey = ${CLIENT_PRIVATE_KEY}
Address = ${CLIENT_IP}/32
DNS = 10.10.0.1
[Peer]
PublicKey = ${SERVER_PUBLIC_KEY}
Endpoint = 176.124.216.197:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF
chmod 600 "${CLIENTS_DIR}/${CLIENT_NAME}.conf"
echo "[5/5] Generating QR code..."
echo ""
echo "========================================="
echo "Client added successfully!"
echo "========================================="
echo ""
echo "Client name: ${CLIENT_NAME}"
echo "Client IP: ${CLIENT_IP}"
echo ""
echo "Configuration file: ${CLIENTS_DIR}/${CLIENT_NAME}.conf"
echo ""
echo "QR Code (scan with WireGuard mobile app):"
echo ""
qrencode -t ansiutf8 < "${CLIENTS_DIR}/${CLIENT_NAME}.conf"
echo ""
echo "Or copy the configuration from:"
echo " cat ${CLIENTS_DIR}/${CLIENT_NAME}.conf"
echo ""

53
scripts/disable-client.sh Executable file
View File

@@ -0,0 +1,53 @@
#!/bin/bash
set -e
# Script to disable a VPN client (keeps keys but removes from WireGuard)
# Usage: ./disable-client.sh <client_name>
if [ "$EUID" -ne 0 ]; then
echo "ERROR: Please run as root"
exit 1
fi
if [ -z "$1" ]; then
echo "Usage: $0 <client_name>"
echo "Example: $0 phone"
exit 1
fi
CLIENT_NAME="$1"
KEYS_DIR="/etc/wireguard/keys"
WG_INTERFACE="wg0"
# Check if client exists
if [ ! -f "${KEYS_DIR}/client_${CLIENT_NAME}.pub" ]; then
echo "ERROR: Client '${CLIENT_NAME}' does not exist"
exit 1
fi
CLIENT_PUBLIC_KEY=$(cat "${KEYS_DIR}/client_${CLIENT_NAME}.pub")
# Check if client is currently active
if ! wg show ${WG_INTERFACE} | grep -q "${CLIENT_PUBLIC_KEY}"; then
echo "Client '${CLIENT_NAME}' is already disabled"
exit 0
fi
echo "Disabling VPN client: ${CLIENT_NAME}"
echo ""
echo "[1/2] Removing peer from WireGuard interface..."
wg set ${WG_INTERFACE} peer ${CLIENT_PUBLIC_KEY} remove
echo "[2/2] Saving WireGuard configuration..."
wg-quick save ${WG_INTERFACE}
echo ""
echo "========================================="
echo "Client disabled successfully!"
echo "========================================="
echo ""
echo "Client '${CLIENT_NAME}' is now disabled"
echo "Keys and configuration are preserved"
echo "To re-enable, use: ./enable-client.sh ${CLIENT_NAME}"
echo ""

66
scripts/enable-client.sh Executable file
View File

@@ -0,0 +1,66 @@
#!/bin/bash
set -e
# Script to enable a previously disabled VPN client
# Usage: ./enable-client.sh <client_name>
if [ "$EUID" -ne 0 ]; then
echo "ERROR: Please run as root"
exit 1
fi
if [ -z "$1" ]; then
echo "Usage: $0 <client_name>"
echo "Example: $0 phone"
exit 1
fi
CLIENT_NAME="$1"
KEYS_DIR="/etc/wireguard/keys"
CLIENTS_DIR="/etc/wireguard/clients"
WG_INTERFACE="wg0"
# Check if client exists
if [ ! -f "${KEYS_DIR}/client_${CLIENT_NAME}.pub" ]; then
echo "ERROR: Client '${CLIENT_NAME}' does not exist"
exit 1
fi
if [ ! -f "${CLIENTS_DIR}/${CLIENT_NAME}.conf" ]; then
echo "ERROR: Client configuration file not found"
exit 1
fi
CLIENT_PUBLIC_KEY=$(cat "${KEYS_DIR}/client_${CLIENT_NAME}.pub")
# Check if client is already active
if wg show ${WG_INTERFACE} | grep -q "${CLIENT_PUBLIC_KEY}"; then
echo "Client '${CLIENT_NAME}' is already enabled"
exit 0
fi
# Extract IP from client config
CLIENT_IP=$(grep "^Address" "${CLIENTS_DIR}/${CLIENT_NAME}.conf" | awk '{print $3}')
if [ -z "${CLIENT_IP}" ]; then
echo "ERROR: Could not determine client IP from config"
exit 1
fi
echo "Enabling VPN client: ${CLIENT_NAME}"
echo ""
echo "[1/2] Adding peer to WireGuard interface..."
wg set ${WG_INTERFACE} peer ${CLIENT_PUBLIC_KEY} allowed-ips ${CLIENT_IP}
echo "[2/2] Saving WireGuard configuration..."
wg-quick save ${WG_INTERFACE}
echo ""
echo "========================================="
echo "Client enabled successfully!"
echo "========================================="
echo ""
echo "Client '${CLIENT_NAME}' is now active"
echo "IP Address: ${CLIENT_IP}"
echo ""

68
scripts/list-clients.sh Executable file
View File

@@ -0,0 +1,68 @@
#!/bin/bash
# Script to list all VPN clients and their status
# Usage: ./list-clients.sh
if [ "$EUID" -ne 0 ]; then
echo "ERROR: Please run as root"
exit 1
fi
WG_INTERFACE="wg0"
KEYS_DIR="/etc/wireguard/keys"
echo "========================================="
echo "VPN Clients Status"
echo "========================================="
echo ""
# Check if interface is up
if ! ip link show ${WG_INTERFACE} &>/dev/null; then
echo "ERROR: ${WG_INTERFACE} interface is not up"
exit 1
fi
# Get list of client keys
CLIENT_KEYS=$(ls ${KEYS_DIR}/client_*.pub 2>/dev/null | sed 's|.*/client_||; s|\.pub$||')
if [ -z "${CLIENT_KEYS}" ]; then
echo "No clients configured"
exit 0
fi
# Table header
printf "%-15s %-15s %-45s %-20s %s\n" "Client" "IP Address" "Public Key" "Latest Handshake" "Transfer"
echo "---------------------------------------------------------------------------------------------------------------------------"
for client in ${CLIENT_KEYS}; do
CLIENT_PUBKEY=$(cat "${KEYS_DIR}/client_${client}.pub")
# Get client info from wg show
CLIENT_INFO=$(wg show ${WG_INTERFACE} | grep -A 5 "${CLIENT_PUBKEY}" || echo "")
if [ -z "${CLIENT_INFO}" ]; then
# Client key exists but not in wg config (disabled)
printf "%-15s %-15s %-45s %-20s %s\n" "${client}" "N/A" "${CLIENT_PUBKEY:0:40}..." "DISABLED" "N/A"
else
# Extract details
ALLOWED_IP=$(echo "${CLIENT_INFO}" | grep "allowed ips:" | awk '{print $3}' | cut -d'/' -f1)
HANDSHAKE=$(echo "${CLIENT_INFO}" | grep "latest handshake:" | cut -d':' -f2- | xargs)
TRANSFER=$(echo "${CLIENT_INFO}" | grep "transfer:" | cut -d':' -f2- | xargs)
# Format handshake
if [ -z "${HANDSHAKE}" ]; then
HANDSHAKE="Never"
fi
# Format transfer
if [ -z "${TRANSFER}" ]; then
TRANSFER="N/A"
fi
printf "%-15s %-15s %-45s %-20s %s\n" "${client}" "${ALLOWED_IP}" "${CLIENT_PUBKEY:0:40}..." "${HANDSHAKE}" "${TRANSFER}"
fi
done
echo ""
echo "Total clients: $(echo "${CLIENT_KEYS}" | wc -w)"
echo ""

51
scripts/remove-client.sh Executable file
View File

@@ -0,0 +1,51 @@
#!/bin/bash
set -e
# Script to remove a VPN client
# Usage: ./remove-client.sh <client_name>
if [ "$EUID" -ne 0 ]; then
echo "ERROR: Please run as root"
exit 1
fi
if [ -z "$1" ]; then
echo "Usage: $0 <client_name>"
echo "Example: $0 phone"
exit 1
fi
CLIENT_NAME="$1"
KEYS_DIR="/etc/wireguard/keys"
CLIENTS_DIR="/etc/wireguard/clients"
WG_INTERFACE="wg0"
# Check if client exists
if [ ! -f "${KEYS_DIR}/client_${CLIENT_NAME}.pub" ]; then
echo "ERROR: Client '${CLIENT_NAME}' does not exist"
exit 1
fi
CLIENT_PUBLIC_KEY=$(cat "${KEYS_DIR}/client_${CLIENT_NAME}.pub")
echo "Removing VPN client: ${CLIENT_NAME}"
echo ""
echo "[1/4] Removing peer from WireGuard interface..."
wg set ${WG_INTERFACE} peer ${CLIENT_PUBLIC_KEY} remove
echo "[2/4] Saving WireGuard configuration..."
wg-quick save ${WG_INTERFACE}
echo "[3/4] Removing client keys..."
rm -f "${KEYS_DIR}/client_${CLIENT_NAME}.key"
rm -f "${KEYS_DIR}/client_${CLIENT_NAME}.pub"
echo "[4/4] Removing client configuration..."
rm -f "${CLIENTS_DIR}/${CLIENT_NAME}.conf"
echo ""
echo "========================================="
echo "Client removed successfully!"
echo "========================================="
echo ""

137
scripts/setup-de-vds.sh Executable file
View File

@@ -0,0 +1,137 @@
#!/bin/bash
set -e
# Setup script for DE VDS (Exit Node)
# Run this script as root on the DE VDS server
echo "========================================="
echo "DE VDS (Exit Node) Setup"
echo "========================================="
echo ""
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "ERROR: Please run as root"
exit 1
fi
echo "[1/7] Updating system packages..."
apt update
apt upgrade -y
echo "[2/7] Installing required packages..."
apt install -y wireguard nftables iptables
echo "[3/7] Enabling IP forwarding..."
cat > /etc/sysctl.d/99-vpn.conf << 'EOF'
# Enable IP forwarding for VPN
net.ipv4.ip_forward = 1
EOF
sysctl -p /etc/sysctl.d/99-vpn.conf
echo "[4/7] Generating WireGuard keys..."
mkdir -p /etc/wireguard/keys
chmod 700 /etc/wireguard/keys
wg genkey | tee /etc/wireguard/keys/server.key | wg pubkey > /etc/wireguard/keys/server.pub
chmod 600 /etc/wireguard/keys/*
echo "[5/7] Creating WireGuard configuration..."
cat > /etc/wireguard/wg0.conf << 'EOF'
[Interface]
Address = 10.20.0.2/30
ListenPort = 51821
PrivateKey = __DE_SERVER_PRIVATE_KEY__
PostUp = nft -f /etc/nftables.conf
PostDown = nft flush ruleset
[Peer]
# RU VDS (server tunnel)
PublicKey = __RU_DE_TUNNEL_PUBLIC_KEY__
AllowedIPs = 10.20.0.1/32, 10.10.0.0/24
EOF
# Replace private key placeholder
PRIVATE_KEY=$(cat /etc/wireguard/keys/server.key)
sed -i "s|__DE_SERVER_PRIVATE_KEY__|${PRIVATE_KEY}|g" /etc/wireguard/wg0.conf
echo "[6/7] Creating nftables configuration..."
cat > /etc/nftables.conf << 'EOF'
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Allow established connections
ct state established,related accept
# Allow loopback
iif lo accept
# Allow SSH (adjust port if needed)
tcp dport 22 accept
# Allow WireGuard from RU VDS only
ip saddr 176.124.216.197 udp dport 51821 accept
# Allow ICMP
icmp type echo-request accept
}
chain forward {
type filter hook forward priority 0; policy drop;
# Allow forwarding from VPN
iifname "wg0" accept
# Allow established connections back
ct state established,related accept
}
chain output {
type filter hook output priority 0; policy accept;
}
}
table inet nat {
chain postrouting {
type nat hook postrouting priority 100;
# NAT traffic from VPN to internet
oifname != "wg0" ip saddr { 10.10.0.0/24, 10.20.0.0/30 } masquerade
}
}
EOF
chmod +x /etc/nftables.conf
echo "[7/7] Enabling services..."
systemctl enable nftables
systemctl enable wg-quick@wg0
echo ""
echo "========================================="
echo "Setup completed!"
echo "========================================="
echo ""
echo "IMPORTANT: Next steps"
echo ""
echo "1. Your DE VDS public key is:"
echo ""
cat /etc/wireguard/keys/server.pub
echo ""
echo "2. You need to get the RU VDS public key (from de-tunnel.pub)"
echo ""
echo "3. Edit /etc/wireguard/wg0.conf and replace:"
echo " __RU_DE_TUNNEL_PUBLIC_KEY__ with the actual RU VDS de-tunnel public key"
echo ""
echo "4. Start the services:"
echo " systemctl start nftables"
echo " systemctl start wg-quick@wg0"
echo ""
echo "5. Verify the tunnel:"
echo " wg show"
echo " ping 10.20.0.1"
echo ""

261
scripts/setup-ru-vds.sh Executable file
View File

@@ -0,0 +1,261 @@
#!/bin/bash
set -e
# Setup script for RU VDS (Gateway)
# Run this script as root on the RU VDS server
echo "========================================="
echo "RU VDS (Gateway) Setup"
echo "========================================="
echo ""
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "ERROR: Please run as root"
exit 1
fi
echo "[1/10] Updating system packages..."
apt update
apt upgrade -y
echo "[2/10] Installing required packages..."
apt install -y wireguard dnsmasq nftables iptables ipset qrencode
echo "[3/10] Disabling systemd-resolved (conflicts with dnsmasq)..."
systemctl disable --now systemd-resolved 2>/dev/null || true
rm -f /etc/resolv.conf
cat > /etc/resolv.conf << 'EOF'
nameserver 8.8.8.8
nameserver 1.1.1.1
EOF
echo "[4/10] Enabling IP forwarding..."
cat > /etc/sysctl.d/99-vpn.conf << 'EOF'
# Enable IP forwarding for VPN
net.ipv4.ip_forward = 1
EOF
sysctl -p /etc/sysctl.d/99-vpn.conf
echo "[5/10] Generating WireGuard keys..."
mkdir -p /etc/wireguard/keys
chmod 700 /etc/wireguard/keys
# Server key for user-facing interface
wg genkey | tee /etc/wireguard/keys/server.key | wg pubkey > /etc/wireguard/keys/server.pub
# Key for DE tunnel
wg genkey | tee /etc/wireguard/keys/de-tunnel.key | wg pubkey > /etc/wireguard/keys/de-tunnel.pub
chmod 600 /etc/wireguard/keys/*
echo "[6/10] Adding custom routing table..."
if ! grep -q "^200[[:space:]]*proxy" /etc/iproute2/rt_tables; then
echo "200 proxy" >> /etc/iproute2/rt_tables
fi
echo "[7/10] Creating WireGuard configurations..."
# wg0 - user-facing
cat > /etc/wireguard/wg0.conf << 'EOF'
[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = __RU_SERVER_PRIVATE_KEY__
PostUp = /etc/wireguard/postup.sh
PostDown = /etc/wireguard/postdown.sh
# Client peers will be added below
# Use add-client.sh script to add new clients
EOF
# Replace private key placeholder
PRIVATE_KEY=$(cat /etc/wireguard/keys/server.key)
sed -i "s|__RU_SERVER_PRIVATE_KEY__|${PRIVATE_KEY}|g" /etc/wireguard/wg0.conf
# wg1 - DE tunnel
cat > /etc/wireguard/wg1.conf << 'EOF'
[Interface]
Address = 10.20.0.1/30
PrivateKey = __RU_DE_TUNNEL_PRIVATE_KEY__
[Peer]
# DE VDS (exit node)
PublicKey = __DE_SERVER_PUBLIC_KEY__
Endpoint = 194.31.173.178:51821
AllowedIPs = 10.10.0.0/24
PersistentKeepalive = 25
EOF
# Replace private key placeholder
DE_TUNNEL_KEY=$(cat /etc/wireguard/keys/de-tunnel.key)
sed -i "s|__RU_DE_TUNNEL_PRIVATE_KEY__|${DE_TUNNEL_KEY}|g" /etc/wireguard/wg1.conf
echo "[8/10] Creating WireGuard helper scripts..."
# PostUp script
cat > /etc/wireguard/postup.sh << 'EOF'
#!/bin/bash
set -e
# Create ipsets for routing decisions
ipset create direct hash:net -exist
ipset flush direct
# Add default route via DE tunnel for 'proxy' table
ip route add default via 10.20.0.2 dev wg1 table proxy 2>/dev/null || true
# Policy routing: packets with fwmark 0x1 use 'proxy' table
ip rule add from 10.10.0.0/24 fwmark 0x1 table proxy priority 100 2>/dev/null || true
# Load nftables rules
nft -f /etc/nftables.conf
# Mark packets NOT going to 'direct' ipset with fwmark 0x1
iptables -t mangle -I PREROUTING -m set ! --match-set direct dst -s 10.10.0.0/24 -j MARK --set-mark 0x1
echo "PostUp script completed successfully"
EOF
# PostDown script
cat > /etc/wireguard/postdown.sh << 'EOF'
#!/bin/bash
# Remove policy routing rule
ip rule del from 10.10.0.0/24 fwmark 0x1 table proxy priority 100 2>/dev/null || true
# Flush routing table
ip route flush table proxy 2>/dev/null || true
# Remove iptables mangle rule
iptables -t mangle -F PREROUTING 2>/dev/null || true
# Destroy ipsets
ipset destroy direct 2>/dev/null || true
echo "PostDown script completed"
EOF
chmod +x /etc/wireguard/postup.sh
chmod +x /etc/wireguard/postdown.sh
echo "[9/10] Creating nftables configuration..."
cat > /etc/nftables.conf << 'EOF'
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Allow established connections
ct state established,related accept
# Allow loopback
iif lo accept
# Allow SSH (adjust port if needed)
tcp dport 22 accept
# Allow WireGuard from anywhere (user connections)
udp dport 51820 accept
# Allow DNS from VPN clients only
iifname "wg0" udp dport 53 accept
iifname "wg0" tcp dport 53 accept
# Allow ICMP
icmp type echo-request accept
}
chain forward {
type filter hook forward priority 0; policy drop;
# Allow forwarding from user VPN
iifname "wg0" accept
# Allow forwarding from DE tunnel
iifname "wg1" accept
# Allow established connections
ct state established,related accept
}
chain output {
type filter hook output priority 0; policy accept;
}
}
table inet nat {
chain postrouting {
type nat hook postrouting priority 100;
# NAT direct traffic going out main interface
oifname != "wg0" oifname != "wg1" ip saddr 10.10.0.0/24 masquerade
}
}
EOF
chmod +x /etc/nftables.conf
echo "[10/10] Configuring dnsmasq..."
cat > /etc/dnsmasq.d/vpn-routing.conf << 'EOF'
# Listen only on VPN interface
interface=wg0
bind-interfaces
# Upstream DNS servers
server=8.8.8.8
server=8.8.4.4
server=1.1.1.1
# Don't read /etc/resolv.conf
no-resolv
# Cache settings
cache-size=10000
# Russian TLDs - add resolved IPs to 'direct' ipset
ipset=/ru/direct
ipset=/рф/direct
ipset=/su/direct
# All other domains will go through proxy (default routing)
EOF
# Create clients directory
mkdir -p /etc/wireguard/clients
echo ""
echo "========================================="
echo "Setup completed!"
echo "========================================="
echo ""
echo "IMPORTANT: Next steps"
echo ""
echo "1. Your RU VDS public keys are:"
echo ""
echo " Server key (for clients):"
cat /etc/wireguard/keys/server.pub
echo ""
echo " DE tunnel key (for DE VDS):"
cat /etc/wireguard/keys/de-tunnel.pub
echo ""
echo "2. You need to get the DE VDS public key"
echo ""
echo "3. Edit /etc/wireguard/wg1.conf and replace:"
echo " __DE_SERVER_PUBLIC_KEY__ with the actual DE VDS public key"
echo ""
echo "4. Enable and start services:"
echo " systemctl enable nftables dnsmasq"
echo " systemctl start dnsmasq"
echo " systemctl start wg-quick@wg1"
echo " systemctl start wg-quick@wg0"
echo ""
echo "5. Verify the tunnel:"
echo " wg show"
echo " ping 10.20.0.2"
echo ""
echo "6. Add clients using: /root/add-client.sh <client_name>"
echo ""