How secure is your Asterisk PBX? – part 2

Protecting your Asterisk server

In part 1, we examined the techniques that are used to probe for vulnerabilities in a SIP server and reviewed the types of exploitation a would-be hacker hopes to use. In this second part, I look at the ways you can protect your Asterisk or other SIP server and guard against weaknesses that could potentially cost your organisation a lot of money. This article was written before the pjsip channel driver was available, so some of it is only relevant if you are using chan_sip.

Basic Internet Security

The first line of defence is your firewall. You must block all unnecessary access from the Internet which generally means everything except port 5060 and the range of ports used for RTP. You will probably also need a rule to permit remote access – typically port 22 for SSH – but if at all possible set all remote access rules so they only allow connections from known source addresses. If you do allow remote access from the Internet of any sort (including through a web browser) then make sure you set a strong password. Never leave the original system default password on any system exposed to the Internet.

As mentioned in part 1, you can greatly improve security by changing to a non-standard port for the incoming SIP or by blocking access to port 5060 from all sources except those you already know and trust. This might be possible in a business that wants to connect a number of branch offices together using VoIP. However, it is far less convenient if you want to allow home based workers to connect to the office PBX using IP phones. For some applications it may be possible to connect through a VPN tunnel, but beware of possible performance issues if the speech (RTP) is going through VPN.

Check logs regularly

Even if you have a smart billing or call logging system, it is sensible to check the application log files quite often. The main log file for Asterisk is either /var/log/asterisk/messages or /var/log/asterisk/full. It is here that you might see hundreds of failed register attempts from the Internet. This may provide essential information in your fight against hackers because it shows you the scale of the problem, the accounts they are trying to crack, the type of attack and, sometimes, the IP addresses that the attack is coming from (the worst offenders can then be blocked at the firewall).

SIP User Accounts

Call requests arriving at your Asterisk server will generally need to be validated with a user id and password. There are exceptions to this rule, most notably when the request comes from a pre-defined peer whose definition in sip.conf includes a setting such as “insecure=invite”.

Use strong passwords

To protect your Asterisk server from brute force password guessing attacks, always make sure all your SIP user accounts have a strong password – at least 6 chars with a mix of upper and lower case letters plus numeric digits and at least one non-standard character such as $, !, #, *, etc. However, note that a few special characters will not work – avoid & or %. The importance of using strong passwords cannot be over-emphasised. It is essential even when you are setting up the accounts for internal extension phones because, unless you are very careful, the same credentials will work for calls from the Internet. To check the list of user accounts and passwords in Asterisk, it sometimes works to run the command “sip show users” at the CLI.

Other cautions when adding SIP User Accounts

Never include the parameter “insecure=invite” or “insecure=very” when defining a dynamic SIP user account. If you do, it will disable password checking for that account. Where possible, restrict the range of IP addresses from which the user is allowed to connect using the “deny” and “permit” parameters. This is a good idea where all possible source IP addresses are known in advance such as from a local LAN in an office. If possible, avoid setting the type to “friend”. Instead use “type=peer” and “host=dynamic” (see below).

Configuration tip:

In the [general] section of sip.conf, set “alwaysauthreject=yes”. This makes it much harder for a hacker to scan your server and identify what extension numbers are being used because it tells Asterisk that when the supplied credentials are wrong on an INVITE or REGISTER request, it should always return the same error no matter whether it was the user id or the password that didn’t match. However, it may also cause the so-called “friendly-scanner” to go into an endless cycle of manic password guessing – if you suspect this is happening to you, then you need to read my article here.

Outbound Routes

If you are using FreePBX (or a package based on it), then you should look carefully at the configuration for “Outbound Routes”. It makes sense to add a route specifically for International calls and, if possible, to restrict the countries that can be called. You can do this by adding a number of “Dial Patterns” that match the countries you want to allow and do not match any others. Make sure no other Outbound Route has a Dial Pattern that allows International calls.

A variation on the above would be to set a “Route Password” on the route that handles International calls or to have two Outbound Routes for International calls – one having no password but restricted to certain acceptable countries and another that has a password and is used for all other International destinations. Note that Outbound Routes are checked in sequence so you must put those with a dial pattern matching specific countries first, then put one with a Dial Pattern that works as a catch-all for any other International destination.

On its own, controls on the Outbound Routes may not be sufficient to fully protect your system, but it is a big help and acts as a second line of defence behind the user accounts.

SIP Peers

When Asterisk receives a SIP INVITE request, the sender will broadly fall into one of three categories:

  1. Those from a dynamic IP address which have to authenticate with user id and password
  2. Those from a “trusted” pre-defined IP address (authentication by password is optional)
  3. The rest.

Security relating to the first category, using password authentication, was discussed in the section above. I now want to look at the second category – Static SIP peers – which are defined in sip.conf. You can list all the SIP peers (categories 1 and 2), at the Asterisk Command Line Interface using the command sip show peers. here is an example:

Name/username              Host            Dyn Nat ACL Port     Status
voiptalk/801234543                5060     OK (23 ms)
smartvox/221221                  5060     OK (27 ms)
sipgate/7654567                  5060     OK (33 ms)
sipbroker                       5060     Unmonitored
myopensips-in                   5060     Unmonitored
2001                       (Unspecified)    D       A  0        UNKNOWN
2002                       (Unspecified)    D       A  0        UNKNOWN
2003/2003             D       A  5060     OK (31 ms)
2004/2004             D          5070     OK (6 ms)
9 sip peers [Monitored: 5 online, 2 offline Unmonitored: 2 online, 0 offline]

