A production-grade guide to configuring remote agents in ViciDial using WebRTC, VPN tunnels, and secure firewall rules for distributed call centers
Prerequisites
Before proceeding, ensure you have:
- ViciDial 2.14+ installed and running on a production server (kernel 4.x+)
- Root or sudo access to the ViciDial server and firewall
- Basic knowledge of Linux networking, iptables/firewalld, and Asterisk
- A public IP address or reverse DNS resolution for your ViciDial server
- OpenVPN or WireGuard installed (choose one for VPN layer)
- A registered SSL/TLS certificate for WebRTC endpoints
- Network bandwidth: minimum 1 Mbps per agent (2.5 Mbps recommended for HD)
- Database access to the
asteriskschema
Verify ViciDial is running:
systemctl status vicidial
asterisk -rx "core show version"
Understanding ViciDial Remote Agent Architecture
Why WebRTC + VPN + Firewall?
ViciDial agents traditionally connected via soft phones (SIP clients) over LAN. Remote agents require a different topology:
- WebRTC Layer — Browser-based calling, DTLS-SRTP encryption, NAT traversal
- VPN Tunnel — Encrypted network tunnel for administrative traffic and database queries
- Firewall Rules — Restrict access to specific ports/IPs, preventing brute-force attacks
The agent's browser initiates a WebRTC connection to your Asterisk server via STUN/TURN servers. Simultaneously, the agent establishes a VPN tunnel for accessing the agent screen at /agc/vicidial.php.
Architecture Diagram Overview
Remote Agent Laptop
├── Browser (WebRTC)
│ └── DTLS-SRTP → TURN Server → Asterisk SIP:5060
├── OpenVPN Client
│ └── 10.8.0.x/24 → VPN Server (Firewall)
└── HTTPS (Agent Screen)
└── VPN Tunnel → nginx/Apache:443
Production ViciDial Server
├── Asterisk (SIP, RTP)
├── TURN Server (coturn)
├── VPN Server (OpenVPN/WireGuard)
├── Firewall (iptables/firewalld)
└── Web UI (nginx)
Step 1: Configure Asterisk for WebRTC
1.1 Update SIP Configuration
Edit /etc/asterisk/sip-vicidial.conf and add WebRTC-specific settings:
[general]
; Existing settings...
bindaddr=0.0.0.0
bindport=5060
transport=udp,tcp
srtpsuite=AES_CM_128_HMAC_SHA1_80
videosupport=yes
icesupport=yes
dtlsenable=yes
dtlsverify=fingerprint
dtlscertfile=/etc/asterisk/keys/asterisk.crt
dtlsprivatekey=/etc/asterisk/keys/asterisk.key
dtlssetup=actpass
; CORS headers
mtu=1500
icesupport=yes
1.2 Generate DTLS Certificates
ViciDial WebRTC requires self-signed certificates. Generate them:
mkdir -p /etc/asterisk/keys
cd /etc/asterisk/keys
# Generate private key (4096-bit RSA)
openssl genrsa -out asterisk.key 4096
# Generate certificate valid for 3 years
openssl req -new -x509 -key asterisk.key -out asterisk.crt \
-days 1095 -subj "/CN=your-vicidial-domain.com/O=YourOrg"
# Set permissions
chown asterisk:asterisk asterisk.key asterisk.crt
chmod 600 asterisk.key asterisk.crt
1.3 Create WebRTC-Enabled Agent Peer Configuration
Add this to /etc/asterisk/sip-vicidial.conf:
[webrtc-agent](!)
type=peer
context=from-internal
disallow=all
allow=opus
allow=vp8
allow=vp9
allow=h264
directmedia=no
rtp_engine=asterisk
icesupport=yes
dtlsenable=yes
avpf=yes
force_avp=yes
encryption=yes
1.4 Configure PJSIP for Modern WebRTC (Alternative to SIP)
For ViciDial 2.14+, consider PJSIP which has better WebRTC support. Create /etc/asterisk/pjsip-vicidial.conf:
[transport-webrtc]
type=transport
protocol=ws
bind=0.0.0.0:5061
[endpoint-webrtc-template](!)
type=endpoint
disallow=all
allow=opus
allow=vp8
direct_media=no
ice_support=yes
dtls_cert=/etc/asterisk/keys/asterisk.crt
dtls_setup=actpass
rtp_engine=asterisk_rtp_engine
1.5 Create Dialplan Extensions for Remote Agents
Edit /etc/asterisk/extensions-vicidial.conf and add:
[from-webrtc-agents]
exten => _X.,1,NoOp(WebRTC Agent Call: ${EXTEN})
exten => _X.,n,Set(CHANNEL(language)=en)
exten => _X.,n,Dial(Local/${EXTEN}@from-internal,30,m)
exten => _X.,n,Hangup()
[from-webrtc-inbound]
exten => _X.,1,NoOp(WebRTC Inbound: ${EXTEN})
exten => _X.,n,Set(SIP_HEADERS(X-ViciDial-Agent)=yes)
exten => _X.,n,Dial(Local/${EXTEN}@from-internal,30)
exten => _X.,n,Hangup()
; Add to existing internal context
[from-internal]
exten => _X.,1,NoOp(Extension: ${EXTEN})
exten => _X.,n,Dial(SIP/${EXTEN},30,m)
exten => _X.,n,Hangup()
1.6 Reload Asterisk Configuration
asterisk -rx "sip reload"
asterisk -rx "dialplan reload"
asterisk -rx "core reload"
# Verify WebRTC endpoints are loaded
asterisk -rx "sip show peers" | grep -i webrtc
Step 2: Install and Configure TURN/STUN Server (coturn)
Remote agents behind NAT/firewalls need TURN servers to relay media. Install coturn:
apt-get update && apt-get install -y coturn
systemctl enable coturn
2.1 Configure coturn
Edit /etc/coturn/turnserver.conf:
# Listening ports
listening-port=3478
listening-ip=0.0.0.0
alt-listening-port=3479
alt-listening-ip=0.0.0.0
# WebRTC DTLS
listening-port=5349
listening-ip=0.0.0.0
# Realm (must match your domain)
realm=your-vicidial-domain.com
server-name=turn.your-vicidial-domain.com
# SSL/TLS
cert=/etc/letsencrypt/live/your-vicidial-domain.com/fullchain.pem
pkey=/etc/letsencrypt/live/your-vicidial-domain.com/privkey.pem
# TURN credentials (static)
user=vicidial-remote:your-secure-password
user=admin-turn:admin-password
# Performance
max-bps=0
bps-capacity=0
total-quota=100000
user-quota=10000
# Security
realm-quota=100
check-origin-value=your-vicidial-domain.com
external-ip=YOUR_PUBLIC_IP/YOUR_PUBLIC_IP
# Logging
log-file=/var/log/coturn/turnserver.log
verbose
2.2 Enable coturn and Start Service
# Allow coturn to run as daemon
sed -i 's/TURNSERVER_ENABLED=0/TURNSERVER_ENABLED=1/' /etc/default/coturn
systemctl restart coturn
systemctl status coturn
# Verify listening ports
netstat -tulpn | grep -E '3478|3479|5349'
Step 3: VPN Setup (OpenVPN)
Remote agents need secure access to the agent screen and database queries. Set up OpenVPN server.
3.1 Install OpenVPN
apt-get install -y openvpn easy-rsa
# Copy easy-rsa to OpenVPN directory
make-cadir /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa
3.2 Generate PKI Certificates
# Initialize PKI
./easyrsa init-pki
# Build CA
./easyrsa build-ca nopass
# Generate server certificate
./easyrsa gen-req server nopass
./easyrsa sign-req server server
# Generate client certificate (for remote agents)
./easyrsa gen-req agent-template nopass
./easyrsa sign-req client agent-template
# Generate Diffie-Hellman parameters
./easyrsa gen-dh
# Copy to OpenVPN config directory
cp pki/ca.crt pki/issued/server.crt pki/private/server.key pki/dh.pem /etc/openvpn/
3.3 Configure OpenVPN Server
Create /etc/openvpn/server.conf:
port 1194
proto udp
dev tun0
ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh /etc/openvpn/dh.pem
# Network configuration
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
# Routes
route 192.168.1.0 255.255.255.0
push "route 192.168.1.0 255.255.255.0"
# DNS
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
# Compression
compress lz4-v2
push "compress lz4-v2"
# Cipher
cipher AES-256-GCM
auth SHA256
# Security
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
verb 3
# Connection handling
keepalive 10 120
client-to-client
explicit-exit-notify 1
# Agent authentication
username-as-common-name
3.4 Enable IP Forwarding and NAT
# Enable IP forwarding
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p
# Configure NAT for VPN clients
iptables -A FORWARD -i tun0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o tun0 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# Save rules persistently
apt-get install -y iptables-persistent
iptables-save > /etc/iptables/rules.v4
3.5 Start OpenVPN Server
systemctl enable openvpn@server
systemctl start openvpn@server
systemctl status openvpn@server
# Verify tun0 interface
ip addr show tun0
3.6 Generate Client Configuration
Create /etc/openvpn/clients/agent-template.ovpn:
client
proto udp
remote YOUR_PUBLIC_IP 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert agent-template.crt
key agent-template.key
cipher AES-256-GCM
auth SHA256
compress lz4-v2
verb 3
; DNS configuration for agent screen access
dhcp-option DNS 10.8.0.1
Step 4: Firewall Configuration
Implement strict firewall rules to allow only necessary traffic.
4.1 UFW Configuration (Simple)
apt-get install -y ufw
# Default policies
ufw default deny incoming
ufw default allow outgoing
# Allow SSH (change 22 if using different port)
ufw allow 22/tcp
# Allow SIP
ufw allow 5060/udp
ufw allow 5060/tcp
# Allow RTP range
ufw allow 10000:20000/udp
# Allow WebRTC TURN
ufw allow 3478/tcp
ufw allow 3478/udp
ufw allow 3479/tcp
ufw allow 3479/udp
ufw allow 5349/tcp
ufw allow 5349/udp
# Allow OpenVPN
ufw allow 1194/udp
# Allow HTTPS for web UI
ufw allow 443/tcp
# Allow HTTP (redirect to HTTPS)
ufw allow 80/tcp
# Enable firewall
ufw enable
ufw status verbose
4.2 iptables Rules (Advanced)
For production, use iptables with connection tracking:
#!/bin/bash
# /etc/network/if-up.d/vicidial-firewall
# Flush existing rules
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
# Default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Loopback
iptables -A INPUT -i lo -j ACCEPT
# Established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# SSH (restrict to VPN subnet if possible)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# SIP (all agents)
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
# TURN (WebRTC)
iptables -A INPUT -p udp --dport 3478 -j ACCEPT
iptables -A INPUT -p tcp --dport 3478 -j ACCEPT
iptables -A INPUT -p tcp --dport 5349 -j ACCEPT
iptables -A INPUT -p udp --dport 5349 -j ACCEPT
# OpenVPN
iptables -A INPUT -p udp --dport 1194 -j ACCEPT
# HTTPS
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# HTTP (minimal)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# ICMP (ping)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# NAT for VPN clients
iptables -A FORWARD -i tun0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o tun0 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# Save rules
iptables-save > /etc/iptables/rules.v4
Make executable and ensure it runs at boot:
chmod +x /etc/network/if-up.d/vicidial-firewall
systemctl enable iptables-persistent
4.3 Rate Limiting (Prevent Brute Force)
Add rate limiting to SSH and SIP:
# Limit SSH connections (5 new connections per minute)
iptables -A INPUT -p tcp --dport 22 -m limit --limit 5/minute --limit-burst 10 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
# Limit SIP registration attempts
iptables -A INPUT -p udp --dport 5060 -m limit --limit 50/second --limit-burst 100 -j ACCEPT
iptables -A INPUT -p udp --dport 5060 -j DROP
Step 5: Configure ViciDial Web UI for Remote Access
5.1 Create Agent VPN Login in Database
Remote agents need database entries that reference their VPN IP:
USE asterisk;
-- Insert remote agent with VPN context
INSERT INTO vicidial_users (
user, pass, full_name, user_level, active,
allowed_campaigns, phone_login, phone_pass,
webphone_url, webphone_type
) VALUES (
'remote-agent-001',
SHA1('secure-password-here'),
'John Doe - Remote',
1,
'Y',
'TESTCAMP',
'6001',
'9876543210',
'wss://your-vicidial-domain.com:5061/ws',
'webrtc'
) ON DUPLICATE KEY UPDATE active='Y';
-- Assign to campaign
UPDATE vicidial_users SET allowed_campaigns='TESTCAMP'
WHERE user='remote-agent-001';
-- Verify
SELECT user, full_name, phone_login, webphone_type FROM vicidial_users
WHERE user='remote-agent-001'\G
5.2 Configure Web Server for WebRTC
Edit /etc/nginx/sites-enabled/vicidial:
upstream asterisk_ari {
server 127.0.0.1:8088;
}
server {
listen 443 ssl http2;
server_name your-vicidial-domain.com;
ssl_certificate /etc/letsencrypt/live/your-vicidial-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-vicidial-domain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# Root directory
root /var/www/html;
index index.php;
# Agent screen
location /agc/ {
proxy_pass http://127.0.0.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# WebRTC endpoint
location ~ ^/ws$ {
proxy_pass ws://asterisk_ari;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
# PHP processing
location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# Deny access to admin files from remote IPs (unless VPN)
location /vicidial/admin.php {
allow 10.8.0.0/24; # VPN subnet
allow 127.0.0.1;
allow 192.168.1.0/24; # Your LAN
deny all;
}
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name your-vicidial-domain.com;
return 301 https://$server_name$request_uri;
}
Reload nginx:
nginx -t
systemctl reload nginx
Step 6: Agent Configuration and Client Setup
6.1 Create Agent Profiles in ViciDial
Add agent to a campaign via admin:
INSERT INTO vicidial_campaigns (
campaign_id, campaign_name, active, dial_method, lead_order_mix,
client_greeting, list_name_id, campaign_description
) VALUES (
'REMOTE01',
'Remote Test Campaign',
'Y',
'POWER',
50,
'en-us/welcome',
1,
'Campaign for remote agents'
) ON DUPLICATE KEY UPDATE active='Y';
INSERT INTO vicidial_campaign_agents (
campaign_id, user, active
) VALUES (
'REMOTE01',
'remote-agent-001',
'Y'
);
6.2 Client-Side Configuration (Agent Laptop)
Provide agents with:
- OpenVPN Profile (
agent-template.ovpn) - ViciDial WebRTC Credentials
- Connection Instructions
Create a deployment package:
mkdir -p /tmp/vicidial-remote-package/{ovpn,docs}
# Copy OpenVPN files
cp /etc/openvpn/easy-rsa/pki/ca.crt /tmp/vicidial-remote-package/ovpn/
cp /etc/openvpn/easy-rsa/pki/issued/agent-template.crt /tmp/vicidial-remote-package/ovpn/
cp /etc/openvpn/easy-rsa/pki/private/agent-template.key /tmp/vicidial-remote-package/ovpn/
cp /etc/openvpn/clients/agent-template.ovpn /tmp/vicidial-remote-package/ovpn/
# Create README
cat > /tmp/vicidial-remote-package/docs/README.txt << 'EOF'
ViciDial Remote Agent Setup Instructions
1. Install OpenVPN:
- Windows: https://openvpn.net/download-open-vpn/
- macOS: brew install openvpn
- Linux: apt-get install openvpn
2. Copy OpenVPN files to:
- Windows: C:\Program Files\OpenVPN\config\
- macOS: /Applications/Tunnelblick.app/Contents/Resources/
- Linux: /etc/openvpn/
3. Connect VPN first, then open browser to:
https://your-vicidial-domain.com/agc/vicidial.php
4. Login credentials will be provided separately.
5. For troubleshooting, check:
/var/log/openvpn/openvpn.log (server)
/var/log/asterisk/messages (Asterisk logs)
EOF
tar -czf vicidial-remote-agents-setup.tar.gz -C /tmp vicidial-remote-package/
6.3 Test Remote Agent Connection
Once agent has VPN and credentials:
# From ViciDial server, verify VPN connection
tail -f /var/log/openvpn/openvpn-status.log
# Check agent's TUN IP
ifconfig tun0
# Test DNS resolution from agent
nslookup your-vicidial-domain.com
# Monitor Asterisk for incoming calls
asterisk -rx "core show channels verbose"
Step 7: Monitoring and Logging
7.1 Monitor VPN Connections
# Real-time VPN status
watch -n 5 'cat /var/log/openvpn/openvpn-status.log'
# Parse client connections
grep "CLIENT_LIST" /var/log/openvpn/openvpn-status.log | awk -F',' '{print $2, $3, $4}'
7.2 Monitor Asterisk WebRTC Connections
# Show active channels
asterisk -rx "core show channels verbose" | grep -i webrtc
# Show RTP streams
asterisk -rx "rtcp show stats"
# Show SIP peers (including WebRTC)
asterisk -rx "pjsip show endpoints" | grep webrtc
7.3 Create Logrotate Configuration
Create /etc/logrotate.d/vicidial-remote:
/var/log/openvpn/*.log {
daily
rotate 7
compress
delaycompress
notifempty
create 0600 nobody nogroup
sharedscripts
postrotate
systemctl reload openvpn@server > /dev/null 2>&1 || true
endscript
}
/var/log/coturn/*.log {
daily
rotate 5
compress
notifempty
postrotate
systemctl reload coturn > /dev/null 2>&1 || true
endscript
}
7.4 Database Logging Query
Track remote agent activity:
-- Query remote agent calls
SELECT
vcl.call_date,
vcl.caller_id_number,
vcl.called_station_id,
vcl.call_duration,
vcl.status,
vcu.user,
vcu.phone_login
FROM vicidial_log vcl
JOIN vicidial_users vcu ON vcl.user = vcu.user
WHERE vcu.phone_login LIKE '600%' -- Remote agent extensions
AND vcl.call_date >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
ORDER BY vcl.call_date DESC;
Troubleshooting
Agent Cannot Connect to VPN
Problem: OpenVPN connection fails with "TLS Error"
Solution:
# Check client logs
cat /var/log/openvpn/*.log | tail -20
# Verify server is running
systemctl status openvpn@server
# Test port connectivity
telnet YOUR_PUBLIC_IP 1194
# Regenerate client certificate
cd /etc/openvpn/easy-rsa
./easyrsa revoke agent-template
./easyrsa gen-req agent-template-new nopass
./easyrsa sign-req client agent-template-new
WebRTC Audio Not Working
Problem: Agents can see the interface but audio doesn't transmit
Solution:
# Verify TURN server is running and accessible
netstat -tulpn | grep coturn
# Check coturn logs
tail -50 /var/log/coturn/turnserver.log
# Test TURN connectivity (from remote location)
echo "Testing TURN server..."
stunclient YOUR_PUBLIC_IP 3478
# Verify media ports are open
sudo ufw status | grep 10000
High Latency/Packet Loss on Calls
Problem: Calls exhibit lag or dropouts
Solution:
# Monitor RTP jitter
asterisk -rx "rtcp show stats"
# Check firewall drops
iptables -L -v -n | grep DROP
# Increase RTP buffer
# Edit /etc/asterisk/rtp.conf:
# rxstart=2000
# rxstop=3000
# rtptimeout=5
# Reload
asterisk -rx "module reload res_rtp_asterisk"
Agent Screen Loads Slowly Over VPN
Problem: /agc/vicidial.php takes >5 seconds to load
Solution:
# Check database query performance
mysql -u asterisk -p asterisk -e "SHOW FULL PROCESSLIST\G"
# Optimize database tables
mysqlcheck -u asterisk -p asterisk --optimize --all-databases
# Monitor VPN bandwidth
iftop -i tun0
# Check if web server is rate-limiting
tail -50 /var/log/nginx/error.log
SIP Registration Failures
Problem: Agents see "SIP Registration Failed"
Solution:
# Check SIP registration attempts
asterisk -rx "sip show registry"
# Verify agent credentials in database
SELECT user, phone_login, phone_pass FROM vicidial_users
WHERE user='remote-agent-001'\G
# Enable SIP debugging
asterisk -rx "sip set debug on"
asterisk -rx "sip set debug off"
# Check for port conflicts
netstat -tulpn | grep 5060
Firewall Blocking Legitimate Traffic
Problem: Calls connect but drop after a few seconds
Solution:
# Check if stateful tracking is enabled
iptables -L -n | grep ESTABLISHED
# Increase connection timeout
echo "net.netfilter.nf_conntrack_tcp_timeout_established=600" >> /etc/sysctl.conf
sysctl -p
# Whitelist remote agent subnet permanently
ufw allow from 10.8.0.0/24
# Verify no DROP rules on FORWARD
iptables -L FORWARD -v -n
Summary
You've now successfully configured ViciDial for remote agents using:
- WebRTC — Browser-based softphone with DTLS encryption
- TURN Server — NAT traversal via coturn for media relay
- OpenVPN — Secure VPN tunnel for administrative and database traffic
- Firewall — UFW/iptables rules protecting SIP, RTP, and TURN ports
- Asterisk Configuration — WebRTC-enabled SIP peers and dialplan extensions
- HTTPS Web UI — Nginx reverse proxy with SSL/TLS for agent screen
- Monitoring — Logging, real-time connection tracking, and performance metrics
Key Takeaways
- Always use VPN + firewall together — WebRTC alone is not secure for call center operations
- Test from multiple locations — Ensure TURN server works from restrictive networks
- Monitor database load — Remote agents generate more DB queries than LAN peers
- Rotate certificates annually — Set reminders for certificate renewal
- Use SIP TLS or PJSIP/WSS for production — Plain UDP SIP is vulnerable to eavesdropping
- Regularly audit firewall rules — Remove unused ports to reduce attack surface
Next Steps
- Deploy to 2-3 pilot agents first
- Monitor
/var/log/asterisk/messagesfor integration issues - Conduct latency tests under load (5+ concurrent calls)
- Document your specific IP ranges and firewall exceptions
- Create runbook for adding new remote agents (certificate generation, VPN config, database inserts)
For ViciDial-specific support, consult the official documentation at https://www.vicidial.org or community forums.