Secure Communication with SRTP and key managemnt protocols like SDES, ZRTP and DTLS


With advent of Voice over IP, the real time streaming of data/audio/video also became critically important to be protected from eavesdropping or modification over the open internet. While Secure Real-time Transport Protocol (SRTP) is a profile of the Real-time Transport Protocol (RTP), which can provide confidentiality, message authentication, and replay protection to the RTP traffic and to the control traffic for RTP, the Real-time Transport Control Protocol (RTCP). ZRTP is a protocol that negotiates the keys and other information required to setup a SRTP audio and video session. To read about RealTime Transport protocol (RTP) , RTP control protocol (RTCP ), before reading about adding security to RTP , RTCP and its feedback use the article link below.

SRTP (Secure Real-time Transport Protocol)

SRTP provides a framework for encryption and message authentication of RTP and RTCP streams by negotiating keys.

It is not a transport but a profile of the Real-time Transport Protocol (RTP) for securing RTP streams in addition to providing confidentiality, integrity protection, source authentication, and replay protection.

The SRTP specification also defines how to setup and maintain a cryptographic context. This context holds all necessary data to perform the security operations, for example the SRTP encryption keys, the packet sequence counters, authentication keys, and so on. Each SRTP session, which is the same as a RTP session, has its own context. Thus a bidirectional SRTP communication requires two different SRTP cryptographic contexts.

Features of SRTP

It is a framework for encryption and message authentication of RTP and RTCP streams.
Offers confidentiality and integrity of the entire RTP and RTCP packets, together with protection against replayed packets.
– secure for unicast and multicast RTP applications
– low computational cost and small footprint
– high throughput and low packet expansion to support bandwidth economy.
– permits upgrading with new cryptographic transforms,
– protection for heterogeneous environments (mix of wired and wireless networks)

Independant from the underlying transport, network, and physical layers used by RTP, in particular high tolerance to packet loss and re-ordering.

Normal RTP Packet
SecureRTP Packet

SRTCP (Secure RTCP)

Secure RTCP (SRTCP) is similar to the SRTP format of the SRTCP packet which has the authentication tag and MKI headers, including two additional headers:

  • SRTCP index
  • Encrypt-flag

Key management protocols for SRTP

Since SRTP does not contain an integrated key management solution, one can employ any of the following key management protocols

SDES (Session Description Protocol Security Descriptions) – SRTP Key management

It is a way to negotiate the key/cryptographic parameters for SRTP.
Keys are transported in the SDP attachment of a SIP message using TLS transport layer (SSLv3/TLSv1) or other methods like S/MIME.

media attribute defined by SDES is “crypto”
a=crypto: inline: [session-parms]

SDES packet

3 commonly used crypto suites are :

  1. AES_CM_128_HMAC_SHA1_80
  2. AES_CM_128_HMAC_SHA1_32
  3. F8_128_HMAC_SHA1_32

DTLS – SRTP Key management

DTLS keying happens on the media path, independent of any out-of-band signalling channel present.

Jitsi Client SRTP configuration

An offer can include any of –

  • plain RTP (RTP/AVP),
  • RTP with RTCP-based feedback (RTP/AVPF),
  • Secure RTP (RTP/SAVP), or
  • Secure RTP with RTCP-based feedback (RTP/SAVPF)

SDP for RTP/AVP

v=0
o=987654321-jitsi.org 0 0 IN IP4 x.x.x.x.
s=-
c=IN IP4 x.x.x.x
t=0 0
m=audio 24380 RTP/AVP 9
a=rtcp-xr:voip-metrics
a=rtpmap:9 G722/8000
a=sendrecv
m=audio 24400 RTP/AVP 9
a=rtcp-xr:voip-metrics
a=rtpmap:9 G722/8000
a=sendrecv

or

v=0.
o=987654321-jitsi.org 0 0 IN IP4 x.x.x.x.
s=-.
c=IN IP4 x.x.x.x.
t=0 0.
m=audio 5018 UDP/TLS/RTP/SAVP 9.
a=rtpmap:9 G722/8000.
a=extmap:1 urn:ietf:params:rtp-hdrext:csrc-audio-level.
a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level.
a=rtcp-xr:voip-metrics.
a=setup:actpass.
a=fingerprint:sha-1 B9:0F:89:EE:BD:1F:B1:C4:86:B6:D7:5C:25:88:53:F4:02:F4:F5:91.
m=audio 5018 RTP/SAVPF 9.
a=rtpmap:9 G722/8000.
a=extmap:1 urn:ietf:params:rtp-hdrext:csrc-audio-level.
a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level.
a=rtcp-xr:voip-metrics.
a=setup:actpass.
a=fingerprint:sha-1 B9:0F:89:EE:BD:1F:B1:C4:86:B6:D7:5C:25:88:53:F4:02:F4:F5:91.

The m line indicates which mode of RTP and RTCP is it offering.

Case where offerer/calleer wants to establish a Secure RTP audio stream on plain RTP with DTLS-SRTP as the key management protocol.

