Several months ago, a client approached me with questions about phone services. She was interested in upgrading from a Time Warner Cable 2-line phone system which as I recall cost around $50 a month. I had actually wired up most of the system myself. It was about as basic as it gets. With five employees and more possibly on the way, two lines was just not enough. On top of this, a number of small issues (echo, noise and call drops) began to crop up. It was time to upgrade, but to what?
I shopped around and received a number of quotes from several local and not-so-local organizations for PBX services and other multi-line solutions, but the prices were absurd. At one point I was told I would have to get a T1 line pulled ($550 a month!) and install a hardware PBX ($50,000! are you serious?) but for a small business in Maine this was unrealistic, at best. I had heard of Asterisk but I didn’t really know what it could do, besides somehow integrate with existing PSTN phone systems, somehow. After some research I realized that my impression of Asterisk, while somewhat accurate, was very incomplete. I was unaware that SIP trunking existed, or that it was possible to use an open-source Linux based PBX to create an all-digital phone system. Asterisk was the obvious choice.
Very early on, I happened upon this guide, which pointed me in the right direction. The guide is fairly outdated now, but I knew there was someone out there who had gone through a project like mine and lived to tell the tale. I started building the PBX, first in a virtual machine, to get a feel of the OS, software and configuration. This is where my first issue crept up: I could not get AsteriskNow, Digium’s own Asterisk CentOS distro, to boot correctly in a VM, and this was unacceptable as I had initially hoped to run it in a VM in a production environment. I tested out PBX in a Flash, which also would not boot in my VirtualBox VM, and finally FreePBX Distro, which installed and booted fine. Since AsteriskNow and FreePBX Distro, and possibly PBX in a Flash (don’t quote me on that one) are more or less the same thing (a Linux distro with Asterisk pre-installed and FreePBX as a web interface), I forged on.
Initially, my client and I opted to order one SIP phone, so that if things didn’t work out, we wouldn’t have invested a lot of money in phones. We opted for a Mitel 5224, per the CypressNorth guide above. After some tinkering, I was able to connect it to the server after making a matching extension in the FreePBX GUI >> Applications >> Extensions section. Oh, and since this temporarily stumped me, the default login details for the Mitel 5224 web interface are admin/5224. Screenshots of the configuration are in the gallery.
Things began moving a lot faster. I tracked down a couple SIP trunk providers, but the only one that really had a plan I liked was Broadvoice. They offered a business plan, at the time of this writing, for $55 a month, which included 5 ports (think of these as phone lines, or concurrent calls) and 1 DID (Direct Inward Dialing number, a phone number accessible from the PSTN). For a mere $2 more a month each, we could transfer the existing business phone numbers, so we opted to. We ordered four more phones, but by the time we decided to, the Mitel 5224 phones were no longer available on Amazon, so we instead ordered four Cisco SPA303 phones for about half the cost per phone as the Mitel! I had read that these phones are notoriously hard to configure as they’re designed to pull a configuration from a TFTP server, meaning that your DHCP server has to support Option 66. I really wanted to find an alternative because it’s ridiculous to set up a dedicated DHCP and TFTP server to provision four phones. I just started blindly adding configuration details in boxes in their web interfaces until I found the right combination. Here are some simple instructions. Browse to your SPA303’s web interface, and click on Admin Login in the upper right. Click on the Ext1 tab. Screenshots of the configuration are in the gallery.
Here’s where I ran into a bunch of problems, and I hope I am able to help a little if you have the same. I used Broadvoice, as mentioned before. My first problem is that I set this system up in my office initially, as a test bed. No reason to disrupt someone else’s business with my testing. Broadvoice wanted a static IP address, since they seem to use the IP as the only form of authentication. There really isn’t any authentication at all; they just send raw SIP data to the IP they have on file and there isn’t any support for dynamic IPs. I had to talk to someone in their “engineering” department to get them to agree to use my IP, which is dynamic, temporarily while I got everything configured. Meanwhile I asked my client to contact her ISP (Time Warner Business Class) and request a static IP. It was $23 a month for this static IP, which I find ridiculous, as my VPS provider will hand out additional static IPs for, I believe, $2 a month. She also increased her bandwidth caps from 7Mbps / 768kbps to 15Mbps / 2Mbps. Not a massive increase, but plenty of headroom. Anyone considering using SIP trunking should consider this. According to Broadvoice, the codec they use consumes 81kbps both ways per active call so I knew we’d need 405kbps for the phone system alone, which doesn’t leave a lot of headroom when the cap is 768kbps.
My next problem was the biggest one. Broadvoice sent me a PDF with the details I would need to register with their system. It did not work at all. I googled and found a page on their site with completely different details. These also failed. I spent over an hour on the phone with one of their technicians, who evidently teamed up with a co-worker, made their own Asterisk VM and made me a configuration that mostly worked. I truly appreciate the time they put into this, especially after I had read that Broadvoice is notoriously cold and unhelpful when it comes to BYOD PBX setups. Finally we nailed down a configuration that works. A screenshot of the settings is in the gallery, but I’ll post it here too. In FreePBX GUI >> Connectivity >> Trunks >> Add SIP Trunk:
Trunk name: Broadvoice
Maximum channels: 5 (your number of ports)
-- Outgoing Settings --
Trunk name: Broadvoice
-- PEER Details --
The Incoming settings and Registration are intentionally left blank. Go to FreePBX GUI >> Settings >> Asterisk SIP Settings and make the following changes:
- NAT – yes if you’re behind a NAT which more than likely you are. If you don’t know this, Asterisk is NOT for you.
- IP Configuration – Static IP
- Try and have it auto configure. If it won’t, fill out the appropriate boxes.
- Allow Anonymous SIP Calls – YES – I know it’s a security issue but we’ll set up a firewall. It’s all good.
Next I had to configure the Routes, so I’ll start with Incoming Routes. This is actually a lot easier than a lot of literature makes it seem. Fill in Description with something like “all” and set the Destination with wherever you want it to go. I set up an IVR and pointed my Incoming route to that. For Outbound Routes, it’s a little less simple, but it’s not terrible. Make a new outbound route, named “All” and use the Dial patterns wizard to put in dial patterns for “Local 7/10 digit” and “Toll free.” MAKE SURE you put your local area code in the prepend section for the rule that only matches NXXXXXX. This enables local 7-digit numbers. Set the sequence 0 to Broadvoice and you’re done.
For my IVR (Interactive Voice Receptionist, I think), it’s configured so that when a caller hits the PBX, it’s transferred to the IVR immediately. The caller heard something to the effect of “You’re reached [business]. Please dial an extension or remain on the line.” They have 3 seconds to dial an extension, and after that 3 seconds the call is transferred to a Ring Group that rings all the phones in the office until one picks up. If no one does, the call is sent directly to my client’s voicemail on extension 100. Ring Groups are very straightforward, so I won’t explain it here. Screenshots are in the gallery.
Extensions seem extremely confusing but they’re really not; there are just a lot of options that aren’t really needed for anything normally. To add an extension, choose Generic SIP Device, and fill out the following boxes:
- User Extension – something like 100
- Display name – the user’s name, usually
- secret – under Device Options, this should be a strong password.
- Assign to a Default user – Create new user
- Password – same thing you set your secret to
- Voicemail status – Enabled (if you want voicemail on the extension)
- Voicemail Password – PIN. I set it to 1234 then let the users choose their own from the menu
By now you should have a mostly working PBX, but there are a few things that need attention. I forgot to mention it before, but ports 5060 and 10000-20000, UDP, need to be forwarded to the PBX. This setup is behind a DD-WRT router and I had no issues with it, but I had a lot of problems at my test site with my pfSense box mangling the SIP headers and replacing the Public IP in it with the PBX’s internal network IP. This prevented inbound audio, and I did end up fixing it but it’s not worth writing here. I’ll make a separate post about it.
Now, this is enormously important. Set up iptables on the PBX. Seriously. We have Anonymous SIP Calls enabled, and this means ANYONE can place calls on your PBX, or at least make the phones ring, crash it, etc. Secure your box! I’m using Broadvoice business, so I called and found what IPs they’re going to send SIP data from, and I configured the iptables appropriately. I decided not to use fail2ban and rely solely on my DD-WRT firewall and my secondary iptables. Here is my /etc/sysconfig/iptables on the PBX:
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1:148]
:WHITELIST - [0:0]
-A INPUT -p udp -m multiport --dports 4569,5000:5082 -j WHITELIST
-A INPUT -s 10.0.0.0/8 -j ACCEPT
-A INPUT -s 127.0.0.0/8 -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p udp -m udp -s 22.214.171.124 --dport 5060 -j ACCEPT
-A INPUT -p udp -m udp -s 126.96.36.199 --dport 5060 -j ACCEPT
-A INPUT -p udp -m udp -s 188.8.131.52 --dport 10000:20000 -j ACCEPT
-A INPUT -p udp -m udp -s 184.108.40.206 --dport 10000:20000 -j ACCEPT
-A INPUT -j DROP
This allows all localnet traffic and restricts all SIP and RTP UDP traffic to those two IPs. It drops all other traffic. Read up on iptables if you don’t understand it.
That’s all that I can think of that went into this, really. Everything else was extremely minor. If you have any questions, I guess, leave a comment.
EDIT 6/12/2014 – UPDATE
Everything is live and working perfectly now. I had no issues at all with the dd-wrt firewall, but my client opted to but a SonicWall TZ205 firewall for VPN purposes. I ran into a very interesting and inconsistent issue with this. I could dial in to the office, and use DISA to dial out, but if someone in the office tried to dial out the SonicWall would deny UDP SIP traffic. I ended up having to disable NAT in Asterisk’s SIP settings and then check the “Enable Consistent NAT” option in the SonicWall’s VoIP settings. When I said “inconsistent,” I meant that the rules didn’t always apply. When I first installed the SonicWall, I was able to dial out. Strange. Must by why the option is called “Consistent NAT.”
Oh, by the way, now would be a good time to add this tidbit about Time Warner Cable. They were the old phone provider my client had. It took two months for them to approve the port of the two phone numbers to the new carrier. Two months. During this time I was contacted numerous times by TWC claiming that I had given them the wrong phone number, the wrong address, the wrong ZIP code, or the wrong account number. Finally I asked my client for a copy of their TWC contract with all the information on it, which I scanned and sent to TWC. The claims from them of course continued. It was truly unbelievable. So, if you’re on Time Warner and planning a project like this, you might want to start the number transfer process first.