#!/bin/bash # ============================================================================== # 1. SETTINGS & GLOBALS # ============================================================================== # Exit immediately if a command exits with a non-zero status set -e # Determine the directory where this script resides SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" # Input arguments client_name="$1" # Global variables server_pubkey="" client_pubkey="" ips="" # ============================================================================== # 2. HELPER FUNCTIONS # ============================================================================== # Load environment variable of the script environment_var() { echo "--- Starting Environment & Pre-flight Checks ---" # --- .env LOADING --- # This safely loads the variables from .env without touching other files if [ -f "$SCRIPT_DIR/.env" ]; then set -a source "$SCRIPT_DIR/.env" set +a echo "[✔] Environment variables loaded." else echo "[!] No .env file found. Using defaults." fi # --- Variable Checks --- server_pubkey=$(cat ${WG0_DIR}/publickey) ips=$(grep -i '^\s*AllowedIPs\s*=\s*' "${WG0_DIR}/wg0.conf" | sed 's/^\s*AllowedIPs\s*=\s*//I; s/\s*$//') } # Find the last registered client IP find_last_ip() { # Find the last ip an create the next ip if [ -n "$ips" ]; then last=$(printf '%s\n' "$ips" | tail -1) addr=${last%/*} # strip /32 if present IFS=. read -r a b c d <<< "$addr" next_ip="10.0.0.$((d + 1))" printf 'Last CIDR: %s\nNext IP: %s/32\n' "$last" "$next_ip" else next_ip="10.0.0.2" printf 'No peers found, starting at %s/32\n' "$next_ip" fi } # Remove the client from wg0.conf client_remove() { # Make sure that the client name doesn't have spaces if [[ "$client_name" =~ [[:space:]] ]]; then printf 'Error: Client name cannot contain spaces. Use underscores instead of spaces.\n' exit 1 elif [[ -z "$client_name" ]]; then printf 'Error: Client name argument is mandatory. Please provide one first.\n' exit 1 fi # Enforce exact match tags local peer_begin="# BEGIN_PEER ${client_name}" local peer_end="# END_PEER ${client_name}" # Check if peer exists if ! grep -q "^${peer_begin}$" "${WG0_DIR}/wg0.conf"; then printf 'Error: Peer "%s" not found in wg0.conf\n' "$client_name" exit 1 fi # Extract peer info before removal for logging peer_block=$(sed -n "/^${peer_begin}$/,/^${peer_end}$/p" "${WG0_DIR}/wg0.conf") client_pubkey=$(echo "$peer_block" | grep "PublicKey" | awk '{print $3}') client_ip=$(echo "$peer_block" | grep "AllowedIPs" | awk '{print $3}') # Locate exact block line numbers start_line=$(grep -n "^${peer_begin}$" "${WG0_DIR}/wg0.conf" | cut -d: -f1) end_line=$(grep -n "^${peer_end}$" "${WG0_DIR}/wg0.conf" | cut -d: -f1) # Include the preceding line if it is blank or contains only whitespace if [ "$start_line" -gt 1 ]; then prev_line=$((start_line - 1)) if sed -n "${prev_line}p" "${WG0_DIR}/wg0.conf" | grep -q '^[[:space:]]*$'; then start_line=$prev_line fi fi # Perform precise line range deletion sudo sed -i "${start_line},${end_line}d" "${WG0_DIR}/wg0.conf" printf 'Peer "%s" removed from wg0.conf\n' "$client_name" # Apply config without restart printf 'Applying config to running WireGuard interface...\n' if wg syncconf wg0 <(wg-quick strip wg0); then printf 'Config applied successfully.\n' else printf 'Error: wg syncconf failed\n' printf 'Check config syntax with: wg-quick strip wg0\n' exit 1 fi # Update CSV log: mark client as removed csv_file="${TOOLS_DIR}/logs/client_log.csv" if [ -f "$csv_file" ]; then timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") tmp_csv=$(mktemp) awk -v cn="$client_name" -v ts="$timestamp" ' BEGIN { FS=OFS="," } NR==1 { print; next } $2 == "\"" cn "\"" { $1 = ts; $6 = "\"removed\"" } { print } ' "$csv_file" > "$tmp_csv" && mv "$tmp_csv" "$csv_file" printf 'CSV updated: "%s" marked as removed\n' "$client_name" fi printf '\n--- Done. The client was removed from WireGuard ---\n' } # ============================================================================== # 3. MAIN LOGIC # ============================================================================== main() { # Load environment variables first environment_var # Print current values printf 'Public Key of the server: %s\n' "$server_pubkey" printf 'List of current clients: %s\n' "$ips" # Find the last IP find_last_ip # Remove the client from wg0.conf client_remove } # Invoke main main "$@"