Troubleshooting OpenSIPS encrypted SIP traffic

March 23, 2021

Sometimes we need to have a quick way to troubleshoot encrypted SIP traffic. Using Homer is great, but if not setup yet, here’s how we can do it with sngrep.

Setting up sngrep

We will configure sngrep to accept and decode HEP/EEP version 3 packets. For this, we will create a configuration file for sngrep:

cat <<EOF >> ~/.sngreprc
set eep.listen on
set eep.listen.version 3
set eep.listen.address 127.0.0.1
set eep.listen.port 5065
EOF

Note1: replace lo, 127.0.0.1 and 5065 with the network interface, IP and port that matches your local setup.

Note2: sngrep can run on a different machine then opensips (example: use the local interface eth0 and local IP 10.10.10.10 as the capture device and the listening address).

Setting up opensips

Next step is to configure opensips as a HEP/EEP capture agent. For this we will load the following modules:

socket=hep_udp:127.0.0.1:6060 use_workers 1
...
loadmodule "proto_hep.so"
  modparam("proto_hep", "hep_id", "[sngrep_hep_id] 127.0.0.1:5065; transport=udp; version=3" )
loadmodule "tracer.so"
  modparam("tracer", "trace_on", 0)
  modparam("tracer", "trace_id", "[sngrep_trace_id]uri=hep:sngrep_hep_id")

Note: The IP and port in the “hep_id” proto_hep module parameter must match the IP and port in the sngrep config file. Same for version.

At the beginning of the main route we trace all transactions:

route {
  if (!has_totag()) {
    if(is_method("INVITE") ) {
      # We need to use the dialog module to have the outgoing ACK traced
      trace("sngrep_trace_id", "d", "sip");
    }
  }
  else {
    match_dialog();
  }
  if (!is_method("INVITE,ACK,BYE,PRACK")) {
    # Requests that are not part of an established dialog will be transaction base traced
    trace("hep_lo", "t", "sip");
  }
  trace("sngrep_trace_id", "t", "sip");
  ...
}

If we want to trace locally generated requests, we setup tracing in the local_route route:

onreply_route[local_route_reply_handle] {
  trace("sngrep_trace_id", "m", "sip");
}
local_route {
  trace("sngrep_trace_id", "m", "sip");
  t_on_reply("local_route_reply_handle");
  ...
}

With the above code snippet, we can trace OPTIONS pings generated by the drouting module.

Capturing

Start opensips:

sudo systemctl start opensips

Start sngrep with dialog rotation:

opensips-cli -x mi trace mode=on
opensips-cli -x mi trace mode=on id=sngrep_hep_id
sudo sngrep -l 4000 -R -Ludp:127.0.0.1:5065 port 5065
opensips-cli -x mi trace mode=off id=sngrep_hep_id
opensips-cli -x mi trace mode=off

Start sngrep with dialog rotation and OPTIONS and REGISTER requests filtered out:

opensips-cli -x mi trace mode=on
opensips-cli -x mi trace mode=on id=sngrep_hep_id
sudo sngrep -l 4000 -R -Ludp:127.0.0.1:5065 -v "OPTIONS\ sip|REGISTER\ sip" port 5065
opensips-cli -x mi trace mode=off id=sngrep_hep_id
opensips-cli -x mi trace mode=off

Enjoy visualising SIP message flows in realtime! Based on this initial setup, more complex tracing scenarios can be implemented.

Note1: ACKs related to a transaction that are leaving OpenSIPS are not traced if dialog tracing is not enabled.

Note2: Locally generated requests don’t have the proper destination IP and port.

Note3: sngrep is not able to export in pcap format packets captured in HEP/EEP format.


Troubleshooting Kamailio encrypted SIP traffic

March 22, 2021

Sometimes we need to have a quick way to troubleshoot encrypted SIP traffic. Using Homer is great, but if not setup yet, here’s how we can do it with sngrep.

Setting up sngrep

We will configure sngrep to accept and decode HEP/EEP version 2 packets (HEP/EEP version 3 packets work only with sngrep 1.4.7 and above). For this, we will create a configuration file for sngrep:

cat <<EOF >> ~/.sngrephep2rc
set capture.device eth0
set eep.listen on
set eep.listen.version 2
set eep.listen.address 10.10.10.10
set eep.listen.port 5065
EOF

Note1: replace eth0, 10.10.10.10 and 5065 with the network interface, IP and port that matches your local setup.

Note2: sngrep can run on the same machine as kamailio (use lo and 127.0.0.1 as the capture device and the listening address) or on a different machine.

Setting up kamailio (easy way)

Next step is to configure kamailio as a HEP/EEP capture agent. For this we will load the siptrace module:


