How to receive audio from external SIP service (ElevenLabs AI) to Asterisk behind NAT in private subnet

Hi all,

I’m experimenting with connecting Asterisk to an external SIP-based AI voice agent service (ElevenLabs) for real-time customer interactions.

Setup:

  • Asterisk Server: AWS EC2 instance in a private subnet (no public IP).

  • Inbound Calls: From telecom provider X via AWS Direct Connect → Asterisk (works fine).

  • Call Flow: Once a call is answered, Asterisk plays a welcome message, then forwards the call to an ElevenLabs AI agent for real-time two-way communication.

  • Problem: ElevenLabs receives my audio, processes it, and generates a spoken response (confirmed via their dashboard), but that audio never reaches my Asterisk server.

    • SIP traces show that Asterisk advertises its private IP (e.g., 10.x.x.x) in SDP, so ElevenLabs tries to send RTP to that unreachable private IP.

    • The inbound RTP path from ElevenLabs fails due to NAT/private addressing.

Goal:

Without changing the existing telecom provider X → Private EC2 Direct Connect architecture, I’d like to allow ElevenLabs to send RTP audio back to my Asterisk server for testing. Ideally by exposing only what’s necessary for the return audio path.

Questions:

  1. Can Asterisk be configured to use a different public IP in its SDP just for the ElevenLabs SIP trunk, while still keeping the telecom provider X trunk as-is?

  2. Is there a recommended NAT traversal setup (e.g., Kamailio, RTP proxy, or Asterisk externaddr settings per peer) that can bridge a private Asterisk to an external SIP provider without giving the EC2 instance a permanent public IP?

  3. Any best practices for handling mixed public/private SIP legs in Asterisk?

Thanks for your help! :folded_hands:

Try rtpkeepalive=1

RTP Keepalive packet will be sent if no other RTP traffic on that connection. Default 0 (no RTP Keepalive)

I tried this along with other options.

; sip.conf -  ElevenLabs SIP Trunk Configuration

[general]
context=default
localnet=10.0.0.0/255.0.0.0
localnet=192.168.0.0/255.255.0.0
localnet=172.31.0.0/255.255.0.0
externip=10.xxx.xxx.xxx    ; Masked AWS private IP
; Enable TCP support for ElevenLabs
tcpenable=yes
tcpbindaddr=0.0.0.0

[elevenlabs]
type=peer
host=sip.rtc.elevenlabs.io
port=5060
transport=tcp
dtmfmode=rfc2833

; Updated codec configuration - try all three codecs as suggested by Pieris
disallow=all
allow=ulaw        ; G711U (µ-law) - Primary codec
allow=alaw        ; G711A (a-law) - Secondary codec  
allow=g722        ; G722 - Third option

; Audio and RTP settings
qualify=no
canreinvite=no    ; Force media through Asterisk
directmedia=no    ; Ensure all RTP goes through Asterisk
insecure=invite,port

; NAT and RTP handling - Critical for audio issues
nat=force_rport,comedia
rtpkeepalive=10   ; Keep RTP alive with 10-second intervals
rtp_symmetric=yes ; Use symmetric RTP

; RTP port range (make sure these ports are open in firewall)
rtpstart=10000
rtpend=60000

; Audio codec negotiation
videosupport=no
t38support=no

; Context for incoming calls
context=from-elevenlabs

; Additional RTP settings for better audio handling
rtcpinterval=5000
strictrtp=yes

Yes, but you need to upgrade to chan_pjsip.

Hi David,
Just to clarify — you mean switching from my current sip.conf (chan_sip) setup to chan_pjsip (pjsip.conf) would solve this?

Right now the issue is that Asterisk always advertises its private IP 10.167.x.x in the SDP and Contact headers, so ElevenLabs sends RTP to that unreachable address. Outbound audio reaches them fine, but their inbound audio never comes back because it’s going to that private IP.

Would moving to chan_pjsip let me configure a different public external_media_address / external_signaling_address just for the ElevenLabs trunk, while keeping my Telco X trunk on the private Direct Connect?

chan_pjsip allows you to have different transports for different endpoints, and those transports indirect the basic transport type and include information like the external addresses.

This will not work for “External” also you need to change in the rtp.conf file “icesupport=yes”

Using pjsip you can configure an external media and signaling address for a specific transport, see:

Try the direct connector to ElevenLabs. In my experience it’s more stable than the original SIP trunk since it runs over WebSocket connections.

hope it helps

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.