DEV Community

Moisi Trungu
Moisi Trungu

Posted on • Originally published at flixzone.icu

SIP 403 Forbidden Error — Trunk Authentication Troubleshooting

SIP 403 Forbidden Error — Trunk Authentication Troubleshooting

Master the complete diagnostic and resolution process for SIP 403 Forbidden errors affecting your ViciDial trunks and Asterisk SIP authentication

Overview

A SIP 403 Forbidden error indicates that your Asterisk server attempted to authenticate with a remote SIP trunk provider, but the credentials or authorization rules were rejected. In ViciDial production environments, this manifests as failed outbound calls, dropped inbound routes, and frustrated agents seeing "trunk unavailable" errors.

This tutorial covers the exact troubleshooting methodology used in production ViciDial deployments running hundreds of concurrent calls. You'll learn to diagnose root causes, modify configurations, validate changes, and implement monitoring to prevent future occurrences.

Prerequisites

  • Active ViciDial installation (16.x or later)
  • Root or sudo access to your Asterisk server
  • Familiarity with Linux command line and basic Asterisk concepts
  • Access to /etc/asterisk/ configuration directory
  • ViciDial MySQL database credentials
  • SIP trunk provider account details and authentication parameters
  • Working Asterisk CLI access via asterisk -rx commands

Understanding SIP 403 Forbidden in Context

What Causes 403 Forbidden Errors

A 403 Forbidden response in SIP means the upstream server understood your request but refused to authorize it. Unlike 401 (Unauthorized, requiring credentials) or 407 (Proxy Authentication Required), a 403 indicates:

  • Invalid or expired credentials
  • Username/password mismatch
  • IP authentication failure
  • Rate limiting or blacklisting
  • Missing or incorrect authentication headers
  • Codec mismatch (rarely, but possible)
  • Subscriber not authorized for that endpoint
  • Account suspension or payment issues

Where ViciDial Processes Trunk Authentication

ViciDial manages trunks through:

  1. SIP Configuration Files: /etc/asterisk/sip-vicidial.conf contains peer definitions
  2. Database: vicidial_carrier_log and trunk definitions in Asterisk dialplan
  3. Extensions Dialplan: /etc/asterisk/extensions-vicidial.conf routes calls through specific trunks
  4. Asterisk Core: Processes authentication before sending requests upstream

ViciDial Trunk Configuration Structure

Database Trunk Definition

First, verify your trunk exists in the database:

SELECT * FROM vicidial_list WHERE list_id = 'YOUR_TRUNK_ID'\G
Enter fullscreen mode Exit fullscreen mode

For carrier-level configuration, check:

SELECT carrier_id, carrier_name, auth_type, carrier_user, carrier_pass, ip_address FROM vicidial_carrier_log ORDER BY date_added DESC LIMIT 10;
Enter fullscreen mode Exit fullscreen mode

SIP Peer Configuration

Locate your trunk definition in /etc/asterisk/sip-vicidial.conf:

[mytrunksip]
type=peer
host=sip.provider.com
port=5060
username=youraccountname
secret=yourpassword
fromuser=youraccountname
fromdomain=sip.provider.com
context=from-trunk
insecure=port,invite
qualify=yes
qualifyfreq=60
canreinvite=no
dtmfmode=rfc2833
nat=force_rport,comedia
directmedia=no
Enter fullscreen mode Exit fullscreen mode

Key fields related to 403 errors:

  • username: The authentication username (must match provider account)
  • secret: The password (must match provider configuration exactly)
  • fromuser: The From: header username in outbound requests
  • fromdomain: The domain used in From: header
  • host: The upstream provider's SIP server address
  • insecure: Whether to accept requests without authentication verification

Step 1: Locate and Review SIP Trunk Logs

Enable SIP Debug Logging

First, enable full SIP debugging to capture the actual 403 response:

asterisk -rx "sip set debug on"
Enter fullscreen mode Exit fullscreen mode

Generate a test call and watch the console output in real-time:

tail -f /var/log/asterisk/messages | grep -i "sip\|forbidden\|auth"
Enter fullscreen mode Exit fullscreen mode

Capture Full SIP Trace

For detailed analysis, use tcpdump to capture the raw SIP messages:

