Tools: VICIdial Asterisk Configuration: SIP, Codecs & NAT
Channel Drivers: chan_sip vs PJSIP (And Why VICIdial Uses Both)
chan_sip: The Legacy Default
PJSIP: Required for WebRTC
The Coexistence Configuration
Codec Configuration: What to Use and When
G.711 ulaw (PCMU) — The North American Default
G.711 alaw (PCMA) — The International Default
G.729 — For Bandwidth-Constrained Links
Opus — The WebRTC Codec
Codec Priority in Carrier Trunks
sip.conf NAT Settings (chan_sip)
Per-Peer NAT Settings
STUN/TURN for Remote Agents
Cluster NAT: The Private Network Shortcut
Trunk Configuration: From VICIdial Admin to sip.conf
Adding a Carrier in VICIdial Admin
Registration Strings
Codec Priority in Trunk Definitions
DTMF Mode
Dialplan Internals: What VICIdial Generates in extensions.conf
The Core Contexts
How an Outbound Call Flows
Custom Dialplan Additions
Security Hardening: Protecting Asterisk on the Public Internet
fail2ban for SIP
iptables Rules for SIP
SIP Registration ACLs
TLS/SRTP for SIP
Asterisk Module Management
Essential Modules for VICIdial
Modules to Disable
Monitoring and Diagnostics
The Essential CLI Commands
AMI Events for Monitoring
SIP Debug Mode
Common Issues and Fixes
One-Way Audio
Registration Failures
Certificate Issues (WebRTC)
Audio Quality Degradation
"All Circuits Busy" on Outbound Calls
astguiclient.conf: The Bridge Between VICIdial and Asterisk
Where ViciStack Fits In
Frequently Asked Questions
Should I switch from chan_sip to PJSIP for all my trunks?
What's the best codec for VICIdial?
Why do my remote agents keep getting one-way audio?
How many SIP channels does my trunk need?
How do I debug SIP registration failures?
Does Asterisk configuration differ in a VICIdial cluster?
How do I monitor Asterisk performance in production?
What happens to my Asterisk configuration when I update VICIdial via SVN? You finished the VICIdial install, agents can log in, and you've got a SIP trunk registered. Then the real problems start. One-way audio on half your calls. Registration drops every 90 seconds. Your carrier complains about codec mismatches. Remote agents hear nothing. And every forum thread you find says "check your NAT settings" without telling you what that actually means. This is the Asterisk configuration guide that VICIdial operators actually need. VICIdial is, at its core, a sophisticated wrapper around Asterisk — the open-source PBX that handles every call, every transfer, every recording, every piece of audio that flows through your contact center. The VICIdial admin GUI manages campaigns, agents, and lists. But underneath all of that, Asterisk is doing the actual telephony work. And Asterisk's configuration determines whether your calls sound crystal clear or like they're being routed through a tin can on a string. We've configured Asterisk on hundreds of VICIdial deployments — from 5-agent shops to 500-agent clusters processing over a million calls per day. This guide covers everything: channel drivers, codec selection, NAT traversal, trunk configuration, dialplan structure, security hardening, module management, and the diagnostic commands that will save you at 2 AM when calls stop connecting. Asterisk has two SIP channel drivers, and understanding which one VICIdial uses — and when — is foundational to every configuration decision that follows. VICIdial has used chan_sip since the beginning. Every SIP trunk, every phone registration, every carrier connection in a standard VICIdial installation runs through chan_sip. The configuration lives in /etc/asterisk/sip.conf, and VICIdial's installer generates most of it automatically. Why does VICIdial still default to chan_sip? Because it works. It has been battle-tested across 14,000+ VICIdial installations for over 15 years. Matt Florell and the VICIdial development team know its behavior intimately — every edge case, every quirk, every workaround. Switching the entire platform to PJSIP would mean regression-testing every call flow, every transfer scenario, every conference bridge interaction. That's a massive engineering effort for a project maintained by a small team. But here's the critical timeline: Asterisk 21 removes chan_sip entirely. It's gone. Not deprecated — removed from the source tree. Asterisk 20 is the last LTS release that includes it, with full support through 2026 and security fixes through 2027. If you're deploying VICIdial today on Asterisk 18 (the recommended version), you have runway. But this is not a problem you can defer indefinitely. PJSIP is Asterisk's modern SIP stack. It runs as res_pjsip and its configuration lives in /etc/asterisk/pjsip.conf. In VICIdial, PJSIP serves one primary purpose: WebRTC support for ViciPhone. ViciPhone — VICIdial's browser-based softphone — requires WebSocket transport (WSS) for SIP signaling and DTLS-SRTP for encrypted media. chan_sip doesn't support either. So VICIdial runs both channel drivers simultaneously: chan_sip handles trunks and traditional SIP phones, while PJSIP handles WebRTC connections from ViciPhone. This dual-driver architecture means you need to be careful about port conflicts. By default: If both try to bind to the same port, one fails silently and you spend an afternoon wondering why registrations work intermittently. The fix: VICIdial's installer handles this correctly on fresh installs with WebRTC enabled. But if you're retrofitting WebRTC onto an existing installation, verify that the ports don't collide. Run asterisk -rx "sip show settings" and asterisk -rx "pjsip show transports" to confirm what's actually bound. Here's what a properly configured dual-driver VICIdial system looks like at the transport level: The key rule: never register the same endpoint on both drivers. A SIP trunk goes in sip.conf OR pjsip.conf, not both. A phone registers to chan_sip OR PJSIP. Mixing creates race conditions where both drivers try to handle the same INVITE and calls fail unpredictably. WebRTC Configuration Giving You Headaches?
ViciStack deploys ViciPhone with PJSIP, STUN/TURN, and certificate management pre-configured. No port conflicts, no certificate debugging. Get Your Free Assessment → Codecs determine how voice audio gets compressed for transmission. The wrong codec choice means either wasted bandwidth, degraded audio quality, or both. VICIdial supports every codec Asterisk supports, but in practice you're choosing between four options. G.711 ulaw is uncompressed audio at 64 kbps per channel. It's the default for VICIdial installations in North America and the codec your SIP trunks almost certainly prefer. Configuration in sip.conf: The disallow=all line is critical. Without it, Asterisk offers every loaded codec during SDP negotiation, and you might end up transcoding G.729 to ulaw on every call — burning CPU for no benefit. G.711 alaw is the same 64 kbps uncompressed audio, but using the A-law companding algorithm instead of u-law. It's the standard in Europe, Asia, and most countries outside North America. In sip.conf, just swap the codec: If you're running a global operation with trunks in multiple regions, allow both: Asterisk will negotiate the first matching codec. Put your preferred codec first. G.729 compresses audio to 8 kbps — one-eighth the bandwidth of G.711. The tradeoff is measurable quality loss (especially on conference bridges and transfers where audio gets re-encoded) and CPU overhead for transcoding. Critical caveat: G.729 is a licensed codec. Asterisk's built-in G.729 implementation (codec_g729) requires a per-channel license from Digium (now Sangoma). However, the open-source bcg729 library provides a free G.729 implementation that works with Asterisk. On ViciBox/AlmaLinux: Do not mix G.729 and G.711 on the same call path without understanding the transcoding cost. Every call that enters your system on G.729 from a remote agent and exits on G.711 to a carrier (or vice versa) requires real-time transcoding. At 20 agents, this is negligible. At 200 agents with 5:1 dial ratios, that's potentially 1,000 simultaneous transcoding operations — enough to measurably impact your telephony server's capacity. Opus is the modern variable-bitrate codec used by WebRTC. When agents connect via ViciPhone, the browser-to-Asterisk leg uses Opus. Asterisk then transcodes to whatever codec your trunks use (almost always G.711). You don't configure Opus in sip.conf — it's handled in the PJSIP WebRTC endpoint configuration. VICIdial's WebRTC installer sets this up automatically, but here's what the relevant pjsip.conf section looks like: The allow=opus line must come before allow=ulaw so Opus is preferred for the WebRTC leg. Asterisk handles the Opus-to-ulaw transcoding internally for the carrier leg. Performance note: Opus transcoding is heavier than G.711 passthrough. Each WebRTC agent on ViciPhone adds roughly 15-20% more CPU load per channel compared to a hardware SIP phone using ulaw. Plan your telephony server capacity accordingly — if your servers handle 20 agents on SIP phones, expect 15-17 on ViciPhone. When you configure a carrier in VICIdial Admin → Carriers, the codec priority is set in the trunk registration string or the sip.conf peer definition. Here's a real-world example for a SIP trunk: The disallow=all followed by allow=ulaw and allow=alaw tells Asterisk to offer ulaw first, fall back to alaw if the carrier doesn't support ulaw. Most North American VoIP carriers support both, but some international routes only do alaw. Always match your trunk codec config to your carrier's documentation. Codec mismatches cause either failed calls (if no common codec exists) or unnecessary transcoding (if Asterisk accepts a codec and then has to transcode for the agent leg). If you've ever had "one-way audio" on a VICIdial system, you've had a NAT problem. If you've had agents who can hear the customer but the customer can't hear them, that's NAT. If calls connect fine for 30 seconds and then go silent, that's probably NAT. NAT traversal issues account for more VICIdial support tickets than every other Asterisk configuration problem combined. Here's why: SIP was designed in the 1990s when every device had a public IP address. The protocol embeds IP addresses directly into signaling messages (SDP bodies). When a server behind a NAT sends a SIP INVITE, it advertises its private IP (10.x.x.x, 172.16.x.x, 192.168.x.x) in the SDP. The remote side tries to send RTP audio to that private IP, the packets hit the NAT boundary, and the audio disappears into the void. The three critical settings in sip.conf [general]: externip tells Asterisk what public IP to substitute into SDP bodies when communicating with endpoints outside the localnet ranges. Without this, every call to/from a carrier on the public internet will have audio issues. localnet defines which networks are "inside" the NAT. Asterisk uses the original private IPs for traffic within these ranges (server-to-server in a cluster) and substitutes externip for everything else. nat=force_rport,comedia is the nuclear option for NAT — and it's the right one for VICIdial. force_rport makes Asterisk ignore the port in the Via header and use the port the packet actually arrived from. comedia makes Asterisk send RTP to the address and port where it receives RTP from, rather than where the SDP says to send it. Together, these settings handle 95% of NAT scenarios. If your server has a dynamic public IP (cloud instances, some colo providers), use externhost instead: Asterisk will resolve the hostname every 60 seconds to get the current IP. For SIP trunks and phones that are behind NAT (which is almost all of them in 2026), set NAT handling on the peer definition: The qualify=yes with qualifyfreq=30 sends OPTIONS packets every 30 seconds. This serves two purposes: it tells you if the peer is reachable (status shows in sip show peers), and — critically — it keeps the NAT pinhole open. Without qualify, many NAT gateways close the UDP mapping after 60-90 seconds of inactivity, causing registration drops and call failures. When agents connect from home networks — behind consumer routers, hotel WiFi, corporate firewalls — the NAT situation gets significantly worse. Double NAT, symmetric NAT, and restrictive firewalls can defeat force_rport,comedia because the RTP port mapping changes unpredictably. This is where STUN and TURN servers become essential, particularly for WebRTC connections via ViciPhone. STUN (Session Traversal Utilities for NAT) helps clients discover their public IP and port mapping. It works for most consumer NAT scenarios but fails with symmetric NAT. TURN (Traversal Using Relays around NAT) relays all media through a server with a public IP. It works in every scenario but adds latency and bandwidth cost because all audio routes through the TURN server. For ViciPhone/WebRTC, configure STUN/TURN in the VICIdial admin under System Settings → WebRTC: Deploy your own TURN server. Don't rely on public STUN servers for production traffic. Install coturn on a dedicated VM with a public IP: Minimal /etc/turnserver.conf: The TURN server needs bandwidth — every active WebRTC call relayed through TURN uses roughly 100-200 kbps in each direction. For 50 remote WebRTC agents, provision at least 20 Mbps on the TURN server. In a VICIdial cluster, inter-server communication (IAX2 between dialers, MySQL connections to the database server) should happen on a private network with no NAT involved. Use dual NICs: This eliminates an entire category of audio issues. Calls that transfer between dialers in a cluster use IAX2 over the private network, and IAX2 handles NAT far better than SIP because it multiplexes signaling and media on a single port. One-Way Audio Is a Solved Problem.
Every ViciStack deployment ships with externip, localnet, STUN/TURN, and dual-NIC configuration verified before your first call. See How We Do It → Configuring SIP trunks in VICIdial involves two layers: the VICIdial admin GUI (Carriers page) and the underlying Asterisk configuration files. Navigate to Admin → Carriers and create a new entry. The critical fields: The Account Entry field is where you paste the actual sip.conf peer definition: When you save the carrier, VICIdial writes this configuration to the Asterisk configuration and triggers a SIP reload. You can verify the trunk registered with: And check the peer status: Some carriers require SIP registration (your server sends REGISTER to the carrier). Others use IP-based authentication (carrier whitelists your IP, no registration needed). Registration-based carrier: IP-authenticated carrier: Leave the registration string blank. Just define the peer with host=sip.carrier.com and ensure your server's IP is whitelisted on the carrier's portal. Registration with specific Contact header (some carriers require this): Your trunk's codec priority should match what your carrier documents. Most North American VoIP carriers prefer this order: If your carrier supports G.729 and you want to conserve bandwidth on the carrier leg: Warning: Using G.729 on carrier trunks when your agents are on G.711 (or Opus via WebRTC) means every single call gets transcoded. At scale, this CPU cost is significant. Only use G.729 on trunks if bandwidth savings justify it. DTMF (touch-tone signals) configuration is a surprisingly common source of issues. If your IVR transfers aren't working, or customers can't navigate phone trees after transfer, DTMF mode mismatch is the likely culprit. Always set dtmfmode=rfc2833 unless your carrier specifically documents otherwise. VICIdial auto-generates its Asterisk dialplan — you should never manually edit extensions.conf on a VICIdial system. But understanding the structure is essential for troubleshooting call flow issues. VICIdial creates several contexts in extensions.conf. The most important: [default] — The catchall context. Inbound calls from carriers land here. VICIdial routes them based on DID matching. [trunkinbound] — Where carrier trunks deliver inbound calls. This context is referenced in the carrier peer definition (context=trunkinbound). [vicidial-auto] — The outbound auto-dial context. When the predictive dialer places a call, it originates through this context. The dialplan here handles answer detection, AMD processing, and routing to agents. [vicidial-auto-agent] — After a call is answered (and passes AMD if enabled), it gets routed here to connect to the waiting agent via a MeetMe/ConfBridge conference. If you need custom dialplan logic (after-hours routing, custom IVR flows, special transfer destinations), add it to extensions_custom.conf — not extensions.conf. VICIdial overwrites extensions.conf on reload, but extensions_custom.conf is included via #include and survives updates. A VICIdial server with SIP ports open to the internet is a target. SIP scanning bots hit every public IP on port 5060 continuously. Without hardening, you'll see registration attempts from random IPs within hours of deployment, and a successful breach means toll fraud — someone making international calls on your trunks at your expense. fail2ban monitors Asterisk logs for failed authentication attempts and blocks offending IPs via iptables. ViciBox includes a pre-configured fail2ban jail for Asterisk, but if you're on a custom install: This bans any IP that fails 3 authentication attempts within 10 minutes, for 24 hours. For production systems, consider bantime = -1 (permanent) and a whitelist for your known IPs. Verify fail2ban is working: Don't rely solely on fail2ban. Use iptables to restrict SIP access to known IP ranges: RTP ports must be open to all sources. You can't restrict RTP to known IPs because carriers route media from different IPs than signaling, and NATed agents send RTP from unpredictable source addresses. The SIP layer is where you lock things down. In sip.conf, use permit and deny to restrict which IPs can register: For individual peers, add ACLs: If your carrier supports SIP over TLS (and most modern carriers do), enable it: For the carrier peer: Note: TLS encrypts SIP signaling. SRTP (encryption=yes) encrypts the audio. For full encryption, you need both. But SRTP adds CPU overhead — roughly 10-15% per channel. Factor this into your server capacity planning. Asterisk loads dozens of modules at startup. VICIdial only needs a subset of them, and unnecessary modules waste memory and can cause conflicts. The module configuration lives in /etc/asterisk/modules.conf. The ConfBridge migration matters here. If you're on Asterisk 18 and have enabled ConfBridge (which you should for new deployments), you still need app_meetme.so loaded because VICIdial's code references both. Set mixing_interval=20 in confbridge.conf as noted in the cluster guide to prevent RTP packet ordering issues. To check what's currently loaded: When calls stop working at 2 AM, you need to know exactly which Asterisk commands give you answers fast. Connect to the Asterisk CLI: The verbosity level controls how much real-time output you see. Level 3 (vvv) shows call setup and teardown. Level 5 (vvvvv) shows SIP message details. Level 10+ shows everything including RTP — useful for deep debugging but extremely noisy on a busy system. Check SIP trunk status: Active call monitoring: Conference monitoring (essential for VICIdial — every call is a conference): Codec negotiation debugging: The Asterisk Manager Interface (AMI) is how VICIdial communicates with Asterisk programmatically. It's also useful for external monitoring. Connect to AMI on port 5038: Login and listen for events: Key events to monitor: When you need to see the actual SIP messages (INVITE, 200 OK, BYE, etc.): Never leave SIP debug on in production. It writes massive amounts of data to the Asterisk log and can fill your disk in hours on a busy system. After hundreds of deployments and thousands of forum threads, these are the Asterisk configuration problems VICIdial operators actually hit. Symptom: Agent hears customer, customer doesn't hear agent (or vice versa). Cause: NAT. 95% of the time. Symptom: sip show registry shows "Rejected" or "Request Sent" that never resolves. Symptom: ViciPhone connects but no audio, or connection fails entirely. WebRTC requires valid TLS certificates. Self-signed certs are rejected by browsers. Use Let's Encrypt: Then create the combined PEM that Asterisk needs: Set up a cron job to renew and restart Asterisk: Symptom: Calls sound robotic, choppy, or have echo. Symptom: Dialer shows trunk errors, agents get no calls. Check trunk capacity: If this number equals your trunk's channel limit, you need more capacity. VICIdial's predictive dialer at a 5:1 ratio with 50 agents tries to maintain 250 simultaneous outbound channels. Make sure your SIP trunk supports that volume. Every VICIdial server has /etc/astguiclient.conf — the configuration file that tells VICIdial how to talk to Asterisk. Key Asterisk-related settings: The VARserver_ip is the IP this server uses for Asterisk operations. In a cluster, this must be the IP in the servers table in the VICIdial database. Get it wrong and calls originate but can't be tracked back to the right server, causing orphaned channels and ghost calls. This guide gives you everything you need to configure Asterisk correctly in VICIdial. But knowing what to configure and keeping it configured correctly across updates, certificate renewals, carrier changes, and capacity scaling are two very different problems. ViciStack ships every deployment with Asterisk pre-configured: correct NAT settings for your network topology, carrier trunks tested and verified, codec optimization for your specific carriers, fail2ban and iptables hardened, WebRTC with valid certificates and TURN servers, and ConfBridge ready for the Asterisk 21 migration. When your Asterisk configuration is right, calls connect cleanly, audio is clear, and your agents hear a human voice instead of dead air. When it's wrong, you're debugging SIP traces at 2 AM. We'd rather you not do that. Get a free Asterisk configuration audit → This guide is maintained by the ViciStack team and updated as VICIdial, Asterisk, and best practices evolve. Last updated: March 2026. Not yet. VICIdial's codebase is still primarily built around chan_sip for trunk and phone registration. Switching all trunks to PJSIP requires testing every call flow — outbound, inbound, transfers, three-way calls, and conferencing. The VICIdial development team is working on full PJSIP migration, but for production systems in 2026, the recommended approach is chan_sip for trunks and phones, PJSIP only for WebRTC/ViciPhone endpoints. Start testing PJSIP trunks in a lab environment so you're ready when the transition becomes necessary. G.711 ulaw for North American operations, G.711 alaw for international. These provide the best call quality with zero transcoding overhead. Only use G.729 when bandwidth constraints genuinely require it (remote offices on limited WAN links, international trunks with per-MB billing). For WebRTC agents on ViciPhone, Opus is used automatically and transcoded to G.711 for the carrier leg. Remote agents behind consumer NAT are the hardest audio scenario. The fix is layered: (1) externip and localnet correctly set on your Asterisk server, (2) nat=force_rport,comedia on both general and peer sections, (3) RTP ports 10000-20000 open, (4) for WebRTC agents, a properly configured TURN server. If you're using hardware SIP phones at remote locations, a SIP-aware router (like those from Grandstream or Ubiquiti) that handles SIP ALG correctly makes a significant difference. Alternatively, move remote agents to ViciPhone — WebRTC with TURN solves NAT problems more reliably than SIP through consumer routers. Multiply your agent count by your expected dial ratio. For predictive dialing at a 5:1 ratio with 50 agents, you need at least 250 simultaneous channels. Add 20% headroom for spikes, so 300 channels. Most SIP trunk providers sell in blocks or offer unlimited channels with per-minute billing. Check your provider's concurrent channel limit — it's often lower than you'd assume on basic plans. Run asterisk -rx "sip set debug peer your-carrier-name" and then trigger a registration with asterisk -rx "sip reload". Watch the output for the SIP exchange. A 401 response means authentication failure (wrong credentials). A 403 means forbidden (IP not whitelisted, or account issue). A 408 timeout means the packets aren't reaching the carrier (firewall, DNS, or routing issue). Check DNS resolution with dig sip.carrier.com and verify outbound UDP 5060 isn't blocked. Yes. In a cluster, each telephony server runs its own Asterisk instance with its own sip.conf. Key differences: (1) each server has its own externip set to its own public IP, (2) localnet includes the private cluster network, (3) IAX2 trunks between dialers use the private network IPs, (4) each server registers independently to SIP carriers (or a subset of carriers for redundancy). The database server and web servers don't run Asterisk at all. See the cluster guide for the complete architecture. Beyond the CLI commands covered above, set up automated monitoring. Use asterisk -rx "core show channels count" in a cron job piped to your monitoring system (Nagios, Zabbix, or Prometheus via the Asterisk exporter). Alert on: channel count approaching trunk limits, peer status changes (trunk going unreachable), and AMI connection failures. For call quality monitoring, enable RTCP statistics in rtp.conf with rtcpinterval=5000 and collect jitter/packet loss metrics per call. VICIdial's SVN update process (svn update followed by running the install scripts) regenerates extensions.conf and may update other Asterisk config files. This is why custom dialplan changes go in extensions_custom.conf — it survives updates. Your sip.conf trunk definitions are managed through the VICIdial admin Carriers page and get regenerated from the database, so they're safe. Manual edits to sip.conf outside of VICIdial's management (like custom global settings) should be documented so you can reapply them after updates. Better yet, put them in sip_custom.conf if your VICIdial version supports custom includes. Templates let you quickly answer FAQs or store snippets for re-use. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse