Tuesday, May 24, 2011

Dynamically Restrict Access to Realtime Asterisk SIP Peer by IP

We have an asterisk deployment where we have users who work from home so their phones need to be able to connect to asterisk remotely.  In order to limit the number of security threats to our system we lock it down by using the permit and deny settings of SIP Peers to make sure that only those users can get in.

In order to do this for external users we originally allowed every IP to connect, simply relying on using very strong random passwords (40+ character random passwords, unique per extension).  This has been working for us for the last year and a half but I decided to take our security one step further and lock it down to the exact IP of the phone.

We use Aastra 6731i and 6757i devices which have the ability to grab a URL when they boot up, the startup event.  In the aastra.cfg you would have this line:
action uri startup: http://asteriskpbx/aastraphone.php?action=register&ext=$$SIPUSERNAME$$

This tells the phone to grab aastraphone.php at startup.  We use this to keep track of phones, so I decided I would use it to add an addtional layer of IP security to our system.

First, I had to add a new column to my Realtime Asterisk sippeers table called externalaccess, which I will only set to true for devices that are allowed to connect to asterisk from the outside world.
mysql> ALTER TABLE  `sippeers` ADD  `externalaccess` BOOL NOT NULL ;

Second, I added the following code to aastraphone.php:


$ext = $_REQUEST['ext'];
if($ext > 0 && is_numeric($ext)){
$query="update sippeers set deny = '0.0.0.0/0.0.0.0', permit = '{$_SERVER['REMOTE_ADDR']}/255.255.255.255' where name = '$ext' and externalaccess = true";
mysql_query($query);
}


Finally, I tested it out by setting externalaccess to 0, booting the phone and verifying that the phone's ip did NOT get updated, which it did not.  Then i set it to 1, and rebooted the phone and it was succesful in updating the realtime peer.  This instantly allows the phone to register, and because the page load happens quickly enough the phone has no problem registering right away. 

Please note that this does still have vulnerabilities, it is not foolproof, just an additional layer of security.  At the moment if you query aastraphone.php with the right extension you automatically grant yourself access to that peer, assuming you know the password you could then make calls, and if you didn't you could then attempt to brute force the system.  It may be prudent to add a little more security to this system by passing another parameter from the phone to the aastraphone.php script to help verify the peer is who it says it is.  Maybe pass through the callerid of the extension, or the context that extension should be dialing from and verify that against sippeers.

Additionally this solution should work for other brands of phones that are able to poll a URL at an interval, or at startup such as Cisco, and Polycom.  I haven't touched my Polycom IP 650 in a while but I'll test it out on that phone in the next few days and update this post with the results.  

No comments:

Post a Comment