# FreePBX PJSIP Trunk Setup: Registration, IP Auth, Routes, NAT

Source: https://srvscripts.com/guides/freepbx-pjsip-trunk-setup/
Updated: 2026-10-07
Publisher: srvScripts (https://srvscripts.com/)

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

## 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](/guides/disable-sip-alg/). Our [PJSIP NAT generator](/tools/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-pstn` so 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](/guides/voip-codec-bandwidth/) 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 `identify` object 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 `NXXNXXXXXX` with prepend `1`, and match `1NXXNXXXXXX` as is. The **Dial patterns wizards** menu can fill common sets.

- Keep international (`011.` or `00.`) in a separate route with a **Route Password**, or leave it out. See our [toll-fraud checklist](/guides/asterisk-freepbx-toll-fraud-prevention/).

### 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`, then `pjsip set logger off` when 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](/tools/sip-trace-analyzer/) to spot NAT and codec issues quickly.

**Official documentation:** [Asterisk: Configuring res_pjsip](https://docs.asterisk.org/Configuration/Channel-Drivers/SIP/Configuring-res_pjsip/) · [Asterisk: PJSIP configuration examples](https://docs.asterisk.org/Configuration/Channel-Drivers/SIP/Configuring-res_pjsip/res_pjsip-Configuration-Examples/) · [Sangoma: FreePBX documentation](https://sangomakb.atlassian.net/wiki/spaces/FP/overview)

**Related:** [PJSIP Behind NAT: Asterisk and FreePBX Settings for Two-Way Audio](/guides/pjsip-nat-asterisk-freepbx/) · [SIP Response Codes: Lookup for Every SIP Error, With Causes and Fixes](/tools/sip-response-codes/) · [How Many SIP Channels Do You Need? Size SIP Trunks with Erlang B](/guides/how-many-sip-channels/) · [Disable SIP ALG: 7 Router Fixes for One-Way Audio and Dropped Calls](/guides/disable-sip-alg/) · [SIP Trace Analyzer: Find NAT, Codec and Dropped-Call Problems in a SIP Log](/tools/sip-trace-analyzer/)

**See also:** [chan_sip to PJSIP Migration: sip_to_pjsip.py, Option Mapping, Tests](/guides/chan-sip-to-pjsip-migration/) · [sip.conf to pjsip.conf Converter for Asterisk](/tools/sip-to-pjsip-converter/) · [Asterisk CLI Commands Cheat Sheet: PJSIP, Calls, Dialplan, Logs](/guides/asterisk-cli-commands-cheat-sheet/) · [PJSIP Endpoint Unreachable or Unavailable: Fix Qualify and NAT](/guides/pjsip-endpoint-unreachable-qualify/)

**See also:** [Asterisk pjsip_wizard.conf: Endpoints and Trunks in a Few Lines](/guides/asterisk-pjsip-wizard/) · [Provision Yealink Phones on FreePBX 17 (Without Commercial EPM)](/guides/yealink-provisioning-freepbx/)

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