Advanced 15 min SIP 408

408 Request Timeout in NAT Traversal

증상

- SIP INVITE times out with 408 — no ringing, no error message, just silence followed by a timeout on the calling endpoint
- One-way audio after a call connects: the caller can hear the callee but not vice versa (or vice versa), indicating RTP flow is asymmetric
- Call setup works inside the LAN but consistently fails when either party is behind a NAT router or firewall
- SIP trace (sngrep or Wireshark) shows the INVITE leaving the endpoint with a private IP (e.g., 192.168.x.x) in the Contact or Via header
- Enabling or disabling SIP ALG on the router changes the failure mode — sometimes making it worse

근본 원인

  • NAT rewrites the SIP Contact header with a private IP address, making the response from the remote SIP proxy unroutable back to the caller — the 200 OK or 180 Ringing never reaches the endpoint
  • SIP ALG (Application Layer Gateway) on the consumer router is enabled and incorrectly modifying SIP headers, corrupting Via, Contact, or SDP media addresses and causing authentication failures or routing loops
  • UDP NAT binding times out before the SIP response arrives — NAT devices typically expire UDP port mappings after 30–60 seconds, and slow SIP servers or retransmission timers exceed this window
  • STUN server is not configured or unreachable, so the endpoint cannot discover its public IP and port to insert correct Contact/SDP addresses
  • Symmetric NAT assigns a different external port for each destination, so STUN-discovered addresses do not work for peer-to-peer RTP — a TURN relay is required but not configured

진단

**Step 1: Capture a SIP trace to inspect headers**
```bash
# On the SIP server or a network tap
sngrep -d eth0 port 5060
# Or with tcpdump for Wireshark analysis
tcpdump -i eth0 -w sip-capture.pcap port 5060 or portrange 10000-20000
```
Inspect the Contact and Via headers in the INVITE — they must contain a routable public IP, not 192.168.x.x or 10.x.x.x.

**Step 2: Check if SIP ALG is enabled on the router**
```
# Most consumer routers: Administration > Advanced > SIP ALG
# Disable SIP ALG / SIP helper — it corrupts headers more often than it helps
# On Linux iptables:
sudo iptables -t raw -A OUTPUT -p udp --dport 5060 -j CT --helper sip
# To disable the nf_conntrack_sip module:
sudo rmmod nf_conntrack_sip
```

**Step 3: Test STUN reachability**
```bash
# Use stun-client to verify your STUN server returns the correct public IP
stun stun.l.google.com:19302
# Expected: External IP should match your WAN IP
curl ifconfig.me # compare with STUN result
```

**Step 4: Check NAT type with STUN**
```bash
# Install stuntman for NAT type detection
stunserver --mode full
stunclient --mode full stun.example.com
# Result: Full Cone, Restricted, Port-Restricted, or Symmetric NAT
# Symmetric NAT requires TURN relay for RTP
```

**Step 5: Verify RTP port range is reachable**
```bash
# Check firewall allows RTP range
sudo iptables -L -n | grep -E '(10000|20000)'
# Test UDP reachability from outside
nc -u -z your-public-ip 10000
```

해결

**Fix 1: Disable SIP ALG on the router**

Log into the router admin panel and disable SIP ALG, SIP Helper, or SIP Passthrough (terminology varies by manufacturer). After disabling, restart both the router and the SIP phone/softphone.

**Fix 2: Configure STUN on the SIP endpoint**
```ini
# In Asterisk sip.conf or pjsip.conf
[general]
stunaddr=stun.l.google.com:19302
externip=auto ; or set to your WAN IP explicitly
localnet=192.168.0.0/255.255.0.0
localnet=10.0.0.0/255.0.0.0
localnet=172.16.0.0/255.240.0.0
```

**Fix 3: Use a Session Border Controller (SBC) as SIP outbound proxy**

Configure the SIP endpoint to register through an SBC or SIP proxy that sits in the public internet. The SBC handles NAT traversal transparently so endpoints behind NAT do not need STUN/TURN themselves.

**Fix 4: Configure TURN relay for symmetric NAT**
```ini
# In WebRTC or ICE-capable SIP clients
turn_server=turn.example.com:3478
turn_username=user
turn_password=secret
# In Asterisk (ICE support via res_pjsip)
ice_support=yes
```

**Fix 5: Keep NAT bindings alive with SIP keep-alives**
```ini
# Asterisk pjsip.conf — send OPTIONS keep-alives every 30s
[transport-udp]
type=transport
protocol=udp
keepalive_interval=30
```

예방

- **Disable SIP ALG by default** on all NAT routers in VoIP deployments — it causes more problems than it solves in modern SIP implementations
- **Use an SBC or SIP proxy** in the DMZ so all SIP traffic flows through a known public IP — endpoints register to the SBC, which handles NAT
- **Set short SIP re-registration intervals** (30–60 seconds) to keep NAT bindings alive and detect connectivity issues before calls fail
- **Open and forward RTP port ranges** (typically UDP 10000–20000) on the firewall to prevent media blackouts even when signaling succeeds
- **Test NAT traversal during setup** using sngrep or a SIP test call from outside the LAN before going to production

관련 상태 코드

관련 용어