type: offer, sdp: 
v=0
o=- 2977074634695769063 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1 2
a=msid-semantic: WMS i2CKXQdort5QF76tyO5SUKyyyyPfMYR4kjZO
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 110 112 113 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:w5/T
a=ice-pwd:zuPM49QcEX3cKRQiKylJU4Y6
a=ice-options:trickle
a=fingerprint:sha-256 5A:70:05:55:C1:5A:82:51:02:D3:00:A3:BF:E7:EF:62:DF:29:EB:F2:9F:5F:51:58:12:D9:4C:AA:41:36:86:13
a=setup:actpass
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid
a=sendrecv
a=msid:i2CKXQdort5QF76tyO5SUKyyyyPfMYR4kjZO 5ffdb0f9-48b1-43bc-9f63-ea032643aeba
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:112 telephone-event/32000
a=rtpmap:113 telephone-event/16000
a=rtpmap:126 telephone-event/8000
a=ssrc:2215726670 cname:e6egqLfRbLu6vH45
a=ssrc:2215726670 msid:i2CKXQdort5QF76tyO5SUKyyyyPfMYR4kjZO 5ffdb0f9-48b1-43bc-9f63-ea032643aeba
a=ssrc:2215726670 mslabel:i2CKXQdort5QF76tyO5SUKyyyyPfMYR4kjZO
a=ssrc:2215726670 label:5ffdb0f9-48b1-43bc-9f63-ea032643aeba
m=application 9 DTLS/SCTP 5000
c=IN IP4 0.0.0.0
a=ice-ufrag:w5/T
a=ice-pwd:zuPM49QcEX3cKRQiKylJU4Y6
a=ice-options:trickle
a=fingerprint:sha-256 5A:70:05:55:C1:5A:82:51:02:D3:00:A3:BF:E7:EF:62:DF:29:EB:F2:9F:5F:51:58:12:D9:4C:AA:41:36:86:13
a=setup:actpass
a=mid:2
a=sctpmap:5000 webrtc-datachannel 1024

SRTP on kamailio

For Secure Communication kamailio supports – Digest SIP User authentication , Authorization via ACL or group membership , IP and Network authentication , TLS support for SIP signaling , transparent handling of SRTP for secure audio , TLS domain name extension support ,authentication and authorization against database (MySQL, PostgreSQL, UnixODBC, BerkeleyDB, Oracle, text files), RADIUS and DIAMETER.

Code to set flag rtp_secure_media to true if both TLS and SRTP are active

<condition field="${rtp_has_crypto}" expression="^(AES_CM_128_HMAC_SHA1_32|AES_CM_128_HMAC_SHA1_80)$" break="never">	
    <action application="set" data="rtp_secure_media=true"/>
</condition>

Invite from Jitsi client alternatively offering 3 different types of audio SDP’s – RTP/SAVPF , RTP/SAVP and RTP/AVP. Which ever will be accepted by the other endpoint will be communicated back using SDP in 200 OK.

INVITE sip:99999999999@x.x.x.x:5080 SIP/2.0
   Call-ID: 2a34d1e981602c82c345513f3f2f89ed@0:0:0:0:0:0:0:0
   CSeq: 1 INVITE
   From: "altanai" ;tag=bed49270
   To: 
   Via: SIP/2.0/UDP y.y.y.y:5060;branch=z9hG4bK-3130-9657d2ae9b662779bc08cdd32881828f
   Max-Forwards: 70
   Contact: "altanai" 
   User-Agent: Jitsi2.10.5550Mac OS X
   Content-Type: application/sdp
   Content-Length: 2336
   v=0
   o=7777777777-jitsi.org 0 0 IN IP4 y.y.y.y
   s=-
   c=IN IP4 y.y.y.y
   t=0 0
   m=audio 5016 UDP/TLS/RTP/SAVP 9
   a=rtpmap:9 G722/8000
   a=extmap:1 urn:ietf:params:rtp-hdrext:csrc-audio-level
   a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level
   a=rtcp-xr:voip-metrics
   a=setup:actpass
   a=fingerprint:sha-1 55:CF:25:5D:D5:65:71:C8:D9:FF:97:AD:CC:F2:08:DB:38:DD:81:38
m=audio 5016 RTP/SAVPF 9
   a=rtpmap:9 G722/8000
   a=extmap:1 urn:ietf:params:rtp-hdrext:csrc-audio-level
   a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level
   a=rtcp-xr:voip-metrics
   a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:Ekb2qAA8F7VCmz0FMSrad0rIt8duHQFedu/KxMbD
   a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:rEeGiaLCUbFw0sS0FxARgX9i5pwEj/frxxbgGkch
   a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:up9VO2T/rfu8V0cecA4RuG0aWgSaCC5gD/p/RdY1odg1p/0Pto0=
   a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:6yLDM31gAuwrlL0qkH72QYJLwtzX1IX+Z+7UML3VA5CpIbUWeAw=
   a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:2Q3b3UpPJMosXTrm/0Ui5q3Mw8tQ6ig5Xq0jt4Ibj0t5hVQx5KBRbC+8sMJDMg==
   a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:yVs8C3xPFY2LAUXIH+dlgBBNSz+jm1cbAQlAgv8hPKGe1zfu2wzx1d465UfFzQ==
   a=crypto:7 F8_128_HMAC_SHA1_80 inline:bhIPhj1TryAB63p/g8B3gL5NXJJ7V4kbjXqYaU54
   a=setup:actpass
   a=fingerprint:sha-1 55:CF:25:5D:D5:65:71:C8:D9:FF:97:AD:CC:F2:08:DB:38:DD:81:38
