Wednesday, August 29, 2012

Asterisk (VoIP PBX) on the cloud with Amazon EC2 (NAT)

In my continuing effort to eliminate the need for a server at my home, I took on moving my Asterisk installation (of just about 10 years) locally run on a Linux server to the cloud using an Amazon EC2 micro-instance.

Background:  Home automation has always been my hobby and a part of that has extended into my phones.  What started off as a simple task of announcing Caller ID over the home intercom, turned in to  an elaborate Session Initiation Protocol (SIP) based Private Branch eXchange (PBX) using Interactive Voice Response (IVR) menus.    (If anyone is interested in what is all automated let me know and Ill write up the use cases.)

My setup was using an x86 based Linux server running Asterisk with various SIP devices as extensions; Zyxel WiFi Handsets, Seimans Gigaset, Grandsteam, Obi100 FXS -> POTS Dect 5.0 phones, and Android Handsets.   I have a VoIP provider giving me Plain Old Telephone Service (POTS) access with standard phone numbers via a SIP trunk.     This was all running on residential internet with a Dynamic IP address, behind a standard Wireless firewall / router (Asus RTN-16), and running Network Address Translation (NAT) on a private internal network.

For the most part this was a typical personal installation of Asterisk with the trunk connection going through NAT and  all of the clients connecting directly on the local private network.

Protocols Involved: What helps is a general understanding of how the SIP / Real-time Transport Protocol (RTP) works.  SIP is a text based protocol that coordinates communications between devices using User Datagram Protocol (UDP) generally on port 5060.  This handles authentication, routing, registry, status, and more importantly the port numbers established for RTP to commence.

RTP sends the actual voice data between devices also using UDP but its ports need to be allocated at time of transmission and generally range between 10,000 and 20,000.

Due to both of these protocols technically being stateless, NAT alone does not sufficiently allow these to route correctly without help.

On the cloud:  The Asterisk server is now running on a Amazon EC2 Microinstance with the clients still on my private network locally (for obvious reasons of needed to use my handsets at my house ;) )   

Here is what I needed to make this happen:
  • EC2 Server: Asterisk config remains setup to talk with my VoIP provider through a NAT,  as Amazon EC2 instances do not get a real IP address mapped locally to an interface. 
    • (sip.conf) [provider] nat=yes
    • (sip.conf) [provider] canreinvite=no
  • EC2 Server: Because clients will be connecting through the Wide Area Network (WAN) interface now, I need to tell Asterisk what its IP address and local network is
    • (sip.conf) [general] externalip=54.54.54.54
    • (sip.conf) [general] localnet=192.168.0.0/255.255.255.0
  • EC2 Server: Clients need to be configured as NAT devices as well
    • (sip.conf) [kitchen phone] nat=yes | canreinvite=no [den phone] nat=yes | canreinvite=no, etc
  • EC2 Firewall:  Ports need to be opened for SIP / RTP:
    • Security Policy -> (Allow) UDP 5060-5083
    • Security Policy -> (Allow) UDP 10000-20000
  • Client Router: NAT needs to be "helped" and configured:
    • (Tomato Firmware) Advanced -> Tracking / NAT Helpers -> SIP (enable) / RTSP (enable)
  • Client Handsets: The internal private network will not be recognized (or useful) to the Asterisk server so they need to register under a common domain:
    • [Domain] 54.54.54.54 (External IP of the server)
Woila, now we have a PBX system on the cloud.



***Trouble shooting tips:
  • Asterisk "set sip debug on" and "rtp set debug on" are your friends.
  • If your handsets register but you cannot hear / transmit sound, RTP is not routing to either the correct IP address or your firewall / nat is not allowing it to pass correctly.  Check domain and your router firmware for supporting SIP and RTP "helpers".
  • If your phones ring at 1:21am in the morning the following night, you may have forgotten to restrict the 5060 port to just your EC2 server / client IPs and you are being hacked.  Not a good night ;)