CR: IOT_WAN VPN Passthrough and Drop Logging

Change Summary

Field Value

CR ID

CR-2026-04-07-iot-wan-vpn-passthrough

Date

2026-04-07

Priority

P2 - High

Type

Firewall Policy Change

Status

Complete — all 4 rules applied and verified

Requestor

Evan Rosado

Implementor

Evan Rosado

Risk Level

Low (outbound-only rules, no inbound changes, IoT security posture preserved)

Systems Affected

VyOS vyos-01 — firewall ipv4 name IOT_WAN

Related Incident

INC-2026-04-06-001: Domus-IoT VPN Connectivity

Objective

  1. Enable drop logging on IOT_WAN to provide visibility into blocked outbound traffic from the IoT VLAN (10.50.40.0/24)

  2. Add IPsec protocol rules (ESP, UDP 4501, UDP 500) to IOT_WAN to permit Palo Alto GlobalProtect VPN data transport

Background

Users on the Domus-IoT VLAN cannot use Palo Alto GlobalProtect work VPN. The tunnel handshake succeeds on TCP 443 (permitted by IOT_WAN rule 20), but after authentication the VPN client transitions to IPsec for data transport. IPsec uses ESP (IP protocol 50), UDP 4501 (NAT Traversal), and UDP 500 (IKE key exchange) — none of which are permitted by IOT_WAN. The default action is drop.

Additionally, IOT_WAN had no default-log enabled, meaning all drops were silent — no log entries, no visibility. This allowed the issue to persist undetected.

Comparison: DATA_WAN has default-action: accept, so VPN works from the DATA VLAN. Only IoT is affected due to its restrictive allow-list policy.

IOT_WAN Policy Summary (After Both Changes)

Rule Description Protocol/Port Status

10

Established/related

stateful

Existing

20

HTTP/HTTPS

TCP 80,443

Existing

30

NTP

UDP 123

Existing

40

ICMP

icmp

Existing

50

DNS

UDP 53

Existing

60

CAPWAP control

UDP 5246

Existing

70

CAPWAP data

UDP 5247

Existing

75

GlobalProtect VPN portal

TCP 2443

New — PROOF CONFIRMED

80

IPsec ESP

protocol esp

New (pending)

85

IPsec NAT-T

UDP 4501

New (pending)

90

IKE

UDP 500

New (pending)

default

Drop + log

all

Logging added

API Queries — domus-api

Query this incident and its linked change record via the documentation REST API.

Start the API

cd ~/atelier/_projects/personal/domus-api && uv run uvicorn domus_api.main:app --host 0.0.0.0 --port 8080

Incident Queries

# Incident title
curl -s localhost:8080/pages/case-studies/incidents/INC-2026-04-06-domus-iot-vpn-connectivity | jq -r '.title'

# Incident content (readable plain text)
curl -s localhost:8080/pages/case-studies/incidents/INC-2026-04-06-domus-iot-vpn-connectivity | jq -r '.content' | head -80

# Search for all IOT_WAN references across the documentation system
curl -s 'localhost:8080/search?q=IOT_WAN' | jq -r '.results[] | "\(.title)\t\(.path)"'

# Search for VPN-related content
curl -s 'localhost:8080/search?q=GlobalProtect' | jq -r '.results[] | "\(.title)\t\(.path)"'

Change Record Queries

# CR title
curl -s localhost:8080/pages/case-studies/changes/CR-2026-04-07-iot-wan-vpn-passthrough | jq -r '.title'

# CR content
curl -s localhost:8080/pages/case-studies/changes/CR-2026-04-07-iot-wan-vpn-passthrough | jq -r '.content' | head -80

# List all change records
curl -s 'localhost:8080/pages?category=case-studies' | jq -r '.pages[] | select(.path | contains("changes")) | "\(.title)\t\(.path)"'

Traceability — Incident to CR

# Find all documents referencing this incident
curl -s 'localhost:8080/search?q=INC-2026-04-06-001' | jq -r '.results[] | {title, path}'

# Find the CR linked to this incident
curl -s 'localhost:8080/search?q=CR-2026-04-07-iot-wan' | jq -r '.results[] | {title, path}'

# Verify bidirectional link — incident references CR and CR references incident
curl -s localhost:8080/pages/case-studies/incidents/INC-2026-04-06-domus-iot-vpn-connectivity | jq -r '.content' | grep -i "CR-2026-04-07"
curl -s localhost:8080/pages/case-studies/changes/CR-2026-04-07-iot-wan-vpn-passthrough | jq -r '.content' | grep -i "INC-2026-04-06"

Export for Reporting

# Terminal table — all incidents
curl -s 'localhost:8080/pages?category=case-studies' | jq -r '.pages[] | select(.path | contains("incidents")) | [.title, .path] | @tsv' | column -t -s $'\t'

# Export incident as text file for email/ticket
curl -s localhost:8080/pages/case-studies/incidents/INC-2026-04-06-domus-iot-vpn-connectivity | jq -r '.content' > /tmp/INC-2026-04-06-001-report.txt

# Export CR as text file
curl -s localhost:8080/pages/case-studies/changes/CR-2026-04-07-iot-wan-vpn-passthrough | jq -r '.content' > /tmp/CR-2026-04-07-report.txt

Metadata

Field Value

CR ID

CR-2026-04-07-iot-wan-vpn-passthrough

Author

Evan Rosado

Created

2026-04-07

Last Updated

2026-04-07

Status

Complete — All changes applied and verified 2026-04-07 12:10 PST