Seven Steps to Better SIP Security with Asterisk

In case any of you were wondering why there has been a fairly notable upswing in the attacks happening on SIP endpoints, the answer is “script kiddies.”  In the last few months, a number of new tools have made it easy for knuckle-draggers to attack and defraud SIP endpoints, Asterisk-based systems included.  There are easily-available tools that scan networks looking for SIP hosts, and then scan hosts looking for valid extensions, and then scan valid extensions looking for passwords.  You can take steps, NOW, to eliminate many of these problems.  I think the community is interested in coming up with an integrated Asterisk-based solution that is much wider in scope for dynamic protection (community-shared blacklists is the current thinking) but that doesn’t mean you should wait for some new tool to defend your systems.  You can IMMEDIATELY take fairly common-sense measures to protect your Asterisk server from the bulk of the scans and attacks that are on the increase. The methods and tools for protection already exists – just apply them, and you’ll be able to sleep more soundly at night.
Seven Easy Steps to Better SIP Security on Asterisk:
1) Don’t accept SIP authentication requests from all IP addresses. Use the “permit=” and “deny=” lines in sip.conf to only allow a reasonable subset of IP addresess to reach each listed extension/user in your sip.conf file.  Even if you accept inbound calls from “anywhere” (via [default]) don’t let those users reach authenticated elements!
2) Set “alwaysauthreject=yes” in your sip.conf file. This option has been around for a while (since 1.2?) but the default is “no”, which allows extension information leakage.  Setting this to “yes” will reject bad authentication requests on valid usernames with the same rejection information as with invalid usernames, denying remote attackers the ability to detect existing extensions with brute-force guessing attacks.
3) Use STRONG passwords for SIP entities. This is probably the most important step you can take.  Don’t just concatenate two words together and suffix it with “1″ – if you’ve seen how sophisticated the tools are that guess passwords, you’d understand that trivial obfuscation like that is a minor hinderance to a modern CPU.  Use symbols, numbers, and a mix of upper and lowercase letters at least 12 digits long.
4) Block your AMI manager ports. Use “permit=” and “deny=” lines in manager.conf to reduce inbound connections to known hosts only.  Use strong passwords here, again at least 12 characters with a complex mix of symbols, numbers, and letters.
5) Allow only one or two calls at a time per SIP entity, where possible. At the worst, limiting your exposure to toll fraud is a wise thing to do.  This also limits your exposure when legitimate password holders on your system lose control of their passphrase – writing it on the bottom of the SIP phone, for instance, which I’ve seen.
6) Make your SIP usernames different than your extensions. While it is convenient to have extension “1234″ map to SIP entry “1234″ which is also SIP user “1234″, this is an easy target for attackers to guess SIP authentication names.  Use the MAC address of the device, or some sort of combination of a common phrase + extension MD5 hash (example: from a shell prompt, try “md5 -s ThePassword5000″)
7) Ensure your [default] context is secure.  Don’t allow unauthenticated callers to reach any contexts that allow toll calls.  Permit only a limited number of active calls through your default context (use the “GROUP” function as a counter.)  Prohibit unauthenticated calls entirely (if you don’t want them) by setting “allowguest=no” in the [general] part of sip.conf.
These 7 basics will protect most people, but there are certainly other steps you can take that are more complex and reactive.  Here is a fail2ban recipe which might allow you to ban endpoints based on volume of requests.  There is discussion on the asterisk-user and asterisk-dev mailing lists of incorporating this type of functionality into Asterisk – let’s hear your ideas!
If you’d like to see an example of the tools that you’re up against, see this demo video of an automated attack tool that does scan, guess, and crack methods via a click-and-drool interface.
In summary: basic security measures will protect you against the vast majority of SIP-based brute-force attacks.  Most of the SIP attackers are fools with tools – they are opportunists who see an easy way to defraud people who have not considered the costs of insecure methods.  Asterisk has some methods to prevent the most obvious attacks from succeeding at the network level, but the most effective method of protection are the administrative issues of password robustness and username obscurity.
JT

About the author

I'm the Asterisk Open Source Community Director. You can reach me at jtodd@digium.com. I try to work as a catalyst (yes, an over-used term) for getting ideas and code moving around in our large development community. I'm often as well a promoter, writer, encourager, and behind-the-scenes nag about all things Asterisk both in the community and within Digium.

