Switching to a software PBX, Part 1

This article has been updated since its original publication on May 4 2008. More details have been added, and it has been updated to use Asterisk 1.4.

January, 2011: Notes have been added to reflect Asterisk 1.6. The Aastra 480i CT, while a good device in its day, and still in daily use in our office, is now out-dated and no longer recommended. We have switched to snom 870s as our main office phones. The snom 870 is easier to manage under Linux, and includes built-in OpenVPN client support. And it looks stylish. We may do a future article about the snom 870. We're still on Broadvoice.

Asterisk PBX software, the Aastra 480i CT SIP phone, and Broadvoice

Alexander Graham Bell December 20th, 2008
The first telephone communication ("Watson, come here! I want to see you!") occurred in 1876. Switching went from manual to electro-mechanical to electronic to digital. Today, the Public Switched Telephone Network (PSTN) is almost entirely digital, but the structure is similar to the structure developed 100 years ago.

Voice over IP (VoIP) is the first fundamental change to the model pioneered by Bell. VoIP allows peer-to-peer calls without the need for going through a central switching facility. This allows for great flexibility in calling, and potential cost savings by avoiding the need for a switching business (phone company). VoIP also provides the possibility of a business creating its own phone network for its own needs. In this case, we'll be creating a virtual PBX with several extensions.

There have been several VoIP protocols over the past ten years. One popular protocol for consumer use is Skype. Skype has great sound quality (better than the legacy phone system), compatibility and ease of use. It's also encrypted and allows video calls. However, it is a closed protocol and is not suitable for building a PBX with virtual extensions.

Session Initiation Protocol (SIP) has emerged as the standard. Interoperable SIP phones and software are now available from many vendors. SIP is the HTTP of voice. For programmers, it's an easy protocol to work with, and there are many open source protocol libraries available.

I went to the Internet Telephony Conference and Expo in Los Angeles, shopping for a SIP phone. My plan was to switch Chiral Software from its current conventional phone system to a SIP-based system. I needed to select some SIP phones to make this possible. We would need at least three phones for the office, and to give workers office extensions at home. All had to work with the leading open source PBX, which is Asterisk. There's no better place to shop for VoIP phones than at a VoIP vendor conference.

After checking all the phone options from a dozen vendors, I decided my first would be the Aastra 480i CT. It is a commercial-grade office phone with a cordless handset. The cordless feature is important for me. I stand up and walk as I talk, and I have two desks with computers, so I need a cordless. Sometimes I walk outside if the topic is more creative. The 480i CT is the first SIP office phone that has a cordless handset. It allows up to five cordless handsets to be linked to one base station. You would think that cordless SIP phones would be widely available, but they are not; most of the wireless SIP phones are poor-quality consumer grade phones. At this moment, the 480i CT is the one and only. I know that snom has a new cordless product also. I will be trying some snom phones next. But I had to start with one phone, and that was the 480i CT.

Note, January 2011: We are now buying snom 870s. Look for a future article on them.

What are the goals of this project?

The goal is to create a PBX that is in our server facility, which is accessed by remote workers in various offices. The interface to the Public Switched Telephone Network (PSTN) will be from a SIP carrier. At this time, we're using Broadvoice, although it should be easy to switch to other providers if necessary. The structure will look like this when we're done:

Please install a SVG plugin for your browser, or use Firefox to view this image.

Within this structure, we have requirements:

  1. Typical users today have NAT for their connections. Adding a further complication, the external NAT IP address is dynamic with most consumer DSL plans.
  2. All call data must be authenticated and encrypted. Users may need to activate their extensions over non-secure networks, such as a hotel's network, or an open wireless network. Retrieving call data and authentication data (passwords) is trivial on an unsecured SIP connection.
  3. We need to support both hardware SIP phones, and softphones

We also need these PBX features:

All of these features are possible with a conventional PBX, with enough configuration work. Some of them, like extensions at home, are fairly expensive, because they require a dedicated business line at home. All of them require an advanced, expensive PBX, which is difficult to administer.

We also wanted some features that aren't even possible with a conventional PBX:

And we want some features that go beyond the PBX:

In this Part 1, we're going to go all the way up to getting the SIP handset to connect over the VPN to Asterisk. It's quite a lot of configuration. By the time we're done, we'll be able to get a "Hello World" message on the handset from the Asterisk server over the VPN.

