; ============================================================================= ; VICIdial Remote Agent — NAT Traversal, WebRTC & Firewall Configuration ; ============================================================================= ; Generated by ViciStack — https://vicistack.com — Free VICIdial optimization ; ; WHAT THIS FILE DOES: ; Everything needed to connect remote/work-from-home agents to your ; VICIdial system: SIP NAT traversal, WebRTC softphone setup, firewall ; rules, SRTP encryption, and Kamailio edge proxy configuration. ; ; HOW TO USE: ; This file contains configurations for multiple components: ; - Asterisk (pjsip.conf / sip.conf) ; - Kamailio (optional edge proxy) ; - iptables/firewalld rules ; - WebRTC (SRTP + WSS) ; Each section is clearly marked with the target file. ; ; FULL GUIDE: ; https://vicistack.com/blog/vicidial-remote-agent-setup/ ; https://vicistack.com/blog/vicidial-sip-troubleshooting/ ; https://vicistack.com/blog/sip-registration-failed-fix/ ; https://vicistack.com/blog/asterisk-pjsip-tls-openssl3-guide/ ; ; NEED HELP? hello@vicistack.com ; ============================================================================= ; ============================================================================= ; SECTION 1: ASTERISK SIP SETTINGS FOR NAT TRAVERSAL ; ============================================================================= ; File: /etc/asterisk/pjsip.conf (or sip.conf for older installs) ; ; The #1 problem with remote agents is one-way audio caused by NAT. ; The phone registers fine, calls connect, but the agent can't hear ; the caller (or vice versa). This is because RTP media packets get ; stuck behind the agent's home router. ; ============================================================================= ; --- pjsip.conf: Global transport for remote agents --- ; If you're on PJSIP (Asterisk 16+/VICIdial 3.14+): [transport-udp] type = transport protocol = udp bind = 0.0.0.0:5060 ; Listen on all interfaces. If your server has multiple IPs, bind to ; the public-facing one specifically. external_media_address = YOUR_PUBLIC_IP ; CRITICAL: Set this to your server's public IP. Without it, Asterisk ; sends its private LAN IP in SDP, and the remote phone sends RTP to ; a non-routable address. This is the #1 cause of one-way audio. external_signaling_address = YOUR_PUBLIC_IP ; Same thing for SIP signaling packets. local_net = 10.0.0.0/8 local_net = 172.16.0.0/12 local_net = 192.168.0.0/16 ; Tell Asterisk which networks are "local." For connections from outside ; these ranges, Asterisk uses the external_media_address instead. ; --- pjsip.conf: Remote agent endpoint template --- ; Apply this to all remote agent phone entries. [remote-agent-template](!) type = endpoint transport = transport-udp context = default disallow = all allow = opus ; Opus codec: best quality-to-bandwidth ratio for remote agents. ; 20-40kbps, built-in FEC (forward error correction), handles packet ; loss better than G.711. If the agent's internet is bad, Opus adapts. allow = ulaw ; Fallback to G.711 ulaw if Opus isn't supported by their phone. direct_media = no ; CRITICAL for NAT: Force all RTP through Asterisk. Without this, ; Asterisk tries to set up direct RTP between the caller and the ; remote agent, which fails across NAT 100% of the time. force_rport = yes ; Force rport — use the source port from the incoming packet, not ; the port the phone claims in the Via header. NAT rewrites the ; source port, so the Via header is wrong. rewrite_contact = yes ; Rewrite the Contact header with the actual source IP:port. ; Same reason as force_rport — NAT changes the addressing. rtp_symmetric = yes ; Send RTP back to wherever we received it from, not where the SDP ; says to send it. This punches through NAT reliably. ice_support = yes ; ICE (Interactive Connectivity Establishment) — automatic NAT ; traversal using STUN/TURN. Enable this for WebRTC and modern ; softphones that support ICE. dtmf_mode = rfc4733 ; RFC 4733 DTMF is reliable across NAT. INFO mode can get lost. qualify_frequency = 30 ; Send OPTIONS pings every 30 seconds. This does two things: ; 1. Keeps the NAT pinhole open (most routers close idle UDP after 60s) ; 2. Monitors agent phone status — if pings fail, agent shows offline. ; --- pjsip.conf: Example remote agent --- ; Create one of these per remote phone/extension. [8001](remote-agent-template) type = endpoint auth = 8001-auth aors = 8001-aor [8001-auth] type = auth auth_type = userpass username = 8001 password = STRONG_RANDOM_PASSWORD_HERE ; Generate with: openssl rand -hex 16 ; Never reuse passwords across agents. If one gets compromised, ; you only need to change one. [8001-aor] type = aor max_contacts = 1 ; Allow only 1 registration per extension. Prevents an attacker from ; registering a rogue phone alongside the real one. remove_existing = yes ; If a new registration comes in, kick the old one. Handles cases ; where the agent's router reboots and re-registers with a new port. qualify_frequency = 30 ; --- Legacy sip.conf (for older VICIdial installs) --- ; If you're still on chan_sip, add these to the [general] section: ; [general] ; nat=force_rport,comedia ; force_rport = use actual source port (same as pjsip force_rport) ; comedia = RTP symmetric mode (same as pjsip rtp_symmetric) ; directmedia=no ; Same as pjsip direct_media=no ; externip=YOUR_PUBLIC_IP ; Same as pjsip external_media_address ; localnet=192.168.0.0/255.255.0.0 ; Same as pjsip local_net ; qualify=yes ; Keep NAT pinholes open ; ============================================================================= ; SECTION 2: WEBRTC CONFIGURATION ; ============================================================================= ; WebRTC lets agents use a browser-based softphone — no software install. ; VICIdial's built-in WebRTC phone uses the agent web interface directly. ; Requires: TLS certificate, WSS transport, SRTP. ; ; See: https://vicistack.com/blog/asterisk-pjsip-tls-openssl3-guide/ ; ============================================================================= ; --- pjsip.conf: WSS (WebSocket Secure) transport --- [transport-wss] type = transport protocol = wss bind = 0.0.0.0:8089 ; WebSocket secure port. Make sure this is open in your firewall. cert_file = /etc/asterisk/keys/asterisk.pem ; TLS certificate. Use Let's Encrypt: ; certbot certonly --standalone -d dialer.yourdomain.com ; cat /etc/letsencrypt/live/dialer.yourdomain.com/fullchain.pem \ ; /etc/letsencrypt/live/dialer.yourdomain.com/privkey.pem \ ; > /etc/asterisk/keys/asterisk.pem ; chown asterisk:asterisk /etc/asterisk/keys/asterisk.pem ; IMPORTANT: Renewal cron must regenerate the PEM and reload Asterisk. priv_key_file = /etc/asterisk/keys/asterisk.pem ; Same combined PEM file works for both. external_media_address = YOUR_PUBLIC_IP external_signaling_address = YOUR_PUBLIC_IP local_net = 10.0.0.0/8 local_net = 172.16.0.0/12 local_net = 192.168.0.0/16 ; --- pjsip.conf: WebRTC endpoint template --- [webrtc-agent-template](!) type = endpoint transport = transport-wss context = default disallow = all allow = opus ; Opus is mandatory for WebRTC — browsers don't support G.711 natively ; over WebRTC (they do over plain RTP, but not SRTP+DTLS). dtls_auto_generate_cert = yes ; Auto-generate DTLS certificate for SRTP key exchange. ; WebRTC requires encrypted media — there's no way around this. webrtc = yes ; Master switch for WebRTC support on this endpoint. ; Enables: DTLS, ICE, SRTP, AVPF media_encryption = dtls ; DTLS-SRTP encryption. Required by all browsers. direct_media = no force_rport = yes rewrite_contact = yes rtp_symmetric = yes ice_support = yes ; --- VICIdial WebRTC Phone Setup --- ; In Admin > Phones, create the WebRTC phone entry: ; Server IP: your_dialer_ip ; Dial Plan Number: 8001 ; Phone Type: WebRTC ; WebSocket URL: wss://dialer.yourdomain.com:8089/ws ; Registration: Y ; ; The agent logs in normally. The web interface detects the WebRTC ; phone config and initializes the browser audio automatically. ; Agent needs: Chrome/Firefox, headset, decent internet (1Mbps+ up/down). ; ============================================================================= ; SECTION 3: FIREWALL RULES FOR REMOTE AGENTS ; ============================================================================= ; Open only what's needed. SIP + RTP + HTTPS. ; ============================================================================= ; --- iptables rules --- ; Add to /etc/sysconfig/iptables or run directly. ; Replace YOUR_SERVER_IP with your VICIdial server's IP. ; SIP signaling (UDP 5060) ; -A INPUT -p udp --dport 5060 -j ACCEPT ; NOTE: Opening 5060 to the world invites SIP scanners. Better options: ; Option A: VPN — agents connect via WireGuard/OpenVPN, SIP stays on LAN ; Option B: Kamailio edge proxy (see Section 4) ; Option C: Restrict by agent IP (only works for static IPs) ; RTP media (UDP 10000-20000) ; -A INPUT -p udp --dport 10000:20000 -j ACCEPT ; Asterisk uses these ports for audio. The range is set in rtp.conf. ; If you narrow the range (e.g., 10000-12000), update rtp.conf to match. ; WebRTC WebSocket (TCP 8089) ; -A INPUT -p tcp --dport 8089 -j ACCEPT ; HTTPS for agent interface (TCP 443) ; -A INPUT -p tcp --dport 443 -j ACCEPT ; --- /etc/asterisk/rtp.conf --- ; Match your firewall's RTP port range: ; [general] ; rtpstart=10000 ; rtpend=20000 ; ; Default range. 10,000 ports supports ~5,000 concurrent calls. ; ; For 50 agents, you could narrow to 10000-10500. ; ; Narrower range = fewer firewall ports open = smaller attack surface. ; strictrtp=yes ; ; Drop RTP from IPs that aren't in the SDP. Prevents RTP injection attacks. ; icesupport=true ; ; Required for WebRTC ICE. ; ============================================================================= ; SECTION 4: KAMAILIO EDGE PROXY (OPTIONAL BUT RECOMMENDED) ; ============================================================================= ; Kamailio sits between the internet and Asterisk. It handles: ; - SIP registration from remote agents ; - NAT keep-alive ; - SIP attack filtering (stops scanners before they hit Asterisk) ; - TLS termination ; - Load balancing across multiple Asterisk servers ; ; See: https://vicistack.com/blog/vicidial-kamailio-load-balancing/ ; ; Install: yum install kamailio kamailio-tls kamailio-websocket ; Config: /etc/kamailio/kamailio.cfg ; ============================================================================= ; --- Minimal Kamailio config for SIP proxy --- ; This is a simplified version. Full config is in the blog post above. ; # kamailio.cfg snippet — NAT handling module ; loadmodule "nathelper.so" ; loadmodule "rtpproxy.so" ; modparam("nathelper", "natping_interval", 30) ; ; Ping registered endpoints every 30s to keep NAT open. ; modparam("nathelper", "sipping_bflag", 7) ; modparam("registrar", "received_avp", "$avp(RECEIVED)") ; ; # Route: fix NATted contacts on registration ; route[NATDETECT] { ; force_rport(); ; if (nat_uac_test("19")) { ; fix_nated_contact(); ; setbflag(7); # mark for NAT pinging ; } ; } ; ; # Route: fix NATted SDP in INVITE ; route[NATMANAGE] { ; if (is_request()) { ; if (nat_uac_test("19")) { ; fix_nated_sdp("7"); # rewrite SDP with actual IP ; } ; } ; } ; ============================================================================= ; SECTION 5: REMOTE AGENT TROUBLESHOOTING ; ============================================================================= ; ; Problem: One-way audio (agent hears caller but caller can't hear agent) ; Fix: Check direct_media=no, rtp_symmetric=yes, external_media_address ; Then check the agent's router — some routers have "SIP ALG" which ; mangles SIP packets. DISABLE SIP ALG on the router. ; Common routers: Netgear, Linksys, ASUS all have SIP ALG on by default. ; ; Problem: Registration drops every 30-60 seconds ; Fix: The router's NAT timeout is shorter than the registration expiry. ; Set qualify_frequency=15 to send keep-alives more often. ; Or set the phone's registration expiry to 60 seconds. ; ; Problem: Calls connect but audio is choppy/robotic ; Fix: The agent's internet is congested. Check with a VoIP quality test ; (voiptest.org). They need: <150ms latency, <1% packet loss, ; >500kbps dedicated bandwidth. If they're on WiFi, try ethernet. ; Switch to Opus codec (better packet loss handling than G.711). ; ; Problem: WebRTC phone won't connect ; Fix: Check: 1) Valid TLS cert (not self-signed, browsers reject it) ; 2) WSS port 8089 is open in firewall ; 3) Phone config has the correct wss:// URL ; 4) No corporate proxy blocking WebSocket connections ; 5) Try incognito mode (browser extensions can break WebRTC) ; ; Problem: SIP scanner attacks / phantom calls ; Fix: See vicidial-security-hardening.conf in this template set. ; Immediate: fail2ban on port 5060, strong SIP passwords. ; ; For remote agent setup assistance: ; https://vicistack.com — hello@vicistack.com ; =============================================================================