Asterisk 8 and later on Debian

Some Asterisk tips and tricks.

IPv6 Configuration

Asterisk supports IPv6 for IAX, RTP and SIP.

asterisk.conf

Automatically set systemname to hostname doesn't always work the way it should.

systemname=my_system_name

iax.conf

More recent versions of Asterisk support IPv6 for IAX as well.
Enable IPv6;

bindaddr=::

sip.conf

Note: pjsip.conf has a completely different syntax.
For PjSip see: Freedom Internet PjSip

Enable IPv6

Make sure that '/proc/sys/net/ipv6/bindv6only' is '0'. Otherwise Asterisk will be IPv6 only! You can set this in '/etc/sysctl.d/bindv6only.conf'.

bindaddr=::

RTP proxy

'directmedia=no' will turn Asterisk into a RTP audio proxy server. It will convert IPv6 RTP audio streams into IPv4 and IPv4 into IPv6 whenever required.

directmedia=no

Call-ID

Asterisk may use IPv6 address based Call-IDs when communicating with IPv4 only systems. This may confuse some software. Using a domain instead solves this problem.

fromdomain=mydomain.tld

TCP

If you want to use TCP enable it;

tcpenable=yes

To use SIP over TCP, just put it in the dial string;

SIP/username[:password[:md5secret[:authname[:transport]]]]@host[:port]

EG;

SIP/john::::tcp@example.org

TLS

If you want to use TLS enable it;

tlsenable=yes

TLS cert and key;

tlscertfile=/etc/asterisk/asterisk.crt
tlsprivatekey=/etc/asterisk/asterisk.key

Allow self signed certs;

tlsdontverifyserver=yes

For a self singed cert, a modified version of the Exim cert generation script can be used. Modify to suit your needs.
A let's encrypt dehydrated setup here. It uses a dns-01 DNS challenge and wildcard.

A combination of 'bindaddr=::', 'tcpenable=yes' and 'tlsenable=yes' results in the following netstat output;

~$ netstat -an | egrep "506[01]"
tcp6       0      0 :::5060                 :::*                    LISTEN
tcp6       0      0 :::5061                 :::*                    LISTEN
udp6       0      0 :::5060                 :::*

If you want to do the same with PjSip look here: Freedom Internet PjSip

Example dial string;

SIP/john:tls@example.org

Paranoid options

Stuff for extra security

File permissions

Default, Debian will install the config files mode 640 / -rw-r----- asterisk:asterisk. This means that the Asterisk daemon can write to it's own config files. Personally I do not think that this a good idea. This is why I change the owner to 'root:asterisk'. And the 'manager.d/' to mode 775 / drwxrwxr-x. In extensions.conf I set 'writeprotect=yes'. So only root can change the configuration (this may interfere with the way you like to administer Asterisk).
Note: Debian will reset these permissions during updates!

Incoming calls

In sip.conf I set 'allowguest=no'. This means that Asterisk will demand a login for incoming calls from unknown IP addresses.
This may cause trouble if your trunk provider uses multiple IP addresses!
An example of how to fix this here: Freedom Internet VoIP

Music on hold