The IP address of each static peer is defined using “host=<ip_address>” in the relevant section of sip.conf and you can specify that a peer does not need to authenticate (i.e. that you trust it soley on the basis of knowing the sender’s IP address) by adding the line “insecure=invite” to the peer definition. SIP Peers can be used very effectively to protect Asterisk against unauthorised call handling as long as you set the parameter “allowguest=no” in the general section of sip.conf. On FreePBX/Trixbox, this parameter is found on the General Settings page, near the end, and is called “Allow Anonymous Inbound SIP Calls?: no”. When set like this, Asterisk will only accept SIP requests from the pre-defined peer addresses or from peers that authenticate using a valid username and password. Unfortunately, some VoIP service providers may require that you set this parameter to Yes because it suits them to send calls to your PBX from several different addresses (for reasons of load balancing and/or resilience). I am aware that Voiptalk send calls from more than one server, but others do it too.

Always use “type=peer” and never “type=friend”

When adding static SIP peers (or so-called “SIP Trunks” in FreePBX/Trixbox) set the type to “peer” and never set it to “friend”. This advice may run counter to the majority of documentation, sample files and examples shown on the site and on Asterisk forums, but you’ll have to take my word for it – using “type=friend” is a big mistake! It will make your Asterisk server much more vulnerable because “type=friend” actually causes two objects to be created – a SIP peer and a SIP user. This gives the potential hacker two entrance doors into your PBX, one of which has comparatively weak security. The problem is that a “user” is allowed to connect from any remote IP address, not just the address specified in the host parameter. Even if you want to allow connections from any address, it is much better to use “host=dynamic” than to use “type=friend”.

By far the worst mistake that you could make when defining a static SIP peer would be to have both “type=friend” and “insecure=invite”. In this situation, a hacker could initiate calls from any remote IP address without needing to authenticate with a password. They would only need to guess one piece of data – the user name.

Default Contexts

If your Asterisk server cannot be locked down as described above, perhaps because it needs to accept legitimate requests from IP addresses that cannot be predicted in advance, then it is essential that you examine your configuration and make sure you understand how dial plan contexts are selected for each type of inbound call, especially those in category 3 above. A specific context can, and generally should, be defined for each peer in the sip.conf file using “context=<context_name>” in the peer definition in sip.conf. By doing that you can then be confident that INVITE requests from all other sources (category 3) will use the default context. FreePBX generally expects you to set the context to “from-trunk” when defining a new SIP trunk. To check which context is assigned to any given peer, run the command “sip show peer <name>” at the CLI using the name shown by the “sip show peers” command.

This all sounds straightforward, but in fact there is potential for a huge amount of confusion here! First, you must understand that Asterisk comes with a special pre-defined “default” context. Out of the box, Asterisk will generally use the context called “default” to route any category 3 calls. However, you can reset which context should be used for category 3 SIP calls by inserting a line “context=<my_default_context>” in the [general] section of sip.conf. FreePBX or Trixbox will almost certainly have done this for you using a context with a name like “from-sip-external”. To see which context will be used for calls from unknown sources, run the command “sip show settings” at the CLI. The final section of the output from this command shows you various default settings, including the default context. Here is a sample from a FreePBX unit:

Default Settings:
  Context:                from-sip-external
  Nat:                    RFC3581
  DTMF:                   rfc2833
  Qualify:                0
  Use ClientCode:         No
  Progress inband:        Never
  Language:               (Defaults to English)
  MOH Interpret:          default
  MOH Suggest:
  Voice Mail Extension:   *97

Each context contains steps that define the dial plan for calls handled by that context. One context may insert the code from a number of other contexts using the “include” directive. To see the dialplan details of any given context, run the command “dialplan show <context_name>” at the CLI. For example:

fpbxwarp*CLI> dialplan show from-sip-external
[ Context 'from-sip-external' created by 'pbx_config' ]
  'h' =>            1. NoOp(Hangup)                               [pbx_config]
  'i' =>            1. NoOp(Invalid)                              [pbx_config]
  's' =>            1. GotoIf($["${ALLOW_SIP_ANON}"="yes"]?from-trunk|${DID}|1) [pbx_config]
                    2. Set(TIMEOUT(absolute)=15)                  [pbx_config]
                    3. Answer()                                   [pbx_config]
                    4. Wait(2)                                    [pbx_config]
                    5. Playback(ss-noservice)                     [pbx_config]
                    6. Playtones(congestion)                      [pbx_config]
                    7. Congestion(5)                              [pbx_config]
  't' =>            1. NoOp(Timeout)                              [pbx_config]
  '_.' =>           1. NoOp(Received incoming SIP connection from unknown peer to ${EXTEN}) [pbx_config]
                    2. Set(DID=${IF($["${EXTEN:1:2}"=""]?s:${EXTEN})}) [pbx_config]
                    3. Goto(s|1)                                  [pbx_config]
-= 5 extensions (13 priorities) in 1 context. =-

The above example, from FreePBX, is rather over-complicated to explain here, but it does illustrate how you can use the “dialplan show” command to see if calls from unknown sources will be handled safely.

SIP Domains

Congratulations if you are still reading at this point! The final topic I wanted to cover is the use of SIP Domains, but my typing fingers are now aching and my brain exhausted so I’m going to defer that topic for part 3.

In the meantime, you may want to do some advance reading at this earlier article from the Smartvox knowledgebase:

Configuring and using SIP domains in Asterisk

For part 3 of this article, click here

3 thoughts on “How secure is your Asterisk PBX? – part 2”

  1. Question for users with asterisk behind a sip proxy that shares the same ip.
    the system ignores the default context and always uses one of the real sip users
    context. How can I force the context?

Comments are closed.