Chapter 12. Internet Call Routing

There ain’t no such thing as a free lunch (TANSTAAFL).

Robert Heinlein

One of the attractions of VoIP is the concept of avoiding the use of the PSTN altogether, and routing all calls directly between endpoints using the Internet at little or no cost. While the technology to do this has been around for some time, the reality is that most phone calls still cost money—even those that are routed across VoIP services.

From a technology standpoint, there are still many systems out there that cannot handle routing VoIP calls using anything other than a dialpad on a telephone.

From a cultural standpoint, we are still used to calling each other using a numerical string (a.k.a., a phone number). With VoIP, the concept of being able to phone somebody using name@domain (just as we do with email) makes sense, but there are a few things to consider before we can get there.

So what’s holding everything up?

DNS and SIP URIs

The Domain Name System (DNS) is designed to make it easier for humans to locate resources on the Internet. While ultimately all connections between endpoints are handled through numerical IP addresses, it can be very helpful to associate a name (such as www.google.com) with what may in fact be multiple IP addresses.

In the case of VoIP, the use of a domain name can take something like [email protected] (extension@server) and make it available as [email protected] (which looks so much sexier on a business card).

The SIP URI

A SIP URI generally looks like sip:endpoint@domain.tld. Depending on your SIP client, you may be able to dial a SIP URI as endpoint@domain.tld, or even just as endpoint (if you have a proxy server and the endpoint you are calling is part of your domain).

For a SIP telephone, which often only has a numerical dialpad, it can be problematic to dial a SIP URI by name,[107] so it has become common to use numerical dialing to reach external resources. We are also used to making “phone calls” using “phone numbers.” The SIP protocol itself, however, only understands resource@address, so whatever you dial must ultimately be converted to this format before SIP can do anything with it. Usually the only reason you can dial something by “phone number” from your SIP phone is because you are registered to a resource that understands how to convert the numerical strings you dial into SIP URIs.

In Asterisk, the resource part of the URI (the part before the @) must match an extension in the dialplan.[108] The address portion will be the address (or hostname) of the Asterisk server itself. So, a URI of sip:[email protected] will end up at an extension called 100, somewhere in the dialplan of the server that provides SIP service for shifteight.org.

What is dialed (100) may not in any way relate to the actual identifier of the endpoint being connected to. For example, we might have a user named Leif whose phone may be a device that registers itself by its MAC address, and therefore could be something like [email protected].[109] Much of the purpose of the Asterisk dialplan is to simplify addressing for users and to handle the complexities of the various protocols that Asterisk supports.

SRV Records

A Service Record (SRV) is a somewhat new type of DNS record that provides information about available services. Defined in RFC 2782, it is often used by newer protocols (SIP being one of them). If you want to support SIP lookups on your domain, you will require a relevant SRV record in order to properly respond.

When a SIP connection does a lookup on [email protected], for the purposes of SIP, the SRV record can respond that the requested service (SIP) is actually found on the server pbx.shifteight.org (or possibly even on a completely different domain, such as pbx.tothemoon.net).

Internet hosting providers typically offer a web-based interface for setting up DNS records, but many of them do not provide a good interface for SRV records (assuming they offer anything at all). You can generally set up A records and MX records easily enough, but SRV records can be trickier. If your host does not support SRV records, you will need to move your DNS hosting to another provider if you want to be able to support SIP SRV lookups for your domain.

The majority of DNS servers run BIND (Berkeley Internet Name Daemon). The BIND record for an SRV entry for SIP will look something like this:

_sip._udp.shifteight.org. 86400 IN SRV 0 0 5060 pbx.shifteight.org.

The form of the record is detailed in Table 12-1.

Table 12-1. Components of a SIP SRV record

NameDescriptionExample
ServiceSymbolic name of service_sip.
ProtoTransport protocol_udp.
NameDomain name for this record[a]shifteight.org.
TTLTime to live (in seconds)86400
ClassDNS class field (always IN)IN
PriorityTarget host priority0
WeightRelative weight of this record0
PortTCP/UDP port number5060
TargetHostname of machine providing this servicepbx.shifteight.org.

[a] Note the trailing dot.

When you configure an SRV record, you can test it with the following Linux command:

# dig SRV _sip._udp.shifteight.org

The result will contain several components, but the section you are interested in is:

;; ANSWER SECTION:
_sip._udp.shifteight.org. 14210 IN SRV 0 0 5060 pbx.shifteight.org.

This means that your DNS server is responding correctly to an SRV lookup for SIP to your domain by responding with the hostname of your PBX (in this case, pbx.shifteight.org).

Any SIP requests to your domain will be referred to your Asterisk server, which will be responsible for handling incoming SIP connections.[110]

If your dialplan does not understand the name/resource/endpoint portion of the SIP URI, calls will fail. This means that if you want to be able to offer resources in your Asterisk system by name, you will need relevant dialplan entries.

Accepting Calls to Your System

When a SIP URI comes into your Asterisk system, the resource portion of the URI will arrive in the dialplan as an ${EXTEN}. So, for example, [email protected] would arrive in the dialplan as leif within the ${EXTEN} channel variable in whatever context you use to handle unauthenticated SIP calls (if you are building your dialplan using the examples in this book, that will be the unauthenticated dialplan context).

Modifying sip.conf