You may want to replace the default music on hold files that come with Asterisk by some other public domain music. You may also want to use WAV or SLN instead of GSM files. These sound a lot better than GSM files! For WAV files use mono 8000 samples per second signed 16 bit.
From man soxformat;

 .sln  Asterisk PBX `signed linear' 8khz, 16-bit signed integer, little-endian
       raw format.

So that's like WAV without a header.
Asterisk will convert these files on the fly to alaw, µlaw or whatever is required.

Convert the files

File conversion is done in two steps:

  1. Use ffmpeg to convert APE, FLAC or MP3 to WAV.
  2. Use sox to reduce to sample rate of the WAV file and create a SLN file.

Convert to WAV

The script to-wav.sh converts APE, FLAC or MP3 to WAV. The file gets the extension '.hsr.wav' (High Sample Rate).

#!/bin/bash

OUTFIL=""

if ! [ -f "${1}" ]
then
	echo "File ${1} not found"
	exit 1
fi

NAME=$( basename "${1}" .ape )
if [ "${NAME}.ape" != "${1}" ]
then
	NAME=$( basename "${1}" .flac )
	if [ "${NAME}.flac" != "${1}" ]
	then
		NAME=$( basename "${1}" .mp3 )
		if [ "${NAME}.mp3" != "${1}" ]
		then
			echo "File ${1} is not Ape, Flac or Mp3"
			echo "Exeting"
			exit 1 
		fi
	fi
fi

OUTFIL="${NAME}.hsr.wav"

if [ -f "${OUTFIL}" ]
then
	echo "File ${OUTFIL} exists"
	exit 1
fi

echo "Converting ${1} to Wav file ${OUTFIL}"

ffmpeg -i "${1}" "${OUTFIL}"

Reduce the sample rate

The script wav2lsr.sh (Low Sample Rate) reduces the sample rate to 8000 samples per second. Before the conversion, the data passes a 300 Hz 12 dB/Oct high-pass and a 12 dB/Oct 3400 Hz low-pass filter (red). And when changing the sample rate, sox applies its own filter (blue);
High-pass and Low-pass Filter

Next a SLN file is generated.

#!/bin/bash

if ! [ -f "${1}" ]
then
	echo "File ${1} not found"
	exit 1
fi

NAME=$( basename "${1}" .hsr.wav )
if ! [ -f "${NAME}.hsr.wav" ]
then
	echo "File ${NAME}.hsr.wav not found"
	exit 1
fi

echo "Reducing sample rate of ${1}"
# Convert to wav
if [ -n "${2}" ]
then
	# Volume
	echo "Adjusting volume by ${2}"
	sox -v "${2}" "${1}" -t wav -r 8000 -e signed-integer -b 16 -c 1 "${NAME}.wav" highpass 300 lowpass 3400
else
	sox "${1}" -t wav -r 8000 -e signed-integer -b 16 -c 1 "${NAME}.wav" highpass 300 lowpass 3400
fi

# Convert to sln
sox "${NAME}.wav" -t raw -r 8000 -e signed-integer -b 16 -c 1 "${NAME}.sln"

Filters may cause a bit of ringing. If this script complains about clipping, reduce the volume by half;

~$ wav2lsr.sh File_Name.wav 0.5

Change the volume

If on the other hand, there is no clipping whatsoever and the volume is rather low, you can increase the volume with the script chng-vol.sh. The script can be used for both SLN and WAV files.

#!/bin/bash

if [ -z "${1}" ] || [ -z "${2}" ] || [ -z "${3}" ] || [ "${1}" = "${2}"]
then
	echo "Usage: chng-vol.sh Input_File Output_File Volume"
	exit 1
fi

if ! [ -f "${1}" ]
then
	echo "File ${1} not found"
	exit 1
fi

NAME=$( basename "${1}" .sln )
if [ "${NAME}.sln" = "${1}" ]
then
	sox -v "${3}" -t raw -r 8000 -e signed-integer -b 16 -c 1 "${1}" -t raw -r 8000 -e signed-integer -b 16 -c 1 "${2}"
else
	NAME=$( basename "${1}" .wav )
	if [ "${NAME}.wav" = "${1}" ]
	then
		sox -v "${3}" "${1}" "${2}"
	else
		echo "File ${1} is not Sln or Wav"
	fi
fi

Below a 6 dB increase in volume;

~$ chng-vol.sh Input_File_Name Output_File_Name 2

And you don't have to use integers. Below a 3 dB increase in volume;

~$ chng-vol.sh Input_File_Name Output_File_Name 1.41

Check the volume

Make sure the volume isn't too high. The peek value should be at least a few dB below 0. And the RMS peek value not much higher than -9 dBm. You can use the sox '-n stats' option to check;

~$ sox -t raw -r 8000 -e signed-integer -b 16 -c 1 File_Name.sln -n stats
DC offset   0.000010
Min level  -0.462158
Max level   0.505310
Pk lev dB      -5.93
RMS lev dB    -27.92
RMS Pk dB     -14.87
RMS Tr dB     -90.69
Crest factor   12.58
Flat factor     0.00
Pk count           2
Bit-depth      15/16
Num samples    2.86M
Length s     357.440
Scale max   1.000000
Window s       0.050

Note that the '-n stats' bit goes after the file name.

The values displayed by sox are dBs below clip level. Clip level is about 3 dBm (See dBm and bits). So -9 dBm is about -15 dB RMS below clip level in sox stats. And -12 dBm -18 dB RMS in sox stats. So the 'RMS Pk dB' of -14.87 dB corresponds to about -9 dBm (See dB Conversion table).

I put the files in '/usr/local/share/asterisk/moh/'.

Convert SLN to WAV

If your version of Asterisk supports WAV but not SLN, you can convert your files from SLN to WAV. The format remains 8000 samples per second, 16-bit signed integer mono.

sln2wav.sh;

#!/bin/bash

if ! [ -f "${1}" ]
then
	echo "File ${1} not found"
	exit 1
fi

# Base name
NAME=$( basename "${1}" .sln )
if ! [ -f "${NAME}.sln" ]
then
	echo "File ${NAME}.sln not found"
	exit 1
fi

echo "Converting ${NAME}.sln"

sox -t raw -r 8000 -e signed-integer -b 16 -c 1 "${NAME}.sln" "${NAME}.wav"

This adds a 44 byte WAV header without changing the rest of the file.

Change Asterisk Music on hold configuration

Edit (as root) /etc/asterisk/musiconhold.conf;

directory=/usr/local/share/asterisk/moh

You may want to set the order to random;

sort=random
random=yes

Let Asterisk use the new configuration;

~# asterisk -rx "moh reload"

Check for errors;

~# tail /var/log/asterisk/messages

Anonymous calls

Privacy Manager

Some notes on Privacy Manager.

Below an example;

exten => Your_Extention,1,Answer()
	same => n,PrivacyManager()
	same => n,GotoIf($["${PRIVACYMGRSTATUS}" = "FAILED"]?pmfail:num)
	same => n(num),Dial(Your_Internal_Dial_Command)
	same => n,Hangup()
	same => n(pmfail),Playback(im-sorry)
	same => n,Playback(vm-goodbye)
	same => n,Hangup()

If for some reason you want to test the existence of a number first, you can do that too;

exten => Your_Extention,1,GotoIf($["${CALLERID(num)}" = ""]?nonum:num)
	same => n(nonum),Answer()
	same => n,PrivacyManager()
	same => n,GotoIf($["${PRIVACYMGRSTATUS}" = "FAILED"]?pmfail:num)
	same => n(num),Dial(Your_Internal_Dial_Command)
	same => n,Hangup()
	same => n(pmfail),Playback(im-sorry)
	same => n,Playback(vm-goodbye)
	same => n,Hangup()

In case of an anonymous call the 'number' may be 'anonymous' instead of empty. In this case you have to clear the number first for privacy manager to work;

exten => Your_Extention,1,GotoIf($["${CALLERID(num)}" = "anonymous"]?anon:nona)
	same => n(anon),Set(CALLERID(num)=)
	same => n(nona),Answer()
	same => n,PrivacyManager()
	same => n,GotoIf($["${PRIVACYMGRSTATUS}" = "FAILED"]?pmfail:num)
	same => n(num),Dial(Your_Internal_Dial_Command)
	same => n,Hangup()
	same => n(pmfail),Playback(im-sorry)
	same => n,Playback(vm-goodbye)
	same => n,Hangup()

Privacy Manager will accept any DTMF 'digit' as input, but '#' only after the last 'digit'. So that's 0-9, A-D and '*', possibly followed by '#'.

Blocking anonymous calls

The following blocks anonymous calls completely.

exten => Your_Extention,1,GotoIf($["${CALLERID(num)}" = "anonymous"]?anon:nona)
	same => n(nona),GotoIf($["${CALLERID(num)}" = ""]?anon:num)
	same => n(num),Dial(Your_Internal_Dial_Command)
	same => n,Hangup()
	same => n(anon),Answer(500)
	same => n,PlayBack(/usr/local/share/asterisk/mysounds/anonymous)
	same => n,Hangup()

The '500' in 'Answer(500)' causes a 500 ms delay.
You can record your message with 'rec', which is in fact a symlink to 'sox' (you need 'sox' installed for this).
The following records 8000 16-bit little endian signed samples per second;

Wav format:

rec -c1 -e signed-integer -r 8000 -L anonymous.wav silence 1 0.1 3% 1 3.0 3%

Sln format:

rec -c1 -e signed-integer -r 8000 -t raw -L anonymous.sln silence 1 0.1 3% 1 3.0 3%

Note: You don't include the extension of the file (.wav or .sln) in extensions.conf.
Note: If your microphone doesn't work and you use alsamixer to configure your sound card, look here.

Blocking blacklisted numbers

And this one combines with blocking calls in your blacklist database;

	exten => Your_Extention,1,GotoIf($["${CALLERID(num)}" = "anonymous"]?anon:nona)
	same => n(nona),GotoIf($["${CALLERID(num)}" = ""]?anon:num)
	same => n(num),GotoIf($[${BLACKLIST()} = 1]?blck:nobl)
	same => n(nobl),Dial(Your_Internal_Dial_Command)
	same => n,Hangup()
	same => n(anon),Answer(500)
	same => n,PlayBack(/usr/local/share/asterisk/mysounds/anonymous)
	same => n(blck),Hangup()

A blacklisted caller-id immediately jumps to Hangup().

Edit blacklist

Add a new entry to the blacklist:
In 'rasterisk' / 'asterisk -r';

database put blacklist 9999999999 1

This adds the number '9999999999' to your blacklist.

Show entries;

database show blacklist
/blacklist/9999999999    : 1
1 results found.

Remove;

database del blacklist 9999999999

More info