DEV Community

Jason Shouldice
Jason Shouldice

Posted on • Edited on • Originally published at vicistack.com

VICIdial Remote Agents: Why Calls Break Behind NAT and How to Fix It

Remote agents on VICIdial break in a specific and predictable way: one-way audio, registration drops after 30 seconds, calls that connect but go silent. The root cause is almost always NAT. VoIP was designed for local networks. The moment you put a home router between the agent and your Asterisk server, the SIP protocol lies about where packets should go, and audio stops flowing.

Here's what's happening and how to fix it.

How NAT Breaks SIP — Step by Step

  1. Agent's softphone sends a SIP REGISTER with Contact: <sip:agent@192.168.1.50:5060>
  2. Home router NATs this to the public IP, say 74.125.20.100:12345
  3. Asterisk receives the packet from 74.125.20.100:12345 but the SIP header says 192.168.1.50:5060
  4. Asterisk tries to send RTP audio to 192.168.1.50:5060 — which is unreachable
  5. Result: one-way audio or no audio

The fix is two Asterisk settings in the SIP peer configuration:

[remote-agent-template](!)
type=friend
host=dynamic
nat=force_rport,comedia
qualify=yes
qualifyfreq=30
Enter fullscreen mode Exit fullscreen mode

force_rport — Asterisk ignores the port in the SIP Via header and uses the port the packet actually arrived from. Solves the "SIP says port 5060 but NAT mapped it to 23456" problem.

comedia — Short for "connection-oriented media." Asterisk ignores the IP/port in the SDP and sends RTP to the IP/port where it actually receives RTP from the agent. Solves one-way audio.

Together they mean: "Don't trust what the SIP headers say. Look at where packets actually come from."

The externip/localnet Settings

You also need these in the [general] section of /etc/asterisk/sip.conf:

[general]
externip=YOUR_PUBLIC_IP
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
Enter fullscreen mode Exit fullscreen mode

This tells Asterisk: "If an endpoint is NOT on these local networks, use externip in outgoing SIP headers instead of the internal IP." Without this, Asterisk sends its own private IP to remote agents — causing the same NAT problem in reverse.

If your public IP changes (dynamic ISP), use externhost with a DNS name and set externrefresh=60 for automatic updates.

WebRTC vs SIP: Pick WebRTC for Remote

For centers with 25+ remote agents, WebRTC is the better default. The reduction in support tickets from NAT and firewall issues more than offsets the slight audio quality trade-off. WebRTC was designed for NAT traversal — it handles it automatically through the ICE framework. SIP was not.

WebRTC advantages:

  • Zero software installation — agents use their browser
  • Single port (443/TCP for HTTPS/WSS) instead of SIP signaling plus an RTP port range
  • DTLS-SRTP encryption by default
  • Dramatically simpler agent onboarding

WebRTC disadvantages:

  • Higher server CPU usage — transcoding between Opus (WebRTC native) and G.711 (carrier handoff)
  • Browser updates occasionally break WebRTC behavior
  • Requires valid TLS certificates on the VICIdial web server
  • Slightly higher latency compared to well-configured SIP

WebRTC Setup

Enable the WebSocket transport in /etc/asterisk/http.conf:

[general]
enabled=yes
enablestatic=yes
bindaddr=0.0.0.0
bindport=8088
tlsenable=yes
tlsbindaddr=0.0.0.0:8089
tlscertfile=/etc/letsencrypt/live/your-domain/fullchain.pem
tlsprivatekey=/etc/letsencrypt/live/your-domain/privkey.pem
Enter fullscreen mode Exit fullscreen mode

In sip.conf, add the WebSocket transport:

[general]
transport=udp,ws,wss
Enter fullscreen mode Exit fullscreen mode

For WebRTC agent peers:

[webrtc-agent](!)
type=friend
host=dynamic
transport=wss
nat=force_rport,comedia
encryption=yes
avpf=yes
icesupport=yes
dtlsenable=yes
dtlsverify=fingerprint
dtlscertfile=/etc/asterisk/keys/asterisk.pem
dtlssetup=actpass
disallow=all
allow=opus
allow=ulaw
Enter fullscreen mode Exit fullscreen mode

In VICIdial Admin, go to Phones and set the phone type to WebPhone, transport to wss, encryption to yes, ICE Support to yes. Then configure TURN server credentials in system settings.

STUN and TURN

STUN lets clients discover their own public IP. Configure it in the softphone for SIP agents: stun.l.google.com:19302 or run your own using coturn.

STUN fails in about 15% of NAT scenarios (symmetric NAT, strict corporate firewalls). TURN is the fallback — it relays all media through the server. For WebRTC, TURN is essential because browsers try direct connections first, then fall back automatically.

Install coturn:

yum install coturn -y
Enter fullscreen mode Exit fullscreen mode
# /etc/turnserver.conf
listening-port=3478
tls-listening-port=5349
listening-ip=0.0.0.0
external-ip=YOUR_PUBLIC_IP
relay-ip=YOUR_PUBLIC_IP
realm=your-vicidial-domain.com
fingerprint
lt-cred-mech
user=vicidial:a-strong-password-here
total-quota=100
cert=/etc/letsencrypt/live/your-domain/fullchain.pem
pkey=/etc/letsencrypt/live/your-domain/privkey.pem
Enter fullscreen mode Exit fullscreen mode
systemctl enable coturn && systemctl start coturn
Enter fullscreen mode Exit fullscreen mode

Firewall Rules: WebRTC Needs Far Fewer Ports

For SIP remote agents:

# SIP signaling
iptables -A INPUT -p udp --dport 5060 -j ACCEPT
iptables -A INPUT -p tcp --dport 5060 -j ACCEPT
# RTP media
iptables -A INPUT -p udp --dport 10000:20000 -j ACCEPT
# STUN/TURN
iptables -A INPUT -p udp --dport 3478 -j ACCEPT
Enter fullscreen mode Exit fullscreen mode

For WebRTC-only remote agents:

# HTTPS (WebRTC signaling via WSS)
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# TURN relay
iptables -A INPUT -p tcp --dport 3478 -j ACCEPT
iptables -A INPUT -p udp --dport 3478 -j ACCEPT
Enter fullscreen mode Exit fullscreen mode

Notice WebRTC needs far fewer open ports. That's a significant security advantage — less surface area for SIP brute-force attacks and toll fraud.

Fail2Ban for SIP Protection

# /etc/fail2ban/jail.local
[asterisk]
enabled = true
port = 5060,5061
filter = asterisk
logpath = /var/log/asterisk/messages
maxretry = 3
bantime = 86400
findtime = 600
Enter fullscreen mode Exit fullscreen mode

Generate strong SIP peer passwords (openssl rand -base64 24). Never use dictionary passwords — SIP scanning bots are constant.

The SIP ALG Problem

If you're using SIP softphones and agents have one-way audio despite correct NAT settings, the #1 cause is SIP ALG (Application Layer Gateway) on the home router. This "helpful" feature rewrites SIP headers and breaks everything.

Agents need to disable it in their router:

  • Netgear: Advanced > WAN Setup > Disable SIP ALG
  • Linksys: Security > Firewall > Disable SIP ALG
  • TP-Link: Advanced > NAT Forwarding > ALG > Disable SIP ALG

Put this in your agent setup documentation. It's the most common troubleshooting step.

Audio Quality for Home Internet

Codec Selection

Codec Bandwidth Quality Best For
G.711 (ulaw) 87 kbps Excellent Stable connections, plenty of bandwidth
G.729 31 kbps Good Low bandwidth (requires license)
Opus 6-510 kbps Excellent WebRTC — adapts dynamically

For SIP remote agents, use G.711 if bandwidth is sufficient (most home connections have plenty). For WebRTC agents, Opus is the native codec and the best choice for variable home internet.

Jitter Buffer

Jitter (variation in packet arrival time) is the primary quality killer for remote agents. Configure Asterisk's adaptive jitter buffer:

jbenable=yes
jbforce=yes
jbmaxsize=200
jbresyncthreshold=1000
jbimpl=adaptive
Enter fullscreen mode Exit fullscreen mode

The adaptive buffer adjusts based on observed network conditions — critical for home internet that varies throughout the day.

Agent Requirements

Document minimum requirements:

  • Download: 1 Mbps min (5 Mbps recommended)
  • Upload: 512 Kbps min (2 Mbps recommended)
  • Latency: under 150ms to server
  • Jitter: under 30ms
  • Packet loss: under 1%
  • Wired Ethernet strongly recommended (Wi-Fi adds jitter by design)

Troubleshooting Quick Reference

Registration drops after 30-120 seconds: Set qualifyfreq=25 (must be shorter than the NAT timeout on the agent's router). Set softphone registration expiry to 60 seconds, not 3600.

Audio choppy or robotic: Switch from Wi-Fi to wired. Reduce codec bitrate. Increase jitter buffer size. Check if ISP is throttling UDP traffic.

WebRTC won't connect: Check TLS certificates (must be valid, not expired). Verify WSS port (8089 or 443) is accessible. Ensure TURN server is running. Try a different browser — Chrome and Firefox have the best WebRTC support.

Echo or feedback: Require headsets (not laptop speakers/mic). Enable echo cancellation in softphone settings. Reduce speaker volume.

For scaling beyond 50 remote agents, consider RTPengine as a dedicated media proxy. For agents across time zones or countries, IAX2 trunking between geographically distributed Asterisk servers keeps centralized management while reducing latency.

The full walkthrough with TURN server deployment, multi-server architecture, and troubleshooting flowcharts is at ViciStack's remote agent setup guide.


Originally published at https://vicistack.com/blog/vicidial-remote-agent-setup/

Top comments (0)