#!/bin/bash # WireGuard Secure Installer # Copyright (c) 2025 Muhammad Fadhila Abiyyu Faris # GitHub: [github.com/fadhila36/wireguard-secure-installer](https://github.com/fadhila36/wireguard-secure-installer) new_client() { echo -e "${BLUE}=== Add New Client ===${NC}" echo -n "Enter Client Name (no spaces): " read -r CLIENT_NAME if [[ -z "$CLIENT_NAME" ]]; then log_error "Client name cannot be empty." return fi # Check if client already exists if grep -q "### Client: $CLIENT_NAME" "$WG_CONFIG"; then log_error "Client '$CLIENT_NAME' already exists." return fi # Find next available IP octet # We scan for 10.66.66.X and find the first missing number starting from 2 for i in {2..254}; do if ! grep -q "10.66.66.$i" "$WG_CONFIG"; then NEXT_IP="$i" break fi done if [[ -z "$NEXT_IP" ]]; then fatal_error "No available IPs in the subnet." fi # Re-detect public IP in case it changed detect_public_ip # Use existing function from wg_core.sh create_client_config "$CLIENT_NAME" "$NEXT_IP" echo -e "${GREEN}Client $CLIENT_NAME added with IP 10.66.66.$NEXT_IP${NC}" } remove_client() { echo -e "${BLUE}=== Remove Client ===${NC}" # List clients echo "Existing Clients:" grep "### Client:" "$WG_CONFIG" | cut -d ' ' -f 3 | nl -s ') ' echo -n "Enter Client Name to remove: " read -r CLIENT_TO_REMOVE if [[ -z "$CLIENT_TO_REMOVE" ]]; then log_error "Client name cannot be empty." return fi if ! grep -q "### Client: $CLIENT_TO_REMOVE" "$WG_CONFIG"; then log_error "Client '$CLIENT_TO_REMOVE' not found." return fi # Backup config cp "$WG_CONFIG" "${WG_CONFIG}.bak" # Remove the block from config # We use a more robust sed command that handles the block structure # It deletes from the line containing "### Client: NAME" up to the next blank line sed -i "/### Client: $CLIENT_TO_REMOVE/,/^$/d" "$WG_CONFIG" # Also clean up any potential double empty lines left behind sed -i '/^$/N;/^\n$/D' "$WG_CONFIG" # Reload WireGuard wg syncconf "$SERVER_WG_NIC" <(wg-quick strip "$SERVER_WG_NIC") # Remove config file rm -f "$INSTALL_DIR/clients/$CLIENT_TO_REMOVE.conf" echo -e "${GREEN}Client $CLIENT_TO_REMOVE removed.${NC}" } view_usage_logs() { echo -e "${BLUE}=== Bandwidth Usage ===${NC}" # Header printf "%-20s | %-15s | %-15s | %-20s\n" "Client Name" "Data Received" "Data Sent" "Last Handshake" echo "--------------------------------------------------------------------------------" # Get dump DUMP=$(wg show "$SERVER_WG_NIC" dump) # Iterate over clients in config to map names to keys # Grep Client Names CLIENT_NAMES=$(grep "### Client:" "$WG_CONFIG" | cut -d ' ' -f 3) for NAME in $CLIENT_NAMES; do # Get Public Key for this client from config # We need to read the config file more smartly. # Let's assume the structure: # ### Client: NAME # [Peer] # PublicKey = KEY # Extract Public Key for the specific client PUB_KEY=$(sed -n "/### Client: $NAME/,/PublicKey/p" "$WG_CONFIG" | grep "PublicKey" | cut -d ' ' -f 3) if [[ -n "$PUB_KEY" ]]; then # Find stats in dump # Dump format: public-key preshared-key endpoint allowed-ips latest-handshake transfer-rx transfer-tx persistent-keepalive STATS=$(echo "$DUMP" | grep "$PUB_KEY") if [[ -n "$STATS" ]]; then RX_BYTES=$(echo "$STATS" | awk '{print $6}') TX_BYTES=$(echo "$STATS" | awk '{print $7}') LAST_HANDSHAKE=$(echo "$STATS" | awk '{print $5}') # Convert Bytes RX_HUMAN=$(numfmt --to=iec-i --suffix=B "$RX_BYTES") TX_HUMAN=$(numfmt --to=iec-i --suffix=B "$TX_BYTES") # Convert Handshake Time if [[ "$LAST_HANDSHAKE" -eq 0 ]]; then TIME_HUMAN="Never" else TIME_HUMAN=$(date -d @"$LAST_HANDSHAKE" '+%Y-%m-%d %H:%M') fi printf "%-20s | %-15s | %-15s | %-20s\n" "$NAME" "$RX_HUMAN" "$TX_HUMAN" "$TIME_HUMAN" fi fi done echo "" echo -n "Press Enter to continue..." read -r }