m=audio 5016 RTP/SAVP 9
   a=rtpmap:9 G722/8000
   a=extmap:1 urn:ietf:params:rtp-hdrext:csrc-audio-level
   a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level
   a=rtcp-xr:voip-metrics
   a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:Ekb2qAA8F7VCmz0FMSrad0rIt8duHQFedu/KxMbD
   a=crypto:2 AES_CM_128_HMAC_SHA1_32 inline:rEeGiaLCUbFw0sS0FxARgX9i5pwEj/frxxbgGkch
   a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:up9VO2T/rfu8V0cecA4RuG0aWgSaCC5gD/p/RdY1odg1p/0Pto0=
   a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:6yLDM31gAuwrlL0qkH72QYJLwtzX1IX+Z+7UML3VA5CpIbUWeAw=
   a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:2Q3b3UpPJMosXTrm/0Ui5q3Mw8tQ6ig5Xq0jt4Ibj0t5hVQx5KBRbC+8sMJDMg==
   a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:yVs8C3xPFY2LAUXIH+dlgBBNSz+jm1cbAQlAgv8hPKGe1zfu2wzx1d465UfFzQ==
   a=crypto:7 F8_128_HMAC_SHA1_80 inline:bhIPhj1TryAB63p/g8B3gL5NXJJ7V4kbjXqYaU54
m=audio 5016 RTP/AVP 9
a=rtpmap:9 G722/8000
a=extmap:1 urn:ietf:params:rtp-hdrext:csrc-audio-level
a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=rtcp-xr:voip-metrics

Kamailio in secure mode selects the SRTP block of Audio SDP and responds in 200 OK

RTP to SRTP Bridging in Freeswitch

Enable ZRTP globally. Can override this on a per channel basis http://wiki.freeswitch.org/wiki/ZRTP (on how to enable zrtp).

When SRTP it’s critical to not offer or accept variable bit rate codecs, doing so would leak information and possibly compromising SRTP stream. (FS-6404).

Supported SRTP Crypto Suites:

AEAD_AES_256_GCM_8

This algorithm is identical to AEAD_AES_256_GCM (see Section 5.2 of [RFC5116]), except that the tag length, t, is 8, and an authentication tag with a length of 8 octets (64 bits) is used. An AEAD_AES_256_GCM_8 ciphertext is exactly 8 octets longer than its corresponding plaintext.

AEAD_AES_128_GCM_8

This algorithm is identical to AEAD_AES_128_GCM (see Section 5.1 of [RFC5116]), except that the tag length, t, is 8, and an authentication tag with a length of 8 octets (64 bits) is used. An AEAD_AES_128_GCM_8 ciphertext is exactly 8 octets longer than its corresponding plaintext.

AES_CM_256_HMAC_SHA1_80 | AES_CM_192_HMAC_SHA1_80 | AES_CM_128_HMAC_SHA1_80

AES_CM_128_HMAC_SHA1_80 is the SRTP default AES Counter Mode cipher and HMAC-SHA1 message authentication with an 80-bit authentication tag. The master-key length is 128 bits and has a default lifetime of a maximum of 2^48 SRTP packets or 2^31 SRTCP packets, whichever comes first.

AES_CM_256_HMAC_SHA1_32 | AES_CM_192_HMAC_SHA1_32 | AES_CM_128_HMAC_SHA1_32

This crypto-suite is identical to AES_CM_128_HMAC_SHA1_80 except that the authentication tag is 32 bits. The length of the base64-decoded key and salt value for this crypto-suite MUST be 30 octets i.e., 240 bits; otherwise, the crypto attribute is considered invalid.

AES_CM_128_NULL_AUTH

The SRTP default cipher (AES-128 Counter Mode), but to use no authentication method. This policy is NOT RECOMMENDED unless it is unavoidable; see Section 7.5 of [RFC3711].

SRTP variables that modify behaviors based on direction/leg:

rtp_secure_media

possible values:
mandatory – Accept/Offer SAVP negotiation ONLY
optional – Accept/Offer SAVP/AVP with SAVP preferred
forbidden – More useful for inbound to deny SAVP negotiation
false – implies forbidden
true – implies mandatory

default if not set is accept SAVP inbound if offered.

rtp_secure_media_inbound | rtp_secure_media_outbound

This is the same as rtp_secure_media, but would apply to either inbound or outbound offers specifically.

How to specify crypto suites: By default without specifying any crypto suites FreeSWITCH will offer crypto suites from strongest to weakest accepting the strongest each endpoint has in common. If you wish to force specific crypto suites you can do so by appending the suites in a comma separated list in the order that you wish to offer them in.

Examples:
rtp_secure_media=mandatory:AES_CM_256_HMAC_SHA1_80,AES_CM_256_HMAC_SHA1_32
rtp_secure_media=true:AES_CM_256_HMAC_SHA1_80,AES_CM_256_HMAC_SHA1_32
rtp_secure_media=optional:AES_CM_256_HMAC_SHA1_80
rtp_secure_media=true:AES_CM_256_HMAC_SHA1_80

Additionally you can narrow this down on either inbound or outbound by specifying as so:

rtp_secure_media_inbound=true:AEAD_AES_256_GCM_8
rtp_secure_media_inbound=mandatory:AEAD_AES_256_GCM_8
rtp_secure_media_outbound=true:AEAD_AES_128_GCM_8
rtp_secure_media_outbound=optional:AEAD_AES_128_GCM_8

rtp_secure_media_suites

