Polycom VVX Auto-Provisioning with Nginx
Polycom VVX Auto-Provisioning with Nginx
Polycom VVX phones can automatically download their configuration from an HTTP/HTTPS server on boot. Once set up, phones pull their config automatically on boot, plug one in and it fetches settings by MAC address and registers. This guide covers the nginx provisioning server setup and the Polycom config file structure.
Nginx Configuration
# /etc/nginx/sites-available/provision
# Provisioning server for Polycom VVX phones
server {
listen 443 ssl;
server_name voip.example.com;
root /var/www/provision;
index index.html;
# Phone config provisioning
location / {
autoindex off;
access_log /var/log/nginx/provision.log;
# Uncomment to enable HTTP Basic Auth:
# auth_basic "Provisioning";
# auth_basic_user_file /etc/nginx/provisioning.htpasswd;
}
# Phone log uploads (restrict to authenticated clients)
location /logs/ {
dav_methods PUT;
create_full_put_path on;
dav_access user:rw group:rw all:r;
client_max_body_size 1m;
auth_basic "Provisioning";
auth_basic_user_file /etc/nginx/provisioning.htpasswd;
}
ssl_certificate /etc/letsencrypt/live/voip.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/voip.example.com/privkey.pem;
# WARNING: TLSv1, TLSv1.1, and DES-CBC3-SHA are deprecated.
# These are included only for older Polycom firmware compatibility.
# If all phones support TLSv1.2+, remove TLSv1/TLSv1.1 and DES-CBC3-SHA.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
}
# HTTP fallback - some older Polycom models don't support HTTPS provisioning
server {
listen 80;
server_name voip.example.com;
root /var/www/provision;
location / {
autoindex off;
access_log /var/log/nginx/provision.log;
}
location /logs/ {
dav_methods PUT;
create_full_put_path on;
dav_access user:rw group:rw all:r;
client_max_body_size 1m;
auth_basic "Provisioning";
auth_basic_user_file /etc/nginx/provisioning.htpasswd;
}
}
Security note: Phone config files contain SIP credentials in plaintext.
Enable HTTP Basic Auth (uncomment auth_basic in the main location block)
and use HTTPS whenever possible. The HTTP fallback block should only be
enabled if you have phones that cannot provision over HTTPS. Restrict access
to the provisioning server by IP range if your network allows it.
Enable and test:
sudo ln -sf /etc/nginx/sites-available/provision /etc/nginx/sites-enabled/
sudo nginx -t && sudo nginx -s reload
Polycom Config File Structure
Polycom phones look for two files based on their MAC address:
Boot Config ({MAC}.cfg)
This tells the phone where to find firmware and which config files to load:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<APPLICATION
APP_FILE_PATH="FIRMWARE/polycom/6.4.6/sip.ld"
CONFIG_FILES="0004f2aabbcc-phone.cfg,site.cfg,sip.cfg"
MISC_FILES="ca-certificates.pem"
LOG_FILE_DIRECTORY="logs"
OVERRIDES_DIRECTORY=""
CONTACTS_DIRECTORY=""
/>
Phone Config ({MAC}-phone.cfg)
This contains the per-phone SIP registration, BLF buttons, and NAT settings:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PHONE_CONFIG>
<ALL
voIpProt.server.1.address="voip.example.com"
voIpProt.server.1.port="5060"
voIpProt.server.1.transport="UDPOnly"
voIpProt.server.1.expires="300"
device.prov.serverType="https"
device.prov.serverName="voip.example.com"
reg.1.displayName="Alice Smith"
reg.1.label="100"
reg.1.address="100"
reg.1.type="private"
reg.1.auth.userId="100"
reg.1.auth.password="secure_password_here"
reg.1.lineKeys="1"
reg.2.displayName="Sales Line"
reg.2.label="Sales"
reg.2.address="100-sales"
reg.2.type="private"
reg.2.auth.userId="100-sales"
reg.2.auth.password="another_password_here"
reg.2.lineKeys="1"
feature.messaging.enabled="1"
msg.mwi.1.subscribe="100"
msg.mwi.1.callBack="*97"
msg.mwi.1.callBackMode="registration"
nat.stun.server="stun.l.google.com"
nat.stun.port="19302"
feature.nat.stun.enabled="1"
nat.keepalive.interval="30"
voIpProt.SIP.rport.enabled="1"
sec.srtp.enable="1"
sec.srtp.offer="1"
sec.srtp.require="0"
attendant.resourceList.1.address="101"
attendant.resourceList.1.label="Bob"
attendant.resourceList.1.type="normal"
attendant.resourceList.2.address="*70"
attendant.resourceList.2.label="Park"
attendant.resourceList.2.type="speedDial"
/>
</PHONE_CONFIG>
Directory Layout
/var/www/provision/
0004f2aabbcc.cfg # Boot config (MAC address)
0004f2aabbcc-phone.cfg # Phone config (MAC address)
64167faabbcc.cfg # Another phone
64167faabbcc-phone.cfg
site.cfg # Shared site-wide settings
sip.cfg # Shared SIP settings
ca-certificates.pem # CA certs for TLS
FIRMWARE/
polycom/6.4.6/
sip.ld # Firmware image
logs/ # Phone log uploads (WebDAV)
Setup Steps
# Create provisioning directory
sudo mkdir -p /var/www/provision/logs
sudo chown -R www-data:www-data /var/www/provision
# Generate htpasswd for optional basic auth
sudo apt install apache2-utils
sudo htpasswd -c /etc/nginx/provisioning.htpasswd provision
# Set phone's boot server (on the phone's web UI or via DHCP Option 66)
# DHCP Option 66: https://voip.example.com/
DHCP Option 66
The easiest way to point phones at your provisioning server is DHCP Option 66. In your DHCP server config:
# ISC DHCP
option tftp-server-name "https://voip.example.com/";
# dnsmasq
dhcp-option=66,"https://voip.example.com/"
When a Polycom phone boots and gets its DHCP lease, it reads Option 66 and fetches https://voip.example.com/{MAC}.cfg to begin provisioning.
Triggering a Remote Reboot
After updating a phone's config on the server, trigger a config check without physically touching the phone:
asterisk -rx 'pjsip send notify polycom-check-cfg endpoint 100'
This sends a SIP NOTIFY that tells the phone to re-fetch its config and reboot if it changed.
User Notes
No notes yet. Be the first to contribute a tip or example.
Contribute a note
Share a tip, gotcha, or practical example. Keep it under 2000 characters. No questions (use the Asterisk community forums for support). Wrap code in backticks.