Getting Started Placing Outbound Calls with Twilio Elastic SIP Trunking and FreeSWITCH

December 15, 2014
Written by

fslogo

A couple of weeks ago we announced the public beta of Elastic SIP Trunking, a new way to connect your SIP gear to the world through Twilio. With Elastic SIP Trunks, you can say sayonara to artificial constraints to scaling and pricing shenanigans. We think this new way of consuming SIP connectivity offers longtime VoIP network administrators and engineers an instantly provisioned, powerfully resilient alternative to the SIP trunk.

One of the more frequent requests we received after opening the Elastic SIP Trunking beta was how to connect an Elastic SIP Trunk from Twilio to FreeSWITCH, the popular open source SIP platform.  Let’s find out how to do that together.

How It Works

A Twilio SIP Trunk provides a domain to connect your SIP switching equipment to Twilio. During our public beta, Elastic SIP Trunks only provides termination service, which is to say you can only place outbound calls.

Two big differences will be familiar to those of you who have purchased SIP trunks before.  First, Twilio Elastic SIP Trunks are available immediately when you need them – no waiting for price quotes and contracts. As we’ll walkthrough shortly, provision a SIP trunk whenever you need it with transparent, volume-based pricing.  Second, Elastic SIP Trunks scale with you – no dealing with channels or concurrency planning.  With Elastic SIP Trunks you can make as many concurrent calls as you want without paying for any minimum concurrent calls.  Instead of paying for what you might use, Twilio Elastic SIP Trunks bill you for what you do use.

With those concepts in mind, let’s look at what we need to get started.

What We’ll Need

Let’s walk through what we need for this project.

With our requirements taken care of, let’s get some information to prepare the project.

A Word About Security

If you are installing FreeSWITCH for the first time, a quick note about securing your installation.  My default the vanilla package comes configured with the default password for all users “1234” and is defined in your vars.xml.  It is very important that you change this default password and also remove any of the default users in the directory that you are not going to be using.

There are many bots that scour the Internet looking for insecure SIP PBXs in order to pump calls to high cost premium routes (also known as “traffic pumping”). All of these bots look for default passwords for popular open source switches like FreeSWITCH or Asterisk. Taking the precaution of securing your host is not difficult, but these steps are necessary to ensure your Twilio account is not abused.

Before leaving your host on the public Internet, be sure to secure your host by following this helpful guide.

Prepping The Project

For this tutorial, we’ll assume you have FreeSWITCH installed and are looking to add Twilio as an external SIP profile.  With our installation ready, we can begin gathering the information we need to connect FreeSWITCH to a Twilio Elastic SIP Trunk.

First, let’s look at how communication between our FreeSWITCH install and Twilio is secured.  Elastic SIP Trunks use a combination of both network security and authentication.  To satisfy the latter requirement, we need to create a new username and password that we’ll register with our Twilio SIP trunk to verify our secrets are shared.  We’ll create that username and password in the next step.  To satisfy the network security requirement, we’ll need to identify the external IP address of the host for our installation of FreeSWITCH.

Let’s start with the network security piece. We need to find the external IP address that our FreeSWITCH installation will be using to connect to Twilio. If you don’t know the external IP address, here’s an easy trick using the handy IPEcho service.

For Linux users, you can find the IP address on the host by opening a terminal and entering the following command:

curl http://ipecho.net/plain

For Windows users, you can find the IP address on the host by opening a web browser and visiting IP Echo.

Once we have a public IP address for the FreeSWITCH host, we’ll keep it handy as we provision our Twilio SIP trunk next.

Provisioning A Twilio Elastic SIP Trunk

With our homework done, let’s light up a new Elastic SIP Trunk instantly from our Twilio Dashboard.  First, we’ll log in to Twilio and navigate our Dashboard to Elastic SIP Trunking by clicking the dropdown menu in the upper left hand corner.

Then we’ll click the SIP Trunks tab.

Now, click Create a SIP Trunk in the upper right hand corner below our account dropdown to start provisioning our SIP trunk.

There are a few things going on here as we provision our first SIP trunk – let’s tick them off row by row.  First, we need to create a SIP URI for our Twilio SIP domain. This URI is going to be the domain that we connect to in our FreeSWITCH configuration and, as such, needs to be unique across Twilio. Second, we need to give our trunk a friendly name that we’ll recognize later. I used “My First SIP Trunk” – you can choose whatever human readable name you prefer.

Lastly, we need to secure our trunk with an IP allow list and a Credentials List.  This will be a two step process of registering an IP list and Credentials with our trunk.

First, we’ll create a new IP list.

The dialog box that appears takes two values – a Friendly Name (hint: a good practice is to use same name as your trunk) and an IP address or address block with CIDR notation.  We’ll use the public IP address we identified in the previous section.

