#!/usr/bin/env bash # Verify UDM Pro port forwarding configuration # Documents manual steps and tests internal connectivity to NPMplus set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" [ -f "${PROJECT_ROOT}/.env" ] && source "${PROJECT_ROOT}/.env" 2>/dev/null || true [ -f "${PROJECT_ROOT}/config/ip-addresses.conf" ] && source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true EVIDENCE_DIR="$PROJECT_ROOT/docs/04-configuration/verification-evidence" # 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}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; } log_error() { echo -e "${RED}[✗]${NC} $1"; } cd "$PROJECT_ROOT" TIMESTAMP=$(date +%Y%m%d_%H%M%S) OUTPUT_DIR="$EVIDENCE_DIR/udm-pro-verification-$TIMESTAMP" mkdir -p "$OUTPUT_DIR" PUBLIC_IP="${PUBLIC_IP:-76.53.10.36}" NPMPLUS_IP="${NPMPLUS_IP:-${IP_NPMPLUS:-${IP_NPMPLUS_ETH0:-192.168.11.166}}}" echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "🔍 UDM Pro Port Forwarding Verification" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" log_info "Expected Configuration:" echo " Public IP: $PUBLIC_IP" echo " NPMplus Internal IP: $NPMPLUS_IP" echo " Rule 1: $PUBLIC_IP:443 → $NPMPLUS_IP:443 (TCP)" echo " Rule 2: $PUBLIC_IP:80 → $NPMPLUS_IP:80 (TCP)" echo "" # Test internal connectivity log_info "Testing internal connectivity to NPMplus..." HTTP_TEST=false HTTPS_TEST=false if curl -s -I --connect-timeout 5 "http://$NPMPLUS_IP:80" > "$OUTPUT_DIR/internal_http_test.txt" 2>&1; then HTTP_CODE=$(head -1 "$OUTPUT_DIR/internal_http_test.txt" | grep -oP '\d{3}' | head -1 || echo "") if [ -n "$HTTP_CODE" ]; then HTTP_TEST=true log_success "HTTP connectivity: $NPMPLUS_IP:80 responded with HTTP $HTTP_CODE" else log_warn "HTTP connectivity: $NPMPLUS_IP:80 responded but couldn't parse status" fi else log_warn "HTTP connectivity: Failed to connect to $NPMPLUS_IP:80 (expected if run from outside LAN/WSL)" fi if curl -s -I -k --connect-timeout 5 "https://$NPMPLUS_IP:443" > "$OUTPUT_DIR/internal_https_test.txt" 2>&1; then HTTPS_CODE=$(head -1 "$OUTPUT_DIR/internal_https_test.txt" | grep -oP '\d{3}' | head -1 || echo "") if [ -n "$HTTPS_CODE" ]; then HTTPS_TEST=true log_success "HTTPS connectivity: $NPMPLUS_IP:443 responded with HTTP $HTTPS_CODE" else log_warn "HTTPS connectivity: $NPMPLUS_IP:443 responded but couldn't parse status" fi else log_warn "HTTPS connectivity: Failed to connect to $NPMPLUS_IP:443 (expected if run from outside LAN/WSL)" fi # Test public IP reachability (from external, if possible) log_info "" log_info "Testing public IP reachability..." PUBLIC_HTTP_TEST=false PUBLIC_HTTPS_TEST=false if curl -s -I --connect-timeout 5 "http://$PUBLIC_IP:80" > "$OUTPUT_DIR/public_http_test.txt" 2>&1; then HTTP_CODE=$(head -1 "$OUTPUT_DIR/public_http_test.txt" | grep -oP '\d{3}' | head -1 || echo "") if [ -n "$HTTP_CODE" ]; then PUBLIC_HTTP_TEST=true log_success "Public HTTP: $PUBLIC_IP:80 responded with HTTP $HTTP_CODE" else log_warn "Public HTTP: $PUBLIC_IP:80 responded but couldn't parse status" fi else log_warn "Public HTTP: Cannot test from internal network (expected)" fi if curl -s -I -k --connect-timeout 5 "https://$PUBLIC_IP:443" > "$OUTPUT_DIR/public_https_test.txt" 2>&1; then HTTPS_CODE=$(head -1 "$OUTPUT_DIR/public_https_test.txt" | grep -oP '\d{3}' | head -1 || echo "") if [ -n "$HTTPS_CODE" ]; then PUBLIC_HTTPS_TEST=true log_success "Public HTTPS: $PUBLIC_IP:443 responded with HTTP $HTTPS_CODE" else log_warn "Public HTTPS: $PUBLIC_IP:443 responded but couldn't parse status" fi else log_warn "Public HTTPS: Cannot test from internal network (expected)" fi # Generate verification results JSON cat > "$OUTPUT_DIR/verification_results.json" < "$REPORT_FILE" <