Once you are familiar with the security implications of allowing unauthenticated SIP connections, you will need to ensure that your sip.conf file allows for them. While Asterisk allows them by default, in earlier chapters of this book we have instructed you to disable unauthenticated SIP calls. The logic for this is simple: if you don’t need it, don’t enable it.

Since we are now interested in allowing calls from the Internet, we will need to allow unauthenticated SIP calls. We do that by setting a general variable in the /etc/asterisk/sip.conf file, as follows:

[general]
context=unauthenticated         ; default context for incoming calls
allowguest=yes                  ; enable unauthenticated calls

After making this change, don’t forget to reload SIP, using this command from the command line:

$ sudo asterisk -rx "sip reload"

or this one from the Asterisk CLI:

*CLI> sip reload

You can verify that the changes have succeeded using the Asterisk CLI command sip show settings. What you want to see is Allow unknown access: Yes under the Global Settings section, and Context: unauthenticated under the Default Settings header.

Standard dialplan

In order to handle an incoming name, your dialplan needs to contain an extension that matches that name.

A dialplan entry on the pbx.shifteight.org system might look like this:

[unauthenticated]
exten => leif,1,Goto(PublicExtensions,100,1)

exten => jim,1,Goto(PublicExtensions,101,1)

exten => tilghman,1,Goto(PublicExtensions,102,1)

exten => russell,1,Goto(PublicExtensions,103,1)

This is by far the simplest way to implement name dialing, but it is also complex to maintain, especially in systems with hundreds of users.

In order to implement name handling in a more powerful way, you could add something like the following to your extensions.conf file. Note that some lines have been wrapped in this example due to space restrictions. These lines must appear on a single line in the dialplan. All lines should start with exten =>, same =>, or a comment indicator (;).

[unauthenticated]
exten => _[A-Za-z0-9].,1,Verbose(2,UNAUTHENTICATED REQUEST TO ${EXTEN} FROM 
${CALLERID(all)})
   same => n,Set(FilteredExtension=${FILTER(A-Za-z0-9,${EXTEN})})
   same => n,Set(CheckPublicExtensionResult=${DIALPLAN_EXISTS(PublicExtensions,
${FilteredExtension},1)})
   same => n,GotoIf($["${CheckPublicExtensionResult}" = "0"]?CheckEmailLookup)
   same => n,Goto(PublicExtensions,${FilteredExtension},1)

; This is our handler for when someone dials a SIP URI with a name
   same => n(CheckEmailLookup),GoSub(subEmailToExtensionLookup,start,1
(${TOLOWER(${FilteredExtension})}))
   same => n,GotoIf($["${GOSUB_RETVAL}" = "NoResult"]?i,1:PublicExtensions,
${GOSUB_RETVAL},1)
   same => n,Goto(i,1)

; This handles invalid numbers/names
exten => i,1,Verbose(2,Incoming call from ${CALLERID(all)} to context ${CONTEXT} 
found no result)
   same => n,Playback(silence/1&invalid)
   same => n,Hangup()

; These are explicit extension matches (useful on small systems)
exten => leif,1,Goto(PublicExtensions,100,1)

exten => jim,1,Goto(PublicExtensions,101,1)

exten => tilghman,1,Goto(PublicExtensions,102,1)

exten => russell,1,Goto(PublicExtensions,103,1)

When a call enters the dialplan, it can match in one of two places: it can match our pattern match at the top, or it can match the explicit named extensions closer to the bottom of our example (i.e., leif, jim, tilghman, or russell).

If the call does not explicitly match our named extensions, the pattern match will be utilized. Our pattern match of _[A-Za-z0-9]. matches any string starting with an alphanumeric character followed by one or more other characters.

The incoming string needs to be made safe, so we utilize the FILTER() function to remove nonalphanumeric characters, and assign the result to the FilteredExtension channel variable.

The DIALPLAN_EXISTS() function will be used to see if the request matches anything in the PublicExtensions context. This function will return either a 0 (if no match is found) or a 1 (when a match is found) and assign the result to the CheckPublicExtensionResult channel variable.

The next line is a GotoIf() that checks the status of the CheckPublicExtensionResult variable. If the result returned was 0, the dialplan will continue at the CheckEmailLookup priority label. If the result was anything other than 0 (in this case, the other result could have been a 1), the next line of the dialplan will be executed. This line will perform a Goto() and continue execution in the PublicExtensions context (presumably to dial our destination endpoint).

Assuming our CheckPublicExtensionResult variable was a 0, our dialplan will continue at the CheckEmailLookup priority label, where we use the subroutine subEmailToExtensionLookup via a GoSub().[111] We pass the value contained within the FilteredExtension channel variable to the subroutine, but you’ll notice that we’ve wrapped it in the TOLOWER() dialplan function (which expects your email addresses to be stored in lowercase as opposed to mixed case).

Upon return from the subEmailToExtensionLookup subroutine, we check the GOSUB_RETVAL channel variable (which was automatically set when the subroutine returned). The result will be one of two things: the extension number that matches the name that was passed to the subroutine, or the string NoResult. Our dialplan checks ${GOSUB_RETVAL}, and if it contains NoResult, the caller is passed to the i (invalid) extension, where we inform the caller that the extension dialed is invalid. If all is well, the call will continue execution in the PublicExtensions context.

File parsing

