# Network Requirements

A SIP trunk carries traffic in both directions: your PBX sends registrations and outbound calls, and Cloud Voice sends inbound calls and keepalives back. Outbound traffic almost always works. Inbound traffic depends on how the firewall, router, or gateway in front of your PBX handles NAT and SIP, which is where most trunk problems begin.

This page covers what your network needs to do for a trunk to stay reachable, how to recognize when it isn't, and where to turn off the firewall features that interfere.

## At a glance

| Setting | What a trunk needs |
| --- | --- |
| SIP ALG / SIP transformations | Disabled |
| NAT mapping | Endpoint-independent and consistent, same external IP and port for every destination |
| NAT filtering | Endpoint-independent, the pinhole accepts traffic from any source |
| UDP idle timeout | At least 2× the refresh interval (300 seconds), never below 120 seconds |
| Registration expiry | Set by Cloud Voice at 300 seconds, your PBX follows it |
| Registration refresh | 150 seconds, half the granted expiry |
| Inbound port forward on 5060 | Not needed, and not recommended |
| Bandwidth per concurrent call | 100 Kbps in each direction, prioritized if the circuit is shared |

## Registration and reachability

A trunk showing **Registered** in the [dashboard](https://portal.voice.izt.cloud) means Cloud Voice received a valid REGISTER from your PBX and answered it. That confirms your PBX can reach us. It doesn't confirm that we can reach your PBX.

The difference matters because inbound calls and keepalives are new requests rather than replies. They only arrive if your network holds the return path open. A trunk can register perfectly on every cycle and still fail every inbound call.

Cloud Voice sends an OPTIONS keepalive to every registered trunk roughly every 30 seconds, which is how the dashboard knows whether the path back to your PBX is working between calls.

The trunk's **reachability** row shows which situation you're in. It reports the round-trip latency of the last keepalive, and a healthy trunk sits in the tens of milliseconds. A reading around **32,000 ms** isn't a slow network, it's the SIP transaction timeout: the OPTIONS request went out, nothing came back, and the attempt gave up after 32 seconds. Any value in that range means the trunk is registered and unreachable, and the cause is almost always one of the sections below.

## SIP ALG and SIP transformations

SIP ALG is a firewall feature that inspects SIP messages in flight and rewrites the addresses inside them. It exists to help NAT traversal, and on a modern SIP trunk it reliably does the opposite. A partially-working implementation rewrites the SIP headers but not the SDP, or the reverse, which produces one-way audio, dropped calls, and failed registrations that look like carrier problems but originate on the local network.

Turn it off. It appears under many names depending on the vendor, including SIP ALG, SIP transformations, SIP helper, SIP inspection, NAT helper, and VoIP profile, and it's frequently enabled by default. [Turning off SIP ALG by vendor](#turning-off-sip-alg-by-vendor) has starting points for the common platforms.

Re-check the setting after every firmware update. Many vendors restore it on upgrade, which is why trunk problems so often appear the morning after maintenance.

## NAT behavior

Two NAT properties determine whether inbound traffic reaches your PBX. Both are described in [RFC 4787](https://www.rfc-editor.org/rfc/rfc4787), the IETF's behavioral requirements for NAT.

**Mapping** needs to be endpoint-independent and consistent (REQ-1). Your PBX's internal socket should always translate to the same external IP address and port, no matter which destination it's sending to. Symmetric NAT, which assigns a new external port per destination, breaks media and keepalives.

**Filtering** needs to be endpoint-independent (REQ-8). Once your PBX has sent traffic out from a socket, that pinhole should accept traffic arriving from any source address and port, not only the exact socket it originally contacted. Address-and-port-dependent filtering is the classic cause of a registered-but-unreachable trunk: REGISTER responses come back from the address your PBX just contacted and pass the filter, while keepalives and inbound INVITEs don't match and are dropped.

The **UDP idle timeout** governs how long the mapping survives between packets. Set it to at least twice your PBX's registration refresh interval, which is 300 seconds against the standard 150-second refresh, and never below 120 seconds. RFC 4787 (REQ-5) sets the same floor and recommends five minutes or more. If the mapping expires between refreshes the pinhole closes, and inbound calls fail until the next REGISTER reopens it.

If your equipment genuinely can't hold a consistent mapping, a static NAT rule that preserves the PBX's source port is a workable fallback. Treat it as a workaround rather than the fix, scope it to the PBX host, and document it, because it won't be obvious to whoever troubleshoots the site next.

## Registration timing

**Cloud Voice sets the registration expiry, not your PBX.** Your PBX proposes an interval when it registers, and Cloud Voice answers with the value it's actually using. That response is authoritative: the binding lasts exactly as long as we say it does, regardless of what was asked for.

Cloud Voice grants a **300-second (five-minute)** expiry on trunk registrations, with a small tolerance either side. Your PBX should refresh at or below **half** that value, so **150 seconds** is the target.

This isn't a Cloud Voice quirk. Standard SIP behavior puts the expiry in the registrar's hands, and a registering endpoint is expected to honor the interval returned in the `200 OK` rather than the one it requested. Most PBXs and SBCs do this automatically. Some, however, treat their configured "registration interval" or "re-register time" as absolute and ignore the granted value, which is where trunks break.

### Example flow

A PBX asking for an hour, and getting five minutes:

```mermaid
sequenceDiagram
    participant P as Your PBX
    participant CV as Cloud Voice
    P->>CV: REGISTER (Expires: 3600)
    CV->>P: 401 Unauthorized (digest challenge)
    P->>CV: REGISTER (Expires: 3600, with credentials)
    CV->>P: 200 OK (expires=300)
    Note over P,CV: The binding is live for 300s, not the 3600s requested
    CV->>P: OPTIONS (keepalive, every 30s)
    P->>CV: 200 OK
    Note over P: Refresh at 150s, half the granted expiry
    P->>CV: REGISTER (refresh)
    CV->>P: 200 OK (expires=300)
```

The value to read is in the `200 OK`, carried on the `Contact` header's `expires` parameter and in the `Expires` header:

```
SIP/2.0 200 OK
Contact: <sip:trunk@203.0.113.10:5060>;expires=300
Expires: 300
```

Your PBX asked for 3600 and was granted 300. Everything from that point on works off 300.

### When the endpoint ignores it

Take the same exchange with a PBX that refreshes on its own configured hour instead of the granted five minutes:

- **t+0s**: registration succeeds, the trunk shows **Registered**, calls work in both directions.
- **t+300s**: the binding expires. Cloud Voice has no valid contact for the trunk, so inbound calls have nowhere to go and keepalives go unanswered. The trunk's reachability reading climbs to the [32,000 ms timeout](#registration-and-reachability).
- **t+300s to t+3600s**: inbound calls fail for the remaining 55 minutes. Outbound calls may still connect, which is why this often gets reported as "inbound only is broken".
- **t+3600s**: the PBX finally refreshes, everything works again, and the cycle repeats.

The signature to look for is a trunk that recovers on its own, on a regular interval, without anyone touching it. If your PBX exposes a registration interval or expiry setting, set it to 150 seconds rather than relying on it to adopt the value we return.

## Inbound ports

[Registering trunks](/sip/trunks/authentication/) need no inbound port forward, no static NAT to the PBX, and no DMZ host. The registration itself opens the path. Forwarding 5060 inbound from any source exposes your PBX directly to internet scanning and is a common route to toll fraud, so leave it closed.

If you use IP-authenticated trunking instead of registration, your PBX has to be reachable, but restrict inbound to the Cloud Voice signaling addresses rather than opening the port to the internet. See [Signaling and media endpoints](#signaling-and-media-endpoints).

## Media and bandwidth

RTP media has to leave your network toward the Cloud Voice media ranges with the return path open. Deep packet inspection, rate limiting, and per-session bandwidth shaping applied to voice traffic all degrade or break audio.

Provision at least 100 Kbps per concurrent call in each direction, and give voice priority if the circuit is shared with data. Segregating voice onto its own VLAN makes both the QoS policy and later troubleshooting considerably easier.

## Firmware and network changes

Firewall, router, and gateway firmware updates change NAT and ALG behavior, sometimes silently. If a site has automatic firmware updates enabled, either disable them or add a post-update check to validate trunk registration and place a test call in each direction.

IP-authenticated trunks are tied to your public address, so let Cloud Voice support know before an ISP change, failover test, or circuit cutover.

## Turning off SIP ALG by vendor

:::danger[Verify against your vendor's documentation, don't copy and paste]
These notes are starting points, not a script to paste into a production firewall. Menu paths, command syntax, and defaults change between firmware versions, and each of these changes affects traffic beyond your SIP trunk. Confirm the current procedure in your vendor's own documentation for the exact version you're running, understand what the change does on your network, and apply it in a maintenance window with a rollback plan.
:::

### Ubiquiti UniFi

On UniFi gateways (UDM, UDM-Pro, UDM-SE, UDR, Cloud Gateway), SIP ALG is the SIP **connection-tracking module**. In current UniFi Network releases it's reached through **UniFi Devices → your gateway → Settings → Firewall Connection Tracking**, where SIP is an individual toggle. Older builds placed the same toggle under **Settings → Routing → NAT**, and legacy USG deployments needed a `config.gateway.json` entry to survive provisioning.

Because the location moves between releases, the most reliable approach is to search `sip` in the Network application's settings and work from what it surfaces. Some recent releases ship with the module already off, so check the toggle's actual state rather than assuming.

### Cisco IOS and IOS XE

The SIP ALG activates as soon as NAT is configured, so on a router doing NAT it's on unless it has been explicitly disabled:

```
no ip nat service sip udp port 5060
no ip nat service sip tcp port 5060
```

Confirm with `show running-config | include ip nat`. The `no ip nat service sip` lines appearing in the output are what tell you it's disabled.

### Cisco ASA and Secure Firewall

SIP inspection is enabled by default in the global policy. Remove it from the inspection class:

```
policy-map global_policy
 class inspection_default
  no inspect sip
```

Verify with `show run policy-map`. ASA SIP inspection is also what rewrites addresses for SIP traffic when NAT is applied, so pair this with NAT and access rules that pass signaling and media on their own.

### Fortinet FortiGate

FortiGate has two separate mechanisms, and both usually need attention. First, move default VoIP handling off the proxy-based ALG:

```
config system settings
 set default-voip-alg-mode kernel-helper-based
end
```

Then remove the SIP session helper. Run `show` under `config system session-helper` to find the SIP entry's index number, which differs between models and firmware versions, then delete that index. Existing sessions keep the old behavior until you clear them (`diagnose sys session filter dport 5060` followed by `diagnose sys session clear`) or reboot.

Note that a firewall policy with a VoIP profile attached uses the SIP ALG regardless of the settings above, so check the policy carrying your SIP traffic as well. Setting `status disable` under that profile's `config sip` forces the session helper path instead.

### SonicWall

Go to **NETWORK → VoIP → Settings** and clear **Enable SIP Transformations**. SonicWall's own guidance is that transformations should be disabled in most deployments where the PBX sits behind the firewall and communicates outward to a VoIP provider, which describes Cloud Voice trunking.

### Cisco Meraki MX

The MX is a stateful firewall with no ALG functionality, so there's no SIP ALG setting and nothing to disable. If a PBX behind an MX relies on ALG behavior, traffic can be dropped in one direction, and the setting to change is in the PBX's own NAT configuration.

### Netgate pfSense

pfSense has no built-in SIP ALG. Two things are worth checking. The **siproxd** package shouldn't be installed for this use case, as Netgate's documentation limits it to upstream PBXs that strictly require a 5060 source port and advises against it for a local PBX. And **Firewall → NAT → Outbound** is where a static-port rule goes if you need to pin the PBX's source port, scoped to the PBX host rather than applied network-wide.

## Signaling and media endpoints

Current signaling addresses, media IP ranges, and port numbers are published at **[sip.voice.izt.cloud](https://sip.voice.izt.cloud)**. Build firewall rules from that page rather than from values copied out of a ticket or an older runbook, it's the authoritative source and stays current as the platform changes.

Where your equipment allows it, configure the **hostname** rather than an IP address. Signaling addresses change as the infrastructure evolves, and hostnames let traffic move without anyone touching your configuration. If a hostname won't resolve on your equipment, that's worth solving as a DNS problem, since a hardcoded IP will strand the site on a future cutover.

## Where the responsibility sits

| Cloud Voice | You |
| --- | --- |
| SBC signaling and media infrastructure | Firewall, router, gateway, and switching |
| Carrier interconnect, numbers, and porting | LAN, VLANs, DHCP, and QoS policy |
| Trunk provisioning and credentials | PBX configuration and licensing |
| STIR/SHAKEN, E911, and regulatory compliance | Internet circuit and ISP relationship |
| Platform monitoring and status reporting | On-site firmware and change control |

Cloud Voice support can tell you exactly what we see from our side, including registration attempts, source addresses, authentication results, and keepalive status, and which of the requirements above isn't being met. Making the change on equipment you manage is yours to do. If you'd prefer Cloud Voice to manage the network side as well, your account manager can walk you through the options.

## Contacting support

Having these details ready lets support skip straight to diagnosis:

1. Account name and trunk name
2. Site public IP address
3. The symptom, and the time it started, with time zone
4. Anything that changed in the previous 48 hours, including firmware, configuration, ISP, PBX, or credentials
5. PBX make, model, and firmware version
6. Firewall make, model, and firmware version
7. Whether SIP ALG is confirmed disabled
8. An example call: calling number, called number, and timestamp

Every contact channel, along with your Support PIN, is on the [Support page](/dashboard/support/). [CDRs & Call Troubleshooting](/sip/cdrs/) covers how to pull the call detail and packet capture for the example call.
