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?
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]
(
)
and make it available as extension
@server
[email protected]
(which looks so much
sexier on a business card).
A SIP URI generally looks like sip:
.
Depending on your SIP client, you may be able to dial a SIP URI as
endpoint
@domain.tld
,
or even just as endpoint
@domain.tld
(if you
have a proxy server and the endpoint you are calling is part of your
domain).endpoint
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
,
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.resource
@address
In Asterisk, the
part of
the URI (the part before the resource
@
)
must match an extension in the dialplan.[108] The
portion
will be the address (or hostname) of the Asterisk server itself. So, a
URI of address
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.
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
Name | Description | Example |
---|---|---|
Service | Symbolic name of service | _sip. |
Proto | Transport protocol | _udp. |
Name | Domain name for this record[a] | shifteight.org. |
TTL | Time to live (in seconds) | 86400 |
Class | DNS class field (always IN ) | IN |
Priority | Target host priority | 0 |
Weight | Relative weight of this record | 0 |
Port | TCP/UDP port number | 5060 |
Target | Hostname of machine providing this service | pbx.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.
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).
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.
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 Check
Public
Extension
Result
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 sub
Email
To
ExtensionLookup
via a GoSub()
.[111] We pass the value contained within the Filtered
Extension
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.
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.
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]
).
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.
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}'
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.
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.
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.
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
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.
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
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 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.
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.
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.
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]
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.
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.
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.
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.
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]!
!^\+*([^\*]*)!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.
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).
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
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:
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 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.
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 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:
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.
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).
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.
The fail2ban daemon is emerging as a popular way to automatically respond to security threats. We’ll discuss it further in Chapter 26.
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™.
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.
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.
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).
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.