This little trick will allow you to use the voicemail.conf file to look up valid usernames against their email address. This could end up being kludgy, and it requires that the email field in voicemail.conf is filled out and contains a username (before the @ symbol) that you will support in your dialplan, but it’s simple to code in the dialplan, and if nothing else it will give you some ideas of how you might handle providing a more automated way of linking names to extension numbers for the purpose of SIP URI dialing. Note that this method will not allow you to exclude some people from name dialing. It’s all or nothing.

We’ve written this as a subroutine, which is invoked something like this:

; where 'name' is the username as found in the email address
GoSub(subEmailToExtensionLookup,start,1(name))

The subroutine looks like this:

[subEmailToExtensionLookup]
exten => start,1,Verbose(2,Checking for user in voicemail.conf)
   same => n,Set(LOCAL(FilteredExtension)=${FILTER(a-z0-9,${ARG1})})
   same => n,Set(LOCAL(Result)=${SHELL(grep "${LOCAL(FilteredExtension)}@" 
/etc/asterisk/voicemail.conf)})
   same => n,GotoIf($[${ISNULL(${LOCAL(Result)})}]?no_Result,1)
   same => n,Set(LOCAL(ExtensionToDial)=${CUT(${LOCAL(Result)},=,1)})
   same => n,Set(LOCAL(ExtensionToDial)=${FILTER(0-9,${LOCAL(ExtensionToDial)})})
   same => n,Return(${LOCAL(ExtensionToDial)})

exten => no_Result,1,Verbose(2,No user ${ARG1} found in voicemail.conf)
   same => n,Return(NoResult)

Let’s go over this code, because there are some useful actions being performed that you may be able to apply for other purposes as well.

First, a channel variable named FilteredExtension is created. This variable is local to the subroutine:

Set(LOCAL(FilteredExtension)=${FILTER(a-z0-9,${ARG1})})

The FILTER() function looks at the entire ${ARG1} and removes any nonalphanumeric characters. This is primarily for security reasons. We are passing this string out to the shell, so it’s critical to ensure it will only contain characters that we expect.

The next step is where the coolness happens:

Set(LOCAL(Result)=${SHELL(grep "${LOCAL(FilteredExtension)}@" /etc/asterisk/voicemail.conf)})

The shell is invoked in order to run the grep shell application, which will search through the voicemail.conf file, return any lines that contain name@, and assign the result to the variable ${Result}:

GotoIf($[${ISNULL(${LOCAL(Result)})}]?no_result,1)

If no lines contain the string we’re looking for, we’ll return from the subroutine the value NoResult (which will be found in the ${GOSUB_RETVAL} channel variable). The dialplan section that called the subroutine will need to handle this condition.

We’ve created an extension named no_result for this purpose:

exten => no_result,1,Verbose(2,No user ${ARG1} found in voicemail.conf)
   same => n,Return(NoResult)

If ${Result} is not null, the next steps will clean up ${Result} in order to extract the extension number[112] of the user with the name passed in ${ARG1}:

Set(LOCAL(ExtensionToDial)=${CUT(${LOCAL(Result)},=,1)})

The CUT() function will use the = symbol as the field delimiter and will assign the value from the first field found in ${Result} to the new variable ExtensionToDial. From there, we simply need to trim any trailing spaces by filtering all nonnumeric characters:

Set(LOCAL(ExtensionToDial)=${FILTER(0-9,${LOCAL(ExtensionToDial)})})

We can now return the extension number of the name we received:

Return(${LOCAL(ExtensionToDial)})

This example was something we whipped up for the purposes of illustrating some methods you can employ in order to easily match names to extension numbers for the purposes of SIP URI dialing. This is by no means the best way of doing this, but it is fairly simple to implement, and in many cases may be all that you need.

Database lookup

Using a database is by far the best way to handle user information on larger, more complex systems. We will discuss integrating Asterisk with databases in more detail in Chapter 16, but it is useful to introduce the concept here.

A database is ideal for handling name lookup, as it makes maintenance of user data (and integration with external systems such as web interfaces) far simpler. However, it does require a bit more effort to design and implement.

The example we will use in this chapter will work, but for a production environment it is probably too simplistic. Our goal here is simply to give you enough information to understand the concept; a tighter integration is part of what is covered in Chapter 16.

First, we’ll need a table to handle our name-to-extension mapping. This could be a separate table from the main user table, or it could be handled in the main user table, provided that that table contains a field that will contain the exact strings that users will publish as their SIP URIs (as an example, some companies have rules regarding how email addresses look, so Leif might have a URI such as [email protected], or [email protected]).

Warning

If you are serious about implementing this example in a production system, make sure you are familiar with the material in Chapter 16, as some key concepts are covered there that we omit here.

Our sample NameMapping table looks like Table 12-2.

Table 12-2. NameMapping table

NameExtensionContext
leif100publicExtensions
leif.madsen100publicExtensions
lmadsen100publicExtensions
jim101publicExtensions
reception0Services[a]
voicemail*98Services

[a] Make sure this context exists on your system.

We believe that having a separate table that only handles name-to-extension/context mapping is the most useful solution, since this table can be used to handle more than just users with telephone sets. You are encouraged to come up with other ways to handle this that may be more suitable to your environment.

In the dialplan, we would refer to this table using Asterisk’s func_odbc function:

[subLookupNameInNameMappingTable]
exten => start,1,Verbose(2,Looking up ${ARG1})

