Files
vpn/scripts/setup-ru-vds.sh

378 lines
10 KiB
Bash
Raw Normal View History

2026-02-02 20:11:05 +03:00
#!/bin/bash
set -e
# Setup script for RU VDS (Gateway)
# Run this script as root on the RU VDS server
#
# This script sets up:
# - WireGuard VPN (dual interface: users + DE tunnel)
# - dnsmasq for DNS resolution
# - nftables for firewall and routing
# - Policy routing for split-tunnel VPN
2026-02-02 20:11:05 +03:00
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/11] Updating system packages..."
2026-02-02 20:11:05 +03:00
apt update
apt upgrade -y
echo "[2/11] Installing required packages..."
apt install -y wireguard dnsmasq nftables qrencode curl bc
2026-02-02 20:11:05 +03:00
echo "[3/11] Disabling systemd-resolved (conflicts with dnsmasq)..."
2026-02-02 20:11:05 +03:00
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/11] Enabling IP forwarding..."
2026-02-02 20:11:05 +03:00
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/11] Generating WireGuard keys..."
2026-02-02 20:11:05 +03:00
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/11] Adding custom routing table..."
2026-02-02 20:11:05 +03:00
if ! grep -q "^200[[:space:]]*proxy" /etc/iproute2/rt_tables; then
echo "200 proxy" >> /etc/iproute2/rt_tables
fi
echo "[7/11] Creating WireGuard configurations..."
2026-02-02 20:11:05 +03:00
# 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/11] Creating WireGuard helper scripts..."
2026-02-02 20:11:05 +03:00
# PostUp script
cat > /etc/wireguard/postup.sh << 'EOF'
#!/bin/bash
set -e
#
# PostUp script for WireGuard wg0 interface
# Pure nftables solution - no iptables/ipset dependencies
#
# Load nftables rules (includes the 'direct' set and packet marking)
nft -f /etc/nftables.conf
2026-02-02 20:11:05 +03:00
# 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
echo "PostUp script completed successfully"
EOF
# PostDown script
cat > /etc/wireguard/postdown.sh << 'EOF'
#!/bin/bash
#
# PostDown script for WireGuard wg0 interface
# Pure nftables solution - no iptables/ipset dependencies
#
2026-02-02 20:11:05 +03:00
# 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
# Flush nftables vpn-routing table (keeps filter and nat rules intact)
nft flush table ip vpn-routing 2>/dev/null || true
2026-02-02 20:11:05 +03:00
echo "PostDown script completed"
EOF
chmod +x /etc/wireguard/postup.sh
chmod +x /etc/wireguard/postdown.sh
echo "[9/11] Creating nftables configuration..."
2026-02-02 20:11:05 +03:00
cat > /etc/nftables.conf << 'EOF'
#!/usr/sbin/nft -f
#
# RU VDS nftables configuration
#
# Routing approach:
# - Russian IP ranges loaded into 'direct' set by update-direct-routes.sh
# - nftables marks packets for policy routing
# - No iptables dependency
#
2026-02-02 20:11:05 +03:00
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 ip vpn-routing {
# Set for Russian IPs (direct routing, no proxy)
# Populated by /etc/wireguard/update-direct-routes.sh
# Auto-expires entries after 6 hours
set direct {
type ipv4_addr
flags interval, timeout
timeout 6h
}
# Packet marking chain for policy routing
chain prerouting {
type filter hook prerouting priority mangle; policy accept;
# Only process traffic from VPN clients
ip saddr != 10.10.0.0/24 return
# Destinations in 'direct' set: no mark (direct routing)
ip daddr @direct return
# Everything else: mark for proxy routing via DE tunnel
meta mark set 0x1
}
}
2026-02-02 20:11:05 +03:00
table inet nat {
chain postrouting {
type nat hook postrouting priority 100;
# NAT traffic going out to internet directly (not via wg1 tunnel)
2026-02-02 20:11:05 +03:00
oifname != "wg0" oifname != "wg1" ip saddr 10.10.0.0/24 masquerade
}
}
EOF
chmod +x /etc/nftables.conf
echo "[10/11] Configuring dnsmasq..."
2026-02-02 20:11:05 +03:00
cat > /etc/dnsmasq.d/vpn-routing.conf << 'EOF'
# dnsmasq configuration for VPN routing
#
# Note: Routing decisions are based on destination IP ranges,
# not DNS responses. Russian IP ranges are loaded into nftables
# by the update-direct-routes.sh script.
2026-02-02 20:11:05 +03:00
# 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, uncomment for debugging)
# log-queries
2026-02-02 20:11:05 +03:00
EOF
echo "[11/11] Creating Russian IP routes update script..."
cat > /etc/wireguard/update-direct-routes.sh << 'SCRIPT'
#!/bin/bash
#
# Downloads Russian IP ranges and adds them to the nftables 'direct' set
# These IPs will be routed directly instead of through the DE proxy
#
# Run this script:
# - Once during initial setup (after services are started)
# - Periodically via cron (weekly) to keep ranges updated
#
# Data source: RIPE NCC delegated statistics
#
set -e
RIPE_URL="https://ftp.ripe.net/pub/stats/ripencc/delegated-ripencc-extended-latest"
TEMP_FILE="/tmp/ripe-delegated.txt"
NFT_TABLE="ip vpn-routing"
NFT_SET="direct"
echo "Downloading RIPE delegation data..."
curl -s "$RIPE_URL" -o "$TEMP_FILE"
echo "Parsing Russian IP allocations..."
# Extract Russian IPv4 allocations and convert to CIDR notation
# Format: ripencc|RU|ipv4|start_ip|count|date|status
RU_RANGES=$(grep '|RU|ipv4|' "$TEMP_FILE" | while IFS='|' read -r registry cc type start count date status rest; do
# Convert count to CIDR prefix length
# count is number of IPs, prefix = 32 - log2(count)
if [[ "$count" =~ ^[0-9]+$ ]] && [ "$count" -gt 0 ]; then
prefix=$(echo "32 - l($count)/l(2)" | bc -l 2>/dev/null | cut -d. -f1)
if [[ "$prefix" =~ ^[0-9]+$ ]] && [ "$prefix" -ge 8 ] && [ "$prefix" -le 32 ]; then
echo "$start/$prefix"
fi
fi
done)
# Count ranges
RANGE_COUNT=$(echo "$RU_RANGES" | grep -c . || echo "0")
echo "Found $RANGE_COUNT Russian IP ranges"
echo "Flushing existing 'direct' set..."
nft flush set $NFT_TABLE $NFT_SET 2>/dev/null || true
echo "Adding ranges to nftables set (this may take a moment)..."
# Add in batches for efficiency
echo "$RU_RANGES" | while read -r cidr; do
if [[ -n "$cidr" ]] && [[ "$cidr" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+$ ]]; then
nft add element $NFT_TABLE $NFT_SET { "$cidr" } 2>/dev/null || true
fi
done
# Cleanup
rm -f "$TEMP_FILE"
echo ""
echo "Done. Russian IP ranges loaded into nftables."
echo "Traffic to these IPs will be routed directly (not through DE proxy)."
SCRIPT
chmod +x /etc/wireguard/update-direct-routes.sh
2026-02-02 20:11:05 +03:00
# Create clients directory
mkdir -p /etc/wireguard/clients
# Add cron job for weekly updates
echo "Setting up weekly cron job for IP range updates..."
cat > /etc/cron.weekly/update-vpn-routes << 'CRON'
#!/bin/bash
/etc/wireguard/update-direct-routes.sh >> /var/log/vpn-routes-update.log 2>&1
CRON
chmod +x /etc/cron.weekly/update-vpn-routes
2026-02-02 20:11:05 +03:00
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 wg-quick@wg0 wg-quick@wg1"
2026-02-02 20:11:05 +03:00
echo " systemctl start dnsmasq"
echo " systemctl start wg-quick@wg1"
echo " systemctl start wg-quick@wg0"
echo ""
echo "5. Load Russian IP ranges (after tunnel is up):"
echo " /etc/wireguard/update-direct-routes.sh"
echo ""
echo "6. Verify the tunnel:"
2026-02-02 20:11:05 +03:00
echo " wg show"
echo " ping 10.20.0.2"
echo ""
echo "7. Add clients using: /root/add-client.sh <client_name>"
2026-02-02 20:11:05 +03:00
echo ""