My VoIP provider recently added support for TLS/SRTP-based call encryption. Here's what I did to enable this feature on my Asterisk server.

First of all, I changed the registration line in /etc/asterisk/sip.conf to use the "tls" scheme:

[general]
register => tls://mydid:mypassword@servername.voip.ms

then I enabled incoming TCP connections:

tcpenable=yes

and TLS:

tlsenable=yes
tlscapath=/etc/ssl/certs/

Finally, I changed my provider entry in the same file to:

[voipms]
type=friend
host=servername.voip.ms
secret=mypassword
username=mydid
context=from-voipms
allow=ulaw
allow=g729
insecure=port,invite
transport=tls
encryption=yes

(Note the last two lines.)

The dialplan didn't change and so I still have the following in /etc/asterisk/extensions.conf:

[pstn-voipms]
exten => _1NXXNXXXXXX,1,Set(CALLERID(all)=Francois Marier <5551234567>)
exten => _1NXXNXXXXXX,n,Dial(SIP/voipms/${EXTEN})
exten => _1NXXNXXXXXX,n,Hangup()
exten => _NXXNXXXXXX,1,Set(CALLERID(all)=Francois Marier <5551234567>)
exten => _NXXNXXXXXX,n,Dial(SIP/voipms/1${EXTEN})
exten => _NXXNXXXXXX,n,Hangup()
exten => _011X.,1,Set(CALLERID(all)=Francois Marier <5551234567>)
exten => _011X.,n,Authenticate(1234) ; require password for international calls
exten => _011X.,n,Dial(SIP/voipms/${EXTEN})
exten => _011X.,n,Hangup(16)

Server certificate

After setting everything up, I saw the following error in my logs:

asterisk[8691]: ERROR[8691]: tcptls.c:966 in __ssl_setup: TLS/SSL error loading cert file. <asterisk.pem>

due to the fact that I didn't set tlscertfile in /etc/asterisk/sip.conf and that it's using its default value of asterisk.pem, a non-existent file.

I initially thought that since my Asterisk server is only acting as a TLS client, and not a TLS server, there's probably no harm in not having a certificate. In practice however, my TLS connection was a little unreliable and it would regularly fail with the following TLS errors:

asterisk[534775]: ERROR[534879]: iostream.c:538 in ast_iostream_close: SSL_shutdown() failed: error:00000005:lib(0):func(0):DH lib, Underlying BIO error: Broken pipe
asterisk[534775]: ERROR[610289]: tcptls.c:553 in ast_tcptls_client_start: Unable to connect SIP socket to w.x.y.z:5061: Connection refused
asterisk[534775]: ERROR[610289]: tcptls.c:553 in ast_tcptls_client_start: Unable to connect SIP socket to w.x.y.z:5061: Connection reset by peer

I therefore decided to setup a Let's Encrypt certificate in Asterisk to eliminate the original error.

Firewall

This originally appeared not to be necessary, but I found that I ran into a number of intermittent connection errors such as:

asterisk[1280841]: ERROR[1537920]: tcptls.c:553 in ast_tcptls_client_start: Unable to connect SIP socket to w.x.y.z:5061: Connection reset by peer

and so I put the official firewall recommendations in /etc/network/iptables.up.rules:

# SIP and RTP on TCP/UDP (servername.voip.ms)
-A INPUT -s w.x.y.z/32 -p tcp --dport 5061 -j ACCEPT
-A INPUT -s w.x.y.z/32 -p udp --sport 5004:5005 --dport 10001:20000 -j ACCEPT

where w.x.y.z is the IP address of servername.voip.ms as returned by dig +short servername.voip.ms.