Init
This commit is contained in:
684
IMPLEMENTATION.md
Normal file
684
IMPLEMENTATION.md
Normal 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
|
||||
Reference in New Issue
Block a user