sudo tcpdump -i any -s 0 -w /tmp/sip_trace.pcap \
  'host sip.provider.com and port 5060'
Enter fullscreen mode Exit fullscreen mode

Run a test call, then stop the capture (Ctrl+C).

Convert to readable format:

sudo tshark -r /tmp/sip_trace.pcap -Y sip -O sip > /tmp/sip_trace.txt
Enter fullscreen mode Exit fullscreen mode

Review the trace for the exact 403 response:

grep -A 5 -B 5 "403\|Forbidden" /tmp/sip_trace.txt
Enter fullscreen mode Exit fullscreen mode

Asterisk Verbose Logging

Enable Asterisk verbose mode to log SIP transactions:

asterisk -rx "core set verbose 10"
Enter fullscreen mode Exit fullscreen mode

This produces output in /var/log/asterisk/messages. Monitor during test calls:

tail -100 /var/log/asterisk/messages | grep -E "INVITE|SIP/2.0 403|Trying|Calling"
Enter fullscreen mode Exit fullscreen mode

Step 2: Validate Credentials Against Provider

Verify Provider-Supplied Values

Contact your SIP trunk provider and confirm:

  1. Account Username: Case-sensitive, no spaces
  2. Password/Secret: Exactly as configured in their system
  3. Outbound Proxy/Host: SIP server address and port
  4. Your IP Address(es): Whitelisted on their system
  5. DID/Extension: Authorized for your account
  6. Authentication Method: Digest, Basic, or IP-based

Example request to provider:

"We're receiving 403 Forbidden errors from sip.provider.com when authenticating with username 'accountname'. Can you confirm: (1) the exact password configured for this account, (2) whether IP whitelisting is enabled, (3) what our outbound IP should be, (4) the correct SIP URI format for requests?"

Test With SIPp (SIP Protocol Tester)

Use the sipp tool to test authentication independently:

sudo apt-get install sipp
Enter fullscreen mode Exit fullscreen mode

Create a test scenario file /tmp/test_sip.xml:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<scenario name="Basic SIP UAC">
  <send retrans="500">
    <![CDATA[
      INVITE sip:test@sip.provider.com SIP/2.0
      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
      From: <sip:youraccountname@yourdomain.com>;tag=[call_number]
      To: <sip:test@sip.provider.com>
      Call-ID: [call_id]
      CSeq: 1 INVITE
      Contact: <sip:[local_ip]:[local_port]>
      Max-Forwards: 70
      User-Agent: Test SIPp
      Content-Length: 0
    ]]>
  </send>
  <recv response="403" />
</scenario>
Enter fullscreen mode Exit fullscreen mode

Run the test:

sipp -sf /tmp/test_sip.xml -s sip.provider.com -p 5060 -ap youraccountname:yourpassword your_local_ip
Enter fullscreen mode Exit fullscreen mode

This tests basic SIP authentication without Asterisk complexity.

Step 3: Check Credential Configuration in ViciDial

Review SIP Configuration File

Open your trunk definition:

grep -A 20 "\[mytrunksip\]" /etc/asterisk/sip-vicidial.conf
Enter fullscreen mode Exit fullscreen mode

Look for:

username=youraccountname
secret=yourpassword
Enter fullscreen mode Exit fullscreen mode

Common mistakes:

  • Extra spaces around = sign
  • Trailing whitespace on password line
  • Password contains special characters not properly escaped
  • Wrong username or password copied from wrong provider account

Verify From: Header Construction

The From: header must match provider expectations:

fromuser=youraccountname
fromdomain=sip.provider.com
Enter fullscreen mode Exit fullscreen mode

This constructs: From: "youraccountname" <sip:youraccountname@sip.provider.com>

Provider may require:

  • Your assigned DID as fromuser
  • Your domain instead of fromdomain
  • A specific format like +1234567890@yourdomain.com

Check Extensions Dialplan

Verify your trunk is invoked correctly in /etc/asterisk/extensions-vicidial.conf:

exten => _9XXXXXXXX,1,Dial(SIP/${EXTEN:1}@mytrunksip)
exten => _9XXXXXXXX,n,Hangup()
Enter fullscreen mode Exit fullscreen mode

The @mytrunksip reference must match your peer definition exactly (case-sensitive).

Step 4: Diagnose IP and Network Issues