Optionaly you can use rtp_secure_media_suites to dictate the suite list and only use rtp_secure_media=[optional|mandatory|false|true] without having to dictate the suite list with the rtp_secure_media* variables.

In vars.xml SIP and TLS settings valid options: sslv2,sslv3,sslv23,tlsv1,tlsv1.1,tlsv1.2 default: tlsv1,tlsv1.1,tlsv1.2 . http://wiki.freeswitch.org/wiki/Tls

TLS cipher suite: default ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH The actual ciphers supported will change per platform. openssl ciphers -v ‘ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH’ Will show you what is available in your verion of openssl.

SRTP to RTP over multiple Crypto suits

Logs and explanation for RTP to SRTP translation in Freeswitch

A client at 7777777777@ is trying to call 9999999999@ , which freeswitch has to proxy and convert from RTP to SRTP. The following debug logs form sofia external show this process.

A RTP SIP INVITE + offer with SDP is received.

INVITE sip:9999999999@:5080;transport=UDP SIP/2.0
   Via: SIP/2.0/UDP :47851;branch=z9hG4bK-524287-1---7cc8ad9383e9787d;rport
   Max-Forwards: 70
   Contact: :47851;transport=UDP>
   To: :5080;transport=UDP>
   From: :5080;transport=UDP>;tag=5df9f82c
   Call-ID: lFNvnuABQfOpROxfFp-MZQ..
   CSeq: 1 INVITE
   Allow: INVITE, ACK, CANCEL, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO, SUBSCRIBE
   Content-Type: application/sdp
   User-Agent: Z 5.2.28 rv2.8.115
   Allow-Events: presence, kpml, talk
   Content-Length: 607
   
   v=0
   o=Z 20472192 0 IN IP4 
   s=Z
   c=IN IP4 
   t=0 0
   m=audio 8000 RTP/AVP 106 9 3 111 0 8 97 110 112 98 101 100 99 102
   a=rtpmap:106 opus/48000/2
   a=fmtp:106 minptime=20; cbr=1; maxaveragebitrate=40000; useinbandfec=1
   a=rtpmap:111 speex/16000
   a=rtpmap:97 iLBC/8000
   a=fmtp:97 mode=20
   a=rtpmap:110 speex/8000
   a=rtpmap:112 speex/32000
   a=rtpmap:98 telephone-event/48000
   a=fmtp:98 0-16
   a=rtpmap:101 telephone-event/8000
   a=fmtp:101 0-16
   a=rtpmap:100 telephone-event/16000
   a=fmtp:100 0-16
   a=rtpmap:99 telephone-event/32000
   a=fmtp:99 0-16
   a=rtpmap:102 G726-32/8000
   a=sendrecv
[NOTICE] switch_channel.c:1104 New Channel sofia/external/7777777777@:5080 [ed5e07ee-bd00-4a47-b4e1-6abc9dd23ed6]
[DEBUG] switch_core_state_machine.c:584 (sofia/external/7777777777@:5080) Running State Change CS_NEW (Cur 1 Tot 33)
[DEBUG] sofia.c:10078 sofia/external/7777777777@:5080 receiving invite from :4642 version: 1.9.0 -742-8f1be0 64bit
[DEBUG] sofia.c:7291 Channel sofia/external/7777777777@:5080 entering state [received][100]

[DEBUG] sofia.c:7301 Remote SDP:
v=0
o=Z 20472192 0 IN IP4 
s=Z
c=IN IP4 
t=0 0
m=audio 8000 RTP/AVP 106 9 3 111 0 8 97 110 112 98 101 100 99 102
a=rtpmap:106 opus/48000/2
a=fmtp:106 minptime=20; cbr=1; maxaveragebitrate=40000; useinbandfec=1
a=rtpmap:111 speex/16000
a=rtpmap:97 iLBC/8000
a=fmtp:97 mode=20
a=rtpmap:110 speex/8000
a=rtpmap:112 speex/32000
a=rtpmap:98 telephone-event/48000
a=fmtp:98 0-16
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=rtpmap:100 telephone-event/16000
a=fmtp:100 0-16
a=rtpmap:99 telephone-event/32000
a=fmtp:99 0-16
a=rtpmap:102 G726-32/8000
[DEBUG] sofia.c:7693 (sofia/external/7777777777@:5080) State Change CS_NEW -> CS_INIT
State NEW
Running State Change CS_INIT (Cur 1 Tot 33)
Standard INIT
State Change CS_INIT -> CS_ROUTING
State INIT going to sleep
Running State Change CS_ROUTING (Cur 1 Tot 33)
Callstate Change DOWN -> RINGING
State ROUTING

send 389 bytes to udp/[]:4642 at 07:08:27.376085:
SIP/2.0 100 Trying

Via: SIP/2.0/UDP :47851;branch=z9hG4bK-524287-1---7cc8ad9383e9787d;rport=4642;received=
   From: :5080;transport=UDP>;tag=5df9f82c
   To: :5080;transport=UDP>
   Call-ID: lFNvnuABQfOpROxfFp-MZQ..
   CSeq: 1 INVITE
   User-Agent: FreeSWITCH-mod_sofia/1.9.0-742-8f1b7e0~64bit
   Content-Length: 0

After the INVITE is received and processed with 100 trying reply, the routing and RTP secure tranformation begins by adding crypto keys and forwarding to destination

