#!/usr/bin/env bash # Query UniFi Network API for firewall zones, ACL rules, traffic matching lists, DPI. # Use output to see if any rule could affect HTTP POST (RPC 405). Official API is L3/L4 only. # Usage: ./scripts/unifi/query-firewall-and-dpi-api.sh [output_dir] set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" # Load UNIFI_* from repo .env, unifi-api/.env, or ~/.env if [ -f "$PROJECT_ROOT/.env" ]; then set -a && source "$PROJECT_ROOT/.env" 2>/dev/null && set +a; fi if [ -f "$PROJECT_ROOT/unifi-api/.env" ]; then set -a && source "$PROJECT_ROOT/unifi-api/.env" 2>/dev/null && set +a; fi if [ -f ~/.env ]; then source <(grep -E '^UNIFI_' ~/.env 2>/dev/null | sed 's/^/export /') 2>/dev/null || true; fi UDM_URL="${UNIFI_UDM_URL:-https://192.168.0.1}" API_KEY="${UNIFI_API_KEY:-}" # Use UUID from sites list; default for single-site "Default" SITE_ID="${UNIFI_SITE_ID:-88f7af54-98f8-306a-a1c7-c9349722b1f6}" if [ "$SITE_ID" = "default" ]; then SITE_ID="88f7af54-98f8-306a-a1c7-c9349722b1f6" fi if [ -z "$API_KEY" ]; then echo "UNIFI_API_KEY is not set. Add it to .env or unifi-api/.env." >&2 exit 1 fi OUT_DIR="${1:-$PROJECT_ROOT/docs/04-configuration/verification-evidence/unifi-api-firewall-query}" mkdir -p "$OUT_DIR" REPORT="$OUT_DIR/report.md" BASE="$UDM_URL/proxy/network/integration/v1" echo "Querying UniFi Network API (Official) for firewall/ACL/DPI..." echo "" # Fetch and save JSON curl -k -s -X GET "$BASE/sites/$SITE_ID/acl-rules?limit=200" \ -H "X-API-KEY: $API_KEY" -H "Accept: application/json" -o "$OUT_DIR/acl-rules.json" curl -k -s -X GET "$BASE/sites/$SITE_ID/firewall/zones?limit=200" \ -H "X-API-KEY: $API_KEY" -H "Accept: application/json" -o "$OUT_DIR/firewall-zones.json" curl -k -s -X GET "$BASE/sites/$SITE_ID/traffic-matching-lists?limit=200" \ -H "X-API-KEY: $API_KEY" -H "Accept: application/json" -o "$OUT_DIR/traffic-matching-lists.json" curl -k -s -X GET "$BASE/dpi/categories?limit=100" \ -H "X-API-KEY: $API_KEY" -H "Accept: application/json" -o "$OUT_DIR/dpi-categories.json" curl -k -s -X GET "$BASE/sites/$SITE_ID/wans" \ -H "X-API-KEY: $API_KEY" -H "Accept: application/json" -o "$OUT_DIR/wans.json" # Build report { echo "# UniFi API firewall/ACL/DPI query report" echo "" echo "Generated: $(date -Iseconds)" echo "Site ID: $SITE_ID" echo "Base: $BASE" echo "" echo "## Summary" echo "" ACL_COUNT=$(jq -r '.totalCount // .count // 0' "$OUT_DIR/acl-rules.json" 2>/dev/null || echo "0") ZONE_COUNT=$(jq -r '.totalCount // .count // 0' "$OUT_DIR/firewall-zones.json" 2>/dev/null || echo "0") TML_COUNT=$(jq -r '.totalCount // .count // 0' "$OUT_DIR/traffic-matching-lists.json" 2>/dev/null || echo "0") DPI_COUNT=$(jq -r '.totalCount // .count // 0' "$OUT_DIR/dpi-categories.json" 2>/dev/null || echo "0") echo "- **ACL rules:** $ACL_COUNT (user-defined L3/L4 rules)" echo "- **Firewall zones:** $ZONE_COUNT" echo "- **Traffic matching lists:** $TML_COUNT" echo "- **DPI categories:** $DPI_COUNT" echo "" echo "## HTTP POST (RPC 405) and this API" echo "" echo "The **Official UniFi Network API** exposes:" echo "- **ACL rules:** L3/L4 only (protocol TCP/UDP, ports, source/dest). No HTTP method (GET vs POST)." echo "- **Firewall zones:** Grouping of networks (Internal, External, etc.). No method filtering." echo "- **Traffic matching lists:** Port/IP lists. No HTTP method." echo "- **DPI categories:** Application categories for app-based blocking (e.g. \"Web services\"). Not method-specific." echo "" echo "**Conclusion:** The 405 Method Not Allowed for RPC POST is **not** configurable or visible via this API. It is likely enforced by the device's port-forward/NAT layer or a built-in proxy that does not expose HTTP-method settings in the API. To fix RPC 405: allow POST on the edge (UDM Pro UI / firmware) or use Cloudflare Tunnel for RPC (see docs/05-network/E2E_RPC_EDGE_LIMITATION.md)." echo "" echo "## Output files" echo "" echo "- \`acl-rules.json\` - ACL rules (empty if no custom rules)" echo "- \`firewall-zones.json\` - Zone definitions" echo "- \`traffic-matching-lists.json\` - Port/IP lists" echo "- \`dpi-categories.json\` - DPI app categories" echo "- \`wans.json\` - WAN interfaces" } > "$REPORT" echo "Report: $REPORT" echo "JSON: $OUT_DIR/*.json" cat "$REPORT"