Emergency server help: get in touch

Provision Yealink Phones on FreePBX 17 (Without Commercial EPM)

Provision Yealink phones on FreePBX 17 without EndPoint Manager: MAC.cfg files, account.1 settings, HTTPS with a password, DHCP option 66 and checks.

Published 10 min read

Short answer: Without Sangoma’s commercial EndPoint Manager, you write the Yealink files yourself: one <mac>.cfg per phone (lowercase MAC) with the account.1.* settings from the FreePBX extension, plus an optional common file for shared settings. Serve them from a folder over HTTPS with a username and password (or TFTP on a trusted VLAN only), and point the phones at it with DHCP option 66 or the phone’s Auto Provision page. Every file must start with #!version:1.0.0.1.

Yealink parameter names checked against Yealink’s Administrator Guide (V86.60) and Auto Provisioning Guide (linked below) on 7 October 2026. We have no Yealink phone in our lab, so the phone-side steps are not tested. On our FreePBX 17.0.33 lab (Debian 12) we confirmed the server-side facts below (TFTP service, Apache user and settings), and we tested the check-sync NOTIFY entry on a separate test Asterisk 22.11 instance.

Your options: EndPoint Manager or your own files

Sangoma sells EndPoint Manager (EPM), a commercial FreePBX module that builds phone files from templates, maps extensions to MAC addresses and manages firmware. Its documentation lists Yealink among the supported brands. The alternative is to write and serve the files yourself, which costs nothing but your time and works with any FreePBX install, including open-source-only ones. Prices last checked: 7 October 2026, on Sangoma’s FreePBX add-on page (linked below):

OptionCostSuitsLimits
EndPoint Manager (commercial)$99 for a 1 year licence or $199 for a 25 year licence, per the add-on page. Sangoma phones include a lifetime EPM licence.Many phones, several models, staff who prefer a GUIPaid licence; needs the commercial module stack
Manual / scripted files (this guide)FreeSmall to medium sites, admins comfortable with text files and scriptsYou maintain templates, secrets and firmware yourself

If you have a handful of phones, manual files are quick. Past a few dozen, generate the files with a script from a CSV of MAC, extension and name, so nobody edits secrets by hand.

The phone needs a provisioning server URL. According to Yealink’s Auto Provisioning Guide, it looks in this order: Zero Touch, PnP server, DHCP options, then the URL saved on the phone. TFTP is the default protocol; FTP, HTTP and HTTPS are also supported.

From that URL it downloads these files (names from the Administrator Guide):

  • Boot files (optional): y000000000000.boot for all phones, or <mac>.boot for one phone. They list which .cfg files to fetch with include:config lines.
  • Common CFG file: one fixed name per model, for example y000000000096.cfg for the T54W, y000000000108.cfg for the T46U and y000000000123.cfg for the T31 family. Shared settings go here.
  • MAC-oriented CFG file: <mac>.cfg, for example 00156574b150.cfg for MAC 00156574B150. The guide is explicit that the name is lowercase. Per-phone settings such as the SIP account go here.

Each file must have #!version:1.0.0.1 on its first line. Parameters starting with static. are static settings (provisioning, security); the rest, such as account.1.*, are non-static. Settings in files read later override the same settings in files read earlier.

Write the per-phone file from the FreePBX extension

In FreePBX, open Applications > Extensions, edit the extension, and note the extension number and its Secret (Advanced tab). Then create the file named after the phone’s MAC address, lowercase, no separators:

