Asterisk Outbound Proxy

Overview

The Skyetel network is a SIP-only network, and does not sit in the media pathway of the calls. This has enormous benefits that we outline here. However, there are circumstances where it is useful to put a server between our network and your endpoints. Specifically, this is useful when:

  • Your endpoint does not speak standards SIP
  • Your endpoint does not do well with NAT Translations
  • You need to extend the ALOC of a Short Duration System
  • You want to hide our IP Addresses

To accomplish this, we recommend using this guide to setup an Asterisk-based Proxy Server. 

We recommend Asterisk for this for two reasons; because it handles NAT very very well and because of the ease with which you can get support from the Asterisk Community. While other platforms offer more in terms of Scalability, Asterisk is unmatched for its support, depth of documentation and simplicity. 

Getting Started

Download & Install CentOS

We won't cover these steps in this guide. However, make sure you use a 64 bit version fo CentOS 7.

For your reference:
You can download a minimal CentOS 7 image here: http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-1804.iso.
For instructions on how to install CentOS 7, click here.

TL:DR

If you don't want to follow the below instructions, you can simply click here to download a bash script that will do all this dark magic for you. Then skip to Section 2 - Working with the Proxy

Disable SELinux

While this is not required, it will make your life much easier to manage and diagnose Asterisk. Be careful - this requires a reboot.

echo 0 > /selinux/enforce
setenforce 0
echo "SELINUX=disabled" > /etc/sysconfig/selinux
reboot

Install Updates and Prerequisites

This bit will install all of the updates and prerequisites required for Asterisk to compile and run

yum update -y
yum groupinstall Development Tools -y
yum install nano wget ncurses-dev uuid-devel libuuid-devel libtsan libxml2-devel sqlite-devel bison subversion libtermcap-devel git-core -y
yum install epel-release dmidecode gcc-c++ ncurses-devel libxml2-devel make wget openssl-devel newt-devel kernel-devel sqlite-devel libuuid-devel gtk2-devel jansson-devel binutils-devel -y

Install Jansson

cd /usr/src
git clone https://github.com/akheron/jansson.git
cd jansson/
autoreconf -i
./configure -prefix=/usr/
make && make install

Download and Prepare Asterisk

cd /usr/src
wget https://files.skyetel.com/asterisk-certified-13.21-current.tar.gz
tar -xzvf asterisk-certified-13.21-current.tar.gz
cd asterisk-certified-13*
./bootstrap.sh
./configure --libdir=/usr/lib64
 

Disable Asterisk Modules

This section is where we trim out a lot of the fat Asterisk ships with. Since we aren't actually using it as a PBX, we don't need things like voicemail or conference bridges. This makes Asterisk run extra lean.

 
make menuselect.makeopts
menuselect/menuselect --disable-all --enable chan_sip --enable pbx_config --enable app_dial --enable res_rtp_asterisk --enable res_rtp_multicast --enable chan_rtp --enable res_http_websocket --enable app_playback --enable app_stack --enable app_system --enable app_chanisavail --enable codec_ulaw --enable format_wav --enable CORE-SOUNDS-EN-WAV --enable CORE-SOUNDS-EN-ULAW --enable MOH-OPSOUND-WAV --enable MOH-OPSOUND-ULAW --enable EXTRA-SOUNDS-EN-WAV --enable EXTRA-SOUNDS-EN-ULAW --enable-category MENUSELECT_BRIDGES --enable-category MENUSELECT_FUNCS menuselect.makeopts

Install Asterisk

make && make install
make samples

Make Asterisk Run As A Service

This is not required - but we recommend it. Otherwise, Asterisk won't start when you reboot!

make config
chkconfig asterisk on

Configure Asterisk To Be A Skyetel Proxy

This section is the most important part. This is where we configure Asterisk to work with Skyetel as a Proxy. 

cd /etc/asterisk
rm -f sip.conf extensions.conf
wget https://files.skyetel.com/extensions.conf
wget https://files.skyetel.com/sip.conf

Install Asterisk Sounds

This is not required - but is useful if you want to have Asterisk play sounds in the call

