If you’ve been reading these articles for a while, you’ll know that I’ve experimented with Twilio a couple of times, but so far I haven’t tried to actually integrate Twilio into the Metaswitch world I normally inhabit.
In this article I’ll give step-by-step instructions for setting up your Metaswitch CFS, Perimeta and your Twilio account to establish a SIP trunk between the two platforms.
Twilio SIP trunking architecture
But first, we should take a moment to establish the paradigm. How should we even be thinking about these two services?
From Twilio’s point-of-view, their voice platform provides an interface to the PSTN through Twilio’s Super Network. Anyone interconnected with Twilio via their Elastic SIP trunking product can place phone calls to anywhere in the world via their Twilio trunks, and equally they can buy national and international phone numbers through Twilio, which are delivered via these SIP trunks.
In other words, Twilio is acting as a carrier. So if you establish a connection to them you are either taking the role of a business PBX getting PSTN connectivity from Twilio, or else you are a class 5 service provider using Twilio as a class 4 interconnection.
Note that this isn’t the only way to think about the connection. If you want to use Twilio to host an advanced IVR function you may think of their service more as a high powered application server, but for today’s purposes we’re going to view the Twilio Elastic SIP trunking product as a network-side carrier SIP trunk off the Metaswitch.
If you haven’t already done so, go ahead and create an account with Twilio and add a few dollars of credit so you can make some test calls.
Once you’re logged in to the Dashboard, use the red circle with the 3 dots (see below) to open up a list of products and then select ‘Elastic SIP Trunking’ from the list. You’ll see that I’ve pinned it to my Dashboard for quicker access.
Within the SIP trunking dashboard, let’s start with the Authentication section, and the IP Access Control Lists.
From this page, hit the + sign to create a new ACL, then fill out the short form with a range of IP addresses that covers the public IPs on your Perimeta that will be interfacing with Twilio. Most likely this will be the range of public IPs configured on the Access Network of your Perimeta – and it should be described by listing one IP address and the size of the subnet (e.g. /28 is 16 IPs as shown below).
Now click on Trunks to add your SIP trunk.
Give your new trunk a name and then we’ll walk through each section of the settings (using the links on the left).
- Under General, find the option for Symmetric RTP and Disable it. (If you leave it active you run the risk that both Twilio and the Perimeta will wait for the other end to send RTP as they both try to traverse NAT with the result that no RTP is ever sent).
- Under Termination you’ll set your SIP URI. It doesn’t matter what you use as long as it’s unique – you’ll need this below. This is also where you select the IP Access Control List you just created. Note that you should leave the Credential Lists blank, as these are not used for this type of connection.
- You can skip Origination and Numbers for now. These are only used if you want to port numbers to Twilio (or buy numbers from Twilio) and then have them routed to your Metaswitch via your SIP trunk. This may be useful if you need access to a number in a location outside your usual territory (including international) – but I haven’t tested this piece.
Before you do anything else in your own network, you need to white-list the Twilio IPs on your Perimeta.
To do this, log-in to your Perimeta as defcraft, and then select option 1 on the menu to enter the CLI. Once there, you’ll want to enter the following commands (assuming service network 2 is your public-facing network). If not, review your system configuration and adjust accordingly.
system ip-access-control trusted-sources permit-peer service-network 2 ipv4 22.214.171.124 permit-peer service-network 2 ipv4 126.96.36.199 permit-peer service-network 2 ipv4 188.8.131.52 permit-peer service-network 2 ipv4 184.108.40.206
Note that this list of IPs is incomplete. I’ve shown just the four IPs for North America Oregon, but the full list can be found here.
Note that it’s important to white list the full set of IPs because an inbound call could come from another part of the world depending on the location of the caller and where they enter Twilio’s network.
Next up you’ll want to create an adjacency for your connection to Twilio. I didn’t do anything fancy with mine, but here it is for reference.
sbc signaling adjacency sip Twilio deactivation-mode normal call-media-policy early-media timeout 240 media-bypass-policy forbid repeat-sdp-on-200ok adjacency-type preset-access privacy trusted realm GeneralPeeringMedia1 service-address GeneralPeering-01 # service-network 2 # signaling-local-address ipv4 220.127.116.11 signaling-local-port 5060 remote-address-range ipv4 18.104.22.168 prefix-len 30 signaling-peer DUMMY.pstn.us2.twilio.com signaling-peer-port 5060 statistics-setting detail default-interop-profile ManagedAccess activate
If your Perimeta has dynamic-peer-routing configured in your call-policy-set then you shouldn’t need to modify any adjacency routing rules. If not, then you’ll need to add the Twilio adjacency to the appropriate table of your call-policy-set so that dialogs that arrive at the Twilio adjacency are routed to the core MetasphereCFS adjacency.
Remote Media Gateway Model
I haven’t done sufficient testing to say with any certainty which are the best settings to use on your Twilio RMGM, however I would (a) recommend that you create a new RMGM for this configured SIP binding, and (b) you need to make sure that you check the “Use E164 numbers” fix bit under the “Fix bits (SIP)” section of the configuration.
Metaswitch Configured SIP Binding
When you build the Configured SIP binding for the Twilio connection on your Metaswitch there are a few fields that are noteworthy.
Most importantly, note that you need to use a domain name to contact the Twilio servers – not an IP address – and that the SIP domain name must match that configured at the Twilio end.
So in this example we have:
- Use DN for identification: True
- SIP domain name: <yourchoice>.pstn.twilio.com
- Contact address scheme: Domain name A/AAAA lookup
- Contact domain name (not shown): <yourchoice>.pstn.us2.twilio.com
- Proxy IP address: <core-side-IP-of-Perimeta>
Note the extra “us2” in the contact domain name versus the SIP domain name. This has the effect of limiting the connection to use Twilio’s servers in Oregon (which matches the set of 4 IPs addresses I put in the Perimeta whitelist and more importantly in the Perimeta adjacency).
If you were so inclined you could create adjacencies for every single Twilio location and white list all of the given IPs and then set the contact domain name simply to <yourchoice>.pstn.twilio.com to get the full benefit of their redundancy.
For my testing purposes this wasn’t necessary, but if you were using this in production you should do that (and test each site individually to make sure it works).
Metaswitch SIP Trunk and Translations updates
There’s really nothing noteworthy here, but you will need to build a SIP Trunk (under Signaling / SIP) that uses your Configured SIP binding in order to allow calls to be routed to Twilio.
And finally, you will need to incorporate your new trunk into your routing tables somehow. There are too many possible ways to approach this for me to cover here.
In my testing I simply added a table that split off calls by dialed number, and if the subscriber had called Twilio’s test number (1-650-4-TWILIO) I routed the calls over the Twilio SIP trunk.
Testing your configuration
To test, I’d begin by checking for alarms. The Twilio servers should respond to the Metaswitch polling OPTIONS messages, so your configured SIP binding should turn green on activation, and stay green on an ongoing basis. If it goes into alarm then that means the OPTIONS messages aren’t getting a response, and you’ll want to investigate that.
Then try placing a test call to 1-650-4-TWILIO from an on-switch subscriber. This is a simple tool that records your voice and plays it back to you, thereby allowing you to test two-way audio.
If it works you’re all set.
Please note that my testing so far has been very limited – but hopefully it’s still useful to anyone out there who’s trying to set up a SIP trunk between their Metaswitch and Twilio.
In time I’d imagine we’ll learn a more comprehensive set of fix bits that should be configured to improve interoperability. If you discover some additional settings that are important please drop me a line to let me know what you found and why – and I’ll be happy to update this text.