# Provision Yealink Phones on FreePBX 17 (Without Commercial EPM)

Source: https://srvscripts.com/guides/yealink-provisioning-freepbx/
Updated: 2026-10-07
Publisher: srvScripts (https://srvscripts.com/)

**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):

| Option | Cost | Suits | Limits |
| --- | --- | --- | --- |
| 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 GUI | Paid licence; needs the commercial module stack |
| Manual / scripted files (this guide) | Free | Small to medium sites, admins comfortable with text files and scripts | You 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.

## How a Yealink phone finds and reads its files

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
```

| Parameter | Meaning (Yealink Administrator Guide) |
| --- | --- |
| account.X.enable | 0 disabled, 1 enabled (default 0) |
| account.X.label | Text shown on the line key |
| account.X.display_name | Caller ID name the phone sends |
| account.X.auth_name | User name for authentication: the FreePBX extension number |
| account.X.user_name | SIP user name: also the extension number |
| account.X.password | The extension secret |
| account.X.sip_server.Y.address | PBX IP address or host name |
| account.X.sip_server.Y.port | SIP port, default 5060 |
| account.X.sip_server.Y.transport_type | 0 UDP, 1 TCP, 2 TLS, 3 DNS NAPTR (default 0) |
| account.X.sip_server.Y.expires | Registration 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.

### HTTPS with a password (recommended)

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

    Options -Indexes
    AllowOverride None
    AuthType Basic
    AuthName "Phone provisioning"
    AuthUserFile /etc/apache2/prov.htpasswd
    Require valid-user

```

```
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

- **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.

- **The folder does not list:** `curl -s -u yealinkprov https://pbx.example.com/prov/` should return 403, not a file list.

- **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.

- **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.

- **Two-way audio on a test call.** If audio is one-way, see [PJSIP behind NAT](/guides/pjsip-nat-asterisk-freepbx/).

## 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](/guides/sip-response-codes/).

**Official documentation:** [Yealink SIP IP Phones Auto Provisioning Guide](https://support-cdn.yealink.com/attachment/upload/attachment/2020-12-10/3/582c3077-9d60-4baa-87de-5f9b6586d2e5/Yealink+SIP+IP+Phones+Auto+Provisioning+Guide+V1.2.pdf) · [Sangoma: EndPoint Manager add-on (pricing)](https://www.freepbx.org/add-on/endpoint-manager-ucp-for-epm/) · [Sangoma: EndPoint Manager documentation](https://sangomakb.atlassian.net/wiki/spaces/PG/pages/31064118) · [Apache: mod_auth_basic](https://httpd.apache.org/docs/2.4/mod/mod_auth_basic.html)

**Related:** [Install FreePBX 17 on Debian 12 (Open-Source Only, Tested)](/guides/install-freepbx-17-debian-12/) · [PJSIP Behind NAT: Asterisk and FreePBX Settings for Two-Way Audio](/guides/pjsip-nat-asterisk-freepbx/) · [PJSIP Endpoint Unreachable or Unavailable: Fix Qualify and NAT](/guides/pjsip-endpoint-unreachable-qualify/) · [Asterisk and FreePBX Toll Fraud Prevention: 10-Point Checklist](/guides/asterisk-freepbx-toll-fraud-prevention/) · [PJSIP NAT Settings Generator: Asterisk, FreePBX, Issabel, VitalPBX, 3CX](/tools/pjsip-nat-generator/)

**See also:** [Asterisk pjsip_wizard.conf: Endpoints and Trunks in a Few Lines](/guides/asterisk-pjsip-wizard/) · [FreePBX PJSIP Trunk Setup: Registration, IP Auth, Routes, NAT](/guides/freepbx-pjsip-trunk-setup/)

## Frequently asked questions

### Do I need EndPoint Manager to use Yealink phones with FreePBX?

No. Yealink phones register to any SIP server. EPM only automates writing their configuration files; you can write and serve those files yourself.

### What is the Yealink MAC config file name?

The phone MAC address in lowercase with no separators and .cfg, for example 00156574b150.cfg. Each file starts with #!version:1.0.0.1.

### Which DHCP option does Yealink use for provisioning?

Option 66 by default (option 59 on IPv6), and a custom option from 128 to 254 if you configure one. Option 43 is also detected.

### Is TFTP provisioning safe?

Only on an isolated phone network. TFTP has no authentication, so anyone who can reach it can download SIP passwords. Use HTTPS with a password where you can.

### How do I make a Yealink phone re-read its config?

Reboot it, use Auto Provision Now in its web interface, or send a SIP NOTIFY with Event check-sync from Asterisk using pjsip send notify.