Verify Outbound IP Address

Your Asterisk server's outbound IP must match what the provider has whitelisted:

curl -s https://api.ipify.org
Enter fullscreen mode Exit fullscreen mode

Or from within Asterisk:

asterisk -rx "sip show settings" | grep "Bindaddr"
Enter fullscreen mode Exit fullscreen mode

Compare this IP against your provider's whitelist.

Test Network Connectivity

Verify basic connectivity to the SIP server:

ping -c 3 sip.provider.com
Enter fullscreen mode Exit fullscreen mode

Test port-level connectivity:

nc -zv sip.provider.com 5060
Enter fullscreen mode Exit fullscreen mode

Check if firewall rules permit SIP traffic:

sudo iptables -L -n | grep 5060
Enter fullscreen mode Exit fullscreen mode

For proper SIP NAT traversal, ensure:

[mytrunksip]
nat=force_rport,comedia
directmedia=no
Enter fullscreen mode Exit fullscreen mode

Verify DNS Resolution

Confirm the provider's hostname resolves correctly:

nslookup sip.provider.com
dig sip.provider.com @8.8.8.8
Enter fullscreen mode Exit fullscreen mode

DNS issues can cause timeouts that look like authentication failures.

Step 5: Resolve Common 403 Scenarios

Scenario A: Credential Mismatch

Symptom: 403 response immediately upon sending INVITE.

Resolution:

  1. Request fresh credentials from provider
  2. Update both username and secret fields:
sudo vi /etc/asterisk/sip-vicidial.conf
Enter fullscreen mode Exit fullscreen mode
  1. If password contains special characters, escape properly:
secret="pa$$w0rd@2024!"
Enter fullscreen mode Exit fullscreen mode
  1. Reload SIP configuration:
asterisk -rx "sip reload"
Enter fullscreen mode Exit fullscreen mode
  1. Test a call and monitor logs:
asterisk -rx "sip set debug on"
# Make test call
asterisk -rx "sip set debug off"
Enter fullscreen mode Exit fullscreen mode

Scenario B: IP Whitelisting

Symptom: 403 error after successful authentication attempts, only from specific network.

Resolution:

  1. Confirm your public IP:
wget -qO- https://checkip.amazonaws.com
Enter fullscreen mode Exit fullscreen mode
  1. Contact provider to whitelist this IP
  2. If using failover/redundancy, whitelist all potential outbound IPs
  3. Test after provider confirms whitelist update:
asterisk -rx "sip qualify mytrunksip"
Enter fullscreen mode Exit fullscreen mode

Scenario C: Rate Limiting/Blacklisting

Symptom: 403 after initial successful calls, becomes persistent.

Resolution:

  1. Contact provider to check if your IP is temporarily blocked
  2. Check for malformed SIP requests in your logs:
grep "malformed\|invalid\|error" /var/log/asterisk/messages | tail -20
Enter fullscreen mode Exit fullscreen mode
  1. Ensure no SIP scanning attacks from your server:
netstat -tupan | grep 5060
Enter fullscreen mode Exit fullscreen mode
  1. If provider has rate limits, implement call queuing in ViciDial dialplan to space out requests

Scenario D: Account Suspension/Expiration

Symptom: Abrupt 403 errors with no configuration changes.

Resolution:

  1. Log into provider's web portal
  2. Check account status, payment status, and service activation
  3. Verify DID/trunk subscription is current
  4. Request manual account re-activation
  5. Once confirmed active, reload SIP:
asterisk -rx "sip reload"
Enter fullscreen mode Exit fullscreen mode

Scenario E: Inbound Route Mismatch

Symptom: 403 only occurs on inbound calls; outbound works fine.

Resolution:

Inbound calls use different SIP URI matching. Check your inbound context in /etc/asterisk/extensions-vicidial.conf:

[from-trunk]
exten => 5551234567,1,Verbose("Inbound from ${CALLERID(num)}")
exten => 5551234567,n,Dial(Local/5551234567@default)
exten => 5551234567,n,Hangup()
Enter fullscreen mode Exit fullscreen mode

Ensure:

  • The inbound DID is exactly what the provider sends (with or without +1 prefix)
  • The extension is properly defined in the context
  • No invalid characters in the DID