Standard EXECUTE
ed5e07ee EXECUTE sofia/external/7777777777@:5080 set(rtp_secure_media=optional)
[rtp_secure_media]=[optional]
ed5e07ee EXECUTE sofia/external/7777777777@:5080 log(INFO Forwarding calls 9999999999@ )
Forwarding calls 9999999999@
…
Set Local audio crypto Key [1 AEAD_AES_256_GCM_8 inline:aHJ1yquBtm4Lzfi2oMpe6cV7IBEy3YgKxrJ3qjvLuRXSuZfHcV4VtVNwHDw]
Set Local video crypto Key [1 AEAD_AES_256_GCM_8 inline:qeJbqlSbnKBNew575hSZ3LX78o6GBsjgOrSMxzGH/zb1E7mkls1Mda93U9w]
Set Local text crypto Key [1 AEAD_AES_256_GCM_8 inline:VghMVsjWQwnOAAjBJ1NTB3jZgfpNV/Yu4poxkAPMqkC7C+fhPKApCJrWg3U]
Set Local audio crypto Key [2 AEAD_AES_128_GCM_8 inline:7XNrjjwC/eOVnWlBSp74DfiIGAEYn/BN+latfA]
Set Local video crypto Key [2 AEAD_AES_128_GCM_8 inline:UQrFpy9Q7L5DI/ww4e5IAmwy7BxSw5yd/T0v0Q]
Set Local text crypto Key [2 AEAD_AES_128_GCM_8 inline:ZqkEPrUFHkaQ+7CROp52H/JO0MbrYWk/Eyl9lQ]
Set Local audio crypto Key [3 AES_CM_256_HMAC_SHA1_80 inline:PTGAm2KlbfuKtIUVGtXknKKzALAzfILZJuPOjfO9S07eWRE6FR0aMUvjuehJgw]
Set Local video crypto Key [3 AES_CM_256_HMAC_SHA1_80 inline:ahHIB0o/dp3SliYWK9BkxM7TfzILwG0bjDn7JuvYi+puRkTM4mYvvsSmywLaYA]
Set Local text crypto Key [3 AES_CM_256_HMAC_SHA1_80 inline:crAs8dPcWJkEEGj5nqTvFGl/TWpxxb86k+dX5gBXhh+q6DO2pEqWNkQmm55aLA]
Set Local audio crypto Key [4 AES_CM_192_HMAC_SHA1_80 inline:SLBJWjgMdfiYX7TUwWQ9CmqUsILLJrpBIVjbfuQmpBIFLvvA/XU]
Set Local video crypto Key [4 AES_CM_192_HMAC_SHA1_80 fNazWgWwNRPjUKNHVqkz44]
Set Local text crypto Key [4 AES_CM_192_HMAC_SHA1_80 inline:hbe9qqETBSK5hRQ8DI9mXL4QAjjGSR8tGDiTHCJF3yxCrRk1ajk]
Set Local audio crypto Key [5 AES_CM_128_HMAC_SHA1_80 inline:8q8mer9N2V4qVxnaazuJeT0KXgW2scONy36J3KaS]
Set Local video crypto Key [5 AES_CM_128_HMAC_SHA1_80 inline:TP5NQ1yB8ZSCCwZMgXur9VHZ5SlpNfnXePj7eZrk]
Set Local text crypto Key [5 AES_CM_128_HMAC_SHA1_80 inline:HT3F3iYG8H/majhBZbOs2Z8ye/WEVGT5Oytx2oQS]
Set Local audio crypto Key [6 AES_CM_256_HMAC_SHA1_32 inline:fEohh92lX2xLmeFYlt8YouM2jN4z5pU05d90BYfoAKU6m4CWv8g8AnifDUKk9A]
Set Local video crypto Key [6 AES_CM_256_HMAC_SHA1_32 inline:+uBNmLcvj41hXoMxNlMNBpq68gU4PmLwYcdopEB/X/jfPElkUgHfguPIgIFJUg]
Set Local text crypto Key [6 AES_CM_256_HMAC_SHA1_32 inline:cqk7D3+KMQ+31R4FFDRRzn/aluyIgjxBL59vfxcsdf5OW9izEJtU+06GewJyIA]
Set Local audio crypto Key [7 AES_CM_192_HMAC_SHA1_32 inline:Tv25TfP9fQZ+ljs/tFlHohkckiK4F6cemzEjHSvo2+q6No4ai+o]
Set Local video crypto Key [7 AES_CM_192_HMAC_SHA1_32 inline:CY/Dizd1QrlobZtgnigr0hWE+oDSx4S1F51Zpo4aZamN+8ZMdp8]
Set Local text crypto Key [7 AES_CM_192_HMAC_SHA1_32 inline:aEox/7IMps5c+uOWbosZ618+opkJV/GnrKc2EnAhVnDNeo91+No]
Set Local audio crypto Key [8 AES_CM_128_HMAC_SHA1_32 inline:0LwKGyljIed0zhukiMMyD5ive0ZsyybwBrnevcAv]
Set Local video crypto Key [8 AES_CM_128_HMAC_SHA1_32 inline:eZN8rAG8UPPntdYxsg1kkWL4qMsVgTiGGiS4UeUM]
Set Local text crypto Key [8 AES_CM_128_HMAC_SHA1_32 inline:bAYzbfr+El8usaTkPBR6iFuTda4uLNGjyx9lQWkX]
Set Local audio crypto Key [9 AES_CM_128_NULL_AUTH inline:5m3142gGG1HZ5VnoXsAOyopSwDCYbrIsGpdbEO3D]
Set Local video crypto Key [9 AES_CM_128_NULL_AUTH inline:zXk67wjwRhSilq0kiz5TWxXqrxuTaWTA3qqbVo/G]
Set Local text crypto Key [9 AES_CM_128_NULL_AUTH inline:FRP9CJbBO+PRj6I9RSBAiMxRZ/qFtyrEXPfxocG0]
sending invite version: 1.9.0 -742-8f1b7e0 64bit
Local SDP:
v=0
o=FreeSWITCH 1552960557 1552960558 IN IP4
s=FreeSWITCH
c=IN IP4
t=0 0
m=audio 18750 RTP/SAVP 102 9 0 8 103 101
a=rtpmap:102 opus/48000/2
a=fmtp:102 useinbandfec=1; maxaveragebitrate=30000; maxplaybackrate=48000; ptime=20; minptime=10; maxptime=40; stereo=1
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:103 telephone-event/48000
a=fmtp:103 0-16
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=crypto:1 AEAD_AES_256_GCM_8 inline:aHJ1yquBtm4Lzfi2oMpe6cV7IBEy3YgKxrJ3qjvLuRXSuZfHcV4VtVNwHDw
a=crypto:2 AEAD_AES_128_GCM_8 inline:7XNrjjwC/eOVnWlBSp74DfiIGAEYn/BN+latfA
a=crypto:3 AES_CM_256_HMAC_SHA1_80 inline:PTGAm2KlbfuKtIUVGtXknKKzALAzfILZJuPOjfO9S07eWRE6FR0aMUvjuehJgw
a=crypto:4 AES_CM_192_HMAC_SHA1_80 inline:SLBJWjgMdfiYX7TUwWQ9CmqUsILLJrpBIVjbfuQmpBIFLvvA/XU
a=crypto:5 AES_CM_128_HMAC_SHA1_80 inline:8q8mer9N2V4qVxnaazuJeT0KXgW2scONy36J3KaS
a=crypto:6 AES_CM_256_HMAC_SHA1_32 inline:fEohh92lX2xLmeFYlt8YouM2jN4z5pU05d90BYfoAKU6m4CWv8g8AnifDUKk9A
a=crypto:7 AES_CM_192_HMAC_SHA1_32 inline:Tv25TfP9fQZ+ljs/tFlHohkckiK4F6cemzEjHSvo2+q6No4ai+o
a=crypto:8 AES_CM_128_HMAC_SHA1_32 inline:0LwKGyljIed0zhukiMMyD5ive0ZsyybwBrnevcAv
a=crypto:9 AES_CM_128_NULL_AUTH inline:5m3142gGG1HZ5VnoXsAOyopSwDCYbrIsGpdbEO3D
a=ptime:20
a=sendrecv

