Asterisk 16 with pjsip and verifies on the dialplan that TLS / SRTP are enabled before making calls

Hi guys

I state that I install Asterisk on Debian directly from the .deb package and I never had any problems.
I upgraded Asterisk from version 13.14 on Debian9 to version 16.2 on Debian10 using the same configurations (pjsip.conf, extensions.conf) and now my sip clients do not make calls to each other because there is verification on the dialplan 'encrypted audio (SRTP) that does not pass.

Looking at the CLI below we note that the {CHANNEL (pjsip, secure)} variable which indicates whether the signaling is safe is ok ie 1, while the {CHANNEL (rtp, secure)} variable which indicates whether the audio is sure it is not the expected one (on Asterisk 13 it results correctly 1), besides there is the WARNING “func_channel_read: Unknown or unavailable item requested: ‘rtp, secure’”. Yet in the documentation, the CHANNEL function on Asterisk 16 is almost the same on Asterisk 13 with the same PJSIP Technology.

I ask, where is the error?

Or if I don’t check to see if both TLS and SRTP are really active, how can I trust that the calls are secure? Is it enough that all endpoints are correctly configured for tls transport and encrypted audio (media_encryption = sdes)?

CLI>
== Setting global variable ‘SIPDOMAIN’ to ‘xxx.xxx.xxx.xxx’
[2019-07-18 11:34:25] WARNING[899]: pjsip/dialplan_functions.c:572 channel_read_rtp: Channel PJSIP/220-00000000 has no audio media/RTP session
[2019-07-18 11:34:25] WARNING[1634][C-00000001]: func_channel.c:463 func_channel_read: Unknown or unavailable item requested: ‘rtp,secure’
– Executing [220@fromsipext:1] NoOp(“PJSIP/220-00000000”, "SECURE signaling (TLS): 1 - SECURE media (SRTP): ") in new stack
– Executing [220@fromsipext:2] GotoIf(“PJSIP/220-00000000”, “0?encrypt_fail”) in new stack
[2019-07-18 11:34:25] WARNING[899]: pjsip/dialplan_functions.c:572 channel_read_rtp: Channel PJSIP/220-00000000 has no audio media/RTP session
[2019-07-18 11:34:25] WARNING[1634][C-00000001]: func_channel.c:463 func_channel_read: Unknown or unavailable item requested: ‘rtp,secure’
– Executing [220@fromsipext:3] GotoIf(“PJSIP/220-00000000”, “1?encrypt_fail”) in new stack
– Goto (fromsipext,220,8)
– Executing [220@fromsipext:8] Playback(“PJSIP/220-00000000”, “unsafe-call”) in new stack
– <PJSIP/220-00000000> Playing ‘unsafe-call.gsm’ (language ‘it’)
– Executing [220@fromsipext:9] Hangup(“PJSIP/220-00000000”, “”) in new stack
== Spawn extension (fromsipext, 220, 9) exited non-zero on ‘PJSIP/220-00000000’
CLI>

Below is a part of the extensions.conf file that delays the dialplan for calls between sip extensions

--------------------------------------- extensions.conf -------------------------------------------------
[fromsipext]
exten => _2[0123456]X,1,NoOp(SECURE signaling (TLS): {CHANNEL(pjsip,secure)} - SECURE media (SRTP): {CHANNEL(rtp,secure)})
exten => _2[0123456]X,n,GotoIf(["{CHANNEL(pjsip,secure)}"=""]?encrypt_fail) ; verify secure signaling enabled on sip client
exten => _2[0123456]X,n,GotoIf(["{CHANNEL(rtp,secure)}"=""]?encrypt_fail) ; verify secure media enabled on sip client
exten => _2[0123456]X,n,Gosub(stdexten,{EXTEN},start(PJSIP/{EXTEN}))
exten => _2[0123456]X,n,NoOp(HANGUPCAUSE Code is {HANGUPCAUSE}) exten => _2[0123456]X,n,GotoIf(["${HANGUPCAUSE}"=“58”]?encrypt_fail)
exten => _2[0123456]X,n,Hangup
exten => _2[0123456]X,n(encrypt_fail),Playback(unsafe-call) ; notify user that retrying via insecure channel
exten => _2[0123456]X,n,Hangup