Part 2 will cover creating the dial plan on the Asterisk side, meaning, setting up extensions and voicemail. Part 2 will also cover softphones, advantages and disadvantages of using a VPN, and XML applications on the phone. Hang on, it's a lot of configuration to get basic connectivity working. But once the first extension is working, adding more extensions is quick and easy.

Implementation

The first step is to link the Aastra SIP phone to the Asterisk server. This was easily done, but a problem came up immediately: the Aastra 480i cannot work with NAT with a dynamic IP address. SIP phones normally use a protocol called Simple Traversal of UDP through NATs (STUN). Unfortunately, the Aastra 480i does not support STUN, so using this phone on a NAT network is not feasible. This shows the importance of doing a feasibility test before rolling out a major deployment of any particular set of VoIP hardware. The lack of ability to traverse NAT only became apparent when we tested it on the first unit. We had to make a change in the implementation plan.

The solution is to use a Virtual Private Network (VPN) to provide the phone a real, non-static IP address. As a side benefit, a VPN also provides the security features of encryption and strong authentication which are part of our requirements. Neither the Aastra 480i nor Asterisk 1.4 support encrypted calls, so an encrypted VPN is the only way to meet our stated requirements. Asterisk 1.6 does have some support for secure calls, and other handsets have some encryption support, but OpenVPN is perhaps the easiest and clearest solution.

We selected the OpenVPN software for this task. OpenVPN has several advantages for this use:

Here is a revised diagram of the new structure, including OpenVPN:

Please install a SVG plugin for your browser, or use Firefox to view this image.

Configuring OpenVPN

Establish VPN connectivity with OpenVPN. We'll want a configuration where the OpenVPN server is on the same LAN as the Asterisk server. Likewise, on the phone side, the Aastra 480i is on the same LAN as the OpenVPN client. In our particular installation, the OpenVPN server is running on the same machine as the Asterisk PBX software itself. A route will be needed on the client side. Here's a table with the IP addresses:

VPN / Asterisk Server computer OpenVPN / Asterisk Server LAN205.134.230.0/24
Asterisk Server IP205.134.230.202
VPN server IP10.8.0.1
VPN network VPN network10.8.0.0/24
VPN Client computer VPN client IPvariable, on 10.8.0.0/24
Client VPN LAN interface IP (default route for phone) 192.168.4.1
VPN client LAN Client VPNed LAN192.168.4.0/24
SIP phone Aastra 480i IP address 192.168.4.99

I won't cover the details of OpenVPN installation and configuration. That information is found on the OpenVPN web site. We will need to generate public and private keys for the server and each client, and a certificate authority key. First go through the basic installation to install the software on both the server and client. Generate and distribute the keys. We'll be using a configuration based on the one described in Expanding the scope of the VPN to include additional machines on the client subnet.

However, I will list a few "gotchas" that can come up when installing the configuration:

Configuring the OpenVPN server

On the server side, the configuration file is:

# Server configuration file for OpenVPN

dev tun

# Path the the certificate authority, certificate, and key files
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key # keep this secret

# dh params
dh /usr/local/etc/openvpn/keys/dh1024.pem

# Define the subnet which will contain VPN interfaces
server 10.8.0.0 255.255.255.0

ifconfig 10.8.0.1 10.8.0.2

# Each client must have a configuration line,
# to provide its IP address, so we create
# a directory of configuration files
client-config-dir /etc/openvpn/clients

# Tell the kernel that the TUN interface
# should be the route for the client VPN LAN
# This LAN matches the LAN specified in the client file
route 192.168.4.0 255.255.255.0

Also create a specific client entry in the /etc/openvpn/clients directory:

# File name: eric-lan
# Route this LAN over the VPN
iroute 192.168.4.0 255.255.255.0

Activate it, and configure the server so that the VPN starts when the machine boots.

OpenVPN client configuration

Now configure the client side of the VPN. VERY IMPORTANT: Turn on IP forwarding on the client machine. If IP forwarding is not turned on, the VPN LAN will not be able to communicate with the server. On a Linux machine, IP forwarding is turned on by making sure this line is present in /etc/sysctl.conf:

net.ipv4.ip_forward = 1

Then reboot. Verify that IP forwarding is active. On Ubuntu 8.04 "Hardy Heron" and 8.10 "Intrepid Ibex":

% cat /proc/sys/net/ipv4/ip_forward
1

