2026-02-02 20:11:05 +03:00
|
|
|
#!/bin/bash
|
|
|
|
|
set -e
|
|
|
|
|
|
|
|
|
|
# Script to add a new VPN client
|
|
|
|
|
# Usage: ./add-client.sh <client_name>
|
2026-02-19 18:18:06 +03:00
|
|
|
#
|
|
|
|
|
# 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}"
|
2026-02-02 20:11:05 +03:00
|
|
|
|
|
|
|
|
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 ""
|
|
|
|
|
|
2026-02-19 18:18:06 +03:00
|
|
|
# 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]*$//')
|
|
|
|
|
|
2026-02-02 20:11:05 +03:00
|
|
|
# Find next available IP
|
2026-02-19 18:18:06 +03:00
|
|
|
USED_IPS=$(wg show ${WG_INTERFACE} allowed-ips 2>/dev/null | grep -oP "${NETWORK_PREFIX//./\\.}\.\K[0-9]+" | sort -n)
|
2026-02-02 20:11:05 +03:00
|
|
|
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
|
2026-02-19 18:18:06 +03:00
|
|
|
echo "ERROR: No available IPs in ${NETWORK_PREFIX}.0/24 range"
|
2026-02-02 20:11:05 +03:00
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
2026-02-19 18:18:06 +03:00
|
|
|
CLIENT_IP="${NETWORK_PREFIX}.${NEXT_IP}"
|
2026-02-02 20:11:05 +03:00
|
|
|
|
|
|
|
|
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
|
2026-02-19 18:18:06 +03:00
|
|
|
DNS = ${USER_VPN_GATEWAY}
|
2026-02-02 20:11:05 +03:00
|
|
|
|
|
|
|
|
[Peer]
|
|
|
|
|
PublicKey = ${SERVER_PUBLIC_KEY}
|
2026-02-19 18:18:06 +03:00
|
|
|
Endpoint = ${RU_VDS_IP}:${WG_CLIENT_PORT}
|
2026-02-02 20:11:05 +03:00
|
|
|
AllowedIPs = 0.0.0.0/0
|
2026-02-19 18:18:06 +03:00
|
|
|
PersistentKeepalive = ${WG_KEEPALIVE}
|
2026-02-02 20:11:05 +03:00
|
|
|
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 ""
|