Step 6: Test the Fix

Manual SIP Test Call

Use Asterisk's dial command directly:

asterisk -rx "channel originate SIP/5551234567@mytrunksip Application VoiceMAil"
Enter fullscreen mode Exit fullscreen mode

Monitor the response in real-time:

tail -f /var/log/asterisk/messages | grep -E "INVITE|403|200 OK|Call"
Enter fullscreen mode Exit fullscreen mode

A successful INVITE shows 200 OK response.

Agent Test Call from ViciDial

Log into the ViciDial agent screen at /agc/vicidial.php:

  1. Log in with test agent account
  2. Select a campaign with your fixed trunk
  3. Dial a test number (external cell phone or test service)
  4. Monitor the call completion

Check call logs in the database:

SELECT call_id, caller_id_number, dialed_number, call_status, 
       length_in_sec, call_date FROM vicidial_log 
WHERE dialed_number = '5551234567' 
ORDER BY call_date DESC LIMIT 5;
Enter fullscreen mode Exit fullscreen mode

Look for call_status = 'COMPLETE' or similar success indicators.

Verify SIP Qualify Status

Check if the trunk qualifies (can reach the provider):

asterisk -rx "sip show peers" | grep mytrunksip
Enter fullscreen mode Exit fullscreen mode

Output should show:

mytrunksip/sip.provider.com    sip.provider.com:5060         OK
Enter fullscreen mode Exit fullscreen mode

If showing UNREACHABLE, the trunk cannot reach the provider at all. This may indicate network issues or wrong host address.

Advanced Troubleshooting

Parse Raw SIP Headers

If you have a tcpdump capture, extract the exact failing INVITE:

sudo tshark -r /tmp/sip_trace.pcap -Y "sip.Request.Method == INVITE" \
  -T fields -e sip.From -e sip.To -e sip.Contact -e sip.User-Agent
Enter fullscreen mode Exit fullscreen mode

Compare the From:/To:/Contact: headers against provider requirements.

Check Asterisk SIP Registry

If your trunk uses outbound registration:

asterisk -rx "sip show registry"
Enter fullscreen mode Exit fullscreen mode

Output shows registration status. Registered means the trunk successfully authenticated with the provider for inbound calls.

If Request Sent or Unregistered, the trunk cannot register:

asterisk -rx "sip set debug on"
asterisk -rx "sip register mytrunksip"
Enter fullscreen mode Exit fullscreen mode

Review Authentication Digest Headers

In tcpdump analysis, look for the response to your INVITE. If it's a 407 (Proxy Authentication Required) followed by your 403 response, your credentials are wrong.

The sequence should be:

  1. INVITE (no auth) → 407 Proxy Auth Required
  2. ACK
  3. INVITE (with Authorization header) → 200 OK or 180 Ringing

If the second INVITE still returns 403, credentials are incorrect.

Extract the Authorization header from tcpdump:

tshark -r /tmp/sip_trace.pcap -Y "sip" -T fields -e sip.Authorization
Enter fullscreen mode Exit fullscreen mode

Compare the username in the Authorization header against your configured username.

Preventive Measures and Monitoring

Monitor for 403 Errors Proactively

Create a monitoring script in /usr/local/bin/check_sip_403.sh:

#!/bin/bash

LOG_FILE="/var/log/asterisk/messages"
THRESHOLD=5

# Count 403 errors in last hour
COUNT=$(grep "SIP/2.0 403" $LOG_FILE | \
  awk -v d="$(date -d '1 hour ago' '+%b %d %H')" \
  '$0 ~ d' | wc -l)

if [ $COUNT -gt $THRESHOLD ]; then
  echo "ALERT: $COUNT SIP 403 errors detected in last hour"
  # Send email, page, etc.
  # mail -s "ViciDial SIP 403 Alert" admin@example.com
  exit 1
fi

exit 0
Enter fullscreen mode Exit fullscreen mode

Make executable and add to crontab:

sudo chmod +x /usr/local/bin/check_sip_403.sh
Enter fullscreen mode Exit fullscreen mode
*/5 * * * * /usr/local/bin/check_sip_403.sh
Enter fullscreen mode Exit fullscreen mode

Document Trunk Configuration

Maintain a reference document with:

Trunk Name: mytrunksip
Provider: Provider Name
Host: sip.provider.com:5060
Username: accountname (NOT case-sensitive at provider)
Password: (hash, not plaintext) - updated DATE
From Domain: sip.provider.com
Outbound IPs: 203.0.113.45
Inbound DIDs: 555-123-4567, 555-123-4568
Support Contact: +1-555-0000
Rate Limits: 100 CPS
Last Verified: DATE
Known Issues: None
Enter fullscreen mode Exit fullscreen mode

Implement Health Checks

Add to your monitoring system (Nagios, Zabbix, etc.):

check_sip_qualify() {
  local trunk=$1
  asterisk -rx "sip show peers" | grep -q "$trunk.*OK"
}

check_sip_qualify mytrunksip && echo "OK" || echo "CRITICAL"
Enter fullscreen mode Exit fullscreen mode

Log Rotation Configuration

Ensure Asterisk logs don't fill disk, which can mask 403 errors. Check /etc/logrotate.d/asterisk:

/var/log/asterisk/messages {
    daily
    missingok
    rotate 7
    compress
    delaycompress
    notifempty
    create 0640 asterisk asterisk
    postrotate
        /usr/sbin/asterisk -rx "logger rotate" > /dev/null 2>&1 || true
    endscript
}
Enter fullscreen mode Exit fullscreen mode

Troubleshooting Decision Tree

Is the trunk showing in "sip show peers"?
├─ NO → Check sip-vicidial.conf syntax and reload
├─ YES → Does "sip show registry" show it registered?
    ├─ NO (401 or 407) → Credentials are wrong
    ├─ YES → Are you seeing 403 on INVITE only?
        ├─ YES → IP whitelist or rate limit issue
        └─ NO → Check From: header format
Enter fullscreen mode Exit fullscreen mode

Common ViciDial-Specific Issues

Issue: Multiple Trunks, One Returns 403

ViciDial may route calls through the wrong trunk. Check extensions-vicidial.conf:

exten => _9XXXXXXXX,1,Dial(SIP/${EXTEN:1}@mytrunksip)
Enter fullscreen mode Exit fullscreen mode

If this extension pattern is ambiguous, other patterns might match first. Use more specific patterns:

exten => _91NXXXXXX,1,Dial(SIP/${EXTEN:1}@mytrunksip)
exten => _9011.,1,Dial(SIP/${EXTEN:1}@intl_trunk)
Enter fullscreen mode Exit fullscreen mode

Issue: Campaign Trunk Assignment

In ViciDial, verify campaign uses the correct trunk in database:

SELECT campaign_id, campaign_name, vtiger_id FROM vicidial_campaigns 
WHERE campaign_id = 'TESTCAMP';

SELECT trunk_id, carrier_id FROM vicidial_campaign_carriers 
WHERE campaign_id = 'TESTCAMP';
Enter fullscreen mode Exit fullscreen mode

Wrong trunk assignment will route calls through a trunk with bad credentials.

Issue: Lead Filtering by Trunk

Check if leads are filtered to specific trunks in vicidial_list:

SELECT list_id, carrier_id, count(*) FROM vicidial_list 
WHERE carrier_id IS NOT NULL 
GROUP BY list_id, carrier_id;
Enter fullscreen mode Exit fullscreen mode

If a list requires a specific trunk with 403 errors, leads cannot be called.

Summary

SIP 403 Forbidden errors in ViciDial require systematic diagnosis:

  1. Enable debugging to see the actual error in context
  2. Validate credentials match provider configuration exactly
  3. Verify networking allows packets to reach the provider
  4. Check IP whitelisting with your provider
  5. Test independently using sipp before restarting Asterisk
  6. Monitor proactively with log analysis and SIP qualify checks
  7. Document everything for future troubleshooting

The most common causes are wrong credentials, IP whitelisting issues, and provider account problems. Always contact your SIP provider with specific details:

"SIP 403 Forbidden error from [your outbound IP] to [their SIP host] with username [username] at [specific time]. Can you check authentication logs?"

Keep Asterisk SIP logging enabled in production (sip set debug on in verbosity levels), rotate logs regularly, and set up alerts for repeated 403 errors. This prevents lost calls and identifies problems before they impact your operation.

Top comments (0)