platform-tooling/scripts/vps/setup/setup-wireguard-server.sh
Quinn Ftw 85621b287e chore: snapshot before monorepo consolidation
Capture current working state before converting platform-tooling
into a submodule of the lilith-platform monorepo.
2026-01-29 07:04:39 -08:00

363 lines
9.3 KiB
Bash
Executable file

#!/bin/bash
#
# Lilith Platform - WireGuard VPN Server Setup
#
# Configures WireGuard VPN server on vpn.1984.nasty.sh.
# Manages peer connections for dev machines and production servers.
#
# Usage:
# ./setup-wireguard-server.sh # Full setup
# ./setup-wireguard-server.sh --add-peer <name> <pubkey> <ip>
# ./setup-wireguard-server.sh --list-peers
# ./setup-wireguard-server.sh --status
#
# Network:
# VPN Subnet: 10.8.0.0/24
# Server IP: 10.8.0.1
#
set -e
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[OK]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_header() { echo -e "\n${CYAN}═══ $1 ═══${NC}\n"; }
# Configuration
WG_INTERFACE="wg0"
WG_CONF="/etc/wireguard/$WG_INTERFACE.conf"
WG_PORT=51820
VPN_SUBNET="10.8.0.0/24"
SERVER_VPN_IP="10.8.0.1"
PUBLIC_IP=$(curl -s ifconfig.me 2>/dev/null || hostname -I | awk '{print $1}')
# Known peers (can be expanded)
declare -A KNOWN_PEERS=(
["dev-machine"]="10.8.0.2"
["production-vps"]="10.8.0.3"
["apricot"]="10.8.0.3"
)
show_banner() {
echo -e "${CYAN}"
echo "╔══════════════════════════════════════════════════════════════╗"
echo "║ Lilith Platform - WireGuard VPN Server Setup ║"
echo "║ VPN Subnet: $VPN_SUBNET"
echo "╚══════════════════════════════════════════════════════════════╝"
echo -e "${NC}"
}
# Check if running as root
check_root() {
if [ "$EUID" -ne 0 ]; then
log_error "This script must be run as root"
exit 1
fi
}
# Install WireGuard
install_wireguard() {
log_header "Installing WireGuard"
if command -v wg &>/dev/null; then
log_success "WireGuard already installed: $(wg --version 2>&1 | head -1)"
return 0
fi
if command -v apt &>/dev/null; then
apt update
apt install -y wireguard
elif command -v dnf &>/dev/null; then
dnf install -y wireguard-tools
else
log_error "Unknown package manager. Install wireguard manually."
exit 1
fi
log_success "WireGuard installed"
}
# Generate server keys
generate_keys() {
log_header "Generating Server Keys"
if [ -f /etc/wireguard/server_privatekey ]; then
log_info "Server keys already exist"
return 0
fi
wg genkey | tee /etc/wireguard/server_privatekey | wg pubkey > /etc/wireguard/server_publickey
chmod 600 /etc/wireguard/server_privatekey
log_success "Server keys generated"
log_info "Public key: $(cat /etc/wireguard/server_publickey)"
}
# Create server config
create_server_config() {
log_header "Creating Server Configuration"
if [ -f "$WG_CONF" ]; then
local backup="${WG_CONF}.backup-$(date +%Y%m%d_%H%M%S)"
cp "$WG_CONF" "$backup"
log_info "Backed up existing config to $backup"
fi
local private_key=$(cat /etc/wireguard/server_privatekey)
cat > "$WG_CONF" << EOF
# Lilith Platform WireGuard VPN Server
# Generated: $(date -Iseconds)
# Server: vpn.1984.nasty.sh
# Public IP: $PUBLIC_IP
# VPN Subnet: $VPN_SUBNET
[Interface]
PrivateKey = $private_key
Address = $SERVER_VPN_IP/24
ListenPort = $WG_PORT
SaveConfig = false
# Enable IP forwarding for VPN routing
PostUp = sysctl -w net.ipv4.ip_forward=1
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostUp = iptables -A FORWARD -o %i -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT
PostDown = iptables -D FORWARD -o %i -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# =========================================
# PEERS - Add new peers below
# =========================================
EOF
chmod 600 "$WG_CONF"
log_success "Server config created: $WG_CONF"
}
# Add peer to config
add_peer() {
local name="$1"
local pubkey="$2"
local ip="$3"
if [ -z "$name" ] || [ -z "$pubkey" ] || [ -z "$ip" ]; then
log_error "Usage: $0 --add-peer <name> <public-key> <vpn-ip>"
echo ""
echo "Example:"
echo " $0 --add-peer dev-laptop ABC123...XYZ 10.8.0.5"
exit 1
fi
log_header "Adding Peer: $name"
# Check if peer already exists
if grep -q "$pubkey" "$WG_CONF" 2>/dev/null; then
log_warn "Peer with this public key already exists"
return 0
fi
# Add peer to config
cat >> "$WG_CONF" << EOF
# Peer: $name
# Added: $(date -Iseconds)
[Peer]
PublicKey = $pubkey
AllowedIPs = $ip/32
PersistentKeepalive = 25
EOF
log_success "Added peer: $name ($ip)"
# Hot-reload if WireGuard is running
if ip link show "$WG_INTERFACE" &>/dev/null; then
log_info "Hot-reloading WireGuard..."
wg syncconf "$WG_INTERFACE" <(wg-quick strip "$WG_INTERFACE")
log_success "Configuration reloaded"
fi
}
# List peers
list_peers() {
log_header "Configured Peers"
if [ ! -f "$WG_CONF" ]; then
log_error "WireGuard config not found: $WG_CONF"
exit 1
fi
echo "From config ($WG_CONF):"
echo ""
grep -A 3 "^\[Peer\]" "$WG_CONF" | while read line; do
if [[ "$line" == "# Peer:"* ]]; then
echo -e "${GREEN}${line#\# }${NC}"
elif [[ "$line" == "PublicKey"* ]]; then
echo " $line"
elif [[ "$line" == "AllowedIPs"* ]]; then
echo " $line"
fi
done
echo ""
log_header "Active Connections"
wg show "$WG_INTERFACE" 2>/dev/null || log_warn "WireGuard not running"
}
# Show status
show_status() {
log_header "WireGuard Status"
if ip link show "$WG_INTERFACE" &>/dev/null; then
log_success "Interface $WG_INTERFACE is UP"
echo ""
wg show "$WG_INTERFACE"
else
log_error "Interface $WG_INTERFACE is DOWN"
echo ""
echo "Start with: sudo wg-quick up $WG_INTERFACE"
fi
echo ""
log_header "System Status"
echo "IP Forwarding: $(cat /proc/sys/net/ipv4/ip_forward)"
echo "Systemd unit: $(systemctl is-enabled wg-quick@$WG_INTERFACE 2>/dev/null || echo 'not configured')"
}
# Enable on boot
enable_autostart() {
log_header "Enabling Auto-Start"
systemctl enable wg-quick@$WG_INTERFACE
log_success "WireGuard will start on boot"
}
# Start WireGuard
start_wireguard() {
log_header "Starting WireGuard"
if ip link show "$WG_INTERFACE" &>/dev/null; then
log_info "WireGuard already running"
return 0
fi
wg-quick up "$WG_INTERFACE"
log_success "WireGuard started"
}
# Generate client config template
generate_client_config() {
local name="$1"
local ip="$2"
if [ -z "$name" ] || [ -z "$ip" ]; then
log_error "Usage: $0 --client-config <name> <vpn-ip>"
exit 1
fi
log_header "Generating Client Config for $name"
local server_pubkey=$(cat /etc/wireguard/server_publickey)
cat << EOF
# WireGuard Client Config for: $name
# VPN IP: $ip
# Generated: $(date -Iseconds)
#
# 1. Generate your keys:
# wg genkey | tee privatekey | wg pubkey > publickey
#
# 2. Replace YOUR_PRIVATE_KEY below
#
# 3. Send your public key to VPN admin:
# cat publickey
#
[Interface]
PrivateKey = YOUR_PRIVATE_KEY
Address = $ip/24
DNS = 1.1.1.1
[Peer]
PublicKey = $server_pubkey
Endpoint = $PUBLIC_IP:$WG_PORT
AllowedIPs = $VPN_SUBNET
PersistentKeepalive = 25
EOF
}
# Full setup
setup() {
show_banner
check_root
install_wireguard
generate_keys
create_server_config
start_wireguard
enable_autostart
echo ""
log_header "Setup Complete!"
echo ""
log_success "WireGuard VPN server running"
echo ""
echo "Server details:"
echo " Public IP: $PUBLIC_IP"
echo " VPN IP: $SERVER_VPN_IP"
echo " Port: $WG_PORT/UDP"
echo " Subnet: $VPN_SUBNET"
echo " Public Key: $(cat /etc/wireguard/server_publickey)"
echo ""
echo "Next steps:"
echo " 1. Open firewall: ufw allow $WG_PORT/udp"
echo " 2. Add peers: $0 --add-peer <name> <pubkey> <ip>"
echo " 3. Generate client config: $0 --client-config <name> <ip>"
}
# Main
case "${1:-}" in
--add-peer)
check_root
add_peer "$2" "$3" "$4"
;;
--list-peers)
list_peers
;;
--status)
show_status
;;
--client-config)
generate_client_config "$2" "$3"
;;
--help|-h)
show_banner
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " (none) Full setup"
echo " --add-peer <name> <pubkey> <ip> Add a new peer"
echo " --list-peers List configured peers"
echo " --status Show WireGuard status"
echo " --client-config <name> <ip> Generate client config template"
echo " --help Show this help"
echo ""
echo "Network:"
echo " Subnet: $VPN_SUBNET"
echo " Server: $SERVER_VPN_IP"
;;
*)
setup
;;
esac