; where 'name' is the username as found in the email address 
   same => n,Set(ARRAY(CalleeExtension,CalleeContext)=${GET_NAME_LOOKUP(${ARG1})})
   same => n,GotoIf($[${ISNULL(${CalleeExtension})}]?no_result,1)
   same => n,GotoIf($[${ISNULL(${CalleeContext})}]?no_result,1)
   same => n,Return() ; You'll need to handle the new CalleeExtension and 
                      ; CalleeContext variables in the code that called this 
                      ; subroutine

exten => no_result,1,Verbose(2,Name was not found in the database.)
   same => n,Return(NoResult)

The /etc/asterisk/func_odbc.conf file will require the following entry:

[NAME_LOOKUP](DB)
prefix=GET
SELECT Extension,Context FROM NameMapping WHERE Name='${ARG1}'

Note

Keep in mind that there’s nothing to say you can’t reference more than one datastore to look up names. For example, you might have a table such as the one we’ve described here, but also have a secondary lookup that goes to, say, an LDAP database to try to resolve names there as well. This can get complicated to configure and maintain, but if designed right it can also mean that your Asterisk system can be tightly integrated with other systems in your enterprise.

Details on how to handle all of this in your dialplan are beyond the scope of this book. Suffice it to say that in your dialplan you will still need to handle the values that your subroutine creates or assigns.

Dialing SIP URIs from Asterisk

Asterisk can dial a SIP URI as easily as any other sort of destination, but it is the endpoint (namely, your telephone) that is ultimately going to shoulder the burden of composing the address, and there lies the difficulty.

Most SIP telephones will allow you to compose a SIP URI using the dialpad. This sounds like a great idea at first, but since there are no typewriter keys on a phone set, in order to dial something like [email protected] what you would need to actually input into the phone would be something along the lines of:

5-444-6-*-888-2-66(pause)-6-33-4(pause)-4-33-555-33-66-#-7777-44(pause)-444-333-8-33-
444-(pause)-4(pause)-44-8-*-666-777-4

To support this in your dialplan, you would need something similar to this[113]:

exten => _[0-9a-zA-Z].,1,Verbose()
   same => n,Set(FilteredExtension=${FILTER(0-9a-zA-Z@-_.,${EXTEN})})
   same => n,Dial(SIP/${FilteredExtension})

It’s simple, it’s fun, and it works! … ?

The reality is that until all phones support complex and flexible address books, as well as a QWERTY-style keyboard (perhaps via touchscreen), SIP URI dialing is not going to take off.

If you have a SIP URI that you want to dial on a regular basis (for example, during the writing of this book there were many calls made between Jim and Leif), you could add something like this to your dialplan:

exten => 5343,1,Dial(SIP/[email protected])

With this in your dialplan, you could dial 5343 (LEIF) on your phone and the Asterisk dialplan would translate it into the appropriate SIP URI. It’s not practical for a large number of URIs, but for a few here and there it can be a helpful shortcut.

Nevertheless, keep reading, because there are some very useful components of DNS that simplify the process of dialing directly between systems without the use of the PSTN.

ENUM and E.164

Although the SIP protocol really doesn’t think in terms of phone numbers, the reality is that phone numbers are not going away any time soon, and if you want to properly integrate a VoIP system with as many telephone networks as possible, you’re going to need to handle the PSTN in some way.

ENUM maps telephone numbers onto the Domain Name System (DNS). In theory, ENUM is a great idea. Why not cut out the PSTN altogether, and simply route phone calls directly between endpoints using the same numbering plan? We’re not sure this idea is ever going to become what the emerging telecom community would like it to be, though. The reason? Nobody really can say who owns phone numbers.

E.164 and the ITU

The International Telecommunication Union (ITU) is a United Nations agency that is actually older than the UN itself. It was founded in 1865 as the International Telegraph Union. The ITU-T sector, known for many decades as CCITT (Comité consultatif international téléphonique et télégraphique), is the standards body responsible for all of the protocols used by the PSTN, as well as many that are used in VoIP. Prior to the advent of VoIP, the workings of the ITU-T sector were of little interest to the average person, and membership was generally limited to industries and institutions that had a vested interest in telecommunications standards.

ITU standards tend to follow a letter-dot-number format. ITU-T standards you may have heard of include H.323, H.264, G.711, G.729, and so forth.

E.164 is the ITU-T standard that defines the international numbering plan for the PSTN. If you’ve ever used a telephone, you’ve used E.164 addressing.

Each country in the world has been assigned a country code,[114] and control of addressing in those countries is handled by the local authorities.

E.164 numbers are limited to 15 digits in length (excluding the prefix).

In Asterisk, there is nothing special that needs to be done in order to handle E.164 addressing, other than to make sure your dialplan is suitable to the needs of any PSTN-compatible channels you may have.

For example, if you’re operating in a NANP country, you will probably need to have the following pattern matches:

_NXXNXXXXXX
_1NXXNXXXXXX
_011X.
_N11

In the UK, you might need something more like this:

_0[123789]XXXXXXXXX
_0[123789]XXXXXXXX

And in Australia, your dialplan might have these pattern matches:

_NXXXXXXX
_0XXXXXXXXX

Warning

Please don’t just copy and paste these pattern matches into your dialplan. The peculiarities of regional dialplans are tricky, and change constantly. One important item that needs to be carefully considered is the region-specific number for emergency calling, as discussed in Emergency Dialing. You don’t want to get this stuff wrong.

ENUM

