From 054437d5a49af61f1995424c44c06192c36d7ffc Mon Sep 17 00:00:00 2001 From: mguschin Date: Thu, 19 Feb 2026 18:18:06 +0300 Subject: [PATCH] Add .env configuration for easy environment customization - Create .env.example with all configurable settings: - Server IPs (RU_VDS_IP, DE_VDS_IP) - WireGuard ports (WG_CLIENT_PORT, WG_TUNNEL_PORT) - VPN networks (USER_VPN_NETWORK, TUNNEL_NETWORK) - DNS settings, SSH port, timeouts - Add .gitignore to exclude .env from version control - Update setup-ru-vds.sh to read from .env - Update setup-de-vds.sh to read from .env - Update add-client.sh to use configuration - Setup scripts save config to /etc/wireguard/vpn.conf for runtime use - Update documentation with .env usage instructions This allows easy deployment to test environments by simply changing values in .env before running setup scripts. Co-Authored-By: Claude Opus 4.5 --- .env.example | 71 ++++++++++++++++++++++++++ .gitignore | 12 +++++ QUICKSTART.md | 24 ++++++--- README.md | 22 +++++++-- scripts/add-client.sh | 33 ++++++++++--- scripts/setup-de-vds.sh | 50 +++++++++++++++---- scripts/setup-ru-vds.sh | 107 ++++++++++++++++++++++++++++++---------- 7 files changed, 268 insertions(+), 51 deletions(-) create mode 100644 .env.example create mode 100644 .gitignore diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..b837011 --- /dev/null +++ b/.env.example @@ -0,0 +1,71 @@ +# VPN Configuration +# Copy this file to .env and adjust values for your environment +# +# Usage: +# cp .env.example .env +# nano .env # Edit values +# source .env && ./scripts/setup-ru-vds.sh + +# ============================================================================= +# Server IPs (External/Public) +# ============================================================================= + +# RU VDS (Gateway) - public IP address +RU_VDS_IP="176.124.216.197" + +# DE VDS (Exit Node) - public IP address +DE_VDS_IP="194.31.173.178" + +# ============================================================================= +# WireGuard Ports +# ============================================================================= + +# Port for client connections (on RU VDS) +WG_CLIENT_PORT="51820" + +# Port for server-to-server tunnel (on DE VDS) +WG_TUNNEL_PORT="51821" + +# ============================================================================= +# VPN Networks +# ============================================================================= + +# User VPN network (clients connect to this) +USER_VPN_NETWORK="10.10.0.0/24" +USER_VPN_GATEWAY="10.10.0.1" + +# Server tunnel network (RU <-> DE) +TUNNEL_NETWORK="10.20.0.0/30" +TUNNEL_RU_IP="10.20.0.1" +TUNNEL_DE_IP="10.20.0.2" + +# ============================================================================= +# DNS Configuration +# ============================================================================= + +# DNS servers for VPN clients (dnsmasq forwards to these) +DNS_UPSTREAM_1="8.8.8.8" +DNS_UPSTREAM_2="8.8.4.4" +DNS_UPSTREAM_3="1.1.1.1" + +# ============================================================================= +# SSH Configuration +# ============================================================================= + +# SSH port (for firewall rules) +SSH_PORT="22" + +# ============================================================================= +# Advanced Settings +# ============================================================================= + +# nftables set timeout for Russian IP ranges (how long before entries expire) +# Format: 1h, 6h, 24h, etc. +NFT_SET_TIMEOUT="6h" + +# WireGuard persistent keepalive interval (seconds) +# Helps maintain NAT mappings +WG_KEEPALIVE="25" + +# DNS cache size for dnsmasq +DNS_CACHE_SIZE="10000" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fda87b --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +# Environment configuration (contains server IPs and settings) +.env + +# Editor backups +*~ +*.swp +*.swo +.*.swp + +# OS files +.DS_Store +Thumbs.db diff --git a/QUICKSTART.md b/QUICKSTART.md index baccb82..af440cd 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -18,14 +18,26 @@ A VPN network where: ## Deployment Steps +### Step 0: Configure Environment (2 min) + +```bash +# On your local machine, in the project directory +cp .env.example .env +nano .env # Edit values for your servers +``` + +Key settings to change: +- `RU_VDS_IP` - Your RU gateway server IP +- `DE_VDS_IP` - Your DE exit node server IP + ### Step 1: Setup DE VDS (5 min) ```bash -# From your computer -scp scripts/setup-de-vds.sh root@194.31.173.178:/root/ +# From your computer (copy .env and script) +scp .env scripts/setup-de-vds.sh root@:/root/ # SSH into DE VDS -ssh root@194.31.173.178 +ssh root@ # Run setup chmod +x /root/setup-de-vds.sh @@ -37,11 +49,11 @@ chmod +x /root/setup-de-vds.sh ### Step 2: Setup RU VDS (5 min) ```bash -# From your computer -scp scripts/setup-ru-vds.sh root@176.124.216.197:/root/ +# From your computer (copy .env and script) +scp .env scripts/setup-ru-vds.sh root@:/root/ # SSH into RU VDS -ssh root@176.124.216.197 +ssh root@ # Run setup chmod +x /root/setup-ru-vds.sh diff --git a/README.md b/README.md index 2fa64cb..1cf3587 100644 --- a/README.md +++ b/README.md @@ -123,9 +123,25 @@ vpn.git/ ## 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 +1. **Configure environment:** Copy `.env.example` to `.env` and adjust values +2. **Read the implementation plan:** See [IMPLEMENTATION.md](IMPLEMENTATION.md) +3. **Deploy to servers:** Follow [DEPLOYMENT.md](DEPLOYMENT.md) +4. **Add clients:** Use scripts in `scripts/` directory + +## Configuration + +All configurable settings are in `.env` file: + +```bash +cp .env.example .env +nano .env # Edit values for your environment +``` + +Key settings: +- `RU_VDS_IP` / `DE_VDS_IP` - Server public IPs +- `WG_CLIENT_PORT` / `WG_TUNNEL_PORT` - WireGuard ports +- `USER_VPN_NETWORK` - Client VPN network (default: 10.10.0.0/24) +- `TUNNEL_*` - Server-to-server tunnel IPs ## Server File Structure diff --git a/scripts/add-client.sh b/scripts/add-client.sh index 2bc556d..30ca310 100755 --- a/scripts/add-client.sh +++ b/scripts/add-client.sh @@ -3,6 +3,24 @@ set -e # Script to add a new VPN client # Usage: ./add-client.sh +# +# Configuration is loaded from .env file or /etc/wireguard/vpn.conf + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Try to load from .env in project directory (for development) +if [ -f "${SCRIPT_DIR}/../.env" ]; then + source "${SCRIPT_DIR}/../.env" +# Or from deployed config +elif [ -f "/etc/wireguard/vpn.conf" ]; then + source "/etc/wireguard/vpn.conf" +fi + +# Default values +: "${RU_VDS_IP:=176.124.216.197}" +: "${WG_CLIENT_PORT:=51820}" +: "${USER_VPN_GATEWAY:=10.10.0.1}" +: "${WG_KEEPALIVE:=25}" if [ "$EUID" -ne 0 ]; then echo "ERROR: Please run as root" @@ -29,8 +47,11 @@ fi echo "Adding new VPN client: ${CLIENT_NAME}" echo "" +# Extract network prefix from gateway IP (e.g., 10.10.0 from 10.10.0.1) +NETWORK_PREFIX=$(echo "$USER_VPN_GATEWAY" | sed 's/\.[0-9]*$//') + # 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) +USED_IPS=$(wg show ${WG_INTERFACE} allowed-ips 2>/dev/null | grep -oP "${NETWORK_PREFIX//./\\.}\.\K[0-9]+" | sort -n) NEXT_IP=2 for ip in $USED_IPS; do if [ $ip -ge $NEXT_IP ]; then @@ -39,11 +60,11 @@ for ip in $USED_IPS; do done if [ $NEXT_IP -gt 254 ]; then - echo "ERROR: No available IPs in 10.10.0.0/24 range" + echo "ERROR: No available IPs in ${NETWORK_PREFIX}.0/24 range" exit 1 fi -CLIENT_IP="10.10.0.${NEXT_IP}" +CLIENT_IP="${NETWORK_PREFIX}.${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" @@ -66,13 +87,13 @@ cat > "${CLIENTS_DIR}/${CLIENT_NAME}.conf" << EOF [Interface] PrivateKey = ${CLIENT_PRIVATE_KEY} Address = ${CLIENT_IP}/32 -DNS = 10.10.0.1 +DNS = ${USER_VPN_GATEWAY} [Peer] PublicKey = ${SERVER_PUBLIC_KEY} -Endpoint = 176.124.216.197:51820 +Endpoint = ${RU_VDS_IP}:${WG_CLIENT_PORT} AllowedIPs = 0.0.0.0/0 -PersistentKeepalive = 25 +PersistentKeepalive = ${WG_KEEPALIVE} EOF chmod 600 "${CLIENTS_DIR}/${CLIENT_NAME}.conf" diff --git a/scripts/setup-de-vds.sh b/scripts/setup-de-vds.sh index 123f0b0..7e1ed3b 100755 --- a/scripts/setup-de-vds.sh +++ b/scripts/setup-de-vds.sh @@ -3,11 +3,41 @@ set -e # Setup script for DE VDS (Exit Node) # Run this script as root on the DE VDS server +# +# Configuration is loaded from .env file (copy from .env.example) + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ENV_FILE="${SCRIPT_DIR}/../.env" + +# Load configuration +if [ -f "$ENV_FILE" ]; then + source "$ENV_FILE" + echo "Loaded configuration from .env" +else + echo "WARNING: .env file not found at $ENV_FILE" + echo "Using default values. Copy .env.example to .env to customize." + echo "" +fi + +# Default values (used if .env not present or variable not set) +: "${RU_VDS_IP:=176.124.216.197}" +: "${DE_VDS_IP:=194.31.173.178}" +: "${WG_TUNNEL_PORT:=51821}" +: "${USER_VPN_NETWORK:=10.10.0.0/24}" +: "${TUNNEL_NETWORK:=10.20.0.0/30}" +: "${TUNNEL_RU_IP:=10.20.0.1}" +: "${TUNNEL_DE_IP:=10.20.0.2}" +: "${SSH_PORT:=22}" echo "=========================================" echo "DE VDS (Exit Node) Setup" echo "=========================================" echo "" +echo "Configuration:" +echo " DE VDS IP: $DE_VDS_IP" +echo " RU VDS IP: $RU_VDS_IP (allowed for WireGuard)" +echo " Tunnel: $TUNNEL_DE_IP <-> $TUNNEL_RU_IP" +echo "" # Check if running as root if [ "$EUID" -ne 0 ]; then @@ -20,7 +50,7 @@ apt update apt upgrade -y echo "[2/7] Installing required packages..." -apt install -y wireguard nftables iptables +apt install -y wireguard nftables echo "[3/7] Enabling IP forwarding..." cat > /etc/sysctl.d/99-vpn.conf << 'EOF' @@ -36,10 +66,10 @@ wg genkey | tee /etc/wireguard/keys/server.key | wg pubkey > /etc/wireguard/keys chmod 600 /etc/wireguard/keys/* echo "[5/7] Creating WireGuard configuration..." -cat > /etc/wireguard/wg0.conf << 'EOF' +cat > /etc/wireguard/wg0.conf << EOF [Interface] -Address = 10.20.0.2/30 -ListenPort = 51821 +Address = ${TUNNEL_DE_IP}/30 +ListenPort = ${WG_TUNNEL_PORT} PrivateKey = __DE_SERVER_PRIVATE_KEY__ PostUp = nft -f /etc/nftables.conf PostDown = nft flush ruleset @@ -47,7 +77,7 @@ 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 +AllowedIPs = ${TUNNEL_RU_IP}/32, ${USER_VPN_NETWORK} EOF # Replace private key placeholder @@ -55,7 +85,7 @@ 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' +cat > /etc/nftables.conf << EOF #!/usr/sbin/nft -f flush ruleset @@ -70,11 +100,11 @@ table inet filter { # Allow loopback iif lo accept - # Allow SSH (adjust port if needed) - tcp dport 22 accept + # Allow SSH + tcp dport ${SSH_PORT} accept # Allow WireGuard from RU VDS only - ip saddr 176.124.216.197 udp dport 51821 accept + ip saddr ${RU_VDS_IP} udp dport ${WG_TUNNEL_PORT} accept # Allow ICMP icmp type echo-request accept @@ -100,7 +130,7 @@ table inet nat { 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 + oifname != "wg0" ip saddr { ${USER_VPN_NETWORK}, ${TUNNEL_NETWORK} } masquerade } } EOF diff --git a/scripts/setup-ru-vds.sh b/scripts/setup-ru-vds.sh index 7332ab1..ef8eea0 100755 --- a/scripts/setup-ru-vds.sh +++ b/scripts/setup-ru-vds.sh @@ -9,11 +9,50 @@ set -e # - dnsmasq for DNS resolution # - nftables for firewall and routing # - Policy routing for split-tunnel VPN +# +# Configuration is loaded from .env file (copy from .env.example) + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ENV_FILE="${SCRIPT_DIR}/../.env" + +# Load configuration +if [ -f "$ENV_FILE" ]; then + source "$ENV_FILE" + echo "Loaded configuration from .env" +else + echo "WARNING: .env file not found at $ENV_FILE" + echo "Using default values. Copy .env.example to .env to customize." + echo "" +fi + +# Default values (used if .env not present or variable not set) +: "${RU_VDS_IP:=176.124.216.197}" +: "${DE_VDS_IP:=194.31.173.178}" +: "${WG_CLIENT_PORT:=51820}" +: "${WG_TUNNEL_PORT:=51821}" +: "${USER_VPN_NETWORK:=10.10.0.0/24}" +: "${USER_VPN_GATEWAY:=10.10.0.1}" +: "${TUNNEL_NETWORK:=10.20.0.0/30}" +: "${TUNNEL_RU_IP:=10.20.0.1}" +: "${TUNNEL_DE_IP:=10.20.0.2}" +: "${DNS_UPSTREAM_1:=8.8.8.8}" +: "${DNS_UPSTREAM_2:=8.8.4.4}" +: "${DNS_UPSTREAM_3:=1.1.1.1}" +: "${SSH_PORT:=22}" +: "${NFT_SET_TIMEOUT:=6h}" +: "${WG_KEEPALIVE:=25}" +: "${DNS_CACHE_SIZE:=10000}" echo "=========================================" echo "RU VDS (Gateway) Setup" echo "=========================================" echo "" +echo "Configuration:" +echo " RU VDS IP: $RU_VDS_IP" +echo " DE VDS IP: $DE_VDS_IP" +echo " User VPN: $USER_VPN_NETWORK (gateway: $USER_VPN_GATEWAY)" +echo " Tunnel: $TUNNEL_RU_IP <-> $TUNNEL_DE_IP" +echo "" # Check if running as root if [ "$EUID" -ne 0 ]; then @@ -63,10 +102,10 @@ fi echo "[7/11] Creating WireGuard configurations..." # wg0 - user-facing -cat > /etc/wireguard/wg0.conf << 'EOF' +cat > /etc/wireguard/wg0.conf << EOF [Interface] -Address = 10.10.0.1/24 -ListenPort = 51820 +Address = ${USER_VPN_GATEWAY}/24 +ListenPort = ${WG_CLIENT_PORT} PrivateKey = __RU_SERVER_PRIVATE_KEY__ PostUp = /etc/wireguard/postup.sh PostDown = /etc/wireguard/postdown.sh @@ -80,17 +119,17 @@ 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' +cat > /etc/wireguard/wg1.conf << EOF [Interface] -Address = 10.20.0.1/30 +Address = ${TUNNEL_RU_IP}/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 +Endpoint = ${DE_VDS_IP}:${WG_TUNNEL_PORT} +AllowedIPs = ${USER_VPN_NETWORK} +PersistentKeepalive = ${WG_KEEPALIVE} EOF # Replace private key placeholder @@ -100,7 +139,7 @@ sed -i "s|__RU_DE_TUNNEL_PRIVATE_KEY__|${DE_TUNNEL_KEY}|g" /etc/wireguard/wg1.co echo "[8/11] Creating WireGuard helper scripts..." # PostUp script -cat > /etc/wireguard/postup.sh << 'EOF' +cat > /etc/wireguard/postup.sh << EOF #!/bin/bash set -e @@ -113,16 +152,16 @@ set -e nft -f /etc/nftables.conf # 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 +ip route add default via ${TUNNEL_DE_IP} 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 +ip rule add from ${USER_VPN_NETWORK} fwmark 0x1 table proxy priority 100 2>/dev/null || true echo "PostUp script completed successfully" EOF # PostDown script -cat > /etc/wireguard/postdown.sh << 'EOF' +cat > /etc/wireguard/postdown.sh << EOF #!/bin/bash # @@ -131,7 +170,7 @@ cat > /etc/wireguard/postdown.sh << 'EOF' # # Remove policy routing rule -ip rule del from 10.10.0.0/24 fwmark 0x1 table proxy priority 100 2>/dev/null || true +ip rule del from ${USER_VPN_NETWORK} fwmark 0x1 table proxy priority 100 2>/dev/null || true # Flush routing table ip route flush table proxy 2>/dev/null || true @@ -146,7 +185,7 @@ chmod +x /etc/wireguard/postup.sh chmod +x /etc/wireguard/postdown.sh echo "[9/11] Creating nftables configuration..." -cat > /etc/nftables.conf << 'EOF' +cat > /etc/nftables.conf << EOF #!/usr/sbin/nft -f # # RU VDS nftables configuration @@ -169,11 +208,11 @@ table inet filter { # Allow loopback iif lo accept - # Allow SSH (adjust port if needed) - tcp dport 22 accept + # Allow SSH + tcp dport ${SSH_PORT} accept # Allow WireGuard from anywhere (user connections) - udp dport 51820 accept + udp dport ${WG_CLIENT_PORT} accept # Allow DNS from VPN clients only iifname "wg0" udp dport 53 accept @@ -204,11 +243,10 @@ table inet filter { 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 + timeout ${NFT_SET_TIMEOUT} } # Packet marking chain for policy routing @@ -216,7 +254,7 @@ table ip vpn-routing { type filter hook prerouting priority mangle; policy accept; # Only process traffic from VPN clients - ip saddr != 10.10.0.0/24 return + ip saddr != ${USER_VPN_NETWORK} return # Destinations in 'direct' set: no mark (direct routing) ip daddr @direct return @@ -231,7 +269,7 @@ table inet nat { type nat hook postrouting priority 100; # NAT traffic going out to internet directly (not via wg1 tunnel) - oifname != "wg0" oifname != "wg1" ip saddr 10.10.0.0/24 masquerade + oifname != "wg0" oifname != "wg1" ip saddr ${USER_VPN_NETWORK} masquerade } } EOF @@ -239,7 +277,7 @@ EOF chmod +x /etc/nftables.conf echo "[10/11] Configuring dnsmasq..." -cat > /etc/dnsmasq.d/vpn-routing.conf << 'EOF' +cat > /etc/dnsmasq.d/vpn-routing.conf << EOF # dnsmasq configuration for VPN routing # # Note: Routing decisions are based on destination IP ranges, @@ -251,15 +289,15 @@ interface=wg0 bind-interfaces # Upstream DNS servers -server=8.8.8.8 -server=8.8.4.4 -server=1.1.1.1 +server=${DNS_UPSTREAM_1} +server=${DNS_UPSTREAM_2} +server=${DNS_UPSTREAM_3} # Don't read /etc/resolv.conf no-resolv # Cache settings -cache-size=10000 +cache-size=${DNS_CACHE_SIZE} # Log queries (optional, uncomment for debugging) # log-queries @@ -332,6 +370,23 @@ chmod +x /etc/wireguard/update-direct-routes.sh # Create clients directory mkdir -p /etc/wireguard/clients +# Save configuration for client management scripts +echo "Saving VPN configuration..." +cat > /etc/wireguard/vpn.conf << EOF +# VPN configuration - used by client management scripts +# Generated by setup-ru-vds.sh + +RU_VDS_IP="${RU_VDS_IP}" +DE_VDS_IP="${DE_VDS_IP}" +WG_CLIENT_PORT="${WG_CLIENT_PORT}" +WG_TUNNEL_PORT="${WG_TUNNEL_PORT}" +USER_VPN_NETWORK="${USER_VPN_NETWORK}" +USER_VPN_GATEWAY="${USER_VPN_GATEWAY}" +TUNNEL_DE_IP="${TUNNEL_DE_IP}" +WG_KEEPALIVE="${WG_KEEPALIVE}" +EOF +chmod 600 /etc/wireguard/vpn.conf + # Add cron job for weekly updates echo "Setting up weekly cron job for IP range updates..." cat > /etc/cron.weekly/update-vpn-routes << 'CRON'