Installing VICIphone WebRTC with Let’s Encrypt SSL on ViciBox 11
VICIphone removes the softphone from the agent’s desktop entirely. No X-Lite, no Zoiper, no per-machine SIP configuration. The catch is that WebRTC mandates a secure context, so nothing works until SSL is genuinely correct.
ViciBox 11, released on openSUSE Leap 15.5, ships the pieces you need. This covers wiring them together.
Requirements
- A real domain name pointing at the server’s public IP. Self-signed certificates technically work but require every agent to click through a browser warning and manually trust two separate origins. Do not do this in production.
- Ports 80 and 443 reachable during certificate issuance
- Asterisk 16 or later — Asterisk 18 on ViciBox 11
1. DNS and Hostname
Point an A record at the server, for example dialer.example.com. Confirm it resolves before going further:
dig +short dialer.example.com
hostnamectl set-hostname dialer.example.com
Let’s Encrypt validates over HTTP. If the name does not resolve, issuance fails with an obscure error and you will waste an hour on the wrong thing.
2. Issue the Certificate
ViciBox ships vicibox-ssl, a wrapper around acme.sh:
zypper install vicibox-ssl
vicibox-ssl dialer.example.com
If you prefer to run acme.sh directly:
curl https://get.acme.sh | sh -s email=admin@example.com
source ~/.bashrc
acme.sh --issue -d dialer.example.com --webroot /srv/www/htdocs
acme.sh --install-cert -d dialer.example.com \
--key-file /etc/apache2/ssl.key/dialer.key \
--fullchain-file /etc/apache2/ssl.crt/dialer.crt \
--reloadcmd "systemctl reload apache2"
The --reloadcmd matters. Without it, renewal succeeds every 60 days and Apache keeps serving the expired certificate until someone notices.
3. Apache SSL
Enable the modules:
a2enmod ssl
a2enmod socache_shmcb
a2enflag SSL
Create /etc/apache2/vhosts.d/vicidial-ssl.conf:
<VirtualHost *:443>
ServerName dialer.example.com
DocumentRoot /srv/www/htdocs
SSLEngine on
SSLCertificateFile /etc/apache2/ssl.crt/dialer.crt
SSLCertificateKeyFile /etc/apache2/ssl.key/dialer.key
SSLProtocol -all +TLSv1.2 +TLSv1.3
<Directory /srv/www/htdocs>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
apachectl configtest
systemctl restart apache2
Verify in a browser that https://dialer.example.com/agc/vicidial.php loads with a valid padlock. WebRTC will refuse to request microphone access from any origin the browser does not consider secure.
4. Asterisk WebSocket
Edit /etc/asterisk/http.conf:
[general]
enabled=yes
bindaddr=0.0.0.0
bindport=8088
tlsenable=yes
tlsbindaddr=0.0.0.0:8089
tlscertfile=/etc/apache2/ssl.crt/dialer.crt
tlsprivatekey=/etc/apache2/ssl.key/dialer.key
Asterisk needs read access to those files. If it cannot read the key, the TLS listener silently fails to bind.
chmod 644 /etc/apache2/ssl.crt/dialer.crt
chmod 640 /etc/apache2/ssl.key/dialer.key
chgrp asterisk /etc/apache2/ssl.key/dialer.key
Reload and confirm:
asterisk -rx "module reload res_http_websocket.so"
asterisk -rx "http show status"
You want to see the server enabled and a TLS listener on 8089. If 8089 is absent, it is almost always the certificate permissions.
Open the port:
firewall-cmd --permanent --add-port=8089/tcp
firewall-cmd --reload
5. The WebRTC Phone Template
In Admin → Phones → Templates, create a template with this content:
type=friend
host=dynamic
disallow=all
allow=ulaw
allow=opus
context=default
transport=ws,wss
encryption=yes
avpf=yes
force_avp=yes
icesupport=yes
dtlsenable=yes
dtlsverify=fingerprint
dtlscertfile=/etc/apache2/ssl.crt/dialer.crt
dtlsprivatekey=/etc/apache2/ssl.key/dialer.key
dtlssetup=actpass
rtcp_mux=yes
directmedia=no
nat=force_rport,comedia
qualify=no
A few notes on these:
avpf=yesandforce_avp=yesare required — WebRTC uses AVPF, standard SIP uses AVPrtcp_mux=yesmultiplexes RTCP onto the RTP port, which browsers expectqualify=nobecause browsers do not respond to OPTIONS pings and you will otherwise see the phone flapping between reachable and unreachabledirectmedia=nokeeps media through the server so recording works
6. Create the Phone Entry
- Phone Login / Password: as normal
- Registration Password: same as the phone password
- Template ID: the WebRTC template you just created
- Protocol: SIP
- Webphone:
Y - Webphone Dialpad:
Y - Webphone Auto Answer:
Yfor predictive campaigns - Server IP: your dialer
Then in Admin → System Settings:
- WebRTC/Webphone URL:
https://dialer.example.com/agc/viciphone.php
And on the user, under Admin → Users → Modify → Agent Interface Options, set Use Webphone: Y.
Force the config out:
/usr/share/astguiclient/ADMIN_keepalive_ALL.pl
asterisk -rx "sip reload"
asterisk -rx "sip show peers" | grep 8001
7. Testing
Log in as an agent. The browser will prompt for microphone permission — this must be allowed, and on a shared machine it needs allowing per-origin.
If the phone shows as not registered:
asterisk -rvvvvv
sip set debug on
Watch for the WebSocket upgrade. Common failures:
| Symptom | Cause |
|---|---|
| No WebSocket connection at all | Port 8089 blocked, or TLS listener not bound |
| Connects then immediately drops | Certificate name mismatch between Apache and http.conf |
| Registers but no audio either way | icesupport or dtlsenable missing from the template |
| One-way audio | RTP range not open in the firewall |
| Mic permission never prompts | Page loaded over HTTP, not HTTPS |
Check RTP is open:
firewall-cmd --list-ports
You want your rtp.conf range, typically 10000–20000/udp.
8. Renewal
Test renewal before you forget about it:
acme.sh --renew -d dialer.example.com --force
asterisk -rx "module reload res_http_websocket.so"
Asterisk caches the certificate at module load. Apache reloading is not enough — add the Asterisk reload to your renewal hook, or agents will find the webphone dead one morning 90 days from now.
Summary
The order that works: DNS first, then a real certificate, then Apache HTTPS, then the Asterisk TLS WebSocket, then the phone template. Skipping ahead to the template while SSL is half-configured is how people spend a day on this.