CR: IOT_WAN VPN Passthrough — Implementation
Change 1: Enable Default Drop Logging
Justification
IOT_WAN default-action is drop but default-log was not enabled. All dropped packets were silent — no log entries in show log firewall. This is a visibility gap that prevented detection of the VPN issue and any other outbound IoT traffic being silently blocked.
Pre-Verification
# Verify current state — default-log not set
show configuration commands | grep "IOT_WAN default"
set firewall ipv4 name IOT_WAN default-action 'drop' # NO default-log line present
# Confirm no IOT_WAN entries in firewall log
show log firewall | grep "IOT_WAN" | tail -5
(empty — no logged drops)
Change Commands
configure
set firewall ipv4 name IOT_WAN default-log
commit
save
Post-Verification
# Verify default-log is set
show configuration commands | grep "IOT_WAN default"
set firewall ipv4 name IOT_WAN default-action 'drop' set firewall ipv4 name IOT_WAN default-log
# Verify drops now appear in log (generate traffic from IoT device if needed)
show log firewall | grep "IOT_WAN" | tail -5
Status
Applied — 2026-04-07 ~11:30 PST
Change 2: Add IPsec VPN Passthrough Rules
Justification
Palo Alto GlobalProtect VPN requires IPsec protocols for data transport after the initial SSL/TLS handshake on TCP 443:
| Protocol | Port/ID | Purpose |
|---|---|---|
ESP |
IP Protocol 50 |
Encapsulated Security Payload — the encrypted data tunnel carrying all user traffic |
UDP 4501 |
Destination port |
IPsec NAT Traversal — used when the VPN client is behind NAT (which IoT devices are, via VyOS masquerade rule 140) |
UDP 500 |
Destination port |
Internet Key Exchange (IKE) — negotiates encryption keys for the IPsec tunnel |
Without these protocols, the VPN handshake completes (TCP 443 allowed) but the data tunnel fails silently. Users see "VPN Connected" but cannot access any resources.
Pre-Verification
# Verify current IOT_WAN rules (should show rules 10-70 only)
show firewall ipv4 name IOT_WAN
# Confirm no ESP/4501/500 rules exist
show configuration commands | grep "IOT_WAN rule 8\|IOT_WAN rule 9"
(empty — rules 80/85/90 do not exist yet)
Proof — Firewall Drop Log Evidence (Captured 2026-04-07 12:00 PST)
After enabling default-log on IOT_WAN (Change 1), the user on Domus-IoT (10.50.40.146) attempted to connect GlobalProtect VPN. The following drops were captured:
show log firewall | grep "IOT_WAN" | tail -20
# GlobalProtect VPN gateway — TCP 2443 DROPPED Apr 07 12:00:53 [ipv4-NAM-IOT_WAN-default-D] SRC=10.50.40.146 DST=162.115.35.40 PROTO=TCP SPT=49363 DPT=2443 SYN Apr 07 12:00:54 [ipv4-NAM-IOT_WAN-default-D] SRC=10.50.40.146 DST=162.115.35.40 PROTO=TCP SPT=49363 DPT=2443 SYN Apr 07 12:00:55 [ipv4-NAM-IOT_WAN-default-D] SRC=10.50.40.146 DST=162.115.35.40 PROTO=TCP SPT=49363 DPT=2443 SYN Apr 07 12:00:56 [ipv4-NAM-IOT_WAN-default-D] SRC=10.50.40.146 DST=162.115.35.40 PROTO=TCP SPT=49363 DPT=2443 SYN # ... repeated SYN retransmits through 12:01:28 — connection never established # Google push notifications — TCP 5228 DROPPED (separate issue) Apr 07 11:46:28 [ipv4-NAM-IOT_WAN-default-D] SRC=10.50.40.146 DST=74.125.137.188 PROTO=TCP SPT=65533 DPT=5228 SYN
Analysis of Proof
| Drop | Destination | Port/Proto | Impact |
|---|---|---|---|
|
Palo Alto GlobalProtect VPN gateway |
TCP 2443 — alternate GP portal/gateway port |
VPN cannot establish tunnel — handshake blocked at SYN |
|
Google push notification service |
TCP 5228 — Android/Chrome push |
Push notifications broken on IoT devices |
Key finding: The VPN failure occurred at two stages:
-
TCP handshake stage: GlobalProtect uses TCP 2443 for portal/gateway, blocked by
IOT_WAN(only 80,443 permitted) -
IPsec data stage: After rule 75 (TCP 2443) applied, tunnel established but UDP 4501 (IPsec NAT-T) was blocked, preventing data flow
Post-Fix Verification (2026-04-07 12:10 PST)
After applying rules 75, 80, 85, 90:
show firewall ipv4 name IOT_WAN
rule 75 { action accept; destination { port 2443 }; protocol tcp }
rule 80 { action accept; description "Allow IPsec ESP for VPN"; protocol esp }
rule 85 { action accept; description "Allow IPsec NAT-T for VPN"; destination { port 4501 }; protocol udp }
rule 90 { action accept; description "Allow IKE for VPN"; destination { port 500 }; protocol udp }
show log firewall | grep "IOT_WAN" | grep "4501\|2443" | tail -10
# All drops timestamped 12:00-12:08 — BEFORE rules applied Apr 07 12:00:53 ... DST=162.115.35.40 DPT=2443 SYN ← pre-fix Apr 07 12:01:28 ... DST=162.115.35.40 DPT=2443 SYN ← pre-fix Apr 07 12:02:13 ... DST=162.115.28.58 DPT=4501 ← pre-fix Apr 07 12:08:28 ... DST=162.115.28.58 DPT=4501 ← pre-fix # NO drops after 12:10 — rules are working
show log firewall | grep "IOT_WAN" | tail -10
# TCP 5228 — Google push notifications (not in scope) # TCP 5150 — Application service (not in scope) # TCP 5223 — Apple push notifications (not in scope) # TCP 53 — DNS over TCP (rule 50 only allows UDP 53, separate issue) # NO VPN-related drops (2443, 4501, 500, ESP)
User confirmed: GlobalProtect VPN connected and data flowing. Work resources accessible.
Proof status: VERIFIED — Rules 75, 80, 85, 90 resolved the VPN connectivity failure.
The original hypothesis (IPsec ESP/UDP 4501 blocked after tunnel) is still valid for after the tunnel establishes, but the immediate blocker is TCP 2443.
Proof-of-Concept Test Procedure (Completed)
Step 1: Enabled default-log on IOT_WAN (Change 1, applied 2026-04-07 ~11:30).
Step 2: Monitored firewall log:
tail -f /var/log/messages | grep "IOT_WAN"
Step 3: User on Domus-IoT (10.50.40.146) connected GlobalProtect VPN.
Step 4: Firewall log showed TCP 2443 SYN packets to 162.115.35.40 being dropped by IOT_WAN default action. Repeated SYN retransmits confirm the connection was never established.
Proof status: CONFIRMED — IOT_WAN is blocking the VPN gateway connection on TCP 2443.
[ipv4-NAM-IOT_WAN-default-D] SRC=10.50.40.xxx DST=<vpn-gateway-ip> PROTO=ESP [ipv4-NAM-IOT_WAN-default-D] SRC=10.50.40.xxx DST=<vpn-gateway-ip> PROTO=UDP DPT=4501
This is the proof — ESP or UDP 4501 from the IoT client dropped by IOT_WAN default action.
Step 4: If drops confirmed, proceed to apply the change.
Change Commands
configure
# Rule 75: Allow GlobalProtect VPN portal (TCP 2443) — CONFIRMED BLOCKED in proof
set firewall ipv4 name IOT_WAN rule 75 action accept
set firewall ipv4 name IOT_WAN rule 75 description 'Allow GlobalProtect VPN portal (TCP 2443)'
set firewall ipv4 name IOT_WAN rule 75 destination port 2443
set firewall ipv4 name IOT_WAN rule 75 protocol tcp
# Rule 80: Allow IPsec ESP (IP protocol 50) — encrypted data tunnel
set firewall ipv4 name IOT_WAN rule 80 action accept
set firewall ipv4 name IOT_WAN rule 80 description 'Allow IPsec ESP for VPN'
set firewall ipv4 name IOT_WAN rule 80 protocol esp
# Rule 85: Allow IPsec NAT-T (UDP 4501) — NAT traversal for IPsec
set firewall ipv4 name IOT_WAN rule 85 action accept
set firewall ipv4 name IOT_WAN rule 85 description 'Allow IPsec NAT-T for VPN'
set firewall ipv4 name IOT_WAN rule 85 destination port 4501
set firewall ipv4 name IOT_WAN rule 85 protocol udp
# Rule 90: Allow IKE (UDP 500) — IPsec key exchange
set firewall ipv4 name IOT_WAN rule 90 action accept
set firewall ipv4 name IOT_WAN rule 90 description 'Allow IKE for VPN'
set firewall ipv4 name IOT_WAN rule 90 destination port 500
set firewall ipv4 name IOT_WAN rule 90 protocol udp
# Review before committing
compare
Review the output of compare. Verify ONLY rules 80, 85, 90 are added. No other changes.
# If compare output is correct:
commit
save
Post-Verification
# 1. Verify rules are in place
show firewall ipv4 name IOT_WAN
Rule 80: accept ESP Rule 85: accept UDP DPT=4501 Rule 90: accept UDP DPT=500
# 2. Have user reconnect VPN and test
# On user device:
# - Connect GlobalProtect
# - Access work resources
# - Run: ping -c 10 <work-resource>
# - Run: curl -I https://<work-portal>
# 3. Verify rule hit counters incrementing
show firewall ipv4 name IOT_WAN
Rule 80: accept ESP — Packets > 0 Rule 85: accept UDP DPT=4501 — Packets > 0 Rule 90: accept UDP DPT=500 — Packets > 0
# 4. Verify no new default drops for VPN traffic
show log firewall | grep "IOT_WAN" | tail -10
# 5. Confirm IoT security posture unchanged
# IoT devices should NOT be able to reach internal networks
# Test from IoT device:
# ping 10.50.1.1 ← should still be blocked (IOT_LOCAL only allows DHCP/DNS)
# ping 10.50.10.x ← should still be blocked (IOT_DATA default drop)
Status
Applied — 2026-04-07 ~12:10 PST. Proof verified: no VPN-related drops after commit. User confirmed VPN functional.