[stdexten]
exten => _X.,1(start),NoOp(Start Standard extension - Called Num. {EXTEN} has device state: {DEVICE_STATE({ARG1})}) exten => _X.,n,Set(LOCAL(ext)={EXTEN})
exten => _X.,n,Set(LOCAL(dev)={ARG1}) exten => _X.,n,Set(LOCAL(cntx)={ARG2})
exten => _X.,n,Set(LOCAL(mbx)={ext}{IF([!{ISNULL({cntx})}]?@{cntx})})
exten => _X.,n,GotoIf([{DEVICE_STATE({ARG1})} = BUSY ]?stdexten-BUSY,1) ; If BUSY go to busy exten exten => _X.,n,Dial({dev},30,t) ; Ring the interface, 30 seconds maximum
exten => _X.,n,NoOP(Dial Status of Called Num: {DIALSTATUS} - Device {EXTEN} has state: {DEVICE_STATE({ARG1})})
exten => _X.,n,Goto(stdexten-{DIALSTATUS},1) ; Jump based on status (NOANSWER,BUSY,CHANUNAVAIL,CONGESTION,ANSWER) exten => stdexten-NOANSWER,1,NoOP(Called {ARG1} NO ANSWER - HANGUPCAUSE Code: {HANGUPCAUSE}) ; if NOANSWER (call hangup timeout 30s) exten => stdexten-NOANSWER,n,GotoIf(["{HANGUPCAUSE}"="19"]?stdexten-CONGESTION,1) ; if NOANSWER and HANGUPCAUSE=19 then DND status exten => stdexten-NOANSWER,n,Return() ; If they press #, return to start exten => stdexten-BUSY,1,Playback(vm-theperson) ; If BUSY, playback busy announce exten => stdexten-BUSY,2,Playback(vm-isonphone) exten => stdexten-BUSY,n,Return() ; If they press #, return to start exten => stdexten-CONGESTION,1,NoOP(CONGESTION: called rejected the call because is DND) exten => stdexten-CONGESTION,2,Playback(isdnd-status) exten => stdexten-CONGESTION,n,Return() exten => stdexten-CHANUNAVAIL,1,NoOP(CHANUNAVAIL: the called number not registered or not exsist) exten => stdexten-CHANUNAVAIL,2,Playback(vm-theperson) ; If BUSY, playback unavailable announce exten => stdexten-CHANUNAVAIL,3,Playback(vm-isunavail) exten => stdexten-CHANUNAVAIL,n,Return() exten => _stde[x]te[n]-.,1,NoOP(Dial Status Called Num: {DIALSTATUS})
exten => _stdete[n]-.,2,Goto(stdexten-NOANSWER,1) ; Treat anything else as no answer


Below is a part of the pjsip.conf file

----------------------- pjsip.conf ------------------------
[transport-tls]
type=transport
protocol=tls
bind=0.0.0.0:5061
cert_file=/etc/asterisk/keys/asterisk.pem
priv_key_file=/etc/asterisk/keys/asterisk.key
method=tlsv1
local_net=172.16.10.0/24
local_net=192.168.0.0/24
external_media_address=xxx.xxx.xxx.xxx
external_signaling_address=xxx.xxx.xxx.xxx

[220]
type=endpoint
transport=transport-tls
media_encryption=sdes
context=fromsipext
disallow=all
allow=alaw,ulaw
auth=220
aors=220
direct_media=no
rtp_symmetric=yes
force_rport=yes
rewrite_contact=yes
device_state_busy_at=1

[220]
type=auth
auth_type=userpass
password=XXXXXXXX
username=220

[220]
type=aor
max_contacts=1
remove_existing=yes
qualify_frequency=60

[221]
type=endpoint
transport=transport-tls
media_encryption=sdes
context=fromsipext
disallow=all
allow=alaw,ulaw
auth=221
aors=221
direct_media=no
rtp_symmetric=yes
force_rport=yes
rewrite_contact=yes
device_state_busy_at=1

[221]
type=auth
auth_type=userpass
password=XXXXXXXX
username=221

[221]
type=aor
max_contacts=1
remove_existing=yes
qualify_frequency=60


Any suggestions are appreciated, thanks.

Hmmm. It’s possible there’s a bug in 16. I’m checking.

Here’s the situation… There were changes on how the CHANNEL(rtp,secure) is done between 13 and 16.

In 13 it was possible to check CHANNEL(rtp,secure) before the call was answered and negotiation was completed. Unfortunately, this could lead to misleading results if the client asked for encryption but it wasn’t negotiated successfully.

In Asterisk 16, that was changed so that you can’t call CHANNEL(rtp,secure) until there’s actually a fully negotiated rtp session (the call was answered). This ensures that the response you get reflects what was actually negotiated.

1 Like

Thanks for the reply.

I can only check the tls signaling before the call is answered and the negotiation is complete, in fact the CHANNEL check (pjsip, secure) returns the value 1.
I ask then is it enough that the endopoints are configured correctly with the “media_encryption = sdes” parameter so that SRTP is forced with secure media?

If optimistic SRTP is not enabled then the remote side has to negotiate SRTP, or else the call will be terminated.

In my pjsip.conf configuration the only “media_encryption_optimistic=no” parameter present is commented and its default value in the Asterisk’s documentation is “no”. So I should be quiet and the calls are just encrypted.

Moreover:
If in both clients disable the option for use SRTP (“Media Encryption” in MicroSIP softphone) or (“RTP Encryption” in Snom phone) the call does not even start.

If only one of the sip clients has the option for use SRTP disabled, there are two behaviors:
a) if it is the caller, the call does not even start.
b) if it is the called one, in the CLI I see that the Dial Status of Called Number is CHANUNAVAIL and the HANGUPCAUSE has code 58, so the call stops. In this case, just for information, I check the two variables above and with a GotoIf I can send the caller a playback alert that the call is not secure (only tls enabled but not srtp) and hangup.

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