20 Responses to “Seven Steps to Better SIP Security with Asterisk”

  1. Zach Garcia

    Great writeup John. I can’t tell you how many asterisk “rescues” Chromis Technology gets involved in with insecure/weak passwords. We have spent many many hours rewriting configs costing company’s thousands of dollars in consulting fees (which I personally don’t mind). But all of that time, effort and headache can be saved if strong passwords are implemented from the get go. – ZG

  2. Ward Mundy

    We’ve been wrestling with Fail2Ban in the Asterisk context for close to a year now. You might want to take a look at some of the scripts we’ve prepared which will provide a good blueprint for designing rock-solid Fail2Ban protection for your system:

    http://pbxinaflash.com/forum/showthread.php?t=2379&page=3

    NOTE: Read our install script. Don’t run it! It was designed for PBX in a Flash systems and will probably fail because it looks for an earlier version of Fail2Ban which you probably don’t have. The important point is to review the Fail2Ban config files which are included in the download script.

  3. Jason Sjobeck

    Great info’, John, we will start implementing these items on all our installs right away & from now on.

  4. Edwin

    i just had a question. when you say Don’t accept SIP authentication requests from all IP addresses. could you please give an example? is this done on the peer side? and if i have a private ip do i list permit=192.168.1.0/24 and how do i list multiple networks or ips on the permit. and how do i make deny everything else?

    Thank you.

  5. jtodd

    jtodd

    Edwin -
    You can have multiple permit= lines in your sip.conf file, so just list each permitted network in a separate line (as you have described in your example.) Then to deny all other locations, add a line after the “permit=” section that says “deny=0.0.0.0/0″ to disallow all other hosts that are not permitted.

  6. Stormwind

    Regarding “Make your SIP usernames different than your extensions”, how does one do this? I’ve been fighting with users.conf for a little while without success on an Asterisk 1.6 system. Thanks!

  7. jtodd

    jtodd

    Stormwind – It’s good practice to give a non-numeric, unrelated authentication name to your SIP entries that is different from the numeric extension that people typically use to call that “device”. This also minimizes confusion on your part when you start to have multiple devices or paths that are associated with a particular dialed number – like when you have someone with two or three different SIP devices, or other channel-based devices that will all ring at the same time when a particular number is dialed. Here’s an incomplete example:

    in sip.conf:

    [aa339b92acd912]
    type=friend
    context=from-office-deskphones
    secret=mys33cretehere!
    qualify=yes
    nat=yes
    host=dynamic

    Then, to reach that SIP device from your dialplan when someone dials extension 1234:

    exten => 1234,1,Dial(SIP/aa39b92acd912)

    See how the extension (the number people remember) and the SIP username are vastly different? This prevents easy guessing of the SIP authentication identity. If you had named the SIP device “1234″ then it would be trivial for an automated program to start banging away on guessing passwords if someone knew what your internal extension plan looked like.

    If you use users.conf (which will create entries as if they were in sip.conf, and iax.conf and other files) you can do the same by creating an “entity” with a difficult-to-guess string, but then allowing numeric extensions to reach it via the alternateexts setting.

    in users.conf:
    [aa39b92acd912]
    fullname = Jane User
    email = joe@foo.bar
    secret = mys33cretehere!
    hasvoicemail = yes
    vmsecret = 194828
    hassip = yes
    hasmanager = no
    callwaiting = no
    context = from-office-deskphones
    alternateexts = 1234

    This is not an exhaustive example, but perhaps will point you in the right direction.

    – JT

  8. Jeff

    You said, ‘It’s good practice to give a non-numeric, unrelated authentication name to your SIP entries that is different from the numeric extension that people typically use to call that “device”.’ But as far as I know it’s now possible to do that when using FreePBX, and a LOT of Asterisk users also use FreePBX.

    The biggest problem many of us have is the remote extension (not sitting on your LAN, but somewhere else out on the wide open Internet) that is at some random IP address that could change at the whim of the user’s ISP (or, if the user moves, even if only temporarily). In some cases the authentication name and the password were programmed into the phone and device before they were given/sent to the user, so there’s no way to change them, and trying to talk the user through changing them would be an exercise in frustration. One tool I have wished for is something that would at least allow geographic blocking, so that if you have a user in Minnesota and you get a connection from Nigeria purporting to be that user, you can kick them off and ban them, even if they authenticate correctly. One example of a way to do this is shown at http://michigantelephone.wordpress.com/2010/07/07/geolock-%E2%80%94-a-perl-script-for-asterisk-or-freepbx-users-to-enhance-security/ but as written it only allows limitation by country (so while you could maybe shut down the user from Nigeria, you might not be able to give the boot to a hacker from Utah), and it doesn’t update its database automatically. Also, it’s a Perl script, and I think many users find Perl a bit difficult to work with).

    Finally, I’m confused by your fifth item. How do you “Allow only one or two calls at a time per SIP entity, where possible.” IS that even possible when FreePBX is used?

  9. jtodd

    jtodd

    Jeff – I don’t know precisely how one would do that in FreePBX. The problem is that FreePBX doesn’t really let you get under the hood as much as I am typically used to. There are limits in later versions of Asterisk in the sip.conf file, but I’d do it “manually” by creating a group that has counters associated with it in the dialplan.

  10. Chris

    Some nice information, I am a home user but I am glade I had done some of this before I read this, I have added some points. Other parts well I might save them when I allow access from outside my private LAN. One thing I would like to see is a delay in the fail response or even better a progressive back off per IP i.e. first error is normal, then say 500ms then 1s then 2s 4s and so on. When I am hit I see over 100 attempts in a second faster than the fail2ban can respond although I am trying to improve this. If posible being able to do what fail2ban does from within asterisk i.e. send failure info to a module that can record the IP etc and trigger external events if triggers are met.

  11. Tim Osman

    This writeup is getting old pretty fast.

    i) there was AST-2011-003 which 4) did nothing to prevent.

    ii) fail2ban is a useless tool for blocking bruteforce attacks which do not use REGISTER methods.

    iii) point 6) is rather problematic with people using config managers like FreePBX. This is wishful thinking at its finest.

    iiii) point 2) does nothing to prevent extension scanning. It is possible the patch from AST-2011-011 did fix the problem.

  12. marvinek

    To protect against massive attacks — I use the linux iptables string matching ability to count registrations/invites an when the ip exceeds allowed limits it is banned. It is IMHO not a good idea to let asterisk to protect himself since it will allways be more cpu consuming than to use firewall. it works for me on large sites (hundrets of peers). I can share details of my setup if anyone interested
    marv

  13. Tris

    Great great advice……thanks John!

    As an expansion of jtodds great advice not to have SIP device same name as common extension numbers……Here’s what we do…..and it works for us! :)

    sip.conf

    [HsdfguJd23fhghd55Sfg100bdtfv5Dsvy29d7fb2ksZv]
    type=friend
    context=from-office-deskphones
    secret=mys33cretehere!
    qualify=yes
    nat=yes
    host=dynamic

    So then……for extension 100 (oh boy…yes…we still use 100,200!!)

    For office phones 100,101 etc
    exten => _10X.,1,Dial(SIP/HsdfguJd23fhghd55Sfg{EXTEN}bdtfv5Dsvy29d7fb2ksZv)

    Yup…..as you can see, sandwiching the EXTEN inside of a random string is gonna make those script kiddies work for their calls :)

    Also…..because we only use internally connected extensions for registering handsets…..(you folks probably connect from outside….but that gives me nightmares) we also use the following on each sip extension to lock down to the inside /24

    deny=0.0.0.0/0.0.0.0
    permit=172.22.1.0/255.255.255.0

    All of that sounds smug…..but I’m someone who got (a while ago now!) fried with a USD1200 bill after someone “got in”………never again! I was careless with default context…….nuff said.

    Tris

  14. BTR Naidu

    Is it possible to have a fail2ban regex which parses multiline string? The IP of the attacker in my astrisk log does not appear in the line where it prints the attack type but after some lines. As Fail2ban parses per line, it does not detect this attack and so the attacker continues to hog my system resource. Any clue?

  15. Laurent

    AS said in post of MArvinek, using iptables + fail2ban is quite powerful. Iptables permits to block too much trials form an IP (using “limit=” option). Then, if you log those IP making lots of trials, you can use fail2ban to look in your log file to block those IP. Everithing is done outside asterisk and permits to block attacks from an type, even if theri log trace in asterisk does not appear with their IP (which is the cas for example with call trials.
    That said, I also use strong password, non numerical usernamesand so on…

    My 2 cents

    Laurent

  16. Camilla

    Good post. I learn something totally new and challenging on sites I stumbleupon on a
    daily basis. It’s always interesting to read through content from other authors and practice something from their web sites.

  17. Jose Tapia

    Thanks for the info, very useful, and thanks for your efforts to convert Asterisk in the Best Framework

  18. Enric Alsina

    Many thanks for the info John. It’s very useful, at least as an appetizer for asterisk security…

  19. Mike

    After reading http://forums.asterisk.org/viewtopic.php?p=159984 we no longer put fail2ban on systems. We use the free edition of secast from http://www.generationd.com . It’s happened more than once with fail2ban that even a typo in a regex quietly disabled fail2ban. Very frustrating.

  20. Triston

    One more little nugget that I came up with to make things less “predictable” from a hacker point of view, see what you think.

    Seeing that most/all outbound (trunk) contexts are expecting the full number (or, prefixed with a 9) – it seems to me to make sense to break from this convention to make it less easy to push calls if anything becomes compromised.

    Rather than dialing 0800800152, what if you dialed 0800800152349837984538745 – and what if ONLY you knew that the last n characters were just padding?

    So, on a recent deployment, all phones (yealinks) were configured to add fixed length suffix to EVERY call (e.g. 69696969 so that when someone dials 0800800153, the phone system would see a call to 080080015269696969).

    In my “outbound” context I then strip off this suffix to give me the REAL number to dial.

    The idea is that if any of the sip phone accounts become comprised, or, if access to the outbound context is compromised, the hacker will be merrily pushing his poisonous calls in, and my outbound context will be stripping the last n characters, thus corrupting the number he wants to dial every time!

    A bit of extra parsing could also handle a prefix too…..that would mean the REAL number is nested nicely in a sea of noise, and only you know from where the real number should be plucked!

    Finally, because the number is being added by the handset, there should be no delay in adding it (no DTMFs etc) – so – I suppose there’s nothing to stop you adding long prefixes and suffixes to really mess with convention!!!! As long as you don’t need to go through the logs very often!! :)

    Any thoughts appreciated…..

    T

Leave a Reply