Next, let’s create a new set of Credentials for this trunk.  We can do that by clicking “Create Credentials.”

By default, this menu will autocomplete your Twilio master account’s email address and password.  Note you will need to change the username to something without an @ sign in order to authenticate successfully.

In this example, let’s set a username that matches the name of our host, which we’ll call pbx.myhost.tld. The password should be a strong one – this SIP domain will be able to place toll calls.  Keeping these credentials and IP lists secure is important to prevent exploitation like traffic pumping.

Be sure to remember these values for our credentials – we will need them in the next step when we configure FreeSWITCH to connect to our Twilio Elastic SIP Trunk.

Connect FreeSWITCH To Our Elastic SIP Trunk

The first step to connecting our FreeSWITCH install to our newly provisioned Elastic SIP Trunk is to create a new external SIP profile in our FreeSWITCH configuration.  FreeSWITCH is a highly featured platform with a large number of configuration files, the location of which will differ from platform to platform and from distro to distro.  We’ll need to find the location of the root configuration directory before we can configure FreeSWITCH to use our Elastic SIP Trunk.

For Windows, the location of the root configuration directory is:

  • C:\Program Files\FreeSWITCH\conf

For Linux, it can be in a couple places depending on your installation. You can look in these spots for the configuration directory for your install:

  • /etc/freeswitch
  • /usr/local/freeswitch/conf
  • /opt/freeswitch/conf

With our FreeSWITCH configuration directory located, we’ll need to complete two configuration steps to place outbound calls with our Elastic SIP Trunk – first we’ll need to create a new SIP profile, then a Dial Plan to instruct FreeSWITCH to use our Twilio SIP profile to connect the call.

To begin, let’s create a SIP profile for our Twilio Elastic SIP Trunk. Following the conventions of the vanilla FreeSWITCH configuration structure, we’ll create a file called twilio.xml in the sip_profiles/external directory inside the root of our configuration.

In twilio.xml, we’ll define a new gateway that we’ll call Twilio-outbound with the user credentials and SIP Uri we defined when we first provisioned our SIP trunk in the Twilio dashboard.

 

<include>
 <gateway name="Twilio-outbound">
   <param name="username" value="pbx.myhost.tld"/>
   <param name="password" value="Keep this password secret1" />
   <param name="proxy" value="myexample.pstn.twilio.com"/>
   <param name="register" value="false"/>
 </gateway>
</include>

Next, we’ll set up a Dial Plan to use the Twilio SIP profile we just created to place any outbound calls.  A Dial Plan in FreeSWITCH is a configured extension that matches a regular expression to the action that you specify.  In our case, we’re going to take all domestic and international phone numbers and route them to our Twilio-outbound SIP profile we defined in the previous step.  We can do that by creating a new dialplan file called 02_twilio.xml in dialplan/default directory.  If you already have a dialplan prefixed by 02, pick the last number you see in the directory (e.g. 09_twilio.xml would be fine).

<include>
 <extension name="domestic.twilio.short">
   <condition field="${toll_allow}" expression="domestic"/>
   <condition field="destination_number" expression="^(\d{10})$">
     <action application="set" data="effective_caller_id_number=${outbound_caller_id_number}"/>
     <action application="set" data="effective_caller_id_name=${outbound_caller_id_name}"/>
     <action application="bridge" data="sofia/gateway/Twilio-outbound/+1$1"/>
   </condition>
 </extension>
 <extension name="domestic.twilio">
   <condition field="${toll_allow}" expression="domestic"/>
   <condition field="destination_number" expression="^(\d{11})$">
     <action application="set" data="effective_caller_id_number=${outbound_caller_id_number}"/>
     <action application="set" data="effective_caller_id_name=${outbound_caller_id_name}"/>
    <action application="bridge" data="sofia/gateway/Twilio-outbound/+$1"/>
   </condition>
 </extension>
 <extension name="international.twilio">
   <condition field="${toll_allow}" expression="international"/>
   <condition field="destination_number" expression="^\+(1|2[1-689]\d|2[07]|3[0-469]|3[578]\d|4[0-13-9]|42\d|5[09]\d|5[1-8]|6[0-6]|6[7-9]\d|7|8[035789]\d|8[1246]|9[0-58]|9[679]\d)(\d+)">
    <action application="set" data="country_code=$1"/>
    <action application="set" data="national_number=$2"/>
    <action application="set" data="effective_caller_id_number=${outbound_caller_id_number}"/>
    <action application="set" data="effective_caller_id_name=${outbound_caller_id_name}"/>
    <action application="bridge" data="sofia/gateway/Twilio-outbound/+${country_code}${national_number}"/>
   </condition>
 </extension>
</include>