loadmodule "siptrace.so"
  modparam("siptrace", "trace_mode", 0)
  modparam("siptrace", "trace_to_database", 0)
  modparam("siptrace", "trace_on", 1)
  modparam("siptrace", "duplicate_uri", "sip:10.10.10.10:5065")
  modparam("siptrace", "hep_mode_on", 1)
  modparam("siptrace", "hep_version", 2)
  modparam("siptrace", "hep_capture_id", 1)

Note: The IP and port in the “duplicate_uri” siptrace module parameter must match the IP and port in the sngrep config file. The version number in the “hep_version” siptrace module parameter must match the version in the sngrep config file.

At the beginning of the main request_route we trace all transactions:

request_route {
  sip_trace_mode("t");
  ...
}

We want to trace also relayed ACKs and we do that in the onsend_route:

onsend_route {
  if (is_method("ACK")) {
    sip_trace();
  }
}

If we want to trace locally generated requests, we setup tracing in the tm:local-request route:

onreply_route[local_request] {
  sip_trace();
}
event_route[tm:local-request] {
  t_on_reply("local_request");
  sip_trace();
}

With the above code snippet, we can trace OPTIONS pings generated by the dispatcher module.

Setting up kamailio (easiest way)

Next step is to configure kamailio as a HEP/EEP capture agent. For this we will load the siptrace module:

loadmodule "siptrace.so"
  modparam("siptrace", "trace_mode", 1)
  modparam("siptrace", "trace_to_database", 0)
  modparam("siptrace", "trace_on", 1)
  modparam("siptrace", "duplicate_uri", "sip:10.10.10.10:5065")
  modparam("siptrace", "hep_mode_on", 1)
  modparam("siptrace", "hep_version", 2)
  modparam("siptrace", "hep_capture_id", 1)

Note: The IP and port in the “duplicate_uri” siptrace module parameter must match the IP and port in the sngrep config file. The version number in the “hep_version” siptrace module parameter must match the version in the sngrep config file.

Capturing

Start sngrep:

sudo sngrep -f ~/.sngrephep2rc

Start kamailio:

kamctl start

Enjoy visualising SIP message flows in realtime! Based on one of this initial setups, more complex tracing scenarios can be implemented.

Note: sngrep is not able to export in pcap format packets captured in HEP/EEP format.


Extracting audio from calls recorded with RTPProxy

November 15, 2011

Recording calls with RTPProxy is quite easy, using the rtpproxy module.  Getting the audio out of those pcap files can be tricky sometimes.  Here are the steps of how to extract audio from pcap files:

  • Step1:  Extract the audio out of the pcap file in raw format:
rtpbreak -W -g -f -r [rtpproxy_pcap_record].a.rtp
rtpbreak -W -g -f -r [rtpproxy_pcap_record].o.rtp

A set of files will be generated for each stream:
– rtp.[index].txt – a log of the extraction process;
– rtp.[index].0.txt – characteristics of the audio stream;
– rtp.[index].0.raw – the raw audio stream.

  • Step2:  Merge and convert and the two raw files in a wav file:
sox --combine merge -r 8k -e [format] rtp.0.0.raw \
                    -r 8k -e [format] rtp.1.0.raw \
                    -t wavpcm -s [rtpproxy_pcap_record].wav

Supported formats are listed on then sox manpage (search for −e ENCODING, −−encoding ENCODING).

The format of the raw file can be found in the rtp.[index].0.txt file (look for the “RTP payload type” line).  Make sure that you are using the proper format for the raw file, otherwise the wav file will sound garbled.

For PCMU use:

sox --combine merge -r 8k -e u-law rtp.0.0.raw \
                    -r 8k -e u-law rtp.1.0.raw \
                    -t wavpcm -s [rtpproxy_pcap_record].wav

For PCMA use:

sox --combine merge -r 8k -e a-law rtp.0.0.raw \
                    -r 8k -e a-law rtp.1.0.raw \
                    -t wavpcm -s [rtpproxy_pcap_record].wav

Parallel forking for OpenSIPS in B2B mode

March 2, 2011

OpenSIPS is well-known as a scalable SIP proxy server.   But with the addition of two new modules: b2b_entities and b2b_logic, everything changed.  OpenSIPS is now able to act as a signaling Back to Back User Agent.  Being a signaling B2BUA means that media is still flowing between the end points, but signaling is divided in two individual legs: caller to opensips and opensips to callee.

A particular feature that I was missing with this new addition to opensips was parallel forking.  For instance, if a user is registered at multiple locations, only the one with the higher priority will be used in routing.  Starting with release 1.7, parallel forking for OpenSIPS in B2B mode works out of the box.   Simply perform a lookup() on the incoming INVITE and then relay the call in “b2b – top hiding” mode.

http://lists.opensips.org/pipermail/users/2011-March/017067.html