Platform Guide

Kamailio NAT Traversal with RTPEngine

10 min read  ·  Updated April 2026

NAT traversal is one of the hardest problems in SIP deployments. Kamailio uses RTPEngine (formerly RTPProxy) as a media proxy to anchor RTP streams and handle NAT. Here's how to configure it correctly and troubleshoot media path issues.

In this guide

1. Why RTPEngine?

RTPEngine is a high-performance media proxy that Kamailio uses to anchor RTP streams. When endpoints behind NAT advertise private IP addresses in their SDP, RTPEngine rewrites the SDP to point to itself, proxies the media, and relays it to the correct endpoint. The underlying technique is described in symmetric RTP and latching.

RTPEngine advantages over RTPProxy: kernel-space packet forwarding (much higher performance), native SRTP support and transcoding, ICE support for WebRTC interworking, and active development. RTPProxy is deprecated for most use cases.

2. Installation and setup

; Install on Ubuntu/Debian apt-get install ngcp-rtpengine ; Start RTPEngine rtpengine --interface=eth0 --listen-ng=127.0.0.1:2223 --port-min=10000 --port-max=20000 --log-level=6 --log-facility=daemon ; Or via systemd systemctl enable rtpengine systemctl start rtpengine ; Verify it's running rtpengine-ctl list # Should show: active calls, interfaces

3. Kamailio rtpengine module

loadmodule "rtpengine.so" modparam("rtpengine", "rtpengine_sock", "udp:127.0.0.1:2223") modparam("rtpengine", "rtpengine_disable_tout", 20) modparam("rtpengine", "rtpengine_tout_ms", 5000) modparam("rtpengine", "rtpengine_retr", 5)

4. SDP rewriting for NAT

request_route { if (is_method("INVITE")) { rtpengine_manage("replace-origin replace-session-connection"); } } onreply_route { if (status =~ "[12][0-9][0-9]") { rtpengine_manage("replace-origin replace-session-connection"); } } route[RELAY] { if (is_method("BYE")) { rtpengine_delete(); } t_relay(); }

The key flags: replace-origin rewrites the SDP o= line, replace-session-connection rewrites the c= line. Both are needed to fix private IP addresses in the SDP.

Force RTP proxy for all calls

; Always proxy — useful when you can't detect NAT reliably rtpengine_manage("force");

Proxy only when needed

; Only proxy if source IP != SDP IP (NAT detected) if (nat_uac_test("19")) { rtpengine_manage("replace-origin replace-session-connection"); } else { rtpengine_manage("direct"); }

5. ICE and SRTP handling

ICE removal (SIP-to-WebRTC bridging)

; Strip ICE from SIP side, keep for WebRTC side rtpengine_manage("ICE=remove SDES-off DTLS=off");

SRTP transcoding

; Encrypt plaintext RTP to SRTP for the far end rtpengine_manage("SRTP SDES-off"); ; Decrypt SRTP to plaintext RTP rtpengine_manage("RTP SDES-off");

WebRTC to SIP bridging

; Full WebRTC (DTLS-SRTP + ICE) to plain SIP rtpengine_manage("ICE=remove DTLS=off SDES-off replace-origin replace-session-connection");

6. Troubleshooting media issues

No audio after rtpengine rewrite: Check that RTPEngine is running and reachable from Kamailio. Use rtpengine-ctl list to see active sessions. If sessions are created but no audio flows, check firewall rules — the RTP port range (10000-20000) must be open.

One way audio after rewrite: Usually means only the INVITE SDP was rewritten but not the 200 OK SDP. Verify your onreply_route calls rtpengine_manage() for 1xx and 2xx responses.

Check RTPEngine logs:

journalctl -u rtpengine -f # Look for: "Creating new call", "Received offer", "ICE negotiations" # Errors: "No ports available" = increase port range # "Address family mismatch" = IPv4/IPv6 config issue

BYE not deleting RTPEngine session: Ensure rtpengine_delete() is called for BYE requests. Orphaned sessions accumulate and eventually exhaust the port pool.

Frequently asked questions

What is RTPEngine in Kamailio?

RTPEngine is a high-performance media proxy used with Kamailio for NAT traversal. It rewrites SDP connection addresses, proxies RTP streams between endpoints, and handles SRTP transcoding and WebRTC-to-SIP bridging. It replaces the older RTPProxy with kernel-space packet forwarding for much better performance at scale.

How do I fix one way audio with Kamailio and RTPEngine?

One way audio with RTPEngine usually means the SDP was only rewritten in the INVITE but not in the 200 OK response. Verify your onreply_route calls rtpengine_manage() for all 1xx and 2xx responses. Also check that RTPEngine firewall ports 10000-20000 are open bidirectionally.

How do I bridge WebRTC to SIP with Kamailio RTPEngine?

Use rtpengine_manage() with flags: ICE=remove DTLS=off SDES-off replace-origin replace-session-connection. This strips ICE candidates and converts DTLS-SRTP to plain RTP (or SDES-SRTP) for the SIP side. RTPEngine handles the media transcoding between the WebRTC and SIP legs.

Having NAT or media issues with Kamailio?

Paste your Kamailio SIP trace into SIPSymposium. The analyzer checks SDP rewriting, detects private IPs in connection addresses, and identifies RTPEngine session failures.

Analyze my trace Create free account
Related guides