Note that the default Ubuntu 7.04 (Gutsy Gibbon) /etc/sysctl.conf file has the following line:

# Uncomment the next line to enable packet forwarding for IPv4
#net.ipv4.conf.default.forwarding=1

That line is incorrect. Uncommenting that line does not activate IP forwarding. Use the line as specified in this article.

On a Microsoft Windows machine, IP forwarding is enabled in the network control panel.

Place the appropriate key files on the client. This is the client's OpenVPN configuration:

client # specify this is the client side of OpenVPN
# the OpenVPN package is the same on the server and the client

# Create a TUN device
dev tun

# The remote host name.  Could also be specified by IP address
remote chiralsoftware.net

# Keep this tunnel up.  There are other retry and tuning
# parameters which may be helpful in some situations
resolv-retry infinite

ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/eric-client.crt
key /etc/openvpn/keys/eric-client.key

On Ubuntu Hardy Heron, all OpenVPN configuration files that match /etc/openvpn/*.conf are used by the /etc/init.d/openvpn start-up script, so the client configuration file can be called /etc/openvpn/client.conf, for example.

Make sure that the VPN packets can transit all the firewalls: the server's firewall, the clients' firewall, and any firewall on the router. The VPN packets are UDP packets on port 1194 by default. This can be changed in the OpenVPN configuration files.

Check that OpenVPN is running on the server, and then start it on the client.

Test the VPN link: an end-to-end ping.

$ ping 10.8.0.1
PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data.
64 bytes from 10.8.0.1: icmp_seq=1 ttl=64 time=33.8 ms
64 bytes from 10.8.0.1: icmp_seq=2 ttl=64 time=33.8 ms

The VPN client machine needs to have an interface and a route for the VPN subnet. If the client machine has two Network Interface Cards (NIC s) you could create two separate physical networks: one that is the normal DSL network, and another that is a secure VPN network. In this case, we will use a simple configuration and create a second IP address on a virtual interface on the client machine. To add this interface on the client machine, running Ubuntu, I added the following to the /etc/network/interfaces file:

auto eth0 eth0:1

iface eth0:1 inet static
      address 192.168.4.1
        netmask 255.255.255.0

Restart the network, or reboot, and the neccessary interface is available:

% ifconfig -a
eth0:1    Link encap:Ethernet  HWaddr 00:0c:xx:xx:xx:xx
          inet addr:192.168.4.1  Bcast:192.168.4.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
        Interrupt:17 Base address:0xb400

No additional routes are needed on the client machine. At this point, we should have end-to-end VPN connectivity between the server, and any machine on the client VPN network. To test this, I have configured a laptop with the address 192.168.4.99, and I now ping it from the server machine, setting the source IP address to be the server VPN endpoint:

server %  ping -I 10.8.0.1 192.168.4.99
PING 192.168.4.99 (192.168.4.99) from 10.8.0.1 : 56(84) bytes of data.
64 bytes from 192.168.4.99: icmp_seq=11 ttl=63 time=37.2 ms
64 bytes from 192.168.4.99: icmp_seq=12 ttl=63 time=34.4 ms
64 bytes from 192.168.4.99: icmp_seq=13 ttl=63 time=34.3 ms

We now have successful end-to-end VPN connectivity, allowing devices on the client LAN to communicate with the server, bypassing NAT and dynamic addresses by going over the VPN. And the communication is secure, encrypted using public key cryptography and the OpenSSL library.

Configuring Asterisk on the server

In this example, we are using Asterisk 1.4. The upcoming version is 1.6, but the basic configuration should be the same on both. The server in this case is Ubuntu 8.10 "Intrepid Ibex" but this works equally on other versions. I set up a SIP context in the sip.conf file:

[extension1]
type=friend
host=dynamic
authname=joe
secret=seekrit
dtmfmode=rfc2833
mailbox=1000
context=extension1 ; this is the context we will use in the dialplan
callerid="Joe"
canreinvite=no

Note that the canreinvite=no parameter is very important, and has security implications. By default, Asterisk may try to have the SIP devices (Broadvoice and the Aastra 480i) send their RTP (sound) streams directly to each other, bypassing Asterisk. From a performance and latency point of view, that's great. But from a security and reliability point of view, it is not so great. In most cases, the SIP telephone will be behind firewalls and NAT, and also an OpenVPN tunnel in our case. It may have an address like 192.168.4.101. Packets from that address can't get to Broadvoice, so the call will connect but no sound will go through. That's bad, but it can be even worse.

If the handset is not behind firewalls and NAT, maybe the stream could go through. Broadvoice may or may not allow such a thing to happen. If it did, and the stream were successful, then we have a security problem: an unencrypted sound stream is flowing from your LAN all the way to Broadvoice. Now, no matter what we do, the stream from Asterisk to Broadvoice is unencrypted because Broadvoice doesn't support encrypted connections (this is bad; I hope Broadvoice will correct this defect). But connections on LANs are even easier to tap than connections from a server in a colo.

So, make sure canreinvite=no.

Then create a simple context in extensions.conf:

[extension1]
exten => 101,1,Answer()
exten => 101,2,Playback(hello-world)
exten => 101,3,Hangup()

Now Asterisk is configured to receive connection from the user specified in the sip.conf file. If the user goes to extension 101, "Hello World" will be played. To see if this works, we configure the Aastra 480i phone.

Configuring the Aastra 480i CT phone

Aastra phone logo Set it up physically. When you plug it in, it is likely to gets an IP address from DHCP, if the VPN LAN and the normal DSL LAN are on the same Ethernet segment. However, the DHCP address it gets is not what we want, because it won't go over the VPN. We must manually configure it.

To manually configure, press the setup key, and scroll down to the network configuration menu

It will ask for the admin password. Enter 22222, which is the default.

Select the DHCP menu and turn off DHCP. Then set the IP address, netmask and gateway, using values from the address table above.

The phone will restart. Now, configure a laptop or other computer onto the VPN LAN, with an address like 192.168.4.111, so the phone can be accessed over a web browser.

When the phone restarts, access its IP address in a browser. We'll use the browser to complete configuration.

One advantage of the VPN at this point is that we can now run a TFTP server on the Asterisk server, to allow the central server to distribute firmware upgrade and also configuration files. If the phone is using a firmware version that is not the latest, enable a TFTP server on the VPN server. This TFTP server should be restricted to only interact with clients over the VPN.

Download the latest firmware from the Aastra web site. Firmware upgrades using TFTP are very sensitive to having the correct path and file name. First, the 480i and 480i CT have different firmware packages, so get the right one. Second, when the 480i CT package is unzipped, it gives a firmware file that has spaces in the file name. This somehow didn't work with our TFTP client so we renamed the file and did it again.

After upgrading the firmware (if necessary), the phone restarts and we can start configuring it.

Configure Global SIP:

Note that we are using the VPN tunnel endpoint (10.8.0.1) as the address of the proxy and registrar. The Asterisk server will receive connections on that IP address, through the VPN.

Restart the phone. Now for the final test of connectivity: pick up the handset, or use the cordless, and dial 101. It works! The "hello world" message plays.

But what if it doesn't work?

If your server has a firewall

The handset won't connect if your server is running iptables. The reason is that the OpenVPN interface is still just that, an interface. It does not bypass the firewall any more than any other interface would. This is good; even with OpenVPN, you do want to limit the access that remote machines could have to the server.

Add the following rules:

iptables -A INPUT -p udp -m udp --dport 5060 -j ACCEPT
# RTP - the media stream
iptables -A INPUT -p udp -m udp --dport 10000:20000 -j ACCEPT 

It would be even better to configure these rules so these SIP ports are only open to connections coming through the OpenVPN tunnel. However, in our case, we would also like to allow direct inbound SIP calls, so someone could call numbers at Chiral Software using only the SIP URL, without even using the PTSN at all. Eventually most phone traffic will move out of the PTSN, and we want to be among the first to offer a direct SIP call-in "number". Therefore we're leaving those ports open. Decide what to do based on your own needs, and the principle of least access.

We have now completed the following:

  1. Established a VPN using OpenVPN, creating a "VPN LAN" on the client side
  2. Configured Asterisk with a simple extension plan and SIP configuration
  3. Configured the Aastra 480i CT's basic network connectivity using the keypad
  4. Updated the Aastra 480i CT's firmware
  5. Configured the Aastra 480i CT to connect to Asterisk over the VPN, using the web configuration interface

Conclusion of Part 1

This concludes Part 1. Now that we have established basic security and connectivity, next week, we will go on to Part 2 and configuration Asterisk to provide the PBX features.

If you need help designing and implementing a voice application or PBX based on Asterisk and SIP, contact us at 310 356 7869 to discuss.