cd /var/lib/asterisk/sounds
wget https://files.skyetel.com/asterisk-core-sounds-en-wav-current.tar.gz
wget https://files.skyetel.com/asterisk-extra-sounds-en-wav-current.tar.gz
tar xvf asterisk-core-sounds-en-wav-current.tar.gz
rm -f asterisk-core-sounds-en-wav-current.tar.gz
tar xfz asterisk-extra-sounds-en-wav-current.tar.gz
rm -f asterisk-extra-sounds-en-wav-current.tar.gz

Install SNGrep

SNGrep is one of the best products to get insight into what your equipment is doing. We recommend installing it so you can troubleshoot issues

echo "[irontec]" >> /etc/yum.repos.d/irontec.repo
echo "name=Irontec RPMs repository" >> /etc/yum.repos.d/irontec.repo
echo "baseurl=http://packages.irontec.com/centos/\$releasever/\$basearch/" >> /etc/yum.repos.d/irontec.repo
rpm --import http://packages.irontec.com/public.key
yum install sngrep -y

Reboot

One more reboot... and your Asterisk Proxy will be ready to rock and roll!

reboot

Working with the Proxy

Asterisk has two critical configuration files that you need to be familiar with. sip.conf and extensions.conf.

Everytime you make a change to these documents, execute this command to update Asterisk: service asterisk reload

Doing so will reload your changes into Asterisk. Even cooler - you can do this during active calls in the middle of production. Asterisk will simply begin using your changes on the next call that it receives.

sip.conf

sip.conf is where you tell Asterisk what endpoints are safe, how to interact with them, and what audio codecs to support. The sip.conf file that was installed during this process looks like this:

[General]
bindport=5060
bindaddr=0.0.0.0
tcpbindaddr=0.0.0.0
useragent=UBERPROXY
nat=yes
canreinvite=no
#externip=xxx.xxx.xxx.xxx
#localnet=xxx.xxx.xxx.xxx/24
 
###### SKYETEL NETWORK ######
 
[SkyetelCA]
disallow=all
type=peer
insecure=port,invite
host=52.8.201.128
dtmfmode=rfc2833
context=skyetel
allow=ulaw
qualify=yes
directmedia=no
directrtpsetup=no
sendrpid=no
canreinvite=no
 
[SkyetelTERM]
disallow=all
type=peer
qualify=yes
insecure=port,invite
host=term.skyetel.com
dtmfmode=rfc2833
context=skyetel
allow=ulaw
directmedia=no
directrtpsetup=no
sendrpid=no
canreinvite=no
 
[SkyetelOR]
disallow=all
type=peer
insecure=port,invite
host=52.41.52.34
dtmfmode=rfc2833
context=skyetel
allow=ulaw
qualify=yes
directmedia=no
directrtpsetup=no
sendrpid=no
canreinvite=no
 
[SkyetelVA]
disallow=all
host=50.17.48.216
type=peer
allow=ulaw
dtmfmode=rfc2833
insecure=port,invite
context=skyetel
qualify=yes
directmedia=no
directrtpsetup=no
sendrpid=no
canreinvite=no
 
[SkyetelHC]
disallow=all
host=hc.skyetel.com
type=peer
allow=ulaw
dtmfmode=rfc2833
insecure=port,invite
context=skyetel
directmedia=no
directrtpsetup=no
sendrpid=no
canreinvite=no
 
[SkyetelHC1]
disallow=all
host=52.32.223.28
type=peer
allow=ulaw
dtmfmode=rfc2833
insecure=port,invite
context=skyetel
directmedia=no
directrtpsetup=no
sendrpid=no
canreinvite=no
 
[SkyetelHC2]
disallow=all
host=52.4.178.107
type=peer
allow=ulaw
dtmfmode=rfc2833
insecure=port,invite
context=skyetel
directmedia=no
directrtpsetup=no
sendrpid=no
canreinvite=no
 
#### ENDPOINTS ####
 
[MyPBX]
disallow=all
allow=ulaw
host=xxx.xxx.xxx.xxx
type=peer
dtmfmode=rfc2833
context=proxy
directmedia=no
directrtpsetup=no
sendrpid=no
canreinvite=no

