We’re a bit late to the Nexmo® party. For those unfamiliar with the company, Nexmo was one of the leading communications platform-as-a-service (CPaaS) companies prior to their acquisition by Vonage® four years ago. Perhaps because of the Vonage name, Nexmo never appeared on our Asterisk® radar. This ZDnet article will get you up to speed. Suffice it to say, Nexmo has one of the best APIs in the VoIP business, and their pricing is reasonable. A DID offering multiple call paths will only set you back $1 a month with incoming calls costing $0.0049/minute with per second billing. Outbound U.S. calls are $0.0139/minute. Sending SMS messages using your DID costs $0.0068 per message while incoming messages are $0.0062. While barely scratching the surface of the Nexmo offerings, our goal today is to show you how to deploy a Nexmo trunk in IncrediblePBX® 2020 that provides voice and SMS.
As we have mentioned many times, one of the real beauties of VoIP is not having to put all your eggs in one basket like in the old MaBell days. Other than $1 a month for a DID, there are no other costs associated with a Nexmo account if you don’t use it AND your first $10 of usage is free. It also provides a terrific failover option from one of our two favorite providers: Skyetel and ClearlyIP.
Overview. There are eleven pieces to put in place to get inbound and outbound calls and SMS messages flowing. First, on the Nexmo site, (1) you’ll need to set up an account and (2) order a DID. HINT: When you search for numbers, be sure to use the 1 prefix to search for U.S. numbers by area code. Once the DID number has been activated, edit Your Number and (3) enter a web address to deliver incoming SMS messages to your PBX and (4) enter a SIP URI to send incoming calls to your PBX. (5) You’ll also need to make note of your API credentials and DID number which you will need in setting up the trunk and scripts on your PBX.
Second, on the PBX side, (1) you’ll need to whitelist several IP addresses for Nexmo in your firewall settings, (2) create a PJsip trunk with your Nexmo credentials and 11-digit CallerID number, (3) create an Outbound Route to send calls to Nexmo, (4) create an Inbound Route to accept calls from your Nexmo DID, (5) add a from-internal-custom dialplan rule to allow from-sip-external calls from Nexmo, and (6) install and configure our scripts to process SMS messages. This requires that outbound email is functional on your PBX.
SMS Messaging is a little different on every platform. The way we implemented it with Nexmo goes like this. Incoming SMS messages can be delivered either to an email address of your choice. Or, if your cellphone provider supports it, you can direct the emails to an address that your provider offers to process incoming messages and deliver by SMS to your cellphone:
- AT&T: phonenumber@txt.att.net
- Sprint: phonenumber@messaging.sprintpcs.com
- T-Mobile: phonenumber@tmomail.net
- Verizon: phonenumber@vtext.com or phonenumber@vzwpix.com
- Virgin Mobile: phonenumber@vmobl.com
Keep in mind that you can’t reply to a delivered email message and expect it to reach the sender. Outbound SMS messages with Nexmo must be generated either with a web browser pointed to the SMS directory on your PBX or from the Linux command line of your server. If the incoming SMS messages are redirected to SMS on your cellphone, you can click on the ORIGIN link and send an SMS reply, but it will have the number of your cellphone, not your Nexmo number. We’ll cover the syntax for these options once we get all the pieces in place.
Configuring SendMail with Incredible PBX 2020
Before we get too far along, let’s make sure you can send emails from your PBX. In order to receive SMS messages by email delivery, outbound mail functionality from your server obviously is required. If you’ve deployed your server in your home, your Internet Service Provider probably blocks downstream mail servers such as Incredible PBX from sending mail. This is done to reduce SPAM. In this case, you will need to configure SendMail using either your ISP or Gmail as an SMTP Relay Host. NOTE: If you are using a Gmail account with 2-step verification enabled, you MUST use a Gmail App Key instead of your Gmail account password. You also must enable Less Secure Apps access to the Gmail account. Here are the steps using a Gmail account:
cd /etc/mail yum -y install sendmail-cf hostname -f > genericsdomain touch genericstable cd /usr/bin rm -f makemap ln -s ../sbin/makemap.sendmail makemap cd /etc/mail makemap -r hash genericstable.db < genericstable mv sendmail.mc sendmail.mc.original wget http://incrediblepbx.com/sendmail.mc.gmail cp sendmail.mc.gmail sendmail.mc mkdir -p auth chmod 700 auth cd auth echo AuthInfo:smtp.gmail.com \\"U:smmsp\\" \\"I:user_id\\" \\"P:password\\" \\"M:PLAIN\\" > client-info echo AuthInfo:smtp.gmail.com:587 \\"U:smmsp\\" \\"I:user_id\\" \\"P:password\\" \\"M:PLAIN\\" >> client-info echo AuthInfo:smtp.gmail.com:465 \\"U:smmsp\\" \\"I:user_id\\" \\"P:password\\" \\"M:PLAIN\\" >> client-info # Stop here and edit client-info (nano -w client-info) in all three lines. # Replace user_id with your gMail account name without @gmail.com # Replace password with your real gMail password OR # use your Gmail App Key if 2-step verification is enabled # Be sure to replace the double-quotes shown above if they don't appear in the file!!! # Save your changes (Ctrl-X, Y, then Enter) chmod 600 client-info makemap -r hash client-info.db < client-info cd .. make systemctl restart sendmail
If your server is hosted in the cloud and your provider does not block TCP port 25, then you can send mail without using a SmartHost; however, your server's hostname must actually be real or downstream mail servers will reject your mail. You can set your server's hostname like this: hostname myserver.myhost.com. This is usually sufficient; however, it's a good idea to also add the hostname in /etc/hostname and in /etc/hosts as the first entry on 127.0.0.1 line:
127.0.0.1 myserver.myhost.com pbx.local localhost localhost.localdomain
Next, test outbound mail using this command with your actual email address:
echo "test" | mail -s testmessage yourname@youremaildomain.com
Configuring Nexmo for Use with Incredible PBX
NOTE: For ease of reference in the examples, we'll use 8005551212 to represent your 10-digit DID number, 18005551212 to represent your 11-digit DID number, and 22.33.44.55 to represent the public IP address of your PBX. You'll obviously need to replace these entries.
1. To get started, open Nexmo.com with a web browser and click on Try It Free. No credit card is required to use your $10 credit.
2. Next, purchase a DID to use with your PBX. Login to your Nexmo account, and click # Numbers then Buy Numbers. For Features, choose SMS & Voice. For Type, leave it set to Mobile. For Number, choose Starts With and enter 1800 replacing 800 with your desired area code. Don't forget the 1. When we opened our account, it already had a DID chosen. You can either use that one to experiment, or delete it and choose your own.
3. Click # Numbers then Your Numbers and click on the pencil icon to the right of your DID to edit the DID settings. Under SMS, enter a Webhook URL that looks like this using the public IP address of your PBX: http://22.33.44.55/sms.
4. Under Voice, choose Forward to SIP and enter a SIP URI in this format using your 10-digit DID (not eleven digits here!) and the public IP address of your PBX: 8005551212@22.33.44.55. Then click SAVE.
5. Navigate to Settings under your Account Name and write down your API Key and Secret as well as your purchased DID Number.
Configuring Incredible PBX for Use with Nexmo
1. Incredible PBX includes a whitelist as part of its Travelin' Man 3 firewall design. Begin by editing iptables-custom in /usr/local/sbin. Search for: # custom rules go below here. Below that line, insert the following, save the file, and restart IPtables: iptables-restsrt
# // New entry for Nexmo /usr/sbin/iptables -I INPUT -s api.nexmo.com -j ACCEPT /usr/sbin/iptables -I INPUT -s 169.63.86.0/24 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 5.10.112.121 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 5.10.112.122 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.247.1 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.247.2 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.247.3 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.247.4 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.248.2 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.248.3 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.248.4 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.248.9 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.249.1 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.249.2 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.249.3 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.249.4 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.250.1 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.250.2 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.250.3 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.250.4 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.251.1 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.251.2 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.251.3 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 69.59.251.4 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 119.81.44.6 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 119.81.44.7 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 168.100.88.1 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 168.100.88.2 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 168.100.88.3 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 168.100.88.4 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 169.48.36.56 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 169.48.36.66 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 169.55.62.70 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 169.55.62.215 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 169.60.141.29 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 169.60.141.30 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.0.1 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.0.2 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.1.1 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.1.2 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.2.1 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.2.2 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.3.1 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.3.2 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.4.1 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.4.2 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.5.1 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.5.2 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.62.4 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.62.5 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.63.4 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.63.5 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.63.38 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.63.39 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.63.100 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.63.101 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.63.116 --dport 5060:5069 -j ACCEPT /usr/sbin/iptables -I INPUT -p udp -m udp -s 216.147.63.117 --dport 5060:5069 -j ACCEPT # // End entry for Nexmo
2. Login to FreePBX as admin and navigate to Connectivity -> Trunks -> Add PJsip Trunk.
In General tab, enter Trunk Name: nexmo. Enter Outbound CallerID: your 11-digit Nexmo DID. If you forget the 1 or if your CallerID number doesn't match your Nexmo DID number, outbound calls will be delivered as Anonymous. No CallerID spoofing with Nexmo.
In PJSIP Settings under the General tab, enter your API Key as Username, your API Secret as Secret, Outbound as Authentication, sip.nexmo.com as SIP Server, 5060 as SIP Port, and from-pstn-e164-us as Context. Retain the other defaults.
In PJSIP Settings under the Advanced tab, enter YES for Send LineIn Registration, and 5.10.112.121, 5.10.112.122, 119.81.44.6,119.81.44.7,169.60.141.29,169.60.141.30 for Match.
In PJSIP Settings under the Codecs tab, select ULAW and ALAW. Then click Submit and Reload the Dialplan when prompted. Verify registration: pjsip show registrations
3. Create an Outbound Route under Connectivity. Name the route: Nexmo. For Trunk Sequence, choose nexmo. Create two Dial Patterns: one for NXXNXXXXXX with a prefix of 1 and one for 1NXXNXXXXXX. Click Submit and Reload Dialplan when prompted.
4. Create an Inbound Route under Connectivity with a Description of Nexmo Vonage, a DID Number consisting of your 10-digit DID, and a Destination of your choice for the incoming calls. Click Submit and Reload Dialplan when prompted.
5. Anonymous SIP access typically is blocked with Incredible PBX. Because of the way Nexmo delivers incoming calls, we need to make an adjustment to allow SIR URI access from Nexmo. Edit extensions_custom.conf in /etc/asterisk and scroll to the bottom of the file. Insert the following lines replacing 8005551212 with your actual 10-digit DID. Then SAVE the file and reload your dialplan: asterisk -rx "dialplan reload"
[from-sip-external](+) exten => 8005551212,1,Goto(from-trunk,${DID},1)
6. In FreePBX Settings -> SIP Settings, change the RTP Port Range to 10000-50000.
7. The only remaining piece is to install the scripts to manage SMS Messaging with Nexmo. While logged into your server as root, issue these commands to install all of the components:
# CentOS 6 requires minimum PHP 5.6 with remi.repo enabled # Prerequisites already are in place with Incredible PBX 2020 # On CentOS platforms, use the next command: yum -y install composer # On Raspbian platforms, use the next command: apt-get -y install composer # the remaining commands work on all platforms composer require nexmo/client composer require slim/slim:^3.8 cd /var/www/html wget http://incrediblepbx.com/nexmo-sms.tar.gz tar zxvf nexmo-sms.tar.gz rm -f nexmo-sms.tar.gz cd sms nano -w config.inc.php
When the editor opens, insert your Nexmo API key, secret, and 11-digit DID number. For your email address, you have a choice of using a traditional email address which will cause incoming SMS messages to be delivered to your email account. Or you can use an email address that maps to SMS messaging on your cellphone as explained above. In the HEADER field, insert your 11-digit DID number once again leaving @noreply.nexmo.com unchanged. Save the file: Ctrl-X, Y, then ENTER. Done!
Taking SMS Messaging for a Spin with Nexmo
To try things out, first send an SMS message from some device to your Nexmo DID number. You should receive a copy of the message in your email or as an SMS message on your smartphone if you elected to set that up.
Next, using a browser with WhiteList privileges to your PBX, send an SMS message to some SMS number using the following syntax where 22.33.44.55 is the PBX public IP address:
http://22.33.44.55/sms/sendsms.php/?SENDTO=18431234567&MSG="Test message."
Finally, after logging into your server as root, send another SMS message to some destination using the following syntax:
php /var/www/html/sms/sendsms.php 18431234567 "Test message."
Originally published: Monday, June 15, 2020 Updated: Sunday, October 30, 2022
Need help with Asterisk? Visit the VoIP-info Forum.
Special Thanks to Our Generous Sponsors
FULL DISCLOSURE: ClearlyIP, Skyetel, Vitelity, DigitalOcean, Vultr, VoIP.ms, 3CX, Sangoma, TelecomsXchange and VitalPBX have provided financial support to Nerd Vittles and our open source projects through advertising, referral revenue, and/or merchandise. As an Amazon Associate and Best Buy Affiliate, we also earn from qualifying purchases. We’ve chosen these providers not the other way around. Our decisions are based upon their corporate reputation and the quality of their offerings and pricing. Our recommendations regarding technology are reached without regard to financial compensation except in situations in which comparable products at comparable pricing are available from multiple sources. In this limited case, we support our sponsors because our sponsors support us.
BOGO Bonaza: Enjoy state-of-the-art VoIP service with a $10 credit and half-price SIP service on up to $500 of Skyetel trunking with free number porting when you fund your Skyetel account. No limits on number of simultaneous calls. Quadruple data center redundancy. $25 monthly minimum spend required. Tutorial and sign up details are here.
The lynchpin of Incredible PBX 2020 and beyond is ClearlyIP components which bring management of FreePBX modules and SIP phone integration to a level never before available with any other Asterisk distribution. And now you can configure and reconfigure your new Incredible PBX phones from the convenience of the Incredible PBX GUI.
VitalPBX is perhaps the fastest-growing PBX offering based upon Asterisk with an installed presence in more than 100 countries worldwide. VitalPBX has generously provided a customized White Label version of Incredible PBX tailored for use with all Incredible PBX and VitalPBX custom applications. Follow this link for a free test drive!
Special Thanks to Vitelity. Vitelity is now Voyant Communications and has halted new registrations for the time being. Our special thanks to Vitelity for their unwavering financial support over many years and to the many Nerd Vittles readers who continue to enjoy the benefits of their service offerings. We will keep everyone posted on further developments.