Short answer: In FreePBX 17 go to Connectivity > Trunks > Add Trunk > Add SIP (chan_pjsip) Trunk. For a registration trunk, enter the provider’s username, secret and SIP server, and keep Authentication: Outbound and Registration: Send. For an IP-authenticated trunk, set both to None and put the provider’s signalling IPs in Match (Permit). Then add an outbound route that uses the trunk, an inbound route for each DID, set External Address and Local Networks if the PBX is behind NAT, and check with pjsip show registrations.
We took the field names and defaults below from the FreePBX 17.0.33 core module on our lab server (Debian 12, Asterisk 22.11) on 6 October 2026, and ran the Asterisk commands there. The lab has no live provider account, so the trunk itself was not registered; registration output is described, not shown.
Table of Contents
What to get from your provider first
Every provider’s portal names things differently. Before you open FreePBX, collect:
| Item | Example | Where it goes in FreePBX |
|---|---|---|
| Authentication type | Registration (username/password) or IP authentication | Authentication, Registration |
| SIP server and port | sip.example.com, 5060 | SIP Server, SIP Server Port |
| Transport | UDP, TCP or TLS | Transport (Advanced) |
| Username and password | bob-trunk / generated secret | Username, Secret |
| Signalling IP ranges (for IP auth and firewall) | 203.0.113.0/24 | Match (Permit), your firewall |
| Number format they send and expect | E.164 (+12125551234) or national | Inbound DID, outbound prepend rules |
| Allowed caller ID | Only your DIDs, or any verified number | Outbound CallerID |
| Codecs | G.711 u-law/a-law, sometimes G.729 | Codecs tab |
Also ask whether they need a specific From user or domain. Some providers reject calls unless From User or From Domain match the account.
Set NAT and RTP before the trunk
If the PBX has a private IP behind a router, set NAT first or you will chase one-way audio later. In Settings > Asterisk SIP Settings:
- External Address: your public IP (or use the detect button).
- Local Networks: every private network your phones and PBX use, for example
192.168.1.0/24. - RTP Port Ranges: default 10000 to 20000; forward or allow exactly this range on the firewall.
On our lab, applying those settings produced this transport (from /etc/asterisk/pjsip.transports.conf, example IPs):
[0.0.0.0-udp]
type=transport
protocol=udp
bind=0.0.0.0:5060
external_media_address=203.0.113.25
external_signaling_address=203.0.113.25
allow_reload=no
tos=cs3
cos=3
local_net=192.168.1.0/24
Transport changes need a full restart (fwconsole restart), not just Apply Config. Disable SIP ALG on the router; see Disable SIP ALG. Our PJSIP NAT generator shows the right values for your layout.
Create a registration trunk
Go to Connectivity > Trunks, click Add Trunk and choose Add SIP (chan_pjsip) Trunk.
General tab
- Trunk Name: a short name, for example
provider-a. FreePBX uses it as the PJSIP endpoint name. - Outbound CallerID: your main DID in the format the provider wants. CID Options controls whether extensions may override it.
- Maximum Channels: the number of simultaneous calls your plan allows. Leave it blank only if you have no limit; a cap reduces fraud damage.
PJSIP Settings > General
FreePBX 17 defaults, from its core module: Authentication Outbound, Registration Send, Context from-pstn, Transport 0.0.0.0-udp.
- Username and Secret: from the provider. If the auth username differs from the account name, fill in Auth username too.
- Authentication: Outbound (FreePBX answers the provider’s challenge). Use Both only if the provider also registers or authenticates to you.
- Registration: Send.
- SIP Server and SIP Server Port: from the provider.
- Context: leave
from-pstnso inbound calls go through Inbound Routes.
PJSIP Settings > Advanced
Most trunks work with the defaults. The fields you are most likely to touch:
| Field | Default (FreePBX 17) | When to change |
|---|---|---|
| Qualify Frequency | 60 seconds | Lower for faster failure detection; 0 disables OPTIONS pings |
| Expiration | 3600 seconds | Provider requires a shorter registration interval |
| DTMF Mode | Auto | Set RFC 4733 if IVR digits are missed |
| From User / From Domain | Empty | Provider requires its account or domain in the From header |
| Contact User | Empty | Provider routes inbound calls by the user part of your Contact |
| Send Line in Registration | – | Only if the provider asks for it |
| Rewrite Contact / RTP Symmetric / Force rport | No / Yes / Yes | Rewrite Contact Yes can help when the provider sits behind NAT |
| Direct Media | No | Leave No for trunks, so media stays anchored on the PBX |
| Send RPID/PAI | No | Provider needs P-Asserted-Identity for caller ID |
| Outbound Proxy | Empty | Provider gives a separate proxy address |
Codecs tab
Enable only what the provider supports, in order of preference: usually ulaw (North America) or alaw (most of the rest of the world). Extra codecs the provider rejects cause 488 Not Acceptable Here. Our codec bandwidth guide compares the options.
Click Submit, then Apply Config.
Create an IP-authenticated trunk
Some providers do not use registration. They send calls from fixed IPs and accept calls from your public IP. Differences from the registration trunk:
- Authentication: None (no username or secret).
- Registration: None.
- SIP Server: the provider’s outbound proxy or gateway.
- Match (Permit): every signalling IP or CIDR the provider sends from, comma separated. FreePBX writes these into a PJSIP
identifyobject so inbound INVITEs are matched to this trunk. - Give the provider your public IP for their allow-list.
If an IP is missing from Match (Permit), calls from it do not match the trunk. Asterisk then treats them as unknown and you will see No matching endpoint found in the log, with calls rejected.
Outbound and inbound routes
Outbound route
In Connectivity > Outbound Routes > Add Outbound Route:
- Route Name and optionally Route CID.
- Trunk Sequence for Matched Routes: pick the new trunk (add a second trunk below it for failover).
- Dial Patterns: one row per pattern with prepend, prefix, match pattern and CallerID. Example for a US provider wanting 11 digits: match
NXXNXXXXXXwith prepend1, and match1NXXNXXXXXXas is. The Dial patterns wizards menu can fill common sets. - Keep international (
011.or00.) in a separate route with a Route Password, or leave it out. See our toll-fraud checklist.
Inbound route
In Connectivity > Inbound Routes > Add Inbound Route, set DID Number to the number exactly as the provider sends it (check with the SIP logger if unsure: some send +12125551234, some 2125551234), then Set Destination to an extension, ring group, IVR or queue. A route with a blank DID catches anything not matched by a more specific route.
Check that it worked
asterisk -rx "pjsip show registrations"
asterisk -rx "pjsip show endpoint provider-a"
asterisk -rx "pjsip show identifies"
asterisk -rx "pjsip show contacts"
- A registration trunk should show Registered in
pjsip show registrations. - The trunk’s contact should show Avail with a round-trip time in
pjsip show contacts(when Qualify Frequency is not 0). - An IP trunk should show its Match (Permit) addresses in
pjsip show identifies. - Place a test call each way. To watch the SIP exchange for this provider only:
pjsip set logger host 203.0.113.10, thenpjsip set logger offwhen done.
fwconsole trunks --list lists trunk IDs and whether each is enabled; fwconsole trunks --disable=<id> and --enable=<id> switch one off and on without the GUI.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Registration Rejected, 401/403 in the logger | Wrong username, auth username or secret; account locked | Re-enter credentials; check the provider portal; see SIP error codes |
| Unregistered and no replies | DNS, firewall or wrong port/transport | Check SIP Server Port, transport, outbound firewall |
| Inbound calls rejected, “No matching endpoint found” | IP trunk without the right Match (Permit) IPs | Add all provider signalling IPs |
Inbound caller hears “not in service” and the DID read back; log shows No DID or CID Match | No inbound route matches the DID format | Match DID Number to exactly what the provider sends |
| Outbound 403 Forbidden | Caller ID not allowed, or IP not on provider allow-list | Use a DID you own as Outbound CallerID; give the provider your IP |
| 488 Not Acceptable Here | No common codec | Enable only provider-supported codecs |
| One-way or no audio | NAT settings, SIP ALG, RTP ports blocked | Check External Address, Local Networks, RTP range; see one-way audio fix |
| DTMF not recognised by provider IVRs | DTMF mode mismatch | Set DTMF Mode to RFC 4733 |
Paste a SIP log into our SIP Trace Analyzer to spot NAT and codec issues quickly.
Official documentation: Asterisk: Configuring res_pjsip · Asterisk: PJSIP configuration examples · Sangoma: FreePBX documentation
Related: PJSIP Behind NAT: Asterisk and FreePBX Settings for Two-Way Audio · SIP Response Codes: Lookup for Every SIP Error, With Causes and Fixes · How Many SIP Channels Do You Need? Size SIP Trunks with Erlang B · Disable SIP ALG: 7 Router Fixes for One-Way Audio and Dropped Calls · SIP Trace Analyzer: Find NAT, Codec and Dropped-Call Problems in a SIP Log
See also: chan_sip to PJSIP Migration: sip_to_pjsip.py, Option Mapping, Tests · sip.conf to pjsip.conf Converter for Asterisk · Asterisk CLI Commands Cheat Sheet: PJSIP, Calls, Dialplan, Logs · PJSIP Endpoint Unreachable or Unavailable: Fix Qualify and NAT
See also: Asterisk pjsip_wizard.conf: Endpoints and Trunks in a Few Lines · Provision Yealink Phones on FreePBX 17 (Without Commercial EPM)
Frequently asked questions
Should I use registration or IP authentication for a SIP trunk?
Use registration if your public IP can change or you are behind NAT without a fixed IP. IP authentication suits a fixed public IP and avoids storing a password, but every provider IP must be in Match (Permit).
What context should a FreePBX trunk use?
Leave the default from-pstn. It sends inbound calls through Inbound Routes, where you match DIDs to destinations.
Why does my trunk show Registered but inbound calls fail?
Usually the DID format does not match your inbound route, or calls arrive from a provider IP that is not on your firewall allow-list.
Do I need to restart Asterisk after creating a trunk?
No. Submit and Apply Config is enough for trunks. Transport and NAT changes in Asterisk SIP Settings need fwconsole restart.
How many channels should I set on the trunk?
Your plan’s limit or your real peak, whichever is lower. Our Erlang calculator estimates the peak from call volume.