Site map  

Freedom Internet VOIP

An Asterisk SIP trunk setup with multiple remote IP addresses.

Example Configuration

According to the Freedom internet online documentation (Dutch), one has to register with the following entry in the '[general]' section of /etc/asterisk.sip.conf;

register => Account_Id:PassWord@sipproxy.voipgrid.nl/Account_Id

Problem

According to their website this did register me, but I couldn't be called.
Using an IP address instead of a hostname did work;

register => Account_Id:PassWord@195.35.114.24

Analysis

As it turns out, sipproxy.voipgrid.nl has two IP addresses; 195.35.114.24 and 195.35.115.24. Furthermore, a SRV lookup leads to more hostnames;

pc8:~$ host -t SRV _sip._udp.sipproxy.voipgrid.nl
_sip._udp.sipproxy.voipgrid.nl has SRV record 10 0 6060 sbc2-grq.voipgrid.nl.
_sip._udp.sipproxy.voipgrid.nl has SRV record 20 0 6060 sbc2-ams.voipgrid.nl.
_sip._udp.sipproxy.voipgrid.nl has SRV record 50 0 5060 sipproxy.grq.voipgrid.nl.
_sip._udp.sipproxy.voipgrid.nl has SRV record 60 0 5060 sipproxy.ams.voipgrid.nl.

With even more IP addresses;

sbc2-ams.voipgrid.nl has address 195.35.114.41
sbc2-ams.voipgrid.nl has IPv6 address 2a06:2a80:0:114::41
sbc2-grq.voipgrid.nl has address 195.35.115.41
sbc2-grq.voipgrid.nl has IPv6 address 2a06:2a80:0:115::41
sipproxy.ams.voipgrid.nl has address 195.35.114.119
sipproxy.grq.voipgrid.nl has address 195.35.115.119

I didn't want to disable SRV lookups, so created a _sip._udp.sipproxy.voipgrid.nl DNS blackhole. This did not quite solve the problem though. Only registering to an IP address did.
A tcpdump ('tcpdump -i wan -vvv -s 1500 -U port sip') (a rasterisk (or asterisk -r) 'sip set debug on' will also work) showed the problem: My Asterisk was refusing INVITEs!

11:06:00.460261 IP (tos 0x10, ttl 58, id 30021, offset 0, flags [DF], proto UDP (17), length 1305)
    sbc1-grq.voipgrid.nl.sip > ns4.sput.nl.sip: [udp sum ok] SIP, length: 1277
	INVITE sip:Account_Id@45.83.234.41:5060 SIP/2.0
	Record-Route: <sip:195.35.115.24;r2=on;lr>
	Record-Route: <sip:195.35.115.24:5070;r2=on;lr>
	Record-Route: <sip:195.35.115.40;lr;ftag=XXXXXXXX;did=XXXXXXXX;mc=from-dutch;cc=XXXXXXXX>
	Via: SIP/2.0/UDP 195.35.115.24:5060;branch=XXXXXXXX
	Via: SIP/2.0/UDP 195.35.115.40:5060;branch=XXXXXXXX
	Via: SIP/2.0/UDP 195.35.114.112:5060;received=195.35.114.112;branch=XXXXXXXX;rport=5060
	Max-Forwards: 68
	From: "Sput" <sip:Phone_Number@voipgrid.nl>;tag=XXXXXXXX
	To: <sip:Account_Id@voipgrid.nl:5060>
	Contact: <sip:Phone_Number@195.35.114.112:5060>
	Call-ID: XXXXXXXX@voipgrid.nl
	CSeq: 102 INVITE
	User-Agent: VGUA-18vg14~d10
	Date: Fri, 18 Nov 2022 10:06:00 GMT
	Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
	Supported: replaces, timer
	Content-Type: application/sdp
	Content-Length: 333
	
	v=0
	o=- 1783165561 1783165561 IN IP4 195.35.114.112
	s=VGUA-18vg14~d10
	c=IN IP4 195.35.114.112
	t=0 0
	m=audio 16552 RTP/AVP 8 9 97 18 101
	a=rtpmap:8 PCMA/8000
	a=rtpmap:9 G722/8000
	a=rtpmap:97 iLBC/8000
	a=rtpmap:18 G729/8000
	a=fmtp:18 annexb=no
	a=rtpmap:101 telephone-event/8000
	a=fmtp:101 0-16
	a=maxptime:150
	a=sendrecv
11:06:00.460609 IP (tos 0x0, ttl 64, id 59520, offset 0, flags [none], proto UDP (17), length 751)
    ns4.sput.nl.sip > sbc1-grq.voipgrid.nl.sip: [udp sum ok] SIP, length: 723
	SIP/2.0 401 Unauthorized
	Via: SIP/2.0/UDP 195.35.115.24:5060;branch=XXXXXXXX;received=195.35.115.24
	Via: SIP/2.0/UDP 195.35.115.40:5060;branch=XXXXXXXX
	Via: SIP/2.0/UDP 195.35.114.112:5060;received=195.35.114.112;branch=XXXXXXXX;rport=5060
	From: "Sput" <sip:Phone_Number@voipgrid.nl>;tag=XXXXXXXX
	To: <sip:Account_Id@voipgrid.nl:5060>;tag=XXXXXXXX
	Call-ID: XXXXXXXX@voipgrid.nl
	CSeq: 102 INVITE
	Server: Asterisk PBX Version
	Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
	Supported: replaces, timer
	WWW-Authenticate: Digest algorithm=MD5, realm="sput.nl", nonce="XXXXXXXX"
	Content-Length: 0

Default, Asterisk has allowguest enabled. But in my /etc/sip.conf it says 'allowguest=no' (sure, I'm paranoid). This means that Asterisk wants to authenticate INVITEs from unknown IP addresses. And Asterisk only knows the 'first' IP address of the 'host' it registers to.

Solution

One solution is to create entries in /etc/asterisk.sip.conf for each of the IP addresses.
To avoid lots of typing I first created a template. This holds the information all the entries have in common;

[voipgrid-in](!)
	type=peer
	context=freedom-in
	defaultuser=Account_Id
	fromuser=Account_Id
	fromdomain=voipgrid.nl
	secret=PassWord
	; Codec 
	disallow=all
	allow=alaw
	; Do not require authentication of incoming INVITEs
	insecure=invite
	; Remote-Party-ID should be sent
	sendrpid=yes
	; Remote-Party-ID should be trusted
	trustrpid=yes

And then create an entry per IP address;

[freedom](voipgrid-in)
host=sipproxy.voipgrid.nl

[freedom_1](voipgrid-in)
host=2a06:2a80:0:114::41

[freedom_2](voipgrid-in)
host=2a06:2a80:0:115::41

[freedom_3](voipgrid-in)
host=195.35.114.23

[freedom_4](voipgrid-in)
host=195.35.114.24

[freedom_5](voipgrid-in)
host=195.35.114.41

[freedom_6](voipgrid-in)
host=195.35.114.119

[freedom_7](voipgrid-in)
host=195.35.115.23

[freedom_8](voipgrid-in)
host=195.35.115.24

[freedom_9](voipgrid-in)
host=195.35.115.41

[freedom_A](voipgrid-in)
host=195.35.115.119

The first entry is for dialling out. This actually does a SRV lookup and ends up dialling via IPv6 (I got rid of the DNS SRV blackhole). The other entries are for incoming calls.

Check

Below a 'sip show peers';

sip show peers
Name/username Host Dyn Forcerport Comedia ACL Port Status Description
freedom/Account_Id 2a06:2a80:0:115::41 Auto (No) No 6060 Unmonitored
freedom_1/Account_Id 2a06:2a80:0:114::41 Auto (No) No 5060 Unmonitored
freedom_2/Account_Id 2a06:2a80:0:115::41 Auto (No) No 5060 Unmonitored
freedom_3/Account_Id 195.35.114.23 Auto (No) No 5060 Unmonitored
freedom_4/Account_Id 195.35.114.24 Auto (No) No 5060 Unmonitored
freedom_5/Account_Id 195.35.114.41 Auto (No) No 5060 Unmonitored
freedom_6/Account_Id 195.35.114.119 Auto (No) No 5060 Unmonitored
freedom_7/Account_Id 195.35.115.23 Auto (No) No 5060 Unmonitored
freedom_8/Account_Id 195.35.115.24 Auto (No) No 5060 Unmonitored
freedom_9/Account_Id 195.35.115.41 Auto (No) No 5060 Unmonitored
freedom_A/Account_Id 195.35.115.119 Auto (No) No 5060 Unmonitored

Note that the first IP address also appears further down the list.

A 'sip show peers' does NOT show remote registrations though. A a 'sip show registry' does;

sip show registry
Host dnsmgr Username Refresh State Reg.Time
sipproxy.voipgrid.nl:5060 N Account_Id 105 Registered Sat, 19 Nov 2022 09:19:34

What this doesn't show is the result of a SRV lookup: Incoming calls are also via IPv6. And 'sipproxy.voipgrid.nl' only has IPv4 addresses.

Configuration

If you're dealing with dozens of incoming IP addresses, it's probably best to generate the above stuff with a script, dump the output to a file and include this file in sip.conf. You can even update this from a cron job.
Just below the first entry (the one with the hostname), include a file;

[freedom](voipgrid-in)
host=sipproxy.voipgrid.nl

#include /etc/asterisk/voipgrid-ips.conf

Containing;

; Ip addresses used by voipgrid-in

[freedom_1](voipgrid-in)
host=2a06:2a80:0:114::41

[freedom_2](voipgrid-in)
host=2a06:2a80:0:115::41

[freedom_3](voipgrid-in)
host=195.35.114.23

[freedom_4](voipgrid-in)
host=195.35.114.24

[freedom_5](voipgrid-in)
host=195.35.114.41

[freedom_6](voipgrid-in)
host=195.35.114.119

[freedom_7](voipgrid-in)
host=195.35.115.23

[freedom_8](voipgrid-in)
host=195.35.115.24

[freedom_9](voipgrid-in)
host=195.35.115.41

[freedom_A](voipgrid-in)
host=195.35.115.119

Scripts

The script 'gen-voipgr-ips.sh' below generates this file.

#!/bin/bash

# Generate voipgrid-ips.conf
# Modify to suit your needs

# Hosts, one per line
HOSTS="sip.freedom.nl
sip-tls.freedom.nl
sipproxy.voipgrid.nl
sip.encryptedsip.com"
# Output file name
FILE="voipgrid-ips.conf"
# VOIP Provider name
VOIPISP="freedom"
# VOIP Template name
VOIPTPL="voipgrid-in"


IP4S=""
IP6S=""
IPS=""
SRVS=""

export LC_ALL=C.UTF-8


# Functions

# Find IPv4 addresses
find4addr()
{
	IP4S=$( host "${1}" | grep "has address" | awk '{print $4}' )
}

# Find IPv6 addresses
find6addr()
{
	IP6S=$( host "${1}" | grep "has IPv6 address" | awk '{print $5}' )
}

# Find SRV record addresses
findsrvadr()
{
	while read SRV
	do
		#echo "Find IP addresses of ${SRV}"
		find4addr "${SRV}"
		if [ -n "${IP4S}" ]
		then
			#echo "${IP4S}"
			IPS=$( echo -e "${IPS}\n${IP4S}" )
		fi
		find6addr "${SRV}"
		if [ -n "${IP6S}" ]
		then
			#echo "${IP6S}"
			IPS=$( echo -e "${IPS}\n${IP6S}" )
		fi
	done <<< "${SRVS}"
}

# Find SRV records
findsrv()
{
	# Note: ${2} is a hostname
	SRVS=""
	SRVS=$( host -t SRV "${1}.${2}" | awk '{print $8}' )
}

# Find all SRV record addresses
findallsrvadr()
{
	# Note: ${1} is a hostname
	#echo "Find SRV records of ${1}"
	findsrv "_sip._udp" "${1}"
	if [ -n "${SRVS}" ]
	then
		# Sort and remove duplicates
		SRVS=$( echo "${SRVS}" | sort -uV )
		#echo -e "Udp-Sip\n${SRVS}"
		# Find addresses
		findsrvadr
	fi
	findsrv "_sip._tcp" "${1}"
	if [ -n "${SRVS}" ]
	then
		SRVS=$( echo "${SRVS}" | sort -uV )
		#echo -e "Tcp-Sip\n${SRVS}"
		findsrvadr
	fi
	findsrv "_sips._tcp" "${1}"
	if [ -n "${SRVS}" ]
	then
		SRVS=$( echo "${SRVS}" | sort -uV )
		#echo -e "Sip-Tls\n${SRVS}"
		findsrvadr
	fi
}

# Find IPv4 and IPv6 addresses
findadr()
{
	# Note: ${1} is a hostname
	#echo "Find IP addresses of ${1}"
	# Find IPv4 addresses
	find4addr "${1}"
	# Find IPv6 addresses
	find6addr "${1}"
	# Merge
	if [ -n "${IP4S}" ]
	then
		#echo "${IP4S}"
		if [ -z "${IPS}" ]
		then
			# First time
			IPS="${IP4S}"
		else
			# Join
			IPS=$( echo -e "${IPS}\n${IP4S}" )
		fi
	fi
	if [ -n "${IP6S}" ]
	then
		#echo "${IP6S}"
		if [ -z "${IPS}" ]
		then
			# First time
			IPS="${IP6S}"
		else
			# Join
			IPS=$( echo -e "${IPS}\n${IP6S}" )
		fi
	fi
}

while read HOST
do
	# Find IP addresses
	findadr "${HOST}"
	# Add IP addresses of SRV records
	findallsrvadr "${HOST}"
done <<< "${HOSTS}"

# Sort and remove duplicates
IPS=$( echo "${IPS}" | sort -uV )
#echo -e "IP Addresses are\n${IPS}"

# Generate file
CNT=1
echo "; Ip addresses used by ${VOIPTPL}" > "${FILE}"
echo "" >> "${FILE}"
while read IP
do
	NUM=$( printf "%X" "${CNT}" )
	echo "[${VOIPISP}_${NUM}](${VOIPTPL})" >> "${FILE}"
	echo "host=${IP}" >> "${FILE}"
	echo "" >> "${FILE}"
	let CNT+=1
done <<< "${IPS}"

'sort' has two options: '-uV'. 'u' removes duplicates. 'V' does a version number sort. When sorting host names or IP addresses, This yields a more sensible result then a numeric or alphabetic sort.
'export LC_ALL=C.UTF-8' sets the locale, which includes collation. Collation includes the sort order. With a 'C' locale, this gets set to unsigned ascending byte order.
The 'printf "%X" "${CNT}"' above converts 'CNT' to an upper case hex number. You can change this if you like. Use '%x' for lower case hex, '%d' for decimal or '%02d' for decimal with leading zero.

Cron script

The script 'check-voipgrid.sh' below can be run from cron to check for changes in the IP addresses. You need to create a directory '/var/local/lib/voipgrid/' for this to work.

#!/bin/bash

# Compare versions of voipgrid-ips.conf
# Modify to suit your needs

DIR="/var/local/lib/voipgrid"
FILE="voipgrid-ips.conf"

if [ ! -d "${DIR}" ]
then
	echo "Directory ${DIR} not found"
	exit 1
fi

cd "${DIR}/"

if [ -f "${FILE}" ]
then
	mv "${FILE}" "${FILE}.bak"
else
	> "${FILE}.bak"
	chmod 640 "${FILE}.bak"
	chown root:asterisk "${FILE}.bak"
fi

/usr/local/bin/gen-voipgr-ips.sh
chmod 640 "${FILE}"
chown root:asterisk "${FILE}"

if ! ( diff "${FILE}" "${FILE}.bak" > /dev/null )
then
	echo "Voipgrid IPs changed"
	cat "${FILE}"
fi

Note: Both scripts go in '/usr/local/bin/'.

Use

When the IP addresses change, cron will mail the new addresses to you. If you are happy with the new file, copy 'voipgrid-ips.conf' from '/var/local/lib/voipgrid/' to '/etc/asterisk/'. Then do an 'asterisk -rx "sip reload"' for the changes to take effect;

~# cp /var/local/lib/voipgrid/voipgrid-ips.conf /etc/asterisk/
~# asterisk -rx "sip reload"

Modify to suit your needs.