Skip to content
TriedDocs
Telephony

SIP security

Lock each SIP trunk to known addresses and credentials, encrypt signalling and media, and the infrastructure steps for static IPs, an SBC and packet capture.

An open SIP endpoint attracts scanners and toll fraud. Tried locks each number's trunks with IP allow lists, digest credentials and encryption settings. This page lists what you can set per number or trunk, what is set for you, and the infrastructure steps for a production deployment.

Inbound: who may send calls#

Control Where Effect
allowed_inbound_addresses Number (API) or shared trunk Only these IPs or CIDRs may send INVITEs for the number.
inbound_auth_username, inbound_auth_password Shared trunk Your carrier must answer a digest challenge with these credentials.
Twilio gateway lock Automatic for Twilio trunks Numbers on a *.pstn.twilio.com trunk accept INVITEs only from Twilio's signalling blocks unless you set your own addresses. See Twilio.
TELNYX_INBOUND_ALLOWED_ADDRESSES API env Default allow list for Telnyx numbers. Empty by default.
REGISTER_CALL_ALLOWED_ADDRESSES or REGISTER_CALL_AUTH_* API env Required for the register-call trunk. See Register call.
allowed_inbound_country_list Number Callers from other countries are hung up.

An imported number with no allowed_inbound_addresses (and not on a Twilio trunk) accepts INVITEs for that number from any address. Set the list for your carrier or PBX.

Outbound: who may receive our calls#

  • Outbound calls authenticate to your trunk with sip_trunk_auth_username and sip_trunk_auth_password. The password is stored encrypted with AES-GCM and never returned by the API.
  • Add Tried's SIP address ranges to your trunk's allow list. GET /sip-origination returns them as ip_ranges (from SIP_OUTBOUND_IP_RANGES, defaulting to the LiveKit Cloud SIP ranges 143.223.88.0/21, 161.115.160.0/19 and 153.57.128.0/18).
  • Restrict destinations with allowed_outbound_country_list.

Encryption#

Setting Values Default
transport TCP, UDP, TLS TCP
media_encryption disabled (Off), allowed (Allowed (SRTP if offered)), required (Required (SRTP only)) allowed

Use TLS with required for full encryption of signalling and media when your carrier supports it. Change both on the number's Routing and SIP card; the trunks are re-provisioned.

Webhooks from carriers#

  • LiveKit: https://<api>/internal/livekit/webhook receives participant_joined and egress_ended. Inbound routing depends on it.
  • Telnyx: /telnyx/webhook requires a valid Ed25519 signature (TELNYX_PUBLIC_KEY).

Deployment steps#

These need infrastructure or carrier work, not application settings. Deployment step

Static signalling and media IPs#

  1. Run self-hosted livekit-sip and livekit-server on nodes with Elastic IPs (one per availability zone), with the external IP settings in livekit.yaml so SDP carries them.
  2. Publish the SIP signalling IPs (UDP and TCP 5060, TLS 5061) and the RTP port range to customers for their allow lists.
  3. Send outbound HTTP (webhooks, custom tools) through a NAT gateway with fixed IPs and publish those too.
  4. On LiveKit Cloud, use its published SIP ranges (dedicated addresses are an enterprise arrangement with LiveKit), or self-host for addresses you control.

SBC tier (Kamailio and rtpengine)#

  1. Put Kamailio (signalling) and rtpengine (media) in front of livekit-sip for TLS termination, rate limiting (pike), per-trunk IP ACLs, digest auth, topology hiding and header normalisation. Keep X- headers, User-to-User, Identity and P-Asserted-Identity.
  2. Route by request URI to the LiveKit SIP pool. The SBC addresses become the published static IPs.
  3. For mTLS on enterprise trunks, use per-peer TLS profiles with client certificate checks.

Packet capture#

  1. Run HEP capture on the SBC (Kamailio siptrace, rtpengine --homer) into a Homer cluster, kept 7 to 30 days.
  2. Until then, set TRIED_SIP_LOG_PATH to the livekit-sip log so GET /v2/get-call-sip-trace/:call_id returns the SIP log lines for a call. GET /get-call-pcap/:call_id returns 404 until capture exists.

Checklist#

  • Every imported number has allowed_inbound_addresses or sits on a Twilio trunk.
  • Shared trunks use inbound digest auth or an address list.
  • Outbound trunks use a strong, unique password.
  • Each number has outbound countries limited to where you call.
  • TLS and SRTP are on where the carrier supports them.
  • The LiveKit webhook and Telnyx webhook URLs are set and verified.