We've broken this configuration file into three sections General, Skyetel Network and Endpoints

General

This section is where you spell out how Asterisk should see itself. In the above configuration, we have assumed that you will use port 5060 for both TCP and UDP and want to listen to all interfaces. Its also a good idea to set your useragent to be something useful to you (like PROXY or BOOMSAUCE) as it will appear in our logs. Lastly, we enable configure it for NAT and tell it to work as a full proxy. 

So here's how that looks:

[General]
bindport=5060 #The port you want to listen on
bindaddr=0.0.0.0 #The address you want UDP to listen on. 0.0.0.0 listens everywhere
tcpbindaddr=0.0.0.0 #The address you want TCP to listen on. 0.0.0.0 listens everywhere
useragent=UBERPROXY #A name for your proxy.
nat=yes #This tells Asterisk to be aware of NAT. Leave this on even if your not using NAT.
canreinvite=no #This tells Asterisk that it cannot re-invite
#externip=xxx.xxx.xxx.xxx #If this proxy is behind a firewall, put the PUBLIC IP here
#localnet=xxx.xxx.xxx.xxx/24 #If this proxy is behind a firewall, put the PRIVATE IP here

Skyetel Network

These are the configurations necessary for the Proxy to interact with our network. We recommend not changing these settings.

Endpoints

This is the section that you use to allow your Endpoints to route through the proxy. We recommend not changing these settings as well (smile). However, you will need to put your IP Addresses into a block:

 
[MyPBX]
disallow=all #Disables all codecs except what you specify below
allow=ulaw #Allows the ulaw codec
host=xxx.xxx.xxx.xxx #Put your IP here
type=peer #This tells Asterisk how to work with your endpoint
dtmfmode=rfc2833 #What DTMF standard to use
context=proxy #Sets the context to be "proxy." We need this for extensions.conf to work
directmedia=no #makes all audio go through the proxy
directrtpsetup=no #really makes all audio go through the proxy
sendrpid=no #makes your Caller ID work correctly
canreinvite=no #keeps everything going through the proxy

For each endpoint, you'll need to add a whole block with its own title (the bit at the top with the brackets).

extensions.conf

This is where the magic happens. While sip.conf tells Asterisk what endpoints are allowed to route through it, extensions.conf tells Asterisk what to do with them when they attempt to place a call.

[proxy]
exten => _1xxxxxxxxxx,1,Dial(SIP/SkyetelTERM/${EXTEN},45)
exten => _1xxxxxxxxxx,n,Dial(SIP/SkyetelOR/${EXTEN},45)
exten => _1xxxxxxxxxx,n,Dial(SIP/SkyetelCA/${EXTEN},45)
exten => _1xxxxxxxxxx,n,Dial(SIP/SkyetelVA/${EXTEN},45)
exten => _1xxxxxxxxxx,n,Hangup()
 
[proxy]
exten => _xxxxxxxxxx,1,Dial(SIP/SkyetelTERM/1${EXTEN},45)
exten => _xxxxxxxxxx,n,Dial(SIP/SkyetelOR/1${EXTEN},45)
exten => _xxxxxxxxxx,n,Dial(SIP/SkyetelCA/1${EXTEN},45)
exten => _xxxxxxxxxx,n,Dial(SIP/SkyetelVA/1${EXTEN},45)
exten => _xxxxxxxxxx,n,Hangup()
 
[proxy]
exten => _01xxxxxxxxxx,1,Dial(SIP/SkyetelTERM/1${EXTEN:1},45)
exten => _01xxxxxxxxxx,n,Dial(SIP/SkyetelOR/1${EXTEN:1},45)
exten => _01xxxxxxxxxx,n,Dial(SIP/SkyetelCA/1${EXTEN:1},45)
exten => _01xxxxxxxxxx,n,Dial(SIP/SkyetelVA/1${EXTEN:1},45)
exten => _01xxxxxxxxxx,n,Hangup()
 