Once the SDP is ready with crypto keys it is the forwarded to the next_up

send 2104 bytes to udp/[]:5060 at 07:08:27.378167:
INVITE sip:9999999999@ SIP/2.0
   Via: SIP/2.0/UDP :5080;rport;branch=z9hG4bKmF251mK2pN35B
   Max-Forwards: 69
   From: "7777777777" >;tag=vcKeKD6SN02cB
   To: >
   Call-ID: a27898fd-c4b8-1237-ddaa-02a933b32da0
   CSeq: 1935861 INVITE
   Contact: :5080>
   User-Agent: FreeSWITCH-mod_sofia/1.9.0-742-8f1b7e0~64bit
   Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY
   Supported: timer, path, replaces
   Allow-Events: talk, hold, conference, refer
   Content-Type: application/sdp
   Content-Disposition: session
   Content-Length: 1304
   X-FS-Support: update_display,send_info
   Remote-Party-ID: "7777777777" >;party=calling;screen=yes;privacy=off
   v=0
   o=FreeSWITCH 1552960557 1552960558 IN IP4 
   s=FreeSWITCH
   c=IN IP4 
   t=0 0
   m=audio 18750 RTP/SAVP 102 9 0 8 103 101
   a=rtpmap:102 opus/48000/2
   a=fmtp:102 useinbandfec=1; maxaveragebitrate=30000; maxplaybackrate=48000; ptime=20; minptime=10; maxptime=40; stereo=1
   a=rtpmap:9 G722/8000
   a=rtpmap:0 PCMU/8000
   a=rtpmap:8 PCMA/8000
   a=rtpmap:103 telephone-event/48000
   a=fmtp:103 0-16
   a=rtpmap:101 telephone-event/8000
   a=fmtp:101 0-16
   a=crypto:1 AEAD_AES_256_GCM_8 inline:aHJ1yquBtm4Lzfi2oMpe6cV7IBEy3YgKxrJ3qjvLuRXSuZfHcV4VtVNwHDw
   a=crypto:2 AEAD_AES_128_GCM_8 inline:7XNrjjwC/eOVnWlBSp74DfiIGAEYn/BN+latfA
   a=crypto:3 AES_CM_256_HMAC_SHA1_80 inline:PTGAm2KlbfuKtIUVGtXknKKzALAzfILZJuPOjfO9S07eWRE6FR0aMUvjuehJgw
   a=crypto:4 AES_CM_192_HMAC_SHA1_80 inline:SLBJWjgMdfiYX7TUwWQ9CmqUsILLJrpBIVjbfuQmpBIFLvvA/XU
   a=crypto:5 AES_CM_128_HMAC_SHA1_80 inline:8q8mer9N2V4qVxnaazuJeT0KXgW2scONy36J3KaS
   a=crypto:6 AES_CM_256_HMAC_SHA1_32 inline:fEohh92lX2xLmeFYlt8YouM2jN4z5pU05d90BYfoAKU6m4CWv8g8AnifDUKk9A
   a=crypto:7 AES_CM_192_HMAC_SHA1_32 inline:Tv25TfP9fQZ+ljs/tFlHohkckiK4F6cemzEjHSvo2+q6No4ai+o
   a=crypto:8 AES_CM_128_HMAC_SHA1_32 inline:0LwKGyljIed0zhukiMMyD5ive0ZsyybwBrnevcAv
   a=crypto:9 AES_CM_128_NULL_AUTH inline:5m3142gGG1HZ5VnoXsAOyopSwDCYbrIsGpdbEO3D
   a=ptime:20

