chore: initial commit of wgtool
This commit is contained in:
295
validate_config.sh
Executable file
295
validate_config.sh
Executable file
@@ -0,0 +1,295 @@
|
||||
#!/bin/bash
|
||||
|
||||
# WireGuard Configuration Validator
|
||||
# This script validates WireGuard configuration files for common issues
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_status() {
|
||||
echo -e "${GREEN}[PASS]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[FAIL]${NC} $1"
|
||||
}
|
||||
|
||||
print_header() {
|
||||
echo -e "${BLUE}================================${NC}"
|
||||
echo -e "${BLUE}$1${NC}"
|
||||
echo -e "${BLUE}================================${NC}"
|
||||
}
|
||||
|
||||
# Function to validate IP address format
|
||||
validate_ip() {
|
||||
local ip=$1
|
||||
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/[0-9]{1,2}$ ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to validate port number
|
||||
validate_port() {
|
||||
local port=$1
|
||||
if [[ $port =~ ^[0-9]+$ ]] && [ $port -ge 1 ] && [ $port -le 65535 ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
# Function to validate WireGuard key format
|
||||
validate_wg_key() {
|
||||
local key=$1
|
||||
# WireGuard keys are base64 encoded and typically 44 characters long
|
||||
if [[ $key =~ ^[A-Za-z0-9+/]{43}=$ ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to validate endpoint format
|
||||
validate_endpoint() {
|
||||
local endpoint=$1
|
||||
if [[ $endpoint =~ ^[a-zA-Z0-9.-]+:[0-9]+$ ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to validate a single configuration file
|
||||
validate_config_file() {
|
||||
local config_file=$1
|
||||
local errors=0
|
||||
local warnings=0
|
||||
|
||||
print_header "Validating: $config_file"
|
||||
|
||||
if [ ! -f "$config_file" ]; then
|
||||
print_error "Configuration file not found: $config_file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check file permissions
|
||||
local perms=$(stat -c %a "$config_file")
|
||||
if [ "$perms" != "600" ]; then
|
||||
print_warning "File permissions should be 600, current: $perms"
|
||||
((warnings++))
|
||||
fi
|
||||
|
||||
# Parse the configuration file
|
||||
local in_interface=0
|
||||
local in_peer=0
|
||||
local has_interface=0
|
||||
local has_private_key=0
|
||||
local has_address=0
|
||||
local peer_count=0
|
||||
|
||||
while IFS= read -r line; do
|
||||
# Skip comments and empty lines
|
||||
if [[ $line =~ ^[[:space:]]*# ]] || [[ -z "${line// }" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check for Interface section
|
||||
if [[ $line =~ ^\[Interface\] ]]; then
|
||||
in_interface=1
|
||||
in_peer=0
|
||||
has_interface=1
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check for Peer section
|
||||
if [[ $line =~ ^\[Peer\] ]]; then
|
||||
in_interface=0
|
||||
in_peer=1
|
||||
((peer_count++))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Parse Interface section
|
||||
if [ $in_interface -eq 1 ]; then
|
||||
if [[ $line =~ ^PrivateKey[[:space:]]*=[[:space:]]*(.+)$ ]]; then
|
||||
local private_key="${BASH_REMATCH[1]}"
|
||||
if validate_wg_key "$private_key"; then
|
||||
print_status "Valid private key found"
|
||||
has_private_key=1
|
||||
else
|
||||
print_error "Invalid private key format"
|
||||
((errors++))
|
||||
fi
|
||||
elif [[ $line =~ ^Address[[:space:]]*=[[:space:]]*(.+)$ ]]; then
|
||||
local address="${BASH_REMATCH[1]}"
|
||||
if validate_ip "$address"; then
|
||||
print_status "Valid address: $address"
|
||||
has_address=1
|
||||
else
|
||||
print_error "Invalid address format: $address"
|
||||
((errors++))
|
||||
fi
|
||||
elif [[ $line =~ ^ListenPort[[:space:]]*=[[:space:]]*(.+)$ ]]; then
|
||||
local port="${BASH_REMATCH[1]}"
|
||||
if validate_port "$port"; then
|
||||
print_status "Valid listen port: $port"
|
||||
else
|
||||
print_error "Invalid listen port: $port"
|
||||
((errors++))
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Parse Peer section
|
||||
if [ $in_peer -eq 1 ]; then
|
||||
if [[ $line =~ ^PublicKey[[:space:]]*=[[:space:]]*(.+)$ ]]; then
|
||||
local public_key="${BASH_REMATCH[1]}"
|
||||
if validate_wg_key "$public_key"; then
|
||||
print_status "Valid peer public key"
|
||||
else
|
||||
print_error "Invalid peer public key format"
|
||||
((errors++))
|
||||
fi
|
||||
elif [[ $line =~ ^AllowedIPs[[:space:]]*=[[:space:]]*(.+)$ ]]; then
|
||||
local allowed_ips="${BASH_REMATCH[1]}"
|
||||
# Split multiple IPs if present
|
||||
IFS=',' read -ra IP_ARRAY <<< "$allowed_ips"
|
||||
for ip in "${IP_ARRAY[@]}"; do
|
||||
ip=$(echo "$ip" | xargs) # Trim whitespace
|
||||
if validate_ip "$ip"; then
|
||||
print_status "Valid allowed IP: $ip"
|
||||
else
|
||||
print_error "Invalid allowed IP format: $ip"
|
||||
((errors++))
|
||||
fi
|
||||
done
|
||||
elif [[ $line =~ ^Endpoint[[:space:]]*=[[:space:]]*(.+)$ ]]; then
|
||||
local endpoint="${BASH_REMATCH[1]}"
|
||||
if validate_endpoint "$endpoint"; then
|
||||
print_status "Valid endpoint: $endpoint"
|
||||
else
|
||||
print_error "Invalid endpoint format: $endpoint"
|
||||
((errors++))
|
||||
fi
|
||||
elif [[ $line =~ ^PersistentKeepalive[[:space:]]*=[[:space:]]*(.+)$ ]]; then
|
||||
local keepalive="${BASH_REMATCH[1]}"
|
||||
if validate_port "$keepalive"; then
|
||||
print_status "Valid persistent keepalive: $keepalive"
|
||||
else
|
||||
print_error "Invalid persistent keepalive: $keepalive"
|
||||
((errors++))
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done < "$config_file"
|
||||
|
||||
# Check required fields
|
||||
if [ $has_interface -eq 0 ]; then
|
||||
print_error "Missing [Interface] section"
|
||||
((errors++))
|
||||
fi
|
||||
|
||||
if [ $has_private_key -eq 0 ]; then
|
||||
print_error "Missing PrivateKey in [Interface] section"
|
||||
((errors++))
|
||||
fi
|
||||
|
||||
if [ $has_address -eq 0 ]; then
|
||||
print_error "Missing Address in [Interface] section"
|
||||
((errors++))
|
||||
fi
|
||||
|
||||
if [ $peer_count -eq 0 ]; then
|
||||
print_warning "No [Peer] sections found"
|
||||
((warnings++))
|
||||
fi
|
||||
|
||||
# Summary
|
||||
echo ""
|
||||
if [ $errors -eq 0 ] && [ $warnings -eq 0 ]; then
|
||||
print_status "Configuration file is valid!"
|
||||
return 0
|
||||
elif [ $errors -eq 0 ]; then
|
||||
print_warning "Configuration file has $warnings warning(s)"
|
||||
return 0
|
||||
else
|
||||
print_error "Configuration file has $errors error(s) and $warnings warning(s)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to validate all config files in a directory
|
||||
validate_directory() {
|
||||
local dir=$1
|
||||
local total_errors=0
|
||||
local total_files=0
|
||||
|
||||
print_header "Validating all config files in: $dir"
|
||||
|
||||
if [ ! -d "$dir" ]; then
|
||||
print_error "Directory not found: $dir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
for config_file in "$dir"/*.conf; do
|
||||
if [ -f "$config_file" ]; then
|
||||
((total_files++))
|
||||
if ! validate_config_file "$config_file"; then
|
||||
((total_errors++))
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $total_files -eq 0 ]; then
|
||||
print_warning "No .conf files found in $dir"
|
||||
else
|
||||
print_header "Validation Summary"
|
||||
echo "Total files: $total_files"
|
||||
echo "Files with errors: $total_errors"
|
||||
echo "Files without errors: $((total_files - total_errors))"
|
||||
fi
|
||||
}
|
||||
|
||||
# Show usage
|
||||
show_usage() {
|
||||
echo "Usage: $0 [OPTIONS] <config_file_or_directory>"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -h, --help Show this help message"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 wireguard_configs/test.conf # Validate single file"
|
||||
echo " $0 wireguard_configs/ # Validate all files in directory"
|
||||
echo " $0 TESTING/ # Validate TESTING directory"
|
||||
}
|
||||
|
||||
# Main logic
|
||||
if [ $# -eq 0 ] || [[ $1 =~ ^- ]]; then
|
||||
show_usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
target=$1
|
||||
|
||||
if [ -f "$target" ]; then
|
||||
validate_config_file "$target"
|
||||
elif [ -d "$target" ]; then
|
||||
validate_directory "$target"
|
||||
else
|
||||
print_error "Target not found: $target"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user