[proxy]
exten => _91xxxxxxxxxx,1,Dial(SIP/SkyetelTERM/1${EXTEN:1},45)
exten => _91xxxxxxxxxx,n,Dial(SIP/SkyetelOR/1${EXTEN:1},45)
exten => _91xxxxxxxxxx,n,Dial(SIP/SkyetelCA/1${EXTEN:1},45)
exten => _91xxxxxxxxxx,n,Dial(SIP/SkyetelVA/1${EXTEN:1},45)
exten => _91xxxxxxxxxx,n,Hangup()
 
[proxy]
exten => _911,1,Dial(SIP/SkyetelTERM/${EXTEN},45)
exten => _911,n,Dial(SIP/SkyetelOR/${EXTEN},45)
exten => _911,n,Dial(SIP/SkyetelCA/${EXTEN},45)
exten => _911,n,Dial(SIP/SkyetelVA/${EXTEN},45)
exten => _911,n,Hangup()
 
[proxy]
exten => _933,1,Dial(SIP/SkyetelTERM/${EXTEN},45)
exten => _933,n,Dial(SIP/SkyetelOR/${EXTEN},45)
exten => _933,n,Dial(SIP/SkyetelCA/${EXTEN},45)
exten => _933,n,Dial(SIP/SkyetelVA/${EXTEN},45)
exten => _933,n,Hangup()
 
[proxy]
exten => _0000641xxxxxxxxxx,1,Dial(SIP/SkyetelTERM/${EXTEN},45,F)
exten => _0000641xxxxxxxxxx,n,Wait(20)
exten => _0000641xxxxxxxxxx,n,Hangup()
 
[proxy]
exten => _011.,1,Dial(SIP/SkyetelHC/${EXTEN},45)
exten => _011.,n,Dial(SIP/SkyetelHC1/${EXTEN},45)
exten => _011.,n,Dial(SIP/SkyetelHC2/${EXTEN},45)
exten => _011.,n,Hangup()

Extensions.conf is a smidge more difficult to breakdown. Technically we don't need to have the proxy title above each block, but it does make it easier to read. Each section references a different Dial Pattern.

_1xxxxxxxxxx

This section will match dialed numbers that look like "13609865200". Once its matched, Asterisk will first send the call to term.skyetel.com, and then failover to our three other regions one by one. The calls will come to Skyetel looking like "13609865200" which is our required format.

_xxxxxxxxxx

This section will match dialed numbers that look like "3609865200". Once its matched, Asterisk will first send the call to term.skyetel.com, and then failover to our three other regions one by one. The calls will come to Skyetel looking like "13609865200" which is our required format.

_01xxxxxxxxxx

This section will match dialed numbers that look like "013609865200". Once its matched, Asterisk will first send the call to term.skyetel.com, and then failover to our three other regions one by one. The calls will come to Skyetel looking like "13609865200" which is our required format.

_91xxxxxxxxxx

This section will match dialed numbers that look like "913609865200". Once its matched, Asterisk will first send the call to term.skyetel.com, and then failover to our three other regions one by one. The calls will come to Skyetel looking like "13609865200" which is our required format.

_911

This section will match 911 calls. Once its matched, Asterisk will first send the call to term.skyetel.com, and then failover to our three other regions one by one. The calls will come to Skyetel looking like "911" which is our required format. Read more about E911 here: E911

_933

This section will match 933 calls. Once its matched, Asterisk will first send the call to term.skyetel.com, and then failover to our three other regions one by one. The calls will come to Skyetel looking like "933" which is our required format. Read more about E911 here: E911

_0000641xxxxxxxxxx

This section will match dialed numbers that are using our Short Duration gateway. This section is actually doing a little bit of magic - instead of simply just sending the call along its way, this is actually help keep the Average Call Length longer by delaying the time it takes for a hangup to occur by 20 seconds. This is a great way to avoid Short Call Surcharges

_011.

This section will match international calls. Once its matched, Asterisk will first send the call to hc.skyetel.com, and then failover to our three other regions one by one. The calls will come to Skyetel however they were sent. International calls don't have consistent patterns we can match (tongue)

Conclusion

Thats it! Once you get the hang of it, you can do all kinds of things like record calls, intercept calls, route internally, etc. You can read more about Asterisk and all of the things you can do with it here:

https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+Documentation
https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+Dialplan+Applications

Was this article helpful?
0 out of 0 found this helpful
Return to top