In order to allow the mapping of E.164 numbers onto the DNS namespace, a way of representing phone numbers as DNS names had to be devised.

This concept is defined in RFC 3761, helpfully named “The E.164 to Uniform Resource Identifiers (URI) Dynamic Delegation Discovery System (DDDS) Application (ENUM).” ENUM reportedly stands for Electronic NUmber Mapping.

According to the RFC, converting a phone number into an ENUM-compatible address requires the following algorithm:

1. Remove all characters with the exception of the digits.
For example, the First Well Known Rule produced the Key
"+442079460148".  This step would simply remove the
leading "+", producing "442079460148".

2. Put dots (".") between each digit. Example:
      4.4.2.0.7.9.4.6.0.1.4.8

3. Reverse the order of the digits. Example:
      8.4.1.0.6.4.9.7.0.2.4.4

4. Append the string ".e164.arpa" to the end.  Example:
      8.4.1.0.6.4.9.7.0.2.4.4.e164.arpa

Clear as mud?

ENUM has not taken off. The reasons appear to be mostly political in nature. The problem stems from the fact that there is no one organization that controls numbering on the PSTN the way that IANA does for the Internet. Since no one entity has a clear mandate for managing E.164 numbers globally, the challenge of maintaining an accurate and authoritative database for ENUM has proved elusive.

Some countries in Europe have done a good job of delivering reliable ENUM databases, but in country code 1 (NANP), which contains multiple countries and therefore multiple regulatory bodies, the situation has become an illogical mess. This is hardly surprising, since the carriers that control E.164 addressing can’t reasonably be expected to get enthusiastic about allowing you to bypass their networks. The organizations responsible for implementing ENUM in North America have tended to work toward creating a PSTN on the Internet, which could save them money, but not you or I.

This is not at all what is wanted. Why would I want to route VoIP calls from my system to yours across a network that wants to charge me for the privilege? SIP is designed to route calls between endpoints, and has no real use for the concept of a carrier.

The advantage of all this is supposed to be that when an ENUM lookup is performed, a valid SIP URI is returned.

Asterisk and ENUM

Asterisk can perform lookups against ENUM databases using either the ENUMLOOKUP() function or a combination of the ENUMQUERY() and ENUMRESULT() dialplan functions. ENUMLOOKUP() only returns a single value back from the lookup, and is useful when you know there is likely to only be one return value (such as the SIP URI you want the system to dial), or if you simply want to get the number of records available.

An ENUM lookup in the dialplan might look like this:

exten => _X.,1,Set(CurrentExten=${FILTER(0-9,${EXTEN})})
   same => n,Set(LookupResult=${ENUMLOOKUP(${CurrentExten},sip,,,e164.arpa)})
   same => n,GotoIf($[${EXISTS(${LookupResult})}]?HaveLocation,1)
   same => n,Set(LookupResult=${ENUMLOOKUP(${CurrentExten},sip,,,e164.org)})
   same => n,GotoIf($[${ISNULL(${LookupResult})}]?NormalCall,1:HaveLocation,1)

exten => HaveLocation,1,Verbose(2,Handle dialing via SIP URI returned)
   exten => ...

exten => NormalCall,1,Verbose(2,Handle dialing via standard PSTN route)
   exten => ...

The dialplan code we just looked at will take the number dialed and pass it to the ENUMLOOKUP() function. It requests the method type to be sip (we want the SIP URI returned) and the lookup to be performed first against the listings in DNS found in the e164.arpa zone, and next against the records found at http://www.e164.org.

Outside the countries that have implemented it, there is little uptake of ENUM. As such, many ENUM queries will not return any results. This is not expected to change in the near future, and ENUM will remain a curiosity until more widely implemented.

ISN, ITAD, and freenum.org

Finally we get to the cool part of this chapter.

The biggest shortcoming of ENUM is that it uses a numbering system that is not under the control of any Internet numbering authorities.[115] The freenum.org project solves this problem by utilizing a numbering scheme that is managed by IANA. This means that a formal, globally valid, nongeographic numbering system for VoIP can be immediately and easily implemented without getting mired in the bureaucracy and politics that burden the E.164 numbering system.

Got ISN?

The heart of the freenum.org concept is the ITAD Subscriber Number (ISN). The ISN is a numeric string that is composed of an extension number on your system, an asterisk character separator (*),[116] and a number that is unique to your organization called an IP Telephony Administrative Domain (ITAD) number. The advantage of the ISN is that it can be dialed from any telephone. An ISN would look something like this:

0*1273

which would represent extension zero at ITAD 1273[117] and would resolve to sip:[email protected].

You control your extension numbers (everything to the left of the *). Your ITAD is assigned by IANA (the same organization that controls IP and MAC addresses).

Once your ITAD is assigned, you will be able to publish ISNs on your website, or on business cards, or wherever you would normally publish phone numbers. Any system capable of dialing ISNs will allow its users to call you by dialing your ISN. Calls will be routed directly between the two systems using the SIP URI that freenum.org returns.

ITAD Subscriber Numbers (ISNs)

The ISN does not replace a SIP URI, but rather complements it by allowing dialing of VoIP numbers using only characters found on a standard telephone dialpad. In order to resolve an ISN into a valid URI, the DNS system will query the ISN against the freenum.org domain. Any DNS lookup against your ISN will return a URI that defines how your system expects to receive calls to that ISN.[118]

