SBC Interop: Topology Hiding, Header Hygiene and Carrier Checklists
Interconnecting with carriers is where good PBX software meets bad SIP. The other end has opinions: it rewrites numbers, rejects your codec order, sends private IPs in SDP, and insists on headers you’ve never heard of. A session border controller exists to absorb that.

Topology Hiding
Never let internal addresses leak. Topology hiding has three surfaces:
- Via / Contact — the SBC substitutes its own address so replies come back to the border, not to an internal node
- SDP
c=/o=— media addresses are rewritten per the network profile (see NAT/EIP media routing) - Record-Route / Route sets — kept minimal and coherent across the B2BUA
The payoff is both security (internal topology stays private) and reliability (carriers can’t route BYEs to an address they can’t reach).
Header Hygiene
Carriers are inconsistent, so per-trunk header policy is a first-class feature:
# config/trunks/carrier-eu.toml
header_passthrough = { mode = "whitelist", whitelist = ["X-Campaign-Id"] }
all/whitelist/blacklist/x_only— pick what flows to the outbound INVITE- Standard headers (
Via,From,To,Call-ID, …) are never forwarded blindly - Unset means custom headers stay internal;
x_onlyis the handy default for partners who expectX-metadata
For inbound direction, header manipulation rules add/remove/rewrite headers at the border, so downstream extensions never see a carrier’s proprietary header soup.
Codec Policy as a Border Decision
Per-trunk codec lists do two jobs: strip options the carrier rejects (fewer 488s), and prevent expensive transcode because an endpoint offered something exotic. Pair with the media fast path: if both legs share a codec, relay is free; if you let negotiation get sloppy, you pay CPU on every call.
Number & Identity Handling
- Rewrite on ingress — normalize carrier formats before routing sees them
- Rewrite on egress — apply the carrier’s expected prefix/shape per trunk
- Caller identity — override per route or per HTTP routing decision when a carrier demands a specific CLI
Number pools and DID management build on the same primitives; a DID maps to a normalized destination and a rewrite policy, not a special case in code.
Security at the Border
- IP allowlists per trunk (
allowed_ips) — only the carrier’s real egress addresses - ACL deny-by-default plus the built-in scanner User-Agent blacklist (see the hardening post)
- Frequency limits to absorb floods before they reach auth
- TLS/SRTP for carriers that support it, negotiated automatically (SDES) where they don’t
The Carrier Interop Checklist
- Signaling: transport (UDP/TCP/TLS), port, auth mode, register vs. IP trust
- Numbers: ingress/egress rewrite rules, DID mapping, CLI policy
- Codecs: agreed list, order, ptime; confirm no hidden transcoding
- Media: NAT/EIP routing profile, ICE-lite only if the peer needs it
- Headers: passthrough whitelist for partner metadata; strip the rest
- Health: OPTIONS probes, degraded-trunk skip in routing, specific reject reasons in CDRs
- Failover: backup trunk in the route with a defined priority
Do these seven and a carrier turn-up becomes a checklist instead of a negotiation. Guides: SBC Overview and Trunk Management.