#!version:1.0.0.1
## 805ec0aa1234.cfg - extension 1001 (Bob)
account.1.enable = 1
account.1.label = 1001
account.1.display_name = Bob
account.1.auth_name = 1001
account.1.user_name = 1001
account.1.password = PASTE-THE-EXTENSION-SECRET
account.1.sip_server.1.address = pbx.example.com
account.1.sip_server.1.port = 5060
account.1.sip_server.1.transport_type = 0
account.1.sip_server.1.expires = 3600
ParameterMeaning (Yealink Administrator Guide)
account.X.enable0 disabled, 1 enabled (default 0)
account.X.labelText shown on the line key
account.X.display_nameCaller ID name the phone sends
account.X.auth_nameUser name for authentication: the FreePBX extension number
account.X.user_nameSIP user name: also the extension number
account.X.passwordThe extension secret
account.X.sip_server.Y.addressPBX IP address or host name
account.X.sip_server.Y.portSIP port, default 5060
account.X.sip_server.Y.transport_type0 UDP, 1 TCP, 2 TLS, 3 DNS NAPTR (default 0)
account.X.sip_server.Y.expiresRegistration expiry in seconds (default 3600)

Our FreePBX 17 lab has a single PJSIP UDP transport on port 5060, which is why the example uses port 5060 and transport 0. If you enabled TLS for PJSIP in FreePBX, use transport type 2 and the TLS port instead. X is the account number (1 to 16 depending on model) and Y the server number.

Shared settings in the common file

Put settings every phone of a model should have into its common file, for example y000000000096.cfg for T54W phones:

#!version:1.0.0.1
## shared settings for all T54W phones
static.auto_provision.server.url = https://pbx.example.com/prov/
static.auto_provision.server.username = yealinkprov
static.auto_provision.server.password = PASTE-THE-PROVISIONING-PASSWORD
static.auto_provision.repeat.enable = 1
static.auto_provision.repeat.minutes = 1440
static.security.user_password = admin:PASTE-A-NEW-ADMIN-PASSWORD
local_time.ntp_server1 = pool.ntp.org
  • static.auto_provision.server.url, .username and .password save the provisioning server on the phone, so it keeps using HTTPS with authentication after the first boot.
  • static.auto_provision.repeat.enable = 1 with repeat.minutes (1 to 43200, default 1440) makes the phone re-check its files regularly.
  • static.security.user_password takes the form <user>:<password>. The guide notes the defaults are user, var and admin, so change at least the admin password.

Serve the files: TFTP or HTTPS

TFTP (only on a trusted phone VLAN)

The FreePBX 17 install on our lab includes tftpd-hpa, running and serving /tftpboot on port 69 with the --secure option (see /etc/default/tftpd-hpa). Drop the files in /tftpboot and point phones at tftp://192.168.1.10/.

TFTP has no authentication. Anyone who can reach UDP 69 on the PBX and guesses a MAC address (Yealink MAC addresses start with a small set of vendor prefixes) can download that phone’s SIP password. Never allow TFTP from the internet, and prefer HTTPS even on internal networks.

FreePBX already runs Apache. On our lab Apache runs as the asterisk user, and the default /var/www directories have Options Indexes on, which would list files. So keep phone files out of the web root and serve them from their own folder with listing off and Basic authentication:

mkdir -p /srv/prov
chown root:asterisk /srv/prov && chmod 750 /srv/prov
# copy the .cfg files in, then:
chown root:asterisk /srv/prov/*.cfg && chmod 640 /srv/prov/*.cfg

htpasswd -c /etc/apache2/prov.htpasswd yealinkprov
# /etc/apache2/conf-available/yealink-prov.conf
Alias /prov /srv/prov
<Directory /srv/prov>
    Options -Indexes
    AllowOverride None
    AuthType Basic
    AuthName "Phone provisioning"
    AuthUserFile /etc/apache2/prov.htpasswd
    Require valid-user
</Directory>
a2enconf yealink-prov
apache2ctl configtest && systemctl reload apache2

Use a certificate from a public CA, such as one issued by FreePBX’s Certificate Manager, on the host name in the URL. Yealink phones check server certificates against their trusted list when static.security.trust_certificates is 1, its default, so a self-signed certificate will be refused. Restrict the URL to your phone networks in the firewall as well; the password is a second layer, not the only one.

Point the phones at the server

DHCP option 66 hands the URL to every phone that boots on that network. With dnsmasq:

dhcp-option=66,"https://pbx.example.com/prov/"

With ISC DHCP, option 66 is called tftp-server-name:

option tftp-server-name "https://pbx.example.com/prov/";

If the server needs a password, give the phone the user name and password once, in its web interface under Settings > Auto Provision (Server URL, Username, Password), then click Auto Provision Now. After the first download, the common file keeps those settings in place. Yealink phones also support a custom DHCP option (static.auto_provision.dhcp_option.list_user_options, 128 to 254) if option 66 is already used for something else.

Push changes without a reboot

Yealink phones re-provision when they receive a SIP NOTIFY with Event: check-sync. FreePBX’s pjsip_notify.conf includes sip_notify_custom.conf, so add this there:

; /etc/asterisk/sip_notify_custom.conf
[yealink-check-sync]
Event=>check-sync
asterisk -rx "module reload res_pjsip_notify.so"
asterisk -rx "pjsip send notify yealink-check-sync endpoint 1001"

On our test instance the reload reported Module 'res_pjsip_notify.so' reloaded successfully and the send command answered Sending NOTIFY of type 'yealink-check-sync' to '1001'. Whether the phone then reboots depends on what changed and on its settings.

Check that it worked

  1. The file is reachable with the password and not without it: curl -sI https://pbx.example.com/prov/805ec0aa1234.cfg should return 401, and curl -s -u yealinkprov https://pbx.example.com/prov/805ec0aa1234.cfg | head -3 should return the file.
  2. The folder does not list: curl -s -u yealinkprov https://pbx.example.com/prov/ should return 403, not a file list.
  3. The phone fetched it: watch tail -f /var/log/apache2/access.log (the log the FreePBX 17 default sites use on our lab) during a reboot or Auto Provision Now; you should see 200 responses for the common and MAC files.
  4. The phone registered: asterisk -rx "pjsip show contacts" lists the extension with the phone’s address, and asterisk -rx "pjsip show endpoint 1001" shows it as available.
  5. Two-way audio on a test call. If audio is one-way, see PJSIP behind NAT.

Common problems

  • Phone ignores its file: upper-case MAC in the file name, missing #!version:1.0.0.1 first line, or Windows line endings from an editor. Rename to lowercase and save with Unix line endings.
  • 404 in the Apache log for y0000000000xx.cfg: normal if you do not use a common file for that model. A 404 for <mac>.cfg means a wrong name.
  • 401 repeated in the log: wrong provisioning user name or password on the phone.
  • HTTPS fails, HTTP works: certificate not trusted (self-signed, expired, or host name mismatch).
  • Registers, then 401 or 403 from PBX: wrong auth_name or password, or the phone’s IP is blocked by the FreePBX firewall or fail2ban. See SIP error codes.

Official documentation: Yealink SIP IP Phones Auto Provisioning Guide · Sangoma: EndPoint Manager add-on (pricing) · Sangoma: EndPoint Manager documentation · Apache: mod_auth_basic

Related: Install FreePBX 17 on Debian 12 (Open-Source Only, Tested) · PJSIP Behind NAT: Asterisk and FreePBX Settings for Two-Way Audio · PJSIP Endpoint Unreachable or Unavailable: Fix Qualify and NAT · Asterisk and FreePBX Toll Fraud Prevention: 10-Point Checklist · PJSIP NAT Settings Generator: Asterisk, FreePBX, Issabel, VitalPBX, 3CX

See also: Asterisk pjsip_wizard.conf: Endpoints and Trunks in a Few Lines · FreePBX PJSIP Trunk Setup: Registration, IP Auth, Routes, NAT

Frequently asked questions

Free website test

Is your website set up right?

Check SSL, security headers, redirects, robots.txt, sitemap, llms.txt and security.txt in one test. It takes about 30 seconds.