Let’s dive into what is going on here. We have defined three new extensions – one for ten digit US numbers (e.g. 555-555-5555), eleven digit US numbers (e.g. +1-555-555-5555) and then a large regex for international phone numbers (e.g. for the UK: +44 55 5555 5555).  Each of these respect the toll_allow setting for the registered endpoints, meaning only users with specific permissions to call domestically and internationally will match the dial plan.  We also inherit the outbound_caller_id_number and outbound_caller_id_name defined in vars.xml.  If you are setting up FreeSWITCH for the first time, I’d recommend setting these two caller_id values to a Twilio phone number.  Finally, we set the extension to bridge to our SIP profile using the Twilio-outbound settings we defined earlier.

Next, we’ll need to reload our configurations.  The least intrusive way of doing this is to load the fs_cli utility.

For Windows it is located here:

C:\Program Files\FreeSWITCH\fs_cli

For Linux, you can access it by running:

fs_cli

You will then need to reload your dialplans with this command:

reloadxml

Finally, we can add our new SIP profile with the following command:

sofia profile external rescan

Placing Our First Call

Using our registered SIP endpoint, let’s place a call with our newly configured SIP profile connecting FreeSWITCH to our Elastic SIP Trunk.  If you don’t have a phone number handy, give this one a shot: +1 510.229.4252.

If we are successful, we should hear a congratulatory voice and see something similar to this in our FreeSWITCH log:

 

freeswitch@internal> 2014-12-08 11:54:49.494770 [NOTICE] switch_channel.c:1055 New Channel sofia/internal/rspectre@x.x.x.x [c010b077-646b-4a9d-a1e4-d67c4adc80dd]

2014-12-08 11:54:49.774764 [NOTICE] switch_channel.c:1055 New Channel sofia/external/+15102294252 [50123df5-8d77-4802-a5d8-a6d675494eaa]

2014-12-08 11:54:50.114762 [NOTICE] sofia.c:6716 Ring-Ready sofia/external/+15102294252!

2014-12-08 11:54:50.134734 [NOTICE] mod_sofia.c:2086 Ring-Ready sofia/internal/rspectre@x.x.x.x!

2014-12-08 11:54:50.134734 [NOTICE] switch_ivr_originate.c:527 Ring Ready sofia/internal/rspectre@x.x.x.x!

2014-12-08 11:54:50.374769 [NOTICE] sofia.c:7475 Channel [sofia/external/+15102294252] has been answered

2014-12-08 11:54:50.394783 [NOTICE] sofia_media.c:92 Pre-Answer sofia/internal/rspectre@x.x.x.x!

2014-12-08 11:54:50.394783 [NOTICE] switch_ivr_originate.c:3494 Channel [sofia/internal/rspectre@x.x.x.x] has been answered

If we weren’t successful, read up on the tips in the next section for some common gotchas I encountered as a FreeSWITCH newbie setting up my first Elastic SIP Trunk.

Common Gotchas

There are a lot of moving parts in a FreeSWITCH install – it is an incredibly powerful piece of software with a lot to configure.  Here are some errors you might check if you’re working with FreeSWITCH for the first time.

  • Firewall settings: FreeSWITCH operates over quite a few ports – just opening 5060 on TCP and UDP won’t be enough.  For a full list, check this wiki page. If you are using iptables, it also includes a script for the appropriate rule chains.
  • Dial Plan location: depending on your installation, the location of your dial plan may be incorrect if you do not see sofia attempting to connect to call to the Twilio SIP profile.  For the “vanilla” install of FreeSWITCH, this will be the dialplan/default directory, but it can be different depending on your installation.  Using fs_cli on DEBUG can show you which extensions your numbers match.
  • Inbound calls: Origination is not yet supported by Elastic SIP Trunking while the product is in beta.  If you are interested in setting this up, you can sign up for access when this feature is available here.
  • ACLs: In addition to the firewall your host is likely behind, FreeSWITCH maintains its own Access Control Lists (ACLs).  If you’re unable to receive calls from a Twilio <Dial> verb, you may want to make sure your FreeSWITCH install has added these IP addresses to its ACL set.
Wrapping Up

Awesome – we now have an Elastic SIP Trunk working on our FreeSWITCH install.  This is just the beginning of the journey getting your FreeSWITCH installation to speak SIP to Twilio.  For next steps, try checking out these features:

  • Turn on “Record” for easy, single-click recordings of all your outbound calls.
  • Set up your Dial Plans with different Twilio numbers set as the Caller ID for your international calls, so calls to the UK or any of the many other countries we support appear to come from a local number.
  • Set up a Twilio SIP domain for easy Conferencing or Queueing.

This was my first spin getting FreeSWITCH connected to Twilio – I’m interested to hear more about your experience using this new product.  Please reach out with your FreeSWITCH installation questions and stories to rob@twilio.com or on Twitter at @dn0t.