Management of Internet Numbering

The Internet Assigned Numbers Authority (IANA) is the body responsible for managing any numbering system that exists as a result of an RFC that requires a numerical database of some kind. The most well-known responsibility of IANA is the delegation of IP addresses to the five Regional Internet Registries that control all of the public IP addresses on the planet.[119] These organizations are responsible for the assignment of IP addresses within their regions.

There are many other numbering schemes that have been created as a result of an RFC. Other IANA-managed numbers include MAC addresses—specifically, the Organizationally Unique Identifier (OUI) portion of the MAC addressing space.

Several years ago, a protocol named TRIP (Telephony Routing over IP) was created. While this protocol never took off, and is unlikely to see any future growth, it did offer us one incredibly useful thing: the ITAD. Since ITADs are part of an RFC, the IANA is mandated to maintain a database of ITADs. This is what makes freenum.org possible.

IP Telephony Administrative Domains (ITADs)

Freenum.org takes advantage of IANA’s responsibility to maintain a database of ITAD numbers and allows us to build simple, standards-based, globally relevant, and community-driven numbering plans for VoIP.[120] You can find the list of currently assigned ITAD numbers at http://www.iana.org/assignments/trip-parameters/trip-parameters.xml#trip-parameters-5.

You will want to obtain your own ITAD number by submitting the form located at http://www.iana.org/cgi-bin/assignments.pl.

This form should be filled out as shown in Figure 12-1.

Request for Assignments form

Figure 12-1. Request for Assignments form

Your application will be reviewed by a Real Human Being™, and within a few days you should be assigned an ITAD by IANA. A few days later, you will also receive information for your freenum.org account (there is currently a simple review process to ensure that bots and spammers don’t abuse the system). You will then need to log onto the freenum.org site and define the parameters for your ITAD.

Create a DNS Entry for Your ITAD

In the top-right corner of the freenum.org site, you will see a Sign in here link. Your username is the email address you registered with IANA, and your password will have been emailed to you by the freenum.org system.[121]

You will be presented with a list of your assigned ITADs. In order for your new ITAD to work, you will need to ensure the DNS records are up-to-date.

Note

There are two methods of handling DNS for your ITAD. The first (and simplest) is to have a NAPTR record inserted into the freenum.org zone. The other way is to create a zone for your ITAD, and have freenum.org delegate that zone to your name servers. We will only discuss the first method here, but if you are familiar with NAPTR/ENUM administration for a DNS server, you can use the second method.

The freenum.org folks have created the Freenum Automated Self-Service Tool (FASST) to simplify DNS record entry for you. The essential fields will already be filled out. The only thing you need to change is under the DNS Setting section of the form: specify the hostname of your PBX and save the changes. The FASST tool uses a regular expression to convert an ISN lookup to a SIP URI.

In order to specify your hostname, you will need to modify the sample regular expression provided by FASST, changing the sample hostname sip.yourdomain.com to the hostname of your PBX. So, for example, in our case we would want to change:

!^\+*([^\*]*)!sip:\[email protected]!

to:

!^\+*([^\*]*)!sip:\[email protected]!

The other fields in the DNS entry should not be changed unless you know what you are doing. The rest of the fields in the form are optional, and can be filled out as you see fit.

Testing Your ITAD

As is often the case with DNS changes, it can take a few days for your changes to propagate through the system. To check, you can Google for “online dig tool” to find a web-based lookup tool, or use the dig tool under Linux:

$ dig NAPTR 4.3.2.1.1273.freenum.org

Once your record is updated in the system, the result will include the following:

;; ANSWER SECTION: 
4.3.2.1.1273.freenum.org. 86400 IN NAPTR 100 10 "u" "E2U+sip" 
"!^\+*([^\*]*)!sip:\[email protected]!" .

If the answer section does not include the regular expression containing your domain name, the records have not updated and you should wait a few more hours (or even leave it for a day).

Using ISNs in Your Asterisk System

So now that you’ve got your own ITAD (you did sign up, right?), you’ll want to make it available to others, and also configure your dialplan to allow you to dial other ITADs.

Under the [globals] section of your dialplan (/etc/asterisk/extensions.conf), add a global variable that contains your ITAD:

[globals]
ITAD = 1273 ; replace '1273' with your own ITAD number

To allow calling to ITADs from your system, you will need something like the following dialplan code[122]:

[OutgoingISN]
exten => _X*X!,1,GoSub(subFreenum,start,1(${EXTEN}))
exten => _XX*X!,1,GoSub(subFreenum,start,1(${EXTEN}))
exten => _XXX*X!,1,GoSub(subFreenum,start,1(${EXTEN}))
exten => _XXXX*X!,1,GoSub(subFreenum,start,1(${EXTEN}))
exten => _XXXXX*X!,1,GoSub(subFreenum,start,1(${EXTEN}))
; you may need to add more lines here to handle XXXXXX*X, XXXXXXX*X, and so forth

[subFreenum]
exten => start,1,Verbose(2,Performing ISN lookup)
   same => n,Set(ISN=${FILTER(0-9*,${ARG1})})
   same => n,Set(Result=${ENUMLOOKUP(${ISN},sip,s,,freenum.org)})
   same => n,GotoIf($[${EXISTS(${Result})}]?call,1:no_result,1)

exten => call,1,Verbose(2,Placing call to ISN --${ISN}-- via ${Result})
   same => n,Dial(SIP/${Result})
   same => n,Return()

