Tls: Difference between revisions

From VoIPmonitor.org
(Add Method 3: TLS Decryption in Distributed/Client-Server Mode - explains the critical requirement to send SSL session keys to central server IP when using packetbuffer_sender=yes, not localhost or client sensor)
(Add critical info for FreeSWITCH DTLS+SRTP decryption: User=root required in systemd service with -u/-g flags in ExecStart)
 
(29 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{DISPLAYTITLE:Guide to Decrypting TLS and SRTP Traffic}}
{{DISPLAYTITLE:TLS and SRTP Decryption}}
[[Category:Configuration]]


'''This guide provides a comprehensive overview of the methods used by VoIPmonitor to decrypt encrypted SIP over TLS and encrypted media (SRTP). It covers the two primary decryption approaches: using a static private key and using the dynamic SSL Key Logger.'''
'''This guide covers how to decrypt encrypted SIP (TLS) and media (SRTP/DTLS-SRTP) traffic in VoIPmonitor.'''


== Introduction to TLS Decryption ==
= Understanding TLS Decryption =
VoIPmonitor can decrypt SIP signaling encrypted with TLS (v1.2 and v1.3 supported) and media encrypted with SRTP. It is essential to understand that not all TLS traffic can be decrypted.


'''Important Limitation:''' If the SIP session negotiates a cipher suite using a '''Perfect Forward Secrecy (PFS)''' algorithm, such as '''Diffie-Hellman (DHE/ECDHE)''', decryption using only the server's private key is mathematically impossible. In these cases, you '''must''' use the SSL Key Logger method to capture session-specific keys.
VoIPmonitor can decrypt TLS-encrypted SIP signaling and SRTP media. The method you choose depends on your TLS configuration.


Decrypted SIP packets are stored in PCAP files as virtual UDP packets for consistent analysis within the GUI.
== Cipher Suite Impact ==


== Method 1: Private Key Decryption ==
{| class="wikitable"
This is the simpler method and works well for environments where you control the TLS cipher suites and can disable PFS.
! TLS Version / Cipher !! Private Key Decryption !! SSL Key Logger
|-
| TLS 1.2 with RSA (no DH) || {{Yes}} Works || {{Yes}} Works
|-
| TLS 1.2 with DHE/ECDHE || {{No}} Impossible || {{Yes}} Required
|-
| TLS 1.3 (any cipher) || {{No}} Impossible || {{Yes}} Required
|}


=== Configuration ===
{{Warning|1=Modern VoIP services use TLS 1.3 or PFS ciphers. The SSL Key Logger (Method 2) is the '''only viable method''' for most deployments.}}
To enable this method, add the following to `/etc/voipmonitor.conf`:
 
<pre>
To check your cipher suite, capture the TLS handshake in Wireshark and look for "DHE" or "ECDHE" in the cipher negotiation.
 
== Method Overview ==
 
<kroki lang="mermaid">
%%{init: {'flowchart': {'nodeSpacing': 15, 'rankSpacing': 30}}}%%
flowchart TD
    Q1{Can you control<br>PBX/SBC?} -->|Yes| Q2{Using DHE/ECDHE<br>or TLS 1.3?}
    Q1 -->|No - Cloud/Hosted| M4[Method 4: Vendor Tunneling<br>or Method 5: External Key Provider]
    Q2 -->|No - RSA only| M1[Method 1: Private Key]
    Q2 -->|Yes| M2[Method 2: SSL Key Logger]
    M2 -->|Distributed arch| M3[Method 3: Distributed Mode]
</kroki>
 
'''Quick Reference:'''
* '''Method 1''' - Private Key: Simple, but only works for non-PFS ciphers
* '''Method 2''' - SSL Key Logger: Universal, works for all ciphers (recommended)
* '''Method 3''' - Distributed Mode: For client-server architecture with <code>packetbuffer_sender=yes</code>
* '''Method 4''' - SBC/PBX Tunneling: Ribbon, AudioCodes, or other vendor solutions
* '''Method 5''' - External Key Provider: Hosted platforms (NetSapiens, etc.)
* '''Method 6''' - HEP Protocol: Alternative when SSL Key Logger isn't feasible
 
== Cloud Service Limitations ==
 
{| class="wikitable"
! Scenario !! Decryption Possible?
|-
| Hardware phone → Cloud (Teams, Webex) || {{No}} Not possible (no access to cloud keys)
|-
| Softphone on controlled host → Cloud || {{Yes}} Use SSL Key Logger on the host
|-
| Phone → Local SBC → Cloud || {{Yes}} Use SBC tunneling (Method 4)
|}
 
= Method 1: Private Key Decryption =
 
Works only for TLS 1.2 or older '''without''' Diffie-Hellman ciphers.
 
== Configuration ==
 
<syntaxhighlight lang="ini">
# /etc/voipmonitor.conf
# /etc/voipmonitor.conf
ssl = yes
ssl_ipport = 10.0.0.1:5061 /etc/pki/tls/private/server.key
</syntaxhighlight>


# Enable the SSL decryption module
'''Multiple servers:'''
ssl = yes
<syntaxhighlight lang="ini">
ssl_ipport = 10.0.0.1:5061 /path/to/server1.key
ssl_ipport = 10.0.0.2:5061 /path/to/server2.key
</syntaxhighlight>


# Provide the server's IP, TLS port, and the absolute path to its private key.
== GUI Configuration ==
# The key must be in PEM format. You can have multiple lines for multiple servers.
ssl_ipport = 10.0.0.1 : 5061 /etc/pki/tls/private/my_server.key
</pre>


== Method 2: SSL Key Logger (Recommended & Universal) ==
Navigate to '''Settings > Sensors > wrench icon''' and search for <code>ssl_</code>:
This is the most powerful and recommended method. It works for '''all''' cipher suites, including those with Perfect Forward Secrecy, by dynamically capturing session keys directly from the application's memory.
* <code>ssl = yes</code>
* <code>ssl_ipport = IP:PORT /path/to/key</code>


It works by using the `LD_PRELOAD` mechanism to inject a small library (`sslkeylog.so`) into your SIP application (e.g., Asterisk, Kamailio, FreeSWITCH). This library intercepts the creation of new SSL/TLS session keys and sends them over the network (UDP or secure TCP) to the VoIPmonitor sensor.
= Method 2: SSL Key Logger (Recommended) =


=== Step 1: Compile the SSL Key Logger Library ===
Works for '''all''' cipher suites including PFS. Captures session keys from your PBX/SBC using <code>LD_PRELOAD</code>.
First, you need to compile the `sslkeylog.so` library on the same server as your SIP application.


;1. Install prerequisites:
== Step 1: Compile the Library ==
<pre>
# For Debian/Ubuntu
apt-get install libssl-dev build-essential git


# For CentOS/RHEL/AlmaLinux
<syntaxhighlight lang="bash">
yum install openssl-devel make gcc git
# Install prerequisites
</pre>
apt-get install libssl-dev build-essential git  # Debian/Ubuntu
yum install openssl-devel make gcc git           # RHEL/CentOS


;2. Clone the repository and compile:
# Compile
<pre>
cd /usr/local/src
cd /usr/local/src
git clone https://github.com/voipmonitor/sniffer.git voipmonitor-git
git clone https://github.com/voipmonitor/sniffer.git voipmonitor-git
cd voipmonitor-git/tools/ssl_keylogger/
cd voipmonitor-git/tools/ssl_keylogger/
make
make
</pre>
</syntaxhighlight>
This will create the `sslkeylog.so` library in the current directory.
 
{{Tip|For WolfSSL: <code>make ssl=wolf CXXFLAGS="-DHAVE_WOLFSSL" LDFLAGS="-lwolfssl"</code>}}
 
== Step 2: Configure Your PBX ==
 
=== Asterisk ===


=== Step 2: Configure Your SIP Application to Use the Key Logger ===
<syntaxhighlight lang="bash">
You must modify the startup script or service file of your SIP application to preload the library.
# Create environment file
cat > /etc/default/asterisk-ssl << 'EOF'
SSLKEYLOG_UDP='127.0.0.1:1234'
LD_PRELOAD='/usr/local/src/voipmonitor-git/tools/ssl_keylogger/sslkeylog.so'
EOF


;General Test (works for any application using OpenSSL):
# Add to service
First, test that the library works correctly. This command should print "SSL KEYLOG : OK" messages.
systemctl edit asterisk.service
<pre>
</syntaxhighlight>
env SSLKEYLOG_UDP='127.0.0.1:1234' LD_PRELOAD="/usr/local/src/voipmonitor-git/tools/ssl_keylogger/sslkeylog.so" openssl
</pre>


==== Asterisk ====
Add:
For `systemd`, create an environment file for the Asterisk service.
<syntaxhighlight lang="ini">
;1. Edit the service file: `systemctl edit asterisk.service` and add:
<pre>
[Service]
[Service]
EnvironmentFile=/etc/default/asterisk-ssl
EnvironmentFile=/etc/default/asterisk-ssl
</pre>
</syntaxhighlight>
;2. Create the environment file `/etc/default/asterisk-ssl` with the following content:
<pre>
# IP and Port where VoIPmonitor sensor is listening
SSLKEYLOG_UDP='127.0.0.1:1234'
LD_PRELOAD='/usr/local/src/voipmonitor-git/tools/ssl_keylogger/sslkeylog.so'
</pre>
;3. Reload and restart: `systemctl daemon-reload && systemctl restart asterisk`


==== Kamailio ====
Restart: <code>systemctl daemon-reload && systemctl restart asterisk</code>
Kamailio often loads OpenSSL dynamically, so you must preload both the key logger and the main SSL library.
;Modify your `/etc/init.d/kamailio` or systemd service file's `ExecStart` line:
<pre>
# The path to libssl may vary. Find it with: find / -name "libssl.so*"
env SSLKEYLOG_UDP='127.0.0.1:1234' LD_PRELOAD="/usr/local/src/voipmonitor-git/tools/ssl_keylogger/sslkeylog.so /usr/lib/x86_64-linux-gnu/libssl.so" /usr/sbin/kamailio ...
</pre>


==== FreeSWITCH ====
=== FreeSWITCH ===
FreeSWITCH can be sensitive to `systemd` settings. It's often necessary to modify the service file directly.
;Edit `/lib/systemd/system/freeswitch.service` and change `ExecStart` to:
<pre>
ExecStart=env SSLKEYLOG_UDP='10.0.0.1:1234' LD_PRELOAD='/usr/local/src/voipmonitor-git/tools/ssl_keylogger/sslkeylog.so' /usr/bin/freeswitch -u www-data -g www-data -nonat
</pre>
Then run `systemctl daemon-reload && systemctl restart freeswitch`.


=== Step 3: Configure VoIPmonitor to Receive Session Keys ===
Edit <code>/lib/systemd/system/freeswitch.service</code>:
In `/etc/voipmonitor.conf` on your sensor, you must enable the listener and, crucially, tell the sniffer which traffic to apply the keys to '''using the correct syntax'''.


'''CRITICAL CONFIGURATION NOTE:'''
{{Warning|1='''Critical for DTLS+SRTP decryption:''' systemd must start the service as <code>root</code> so <code>LD_PRELOAD</code> can inject the keylogger before FreeSWITCH drops privileges. Set <code>User=root</code> in the service file and use <code>-u</code>/<code>-g</code> flags in <code>ExecStart</code> for FreeSWITCH to drop privileges internally.}}
When using the SSL Key Logger method, the `ssl_ipport` directive '''must only''' specify the IP address and port. It '''must not''' include a path to a key file.


Including a key file path forces VoIPmonitor to use Method 1 (Private Key) for that specific IP:Port, which will override the key logger and cause decryption to fail if PFS ciphers are in use.
<syntaxhighlight lang="ini">
[Service]
User=root
Group=root
ExecStart=env SSLKEYLOG_UDP='127.0.0.1:1234' LD_PRELOAD='/usr/local/src/voipmonitor-git/tools/ssl_keylogger/sslkeylog.so' /usr/bin/freeswitch -u freeswitch -g freeswitch -nonat
</syntaxhighlight>
 
Then reload and restart:
<syntaxhighlight lang="bash">
systemctl daemon-reload
systemctl restart freeswitch
</syntaxhighlight>


<pre>
=== Kamailio ===
# /etc/voipmonitor.conf
 
{{Warning|1=Kamailio requires '''all three libraries''' in LD_PRELOAD to avoid crashes:}}


# Enable the listener for session keys
<syntaxhighlight lang="bash">
ssl_sessionkey_udp = yes
# Find library paths
find /usr/lib -name "libssl.so*" -o -name "libjson-c.so*"
</syntaxhighlight>


# The port must match the one set in the SSLKEYLOG_UDP environment variable
Edit service file:
ssl_sessionkey_udp_port = 1234
<syntaxhighlight lang="ini">
ExecStart=env SSLKEYLOG_UDP='127.0.0.1:1234' LD_PRELOAD='/usr/local/src/voipmonitor-git/tools/ssl_keylogger/sslkeylog.so:/usr/lib/x86_64-linux-gnu/libssl.so.3:/usr/lib/x86_64-linux-gnu/libjson-c.so.5' /usr/sbin/kamailio ...
</syntaxhighlight>


# Optional: Restrict listener to a specific IP or subnet
== Step 3: Configure VoIPmonitor ==
# ssl_sessionkey_udp_ip = 192.168.0.0/24


# Enable the SSL decryption module globally
<syntaxhighlight lang="ini">
# /etc/voipmonitor.conf
ssl = yes
ssl = yes
ssl_sessionkey_udp = yes
ssl_sessionkey_udp_port = 1234


# CORRECT SYNTAX for the Key Logger Method:
# CRITICAL: No key file path when using SSL Key Logger!
# Tell the sensor which IP:Port to apply the received session keys to.
# Notice there is NO path to a key file.
ssl_ipport = 192.168.0.1:5061
ssl_ipport = 192.168.0.1:5061


# --------------------------------------------------------------------
# Include loopback if sending keys to 127.0.0.1
interface = eth0,lo
</syntaxhighlight>
 
{{Warning|1='''WRONG:''' <code>ssl_ipport = IP:PORT /path/to/key</code> — This forces Method 1 and ignores the key logger!<br>'''CORRECT:''' <code>ssl_ipport = IP:PORT</code> — No key file path.}}
 
== Secure Key Transport (TCP Mode) ==


# INCORRECT SYNTAX for the Key Logger Method:
For production environments, use TCP instead of UDP:
# The following line will IGNORE the key logger and try to use the key file,
# which will fail for DHE/ECDHE ciphers. DO NOT USE THIS SYNTAX WITH THE KEY LOGGER.
# ssl_ipport = 192.168.0.1:5061 /path/to/my_server.key
</pre>


=== Securing Key Transport (TCP Mode) ===
<syntaxhighlight lang="bash">
By default, keys are sent unencrypted over UDP. For production environments where the sensor and PBX are on different hosts, it is recommended to use the secure TCP mode.
# Recompile with TCP support
;1. Compile the keylogger with TCP support:
<pre>
cd /usr/local/src/voipmonitor-git/tools/ssl_keylogger/
cd /usr/local/src/voipmonitor-git/tools/ssl_keylogger/
make with_tcp
make clean && make with_tcp
</pre>
</syntaxhighlight>
;2. Change the environment variable on your PBX from `SSLKEYLOG_UDP` to `SSLKEYLOG_TCP`.
 
;3. Change the VoIPmonitor sensor configuration to listen on TCP:
On PBX: Change <code>SSLKEYLOG_UDP</code> to <code>SSLKEYLOG_TCP</code>
<pre>
 
# In voipmonitor.conf
On VoIPmonitor:
<syntaxhighlight lang="ini">
ssl_sessionkey_udp = no
ssl_sessionkey_udp = no
ssl_sessionkey_bind = 0.0.0.0 # IP for the sniffer to listen on
ssl_sessionkey_bind = 0.0.0.0
ssl_sessionkey_bind_port = 1234
ssl_sessionkey_bind_port = 1234
</pre>
</syntaxhighlight>


== Method 3: TLS Decryption in Distributed/Client-Server Mode ==
= Method 3: Distributed Mode =
When using VoIPmonitor's client-server architecture (<code>packetbuffer_sender=yes</code>), remote sensors forward raw packets to a central server. In this configuration, TLS/SRTP decryption '''must''' occur on the central server. This requires special configuration for the SSL Key Logger to send session keys to the correct destination.


=== Architecture Overview ===
When using <code>packetbuffer_sender=yes</code>, session keys '''must''' go to the central server.
 
When a client sensor forwards packets with <code>packetbuffer_sender=yes</code>:
* The client sensor sends raw packet stream to the central server
* The central server performs packet analysis and decryption
* Session keys from the PBX must be sent to the '''central server''', not the remote client sensor


<kroki lang="plantuml">
<kroki lang="plantuml">
@startuml
@startuml
skinparam shadowing false
skinparam shadowing false
skinparam defaultFontName Arial
rectangle "PBX" as PBX
 
rectangle "PBX Server" as PBX
rectangle "Client Sensor" as Client
rectangle "Client Sensor" as Client
rectangle "Central Server" as Central
rectangle "Central Server" as Central


PBX --(1)--> Central : Session Keys\n(SSLKEYLOG to Central IP)
PBX --> Central : Session Keys (direct)
Client --(2)--> Central : Raw Packets\n(packetbuffer_sender=yes)
Client --> Central : Raw Packets
 
note right of PBX: SSLKEYLOG_UDP must\\npoint to Central IP
note right of Client
  Client does NOT\nreceive session keys
end note
 
note right of PBX
  Send keys to\nCentral Server IP
  NOT to localhost
  or client sensor
end note
@enduml
@enduml
</kroki>
</kroki>


=== Configuration for Distributed Mode ===
'''On PBX:'''
<syntaxhighlight lang="ini">
# Send keys to CENTRAL SERVER, not localhost!
SSLKEYLOG_UDP='192.168.1.100:1234'  # Central server IP
</syntaxhighlight>


'''Step 1: Configure Client Sensor'''
'''On Central Server:'''
<code>/etc/voipmonitor.conf</code> on the remote client sensor:
<syntaxhighlight lang="ini">
<syntaxhighlight lang="ini">
id_sensor              = 2
ssl = yes
server_destination      = central.server.ip
ssl_sessionkey_udp = yes
server_destination_port = 60024
ssl_sessionkey_udp_port = 1234
server_password        = your_strong_password
ssl_ipport = 192.168.1.50:5061  # PBX IP (no key file)
</syntaxhighlight>
 
= Method 4: SBC/PBX Tunneling =
 
Some SBCs decrypt internally and forward unencrypted traffic via tunneling protocols.
 
{| class="wikitable"
! Vendor !! Protocol !! Documentation
|-
| Ribbon/Oracle || Monitoring Profile || [[Ribbon7k_monitoring_profiles]]
|-
| AudioCodes || Proprietary tunnel || [[Audiocodes_tunneling]]
|-
| Generic || IPinIP || Auto-decoded by VoIPmonitor
|}
 
{{Note|1=When using vendor tunneling, '''no SSL configuration''' is needed in VoIPmonitor—traffic arrives unencrypted.}}
 
= Method 5: External Key Providers =
 
Some hosted platforms (e.g., NetSapiens) can export TLS session keys to VoIPmonitor. Configure VoIPmonitor to receive keys via UDP/TCP as in Method 2.
 
= Method 6: HEP Protocol =
 
Alternative when SSL Key Logger doesn't work. The SIP proxy decrypts traffic and sends it via HEP.


packetbuffer_sender    = yes   # Forward raw packets to central server
<syntaxhighlight lang="ini">
interface              = eth0
# /etc/voipmonitor.conf
# NO ssl_* configuration needed on client
receiver_mode = yes
hep = yes
hep_bind_ip = 0.0.0.0
hep_bind_port = 9060
</syntaxhighlight>
</syntaxhighlight>


'''Step 2: Configure PBX sslkeylog to Send Keys to Central Server'''
{{Note|1=HEP is just transport. Your SIP proxy must decrypt TLS '''before''' encapsulating in HEP. See [[Sniffing_modes#HEP_(Homer_Encapsulation_Protocol)|HEP documentation]].}}
On your PBX server, the <code>SSLKEYLOG_UDP</code> or <code>SSLKEYLOG_TCP</code> variable '''MUST'' point to the central server's IP address, '''NOTlocalhost or the client sensor'''.
 
= SRTP/DTLS Decryption =
 
== Recommended Configuration ==


<syntaxhighlight lang="ini">
<syntaxhighlight lang="ini">
# /etc/default/asterisk-ssl (example)
# Enables best-practice DTLS settings
ssl_dtls_boost = yes
</syntaxhighlight>


# CRITICAL: Send keys to CENTRAL SERVER IP and port
== RTP Proxy Issues (rtpengine) ==
# NOT to localhost, NOT to client sensor
SSLKEYLOG_UDP='192.168.1.100:1234'  # Central Server IP : ssl_sessionkey_udp_port
LD_PRELOAD='/usr/local/src/voipmonitor-git/tools/ssl_keylogger/sslkeylog.so'
</syntaxhighlight>


'''Step 3: Configure Central Server'''
If SRTP decryption fails with SDES keys visible in SDP, your RTP proxy may be stripping keys.
<code>/etc/voipmonitor.conf</code> on the central server:
<syntaxhighlight lang="ini">
# Server mode configuration
server_bind            = 0.0.0.0
server_bind_port      = 60024
server_password        = your_strong_password


mysqlhost              = localhost
'''Fix for rtpengine (Kamailio):'''
mysqldb                = voipmonitor
<syntaxhighlight lang="javascript">
mysqluser              = voipmonitor
rtpengine_manage("replace-origin DTLS=no SDES-nonew SDES-pad");
mysqlpassword          = db_password
</syntaxhighlight>


# Enable SSL decryption on central server
== Garbled Audio ==
ssl = yes


# Accept session keys from PBX
Garbled/distorted audio usually means SRTP is encrypted but not decrypted—'''not''' a codec issue.
ssl_sessionkey_udp = yes
ssl_sessionkey_udp_port = 1234  # Must match SSLKEYLOG_UDP port on PBX


# Apply keys to the PBX's TLS/IP address
'''Solution:''' Configure SSL Key Logger as described in Method 2, then verify keys are being received:
ssl_ipport = 192.168.1.50:5061  # PBX IP and TLS port (no key file path)
<syntaxhighlight lang="bash">
tcpdump -i any -n port 1234  # Check for UDP key packets
</syntaxhighlight>
</syntaxhighlight>


=== Common Configuration Error ===
= Troubleshooting =


'''Symptom:''' TLS/SRTP decryption fails when <code>packetbuffer_sender=yes</code> is enabled, but works with <code>packetbuffer_sender=no</code>.
== Decryption Not Working ==


'''Root Cause:''' The PBX's <code>SSLKEYLOG_UDP</code> is pointing to <code>127.0.0.1</code> (localhost) instead of the central server's IP address. Session keys are received by the client sensor, but the client sensor forwards only raw packets to the central server - the keys are lost in transit.
'''Step 1: Verify packets are captured'''
* Check <code>sip:history (+)</code> in CDR detail
* Packets visible but encrypted → decryption issue
* Packets missing → capture issue (check interface config)


'''Fix:''' Change the PBX environment variable:
'''Step 2: Check configuration'''
;Wrong (causes decryption failure in distributed mode):
 
<pre>
{| class="wikitable"
SSLKEYLOG_UDP='127.0.0.1:1234'
! Issue !! Solution
</pre>
|-
| Keys sent to localhost but not captured || Add <code>lo</code> to interface: <code>interface = eth0,lo</code>
|-
| TCP/TLS packets not captured || Remove/fix BPF filter: <code>filter = udp or tcp or (vlan and (udp or tcp))</code>
|-
| <code>ssl_ipport</code> has key file path || Remove key path when using SSL Key Logger
|-
| <code>packetbuffer_sender=yes</code> fails || Send keys to central server IP, not localhost
|-
| FreeSWITCH not capturing DTLS+SRTP keys || Set <code>User=root</code> in systemd service file, use <code>-u</code>/<code>-g</code> flags in <code>ExecStart</code>
|}


;Correct (send keys directly to central server):
== Compilation/Startup Issues ==
<pre>
SSLKEYLOG_UDP='192.168.1.100:1234'  # Central server's IP address
</pre>


=== Using TCP Mode in Distributed Deployments ===
{| class="wikitable"
! Error !! Platform !! Solution
|-
| <code>undefined symbol: dlsym</code> || RHEL/CentOS/VitalPBX || Recompile: <code>g++ -shared -o sslkeylog.so sslkeylog.o -ldl</code> (library flags after objects)
|-
| FreeSWITCH stuck in "activating" || Any || Recompile without TCP: <code>make clean && make</code>; set <code>DEBUG 0</code> and <code>WRITE_THREAD 0</code>
|-
| Kamailio <code>receive_fd(): EOF</code> || Debian 12 || Add libjson-c.so to LD_PRELOAD (see Kamailio section)
|-
| Environment variables not loaded || Any || Use <code>asterisk -r</code> then <code>core stop now</code> instead of systemctl restart
|}


For secure key transport in distributed architectures, use TCP mode.
== High Traffic Issues ==


On the PBX:
'''Symptom:''' Packet drops, TLS calls not decrypted under load
<syntaxhighlight lang="bash">
# Use TCP instead of UDP
SSLKEYLOG_TCP='192.168.1.100:1234'
LD_PRELOAD='/usr/local/src/voipmonitor-git/tools/ssl_keylogger/sslkeylog.so'
</syntaxhighlight>


On the Central Server:
'''Solution 1:''' Increase wait time:
<syntaxhighlight lang="ini">
<syntaxhighlight lang="ini">
ssl_sessionkey_udp = no
ssl_sessionkey_maxwait_ms = 5000
ssl_sessionkey_bind = 0.0.0.0        # Accept connections on all interfaces
ssl_sessionkey_bind_port = 1234
</syntaxhighlight>
</syntaxhighlight>


=== Summary Checklist ===
'''Solution 2:''' Switch to TCP mode (see "Secure Key Transport" above)
 
== Capture for Support ==
 
<syntaxhighlight lang="bash">
# Capture TLS traffic + keylogger packets
tcpdump -i eth0,lo -w /tmp/debug.pcap \
  "((host PBX_IP and port 5061) or (port 1234))"
</syntaxhighlight>


For successful TLS/SRTP decryption with <code>packetbuffer_sender=yes</code>:
Provide to support:
* CDR ID
* <code>voipmonitor --version</code>
* Config snippet (ssl*, interface, packetbuffer_sender)
* The PCAP file


* Client sensor: Enable <code>packetbuffer_sender=yes</code>, forward raw packets
= See Also =
* Central server: Enable <code>ssl=1</code> and configure SSL key listener
* PBX: Set <code>SSLKEYLOG_UDP</code> to '''central server IP''', not localhost or client sensor
* Central server's <code>ssl_ipport</code> must match PBX IP:port (no key file path)
* Central server's <code>ssl_sessionkey_udp_port</code> must match PBX's <code>SSLKEYLOG_UDP</code> port


== Decrypting SRTP (DTLS) ==
* [[Audiocodes_tunneling]] - AudioCodes SBC tunneling
Decrypting SRTP requires capturing both the DTLS handshake packets (which happen before RTP) and the session keys from the key logger. VoIPmonitor uses a sophisticated queueing system to hold DTLS packets until the corresponding session key arrives.
* [[Ribbon7k_monitoring_profiles]] - Ribbon/Oracle SBC monitoring
* [[WebRTC]] - WebRTC/WSS decryption
* [[Sniffer_configuration]] - Full configuration reference
* [[Sniffer_distributed_architecture]] - Client-server architecture


;Recommended Configuration:
= AI Summary for RAG =
The <code>ssl_dtls_boost</code> pseudo-parameter enables a set of recommended defaults for robust decryption. It is enabled by default in recent versions.
<pre>
# This single parameter enables the best-practice settings below it.
ssl_dtls_boost = yes


# --- Settings enabled by ssl_dtls_boost ---
'''Summary:''' Guide to decrypting TLS-encrypted SIP and SRTP media in VoIPmonitor. Six methods: (1) Private Key - only for TLS 1.2 without DHE/ECDHE, configure <code>ssl_ipport=IP:PORT /path/to/key</code>; (2) SSL Key Logger (recommended) - universal for all ciphers, inject <code>sslkeylog.so</code> via LD_PRELOAD into Asterisk/Kamailio/FreeSWITCH, keys sent via UDP or TCP; (3) Distributed Mode - with <code>packetbuffer_sender=yes</code>, send keys to central server IP not localhost; (4) SBC Tunneling - Ribbon/AudioCodes decrypt internally; (5) External Key Providers - hosted platforms export keys; (6) HEP - SIP proxy decrypts then sends via HEP. Critical: when using SSL Key Logger, <code>ssl_ipport</code> must NOT include key file path. For localhost keys, add <code>lo</code> to interface. Kamailio requires three libraries in LD_PRELOAD. FreeSWITCH requires <code>User=root</code> in systemd service file with <code>-u</code>/<code>-g</code> flags in ExecStart for DTLS+SRTP decryption to work. High traffic: use TCP mode or increase <code>ssl_sessionkey_maxwait_ms</code>. Garbled audio = SRTP encryption not codec issue.
# ssl_dtls_queue_expiration = 30
# ssl_sessionkey_keep = yes
# ssl_dtls_queue_keep = yes
# ssl_dtls_handshake_safe = ext
# srtp_rtp_local_instances = yes
</pre>


== AI Summary for RAG ==
'''Keywords:''' tls, ssl, srtp, dtls, decryption, sslkeylog, ld_preload, session key, asterisk, kamailio, freeswitch, ssl_ipport, ssl_sessionkey_udp, packetbuffer_sender, distributed mode, ribbon sbc, audiocodes, hep, rtpengine, pfs, perfect forward secrecy, garbled audio, dlsym error
'''Summary:''' This guide details the three methods for decrypting TLS-encrypted SIP and SRTP media in VoIPmonitor. Method 1, Private Key Decryption, uses `ssl=yes` with an `ssl_ipport` specifying a private key file path; this method fails for Perfect Forward Secrecy (PFS) ciphers like Diffie-Hellman. Method 2, the SSL Key Logger, is the universal solution working with all ciphers. It injects `sslkeylog.so` into SIP applications (Asterisk, Kamailio, FreeSWITCH) via `LD_PRELOAD`, which intercepts and sends session keys to the VoIPmonitor sensor. The critical syntax rule for Method 2: `ssl_ipport` must NOT include a key file path. Method 3 describes TLS decryption in distributed client-server architecture with `packetbuffer_sender=yes`. The common issue in distributed mode is that PBX's `SSLKEYLOG_UDP` often points to `127.0.0.1` instead of the central server's IP, causing decryption failure. The fix is to send session keys directly to the central server (e.g., `SSLKEYLOG_UDP='192.168.1.100:1234'`) and configure `ssl_sessionkey_udp`, `ssl_sessionkey_udp_port`, and `ssl_ipport` on the central server. TCP mode is recommended for secure key transport using `SSLKEYLOG_TCP`, `ssl_sessionkey_bind`, and `ssl_sessionkey_bind_port`. The guide also covers DTLS-SRTP decryption with the recommended `ssl_dtls_boost` parameter.
'''Keywords:''' tls, ssl, srtp, dtls, decryption, decrypt, encrypted, pfs, perfect forward secrecy, diffie-hellman, private key, sslkeylog, ld_preload, session key, asterisk, kamailio, freeswitch, `ssl_ipport`, `ssl_sessionkey_udp`, `ssl_dtls_boost`, `make with_tcp`, syntax, distributed architecture, client-server, `packetbuffer_sender`, central server, remote sensor, `SSLKEYLOG_UDP`, `SSLKEYLOG_TCP`, `ssl_sessionkey_bind`, `ssl_sessionkey_bind_port`
'''Key Questions:'''
* How do I decrypt TLS encrypted SIP calls?
* Why is VoIPmonitor not decrypting my TLS traffic?
* What is the correct syntax for `ssl_ipport` when using the SSL Key Logger?
* What is the SSL Key Logger and how does it work?
* How to configure Asterisk or FreeSWITCH to send TLS session keys to VoIPmonitor?
* How do I decrypt calls that use Diffie-Hellman (DHE/ECDHE) ciphers?
* What is `LD_PRELOAD` and how is it used for decryption?
* How can I decrypt SRTP and DTLS media streams?
* What does the `ssl_dtls_boost` parameter do?
* How to configure TLS decryption with `packetbuffer_sender=yes` in distributed mode?
* Why does TLS decryption work with `packetbuffer_sender=no` but fail with `packetbuffer_sender=yes`?
* Where should I send SSL session keys in a VoIPmonitor client-server architecture?

Latest revision as of 10:43, 9 January 2026


This guide covers how to decrypt encrypted SIP (TLS) and media (SRTP/DTLS-SRTP) traffic in VoIPmonitor.

Understanding TLS Decryption

VoIPmonitor can decrypt TLS-encrypted SIP signaling and SRTP media. The method you choose depends on your TLS configuration.

Cipher Suite Impact

TLS Version / Cipher Private Key Decryption SSL Key Logger
TLS 1.2 with RSA (no DH) ✓ Yes Works ✓ Yes Works
TLS 1.2 with DHE/ECDHE ✗ No Impossible ✓ Yes Required
TLS 1.3 (any cipher) ✗ No Impossible ✓ Yes Required

⚠️ Warning: Modern VoIP services use TLS 1.3 or PFS ciphers. The SSL Key Logger (Method 2) is the only viable method for most deployments.

To check your cipher suite, capture the TLS handshake in Wireshark and look for "DHE" or "ECDHE" in the cipher negotiation.

Method Overview

Quick Reference:

  • Method 1 - Private Key: Simple, but only works for non-PFS ciphers
  • Method 2 - SSL Key Logger: Universal, works for all ciphers (recommended)
  • Method 3 - Distributed Mode: For client-server architecture with packetbuffer_sender=yes
  • Method 4 - SBC/PBX Tunneling: Ribbon, AudioCodes, or other vendor solutions
  • Method 5 - External Key Provider: Hosted platforms (NetSapiens, etc.)
  • Method 6 - HEP Protocol: Alternative when SSL Key Logger isn't feasible

Cloud Service Limitations

Scenario Decryption Possible?
Hardware phone → Cloud (Teams, Webex) ✗ No Not possible (no access to cloud keys)
Softphone on controlled host → Cloud ✓ Yes Use SSL Key Logger on the host
Phone → Local SBC → Cloud ✓ Yes Use SBC tunneling (Method 4)

Method 1: Private Key Decryption

Works only for TLS 1.2 or older without Diffie-Hellman ciphers.

Configuration

# /etc/voipmonitor.conf
ssl = yes
ssl_ipport = 10.0.0.1:5061 /etc/pki/tls/private/server.key

Multiple servers:

ssl_ipport = 10.0.0.1:5061 /path/to/server1.key
ssl_ipport = 10.0.0.2:5061 /path/to/server2.key

GUI Configuration

Navigate to Settings > Sensors > wrench icon and search for ssl_:

  • ssl = yes
  • ssl_ipport = IP:PORT /path/to/key

Method 2: SSL Key Logger (Recommended)

Works for all cipher suites including PFS. Captures session keys from your PBX/SBC using LD_PRELOAD.

Step 1: Compile the Library

# Install prerequisites
apt-get install libssl-dev build-essential git   # Debian/Ubuntu
yum install openssl-devel make gcc git           # RHEL/CentOS

# Compile
cd /usr/local/src
git clone https://github.com/voipmonitor/sniffer.git voipmonitor-git
cd voipmonitor-git/tools/ssl_keylogger/
make

💡 Tip:

Step 2: Configure Your PBX

Asterisk

# Create environment file
cat > /etc/default/asterisk-ssl << 'EOF'
SSLKEYLOG_UDP='127.0.0.1:1234'
LD_PRELOAD='/usr/local/src/voipmonitor-git/tools/ssl_keylogger/sslkeylog.so'
EOF

# Add to service
systemctl edit asterisk.service

Add:

[Service]
EnvironmentFile=/etc/default/asterisk-ssl

Restart: systemctl daemon-reload && systemctl restart asterisk

FreeSWITCH

Edit /lib/systemd/system/freeswitch.service:

⚠️ Warning: Critical for DTLS+SRTP decryption: systemd must start the service as root so LD_PRELOAD can inject the keylogger before FreeSWITCH drops privileges. Set User=root in the service file and use -u/-g flags in ExecStart for FreeSWITCH to drop privileges internally.

[Service]
User=root
Group=root
ExecStart=env SSLKEYLOG_UDP='127.0.0.1:1234' LD_PRELOAD='/usr/local/src/voipmonitor-git/tools/ssl_keylogger/sslkeylog.so' /usr/bin/freeswitch -u freeswitch -g freeswitch -nonat

Then reload and restart:

systemctl daemon-reload
systemctl restart freeswitch

Kamailio

⚠️ Warning: Kamailio requires all three libraries in LD_PRELOAD to avoid crashes:

# Find library paths
find /usr/lib -name "libssl.so*" -o -name "libjson-c.so*"

Edit service file:

ExecStart=env SSLKEYLOG_UDP='127.0.0.1:1234' LD_PRELOAD='/usr/local/src/voipmonitor-git/tools/ssl_keylogger/sslkeylog.so:/usr/lib/x86_64-linux-gnu/libssl.so.3:/usr/lib/x86_64-linux-gnu/libjson-c.so.5' /usr/sbin/kamailio ...

Step 3: Configure VoIPmonitor

# /etc/voipmonitor.conf
ssl = yes
ssl_sessionkey_udp = yes
ssl_sessionkey_udp_port = 1234

# CRITICAL: No key file path when using SSL Key Logger!
ssl_ipport = 192.168.0.1:5061

# Include loopback if sending keys to 127.0.0.1
interface = eth0,lo

⚠️ Warning: WRONG: ssl_ipport = IP:PORT /path/to/key — This forces Method 1 and ignores the key logger!
CORRECT: ssl_ipport = IP:PORT — No key file path.

Secure Key Transport (TCP Mode)

For production environments, use TCP instead of UDP:

# Recompile with TCP support
cd /usr/local/src/voipmonitor-git/tools/ssl_keylogger/
make clean && make with_tcp

On PBX: Change SSLKEYLOG_UDP to SSLKEYLOG_TCP

On VoIPmonitor:

ssl_sessionkey_udp = no
ssl_sessionkey_bind = 0.0.0.0
ssl_sessionkey_bind_port = 1234

Method 3: Distributed Mode

When using packetbuffer_sender=yes, session keys must go to the central server.

On PBX:

# Send keys to CENTRAL SERVER, not localhost!
SSLKEYLOG_UDP='192.168.1.100:1234'  # Central server IP

On Central Server:

ssl = yes
ssl_sessionkey_udp = yes
ssl_sessionkey_udp_port = 1234
ssl_ipport = 192.168.1.50:5061  # PBX IP (no key file)

Method 4: SBC/PBX Tunneling

Some SBCs decrypt internally and forward unencrypted traffic via tunneling protocols.

Vendor Protocol Documentation
Ribbon/Oracle Monitoring Profile Ribbon7k_monitoring_profiles
AudioCodes Proprietary tunnel Audiocodes_tunneling
Generic IPinIP Auto-decoded by VoIPmonitor

ℹ️ Note: When using vendor tunneling, no SSL configuration is needed in VoIPmonitor—traffic arrives unencrypted.

Method 5: External Key Providers

Some hosted platforms (e.g., NetSapiens) can export TLS session keys to VoIPmonitor. Configure VoIPmonitor to receive keys via UDP/TCP as in Method 2.

Method 6: HEP Protocol

Alternative when SSL Key Logger doesn't work. The SIP proxy decrypts traffic and sends it via HEP.

# /etc/voipmonitor.conf
receiver_mode = yes
hep = yes
hep_bind_ip = 0.0.0.0
hep_bind_port = 9060

ℹ️ Note: HEP is just transport. Your SIP proxy must decrypt TLS before encapsulating in HEP. See HEP documentation.

SRTP/DTLS Decryption

Recommended Configuration

# Enables best-practice DTLS settings
ssl_dtls_boost = yes

RTP Proxy Issues (rtpengine)

If SRTP decryption fails with SDES keys visible in SDP, your RTP proxy may be stripping keys.

Fix for rtpengine (Kamailio):

rtpengine_manage("replace-origin DTLS=no SDES-nonew SDES-pad");

Garbled Audio

Garbled/distorted audio usually means SRTP is encrypted but not decrypted—not a codec issue.

Solution: Configure SSL Key Logger as described in Method 2, then verify keys are being received:

tcpdump -i any -n port 1234  # Check for UDP key packets

Troubleshooting

Decryption Not Working

Step 1: Verify packets are captured

  • Check sip:history (+) in CDR detail
  • Packets visible but encrypted → decryption issue
  • Packets missing → capture issue (check interface config)

Step 2: Check configuration

Issue Solution
Keys sent to localhost but not captured Add lo to interface: interface = eth0,lo
TCP/TLS packets not captured Remove/fix BPF filter: filter = udp or tcp or (vlan and (udp or tcp))
ssl_ipport has key file path Remove key path when using SSL Key Logger
packetbuffer_sender=yes fails Send keys to central server IP, not localhost
FreeSWITCH not capturing DTLS+SRTP keys Set User=root in systemd service file, use -u/-g flags in ExecStart

Compilation/Startup Issues

Error Platform Solution
undefined symbol: dlsym RHEL/CentOS/VitalPBX Recompile: g++ -shared -o sslkeylog.so sslkeylog.o -ldl (library flags after objects)
FreeSWITCH stuck in "activating" Any Recompile without TCP: make clean && make; set DEBUG 0 and WRITE_THREAD 0
Kamailio receive_fd(): EOF Debian 12 Add libjson-c.so to LD_PRELOAD (see Kamailio section)
Environment variables not loaded Any Use asterisk -r then core stop now instead of systemctl restart

High Traffic Issues

Symptom: Packet drops, TLS calls not decrypted under load

Solution 1: Increase wait time:

ssl_sessionkey_maxwait_ms = 5000

Solution 2: Switch to TCP mode (see "Secure Key Transport" above)

Capture for Support

# Capture TLS traffic + keylogger packets
tcpdump -i eth0,lo -w /tmp/debug.pcap \
  "((host PBX_IP and port 5061) or (port 1234))"

Provide to support:

  • CDR ID
  • voipmonitor --version
  • Config snippet (ssl*, interface, packetbuffer_sender)
  • The PCAP file

See Also

AI Summary for RAG

Summary: Guide to decrypting TLS-encrypted SIP and SRTP media in VoIPmonitor. Six methods: (1) Private Key - only for TLS 1.2 without DHE/ECDHE, configure ssl_ipport=IP:PORT /path/to/key; (2) SSL Key Logger (recommended) - universal for all ciphers, inject sslkeylog.so via LD_PRELOAD into Asterisk/Kamailio/FreeSWITCH, keys sent via UDP or TCP; (3) Distributed Mode - with packetbuffer_sender=yes, send keys to central server IP not localhost; (4) SBC Tunneling - Ribbon/AudioCodes decrypt internally; (5) External Key Providers - hosted platforms export keys; (6) HEP - SIP proxy decrypts then sends via HEP. Critical: when using SSL Key Logger, ssl_ipport must NOT include key file path. For localhost keys, add lo to interface. Kamailio requires three libraries in LD_PRELOAD. FreeSWITCH requires User=root in systemd service file with -u/-g flags in ExecStart for DTLS+SRTP decryption to work. High traffic: use TCP mode or increase ssl_sessionkey_maxwait_ms. Garbled audio = SRTP encryption not codec issue.

Keywords: tls, ssl, srtp, dtls, decryption, sslkeylog, ld_preload, session key, asterisk, kamailio, freeswitch, ssl_ipport, ssl_sessionkey_udp, packetbuffer_sender, distributed mode, ribbon sbc, audiocodes, hep, rtpengine, pfs, perfect forward secrecy, garbled audio, dlsym error