Multimedia Internet Keying (MIKEY) – Key management of SRTP

can establish multiple security contexts or cryptographic sessions with a single message.
Can be used in p2p or bradcast scenarios where one entity generates the key and needs to distribute the key to a number of participants.

Modes of operations

  • Pre-Shared Key
  • Public Key Encryption
  • Diffie-Hellman
  • HMAC-Authenticated Diffie-Hellman
  • RSA-R
  • TICKET
  • IBAKE
  • SAKKE

References


Kamailio as Inbound/Outbound proxy or Session Border Controller (SBC)


SBC ( Session Border Controller )

A typical voice core network consists of a B2BUA SIP server with media proxy and media processing units/servers along with components for billing, user profile management, shared memory/ cache, transcoders, call routing logic etc. However, a VOIP provider would not want to interface these critical servers to the outside world directly. An SBC ( Session Border Controller ) helps to abstract the core VoIP platform from public access and traffic.

The role of an SBC is to shield the core network from external entities such as user agent’s, carrier networks (topology hiding) while also providing security, auth and accounting services. In many cases, SBC also provides NAT traversal and policy control features ( such as rate-limiting, ACL etc ). In advanced cases, transcoding, topology concealment and load balancing are also achievable via an SBC such as Kamailio.

SBC interfaces

Following sections are usecases / features kamailio can extend to. Routing scripts at https://github.com/altanai/kamailioexamples

Block user based on excessive REGISTER request  till an expiry time

For instance to block DDOS attacks, kamailio can check for the number of register requests a user sends and block above a threshold number subsequently .

if($sht(auth_block_list=>$au::auth_count)==30){
    $var(block) = $Ts - 900;
    $var(expire) = $Ts - 300;

    if($sht(auth_block_list=>$au::last_block) > $var(block)){
        xlog("L_INFO", "$fU@$fd - REGISTER - $au User Already Blocked for Exceeded Register Requests.\n");
        sl_send_reply("403", "Already Blocked Forbidden");
        exit;
    } else if($sht(auth_block_list=>$au::last_auth) > $var(expire)) {
        $sht(auth_block_list=>$au::last_block) = $Ts;
        xlog("L_INFO", "$fU@$fd - REGISTER - $au User Blocked for Exceeded Register Requests.\n");
        sl_send_reply("403", "Blocked Forbidden");
        exit;
    } else {
        $sht(auth_block_list=>$au::auth_count) = 0;
    } 
}

More information on kamailio security can be found on https://telecom.altanai.com/2018/02/17/kamailio-security/. It includes Sanity checks for incoming SIP requests ,Access Control Lists and Permissions, Hiding Topology Details, Anti Flood and Traffic Monitoring and Detection.

Anti Flood with Pike Module

To be on edge of a voip pltform, a SIP server must keep track of all incoming request and their sources. Blocking the ones which exceed the limit or appear like a dos attack. Pike module reports high traffic from an IP if detected.

A sample script to detect high traffic from an IP and add it to ban list for a while . But exclude the known IP sources such as PSTN gateways etc

#!ifdef WITH_ANTIFLOOD
loadmodule "htable.so"
loadmodule "pike.so"
#!endif
...
# ----- pike params -----
modparam("pike", "sampling_time_unit", 2)
modparam("pike", "reqs_density_per_unit", 16)
modparam("pike", "remove_latency", 4)
...
route[REQINIT] {
...
if(src_ip!=myself) {
	if($sht(ipban=>$si)!=$null) {
		# ip is already blocked
		xdbg("request from blocked IP - $rm from $fu (IP:$si:$sp)\n");
		exit;
	}
	if (!pike_check_req()) {
		xlog("L_ALERT","ALERT: pike blocking $rm from $fu (IP:$si:$sp)\n");
		$sht(ipban=>$si) = 1;
		exit;
	}
}

Access Control List with Permission Module

permission module handles ACL by storing permission rules in plaintext configuration files , hosts.allow and hosts.deby by tcpd.

#!ifdef WITH_IPAUTH
loadmodule "permissions.so"
#!endif
...
# ----- permissions params -----
#!ifdef WITH_IPAUTH
modparam("permissions", "db_url", DBURL)
modparam("permissions", "db_mode", 1)
#!endif
..
#!ifdef WITH_IPAUTH
    if((!is_method("REGISTER")) && allow_source_address()) {
        # source IP allowed
        return;
    }
#!endif

Call Routing Functions

if (allow_routing("rules.allow", "rules.deny")) {
    t_relay();
};

Registration permissions

if (method=="REGISTER") {
    if (allow_register("register")) {
        save("location");
        exit;
    } else {
        sl_send_reply("403", "Forbidden");
    };
};

URI permissions

if (allow_uri("basename", "$rt")) {  // Check Refer-To URI
    t_relay();
};

Address permissions

// check if sourec ip/port is in group 1
if (!allow_address("1", "$si", "$sp")) {
    sl_send_reply("403", "Forbidden");
};

Trusted Requests

if (allow_trusted("$si", "$proto")) {
    t_relay();
};

Checks protocols which could be one of the “any”, “udp, “tcp”, “tls”, “ws”, “wss” and “sctp”.

Perform Load Balancing with Dispatcher Module

Load balancing is critical to a production ready system to provide High availability and load sharing among available servers. This could be either stateless or stateful where they use call state tracking

Dispatcher module in Kamailio lends capabilities of SIP traffic dispatcher to it. It can load routes to gateways or destination sets from any storage source such as mysql , psql database or even plain text file (modparam("dispatcher", "db_url", <datasource_name>).

It can also assign priority for routing sip traffic to it ( modparam("dispatcher", "priority_col", "dstpriority"))

To discover active of inactive gateways it uses TM module. One can choose one among many algorithms to share the load , like

  • 0 – hash over callid
  • 1 – hash over from URI
  • 2 – hash over to URI
  • 3 – hash over request-URI
  • 4 – round-robin (next destination)
  • 5 – hash over authorization-username
  • 6 – random destination (using rand())
  • 7 – hash over the content of PVs string
  • 8 – select destination sorted by priority attribute value (serial forking ordered by priority).
  • 9 – use weight based load distribution . Needs attribute ‘weight’ per each address
  • 10 – call load distribution ie route to one that has the least number of calls associated
  • 11 – relative weight based load distribution(rweight)
  • 12 – dispatch to all destination in setid at once (parallel forking).
  • x – if the algorithm is not implemented, the first entry in set is chosen.

Some attributes passed with each destination set

  • duid – identify a destination (gateway address). Practically the load within the group is associated with this value.
  • maxload – upper limit of active calls per destination
  • weight – percent of calls to be sent to that gateways
  • rweight – relative weight based load distribution.
  • socket – sending socket for the gateway including keepalives
  • ping_from – from URI in OPTIONS keepalives

Active host usage probability is, rweight/(SUM of all active host rweights in destination group). recalculation is fired as host enables or disables.

Every destination has congestion threshold(weight) and after enabling c (congestion control), rweight is also used to control congestion tolerance lowering the weight by 1 as congestion is detected.

EWMA ( exponential weighted moving average ) is speed at which the older samples are dampened.

nametypesizedefaultnullkeyextra
idunsigned int10noprimaryauto
increment
setidintnot specified0no
destinationstring192“”no
flagintnot specified“”no
priorityintnot specified0no
attrsstring1980no
descriptionstring64“”no

To insert into dispatcher

INSERT INTO "dispatcher" VALUES(1,1,'sip:192.168.0.1:5060',0,12,'rweight=50;weight=50;cc=1;','');

set ping gateway once per second

modparam("dispatcher", "ds_ping_interval", 1)

enabling congestion metrics

modparam("dispatcher", "ds_ping_latency_stats", 1)

latency estimator

modparam("dispatcher", "ds_latency_estimator_alpha", 900)
loadmodule "dispatcher.so"
...
# ----- dispatcher params ----- 
modparam("dispatcher", "db_url", DBURL) 
modparam("dispatcher", "table_name", "dispatcher") modparam("dispatcher", "flags", 2) 
modparam("dispatcher", "dst_avp", "$avp(AVP_DST)") modparam("dispatcher", "grp_avp", "$avp(AVP_GRP)") modparam("dispatcher", "cnt_avp", "$avp(AVP_CNT)") modparam("dispatcher", "sock_avp", "$avp(AVP_SOCK)")
...

request_route {
# do checks , indialog etc ...
# dispatch destinations 
route(DISPATCH); 
}

# Dispatch requests
route[DISPATCH] {
     # round robin dispatching on gateways group '1'
     if(!ds_select_dst("1", "4")) {
         send_reply("404", "No destination");
         exit;
     }
     xlog("L_DBG", "--- SCRIPT: going to <$ru> via <$du>\n");
     t_on_failure("RTF_DISPATCH");
     route(RELAY);
     exit;
 }


# Try next destinations in failure route, except if session gets cancelled 
failure_route[RTF_DISPATCH] {
     if (t_is_canceled()) {
         exit;
     }
     # next DST - only for 500 or local timeout
     if (t_check_status("500") or (t_branch_timeout() and !t_branch_replied())) {
         if(ds_next_dst()) {
             t_on_failure("RTF_DISPATCH");
             route(RELAY);
             exit;
         }
     }
 }

More on Kamailio Call routing and Control

Kamailio basic setup as proxy for FreeSWITCH

I have added a detailed description of how kamalio based SIP servers can function as proxy / SBC for SIP Application server which could be an enterprise PBX or a full fledged Telecom Application Server such as Asterix , Freeswitch , Oracle Weblogic, telestax sip server etc

Kamailio basic setup as proxy for FreeSWITCH

References