exten => no_result,1,Verbose(2,Lookup for ISN: --${ISN}-- returned no result)
   same => n,Playback(silence/1&invalid)
   same => n,Return()

We have added two new contexts to our dialplan: OutgoingISN and subFreenum. The OutgoingISN context controls who can dial ISN numbers from within your dialplan. If you have been following our examples throughout this book, you should have a context called LocalSets, which is the context where all your telephones enter the dialplan. Including OutgoingISN within LocalSets enables dialing of ISN numbers:

[LocalSets]
include => OutgoingISN  ; include the context that enables ISN dialing
include => CallPlace    ; use subroutine to determine what you can dial

Note

We have placed the OutgoingISN include above the CallPlace include because Asterisk will perform extension matching in the order of the includes, and since CallPlace has a more general pattern match than our OutgoingISN pattern matches, we need to make sure OutgoingISN appears first.

The magic for dialing ISN numbers is handled in the subFreenum context. Our OutgoingISN context will pass the requested extension (e.g., 1234*256) to the subFreenum subroutine. After the initial call to Verbose(), the subroutine will filter the request for numbers and the asterisk (*) character to make the extension safe. The result will then be assigned to the ISN channel variable:

exten => start,n,Set(ISN=${FILTER(0-9*,${ARG1})})

The subroutine will then perform a lookup for the ISN via the DNS system using the ENUMLOOKUP() dialplan function. Options passed to the ENUMLOOKUP() function include:

  • The ISN number to look up

  • The method type to look up and return (SIP)

  • The s option, which tells Asterisk to perform an ISN-style lookup instead of a standard ENUM lookup

  • The zone suffix for performing the lookups (we’ll use freenum.org, but the default is e164.arpa)

Our code for performing the lookup then looks like this:

exten => start,n,Set(Result=${ENUMLOOKUP(${ISN},sip,s,,freenum.org)})

Following the lookup and storing the result in the ${Result} channel variable, our subroutine will verify whether we received a result or not:

exten => start,n,GotoIf($[${EXISTS(${Result})}]?call,1:no_result,1)

If no result is received, the call will be handled in the no_result extension. If a result is received back from our lookup, then execution will continue at the call extension where the call will be placed using the result stored in the ${Result} channel variable.

Receiving calls to your ITAD

Receiving calls to your ITAD is much simpler. If your system supports incoming SIP URIs, ISNs will already work for you.[123] We showed the configuration required to accept calls to your system in Accepting Calls to Your System.

Security and Identity

It is a sad fact of the Internet that there are a few selfish, greedy criminal types out there who think nothing of attempting to take advantage of people for their own gain. In telecom, this behavior represents several risks to you.

In this section, we will focus on security issues relating to the portions of your system that you intend to make publicly available through the Internet. While it would be simple to just refuse to allow any sort of external connections, the reality is that if you want people to be able to call you for free from the Internet (for example, if you intend to publish your company’s SIP URIs on your web page), you are going to have to define a secure place within your system where those calls will arrive. Securing your incoming public VoIP connections is conceptually similar to implementing a DMZ in traditional networking.[124]

In Asterisk, certain contexts in your dialplan cannot be trusted. This means that you will need to carefully consider what resources are available to channels that enter the system through these contexts, and ensure that only certain services and features are available.

Toll Fraud

Toll fraud is by far the biggest risk to your phone system in terms of the potential for ruinous cost. It is not unheard of for fraudsters to rack up tens of thousands of dollars in stolen phone calls over the course of a few days.

Toll fraud is not a new thing, having existed prior to VoIP; however, the enabling nature of VoIP means that it is easier for fraudsters to take advantage of unsecured systems. Most carriers will not take responsibility for these costs, and thus if your system is compromised you could be stuck with a very large phone bill. While carriers are getting better and better at alerting their customers to suspicious activity, that does not absolve you of responsibility for ensuring your system is hardened against this very real and very dangerous threat.

Within your Asterisk system, it is vitally important that you know what resources on your system are exposed to the outside world and ensure that those resources are secure.

The most common form of toll fraud these days is accomplished by brute-force attack. In this scenario, the thieves will have a script that will contact your system and attempt to register as a valid user. If they are able to register as a telephone on your system, the flood of calls will commence, and you will be stuck with the bill. If you are using simple extension numbers and easy-to-guess passwords, and your system accepts registrations from outside your firewall, it is certain that you will eventually be the victim of toll fraud.

Brute-force attacks can also cause performance problems with your system, as one of these scripts can flood your router and PBX with massive numbers of registration attempts.

The following tactics have proven successful in minimizing the risk of toll fraud:

  1. Do not use easy-to-guess passwords. Passwords should be at least eight characters long and contain a mix of digits, letters, and characters. 8a$j03H% is a good password.[125] 1234 is not.

  2. Do not use extension numbers for your SIP registrations in sip.conf. Instead of [1000], use something like a MAC address (something like [0004f2123456] would be much more difficult for a brute-force script to guess).

  3. Use an analysis script such as fail2ban to tweak your internal firewall to block IP addresses that are displaying abusive behavior, such as massive packet floods.

Note

The fail2ban daemon is emerging as a popular way to automatically respond to security threats. We’ll discuss it further in Chapter 26.

Spam over Internet Telephony (SPIT)

