SBC Interop: Topology Hiding, Header Hygiene and Carrier Checklists

M
Miuda Team
Building conversational AI tooling

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.

SIP trunk configuration — where SBC policies live

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_only is the handy default for partners who expect X- 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

  1. Signaling: transport (UDP/TCP/TLS), port, auth mode, register vs. IP trust
  2. Numbers: ingress/egress rewrite rules, DID mapping, CLI policy
  3. Codecs: agreed list, order, ptime; confirm no hidden transcoding
  4. Media: NAT/EIP routing profile, ICE-lite only if the peer needs it
  5. Headers: passthrough whitelist for partner metadata; strip the rest
  6. Health: OPTIONS probes, degraded-trunk skip in routing, specific reject reasons in CDRs
  7. 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.

Get new posts by email

Deep dives on Rust telephony, contact centers and wholesale voice. No spam.

Thanks — you're on the list.

We use cookies for anonymous analytics to improve the site. Nothing is loaded until you accept. Privacy Policy