An Asterisk SIP trunk setup with multiple remote IP addresses.
Note: This setup uses sip.conf. PjSip requires an other setup.
For a PjSip based setup, see:
Freedom Internet PjSip
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
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
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.
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.
Below a '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;
| 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.
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:114::119 [freedom_3](voipgrid-in) host=2a06:2a80:0:115::41 [freedom_4](voipgrid-in) host=2a06:2a80:0:115::119 [freedom_5](voipgrid-in) host=195.35.114.23 [freedom_6](voipgrid-in) host=195.35.114.24 [freedom_7](voipgrid-in) host=195.35.114.41 [freedom_8](voipgrid-in) host=195.35.114.119 [freedom_9](voipgrid-in) host=195.35.115.23 [freedom_A](voipgrid-in) host=195.35.115.24 [freedom_B](voipgrid-in) host=195.35.115.41 [freedom_C](voipgrid-in) host=195.35.115.119
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
sip6.voipgrid.nl
sip.encryptedsip.com"
# Output file name
FILE="voipgrid-ips.conf"
# VoIP service 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 than 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.
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/'.
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.