VoIP spam has not yet taken off, but rest assured, it will. Spammers all over the world are drooling at the prospect of being able to freely assault anyone and everyone with an Internet-enabled phone system.

Like email, VoIP entails a certain level of trust, in that it assumes that every phone call is legitimate. Unfortunately, as with email spam, it only takes a few bad apples to spoil things for the rest of us.

Many organizations and persons are working on ways to address SPIT now, before it becomes a problem. Some concepts being worked on include certificates and whitelists. No one method has emerged as the definitive solution.

While it would be easy to simply lock our systems away from the world, the fact is that Internet telephony is something that every business will be expected to support in the not-too-distant future. SPIT will increasingly become a problem as more and more unsavory characters decide that this is the new road to riches.

Solving the SPIT problem will be an ongoing process: a battle between us and The Bad Guys™.

Distributed Denial of Service Attacks

SIP denial of service attacks are already happening on the Internet. Amazon’s EC2 cloud has become a popular place to originate these attacks from, and other cloud-based or compromised systems will become popular for these activities as well. The actual attacks are not strictly denial of service attacks (in the sense that they are not deliberately trying to choke your system); rather, they are attack campaigns that are typically trying to use brute force to locate exploitable holes in any systems they can find. As the sheer number of these attacks increases, the effect on the network will be similar to that of email spam.

The previously mentioned fail2ban daemon can be useful in minimizing the effects of these attacks. Refer to Chapter 26 for more details.

Phishing

When a VoIP system has been compromised, one popular use of the compromised system is to relay fraud campaigns using the identity of the compromised system. Criminals engaging in so-called phishing expeditions will make random calls to lists of numbers, attempting to obtain credit card or other sensitive information, while posing as your organization.

Security Is an Ongoing Process

In contrast to previous editions, throughout this book we have tried to provide examples and best practices that take security into consideration at all stages. Whatever you are working on, you should be thinking about security. While implementing good security requires more design, development, and testing effort, it will save you time and money in the long run.

Most security holes happen as a result of something that was hastily implemented and wasn’t locked down later. “I’ll just quickly build this now, and I’ll clean it up later” are words you never want to say (or hear).

Conclusion

One of the dreams of VoIP was that it was going to make phone calls free. Over a decade later, we’re still paying for our phone calls. The technology has existed for some time, but the ease of use has not been there.

It costs nothing to register your ITAD and set up your system to handle ISNs. If every Asterisk system deployed had an ITAD, and people started publishing their ISNs on websites, vcards, and business cards, the weight of the Asterisk community would drive industry adoption.

Security considerations for VoIP have to be taken into consideration, but we expect that the benefits will outweigh the risks.

Our collective dream of free Internet calling may be closer than we think.



[106] Seriously, get your butt over to freenum.org and get your ISN today. It’s simple and free, and soon all the cool kids will have one.

[107] Do you know where the @ symbol is on your dialpad?

[108] Bear in mind that an extension in Asterisk can be any alphanumeric string, such as leif or 100.

[109] You could actually dial this URI directly from your phone and bypass the Asterisk server, but you can see how dialing 100 is going to be a lot more popular than trying to figure out how to type [email protected] into your phone using just the numeric dialpad (it can be done, by the way).

[110] This could just as easily be a proxy server, or any other server capable of handling incoming SIP connections.

[111] We explain the use of subEmailToExtensionLookup in the following section.

[112] In actual fact, what we are extracting is the voicemail box number; however, this number is generally going to be the same as the user’s dialable internal extension number. If it is not the same, this particular technique will not accomplish name-to-extension lookups, and another way will have to be found.

[113] Technically, the characters ! # $ % & ' * + / = ? ^ ` { | } ~ are also valid as part of the local-part of an email address; however, they are uncommon, and we have elected not to allow them in our dialplan examples.

[114] With the exception of 24 countries and territories in country code 1, which are all part of the North American Numbering Plan Authority (NANPA).

[115] More to the point, perhaps, is that E.164 numbers are controlled by far too many organizations, each one subjected to different regulations, and having goals that are not always compatible with the concept of global, free VoIP calling.

[116] This character has nothing to do with the software that is the subject of this book; it simply refers to the * that is on the dialpad of every telephone. We wonder what might have been if, instead of Asterisk, Mark Spencer had decided to call his creation Octothorpe.

[117] ITAD 1273 is assigned to shifteight.org.

[118] Although freenum.org can handle ITADs that resolve to non-SIP URIs, the handling of multiple protocols is beyond the scope of this book. For now, we recommend you restrict your ISN to handling SIP URIs.

[119] AfriNIC, APNIC, ARIN, LACNIC, and RIPE NCC.

[120] Note that freenum.org has consulted with the folks at IANA in regard to the use of ITADs with protocols other than TRIP.

[121] This may take a few days, so if you’ve received your ITAD from IANA but not yet a password from freenum.org, give it some time.

[122] If people publish the users’ full DIDs instead of their internal extension numbers, the pattern matches will need to support up to 15 digits.

[123] If you’ve set up your ITAD and ISN correctly, the conversion from ISN dial string to SIP URI will take place before the call arrives on your doorstep.

[124] A DMZ is any portion of your network that you expose to the Internet (such as your website), and therefore cannot completely trust. It is not uncommon for organizations to place the PBX within a DMZ.

[125] Actually, since it’s published in this book, it is no longer a good password, but you get the idea.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset