In the world of telecom, VoIP is still a relatively new concept. For the century or so prior to VoIP, the only way to connect your site to the PSTN was through the use of circuits provided for that purpose by your local telephone company. VoIP now allows for connections between endpoints without the PSTN having to be involved at all (although in most VoIP scenarios, there will still be a PSTN component at some point, especially if there is a traditional E.164 phone number involved).
Until VoIP totally replaces the PSTN, there will be a need to connect calls from VoIP networks to the public telephone network. This process is referred to as termination. What it means is that at some point a gateway connected to the PSTN needs to accept calls from the VoIP network and connect them to the PSTN network. From the perspective of the PSTN, the call will appear to have originated at the termination point.
Asterisk can be used as a PSTN termination point. In fact, given that Asterisk handles protocol conversion with ease, this can be an excellent use for an Asterisk system.
In order to provide termination, an Asterisk box will need to be able to handle all of the protocols you wish to connect to the PSTN. In general, this means that your Asterisk box will need a PRI circuit to handle the PSTN connection, and SIP channels to handle the calls coming from the VoIP network. The underlying principle is the same regardless of whether you’re running a small system providing PSTN trunks to an office full of VoIP telephones, or a complex network of gateway machines deployed in strategic locations, offering termination to thousands of subscribers.
Calls from the VoIP network will arrive in the dialplan in whatever context you assigned to the incoming SIP channels, and the dialplan will relay the calls out through the PSTN interface. At its very simplest, a portion of a dialplan that supports termination could look like this:
[from-voip-network] exten => _X.,1,Verbose(2, Call from VoIP network to ${EXTEN}) same => n,Dial(DAHDI/g0/${EXTEN})
In reality, though, you will often have to handle a more complex routing plan that takes into consideration things like geography, corporate policy, cost, available resources, and so forth.
Given that most PSTN circuits will allow you to dial any number, anywhere in the world, and given that you will be expected to pay for all incurred charges, we cannot stress enough the importance of security on any gateway machine that is providing PSTN termination. Criminals put a lot of effort into cracking phone systems (especially poorly secured Asterisk systems), and if you do not pay careful attention to all aspects of security, you will be the victim of toll fraud. It’s only a matter of time.
Do not allow any unsecured VoIP connections into any context that contains PSTN termination.
Obviously, if you want to pass calls from your VoIP network to the PSTN, you might also want to be able to accept calls from the PSTN into your VoIP network. The process of doing this is commonly referred to as origination. This simply means that the call originated in the PSTN.
In order to provide origination, a phone number is required. You will therefore need to obtain a circuit from your local phone company, which you will connect to your Asterisk system. Depending on where you are in the world, there are several different types of circuits that could provide this functionality, from a basic analog POTS line to a carrier-grade SS7 circuit.
Phone numbers as used for the purpose of origination are commonly called direct inward dialing numbers (DIDs). This is not strictly the case in all situations (for example, the phone number on a traditional analog line would not be considered a DID), but the term is useful enough that it has caught on. Historically, a DID referred to a phone number associated with a trunk connected to customer premise equipment (CPE).
Since phone numbers are controlled by the traditional telecom industry, you will need to obtain the number either from a carrier directly, or from one of the many companies that purchase numbers in bulk and resell them in smaller blocks. If you obtain a circuit such as a PRI circuit, you will normally be able to order DID numbers to be delivered with that circuit.
In order to accept a call from a circuit you are using for origination, you will normally need to handle the passing of the phone number that was called. This is because PSTN trunks can typically handle more than one phone number, and thus the carrier needs to identify which number was called so that your Asterisk system will know how to route the call. The number that was dialed is commonly referred to as the Dialed Number Identification Service (DNIS) number. The DNIS number and the DID do not have to match,[78] but typically they will. If you are ordering a circuit from the carrier, you will want to ask that they send the DNIS (if they don’t understand that, you may want to consider another carrier).
In the dialplan, you associate the incoming circuit with a context that will know how to handle the incoming digits. As an example, it could look something like this:
[from-pstn] ; This is the context that would be listed in the config file ; for the circuit (i.e. chan_dahdi.conf) exten => _X.,1,Verbose(2,Incoming call to ${EXTEN}) same => n,Goto(number-mapping,${EXTEN},1) [number-mapping] ; This context is not strictly required, but will make it easier ; to keep track of your DIDs in a single location in your dialplan. ; From here you can pass the call to another part of the dialplan ; where the actual dialplan work will take place. exten => 4165551234,1,Dial(SIP/0000FFFF0001) exten => 4165554321,1,Goto(autoattendant-context,start,1) exten => 4165559876,1,VoiceMailMain() ; a handy back door for listening ; to voice messages exten => i,1,Verbose(2,Incoming call to invalid number)
In the number-mapping
context you explicitly list all of the DIDs that you expect to
handle, plus an invalid handler for any DIDs that are not listed (you
could send invalid numbers to reception, or to an automated attendant,
or to some context that plays an invalid prompt).
Eventually, the need for the PSTN will likely vanish, and most voice communications will take place over network connections.
The original thinking behind the SIP protocol was that it was to be a peer-to-peer protocol. Technically, this is still the case. What has happened, however, is that things have gotten a bit more complicated. Issues such as security, privacy, corporate policies, integration, centralization, and so forth have made things a bit more involved than simply putting a URI into a SIP phone and having a SIP phone somewhere else ring in response.
The SIP protocol has become bloated and complex. Implementing SIP-based systems and networks has arguably become even more complicated than implementing traditional phone PBXs and networks.[79]
We are not going to get into the complexities of designing and implementing VoIP networks in this book, but we will discuss some of the ways you can configure Asterisk to support VoIP connectivity to other VoIP systems.
In Asterisk, there is no need to explicitly install your VoIP modules (unless for some reason you did not compile Asterisk with the required modules). There are several VoIP protocols that you can choose to use with Asterisk, but we will focus on the two most popular: SIP and IAX.
SIP is far and away the most popular of the VoIP protocols—so much so that many people would consider other VoIP protocols to be obsolete (they are not, but it cannot be denied that SIP has dominated VoIP for several years now).
The SIP protocol is peer-to-peer and does not really have a formal trunk specification. This means that whether you are connecting a single phone to your server or connecting two servers together, the SIP connections will be similar.
The need to be able to
connect two Asterisk systems together to allow calls to be sent
between them is a fairly common requirement. Perhaps you have a
company with two physical locations and want to have a PBX at each
location, or maybe you’re the administrator of the company PBX and
you like Asterisk so much that you would also like to install it at
home. This section provides a quick guide on configuring two
Asterisk servers to be able to pass calls to each other over SIP. In
our example, we will creatively refer to the two servers as serverA
and serverB
.
The first file that must
be modified is /etc/asterisk/sip.conf
. This is the main
configuration file for setting up SIP accounts. First, this entry
must be added to sip.conf
on
serverA
. It defines a SIP peer
for the other server:
[serverB] ; ; Specify the SIP account type as 'peer'. This means that incoming ; calls will be matched on IP address and port number. So, when Asterisk ; receives a call from 192.168.1.102 and the standard SIP port of 5060, ; it will match this entry in sip.conf. It will then request authentication ; and expect the password to match the 'secret' specified here. ; type = peer ; ; This is the IP address for the remote box (serverB). This option can also ; be provided a hostname. ; host = 192.168.1.102 ; ; When we send calls to this SIP peer and must provide authentication, ; we use 'serverA' as our username. ; username = serverA ; ; This is the shared secret with serverB. It will be used as the password ; when either receiving a call from serverB, or sending a call to serverB. ; secret = apples ; ; When receiving a call from serverB, match it against extensions ; in the 'incoming' context of extensions.conf. ; context = incoming ; ; Start by clearing out the list of allowed codecs. ; disallow = all ; ; Only allow the ulaw codec. ; allow = ulaw
Now put the following
entry in /etc/asterisk/sip.conf
on serverB
. It is nearly
identical to the contents of the entry we put on serverA
, but the name of the peer and the
IP address were changed:
[serverA] type = peer host = 192.168.1.101 username = serverB secret = apples context = incoming disallow = all allow = ulaw
At this point you should be able to verify that the configuration has been successfully loaded into Asterisk using some CLI commands. The first command to try is sip show peers. As the name implies, it will show all SIP peers that have been configured:
*CLI>
sip show peers
Name/username Host Dyn Forcerport ACL Port Status serverB/serverA 192.168.1.101 5060 Unmonitored 1 sip peers [Monitored: 0 online, 0 offline Unmonitored: 1 online, 0 offline]
You can also try sip show peer serverB. That command will show much more detail.
The last step in setting
up SIP calls between two Asterisk servers is to modify the dialplan
in /etc/asterisk/extensions.conf
. For
example, if you wanted any calls made on serverA
to extensions 6000 through 6999 to
be sent over to serverB
, you
would use this line in the dialplan:
exten => _6XXX,1,Dial(SIP/${EXTEN}@serverB)
When you sign up for a SIP provider, you may have service for sending and/or receiving phone calls. The configuration will differ slightly depending on your usage of the SIP provider. Further, the configuration will differ between each provider. Ideally, the SIP provider that you sign up with will provide Asterisk configuration examples to help get you connected as quickly as possible. In case they do not, though, we will attempt to give you a common setup that will help you get started.
If you will be receiving
calls from your service provider, the service provider will most
likely require your server to register with one of its servers. To
do so, you must add a registration line to the [general]
section of /etc/asterisk/sip.conf
:
[general] ... register =>username
:password
@your.provider.tld
...
Next, you will need to
create a peer entry in sip.conf
for your service provider. Here is a sample peer entry:
[myprovider
] type = peer host =your.provider.tld
username =username
secret =password
; Most providers won't authenticate when they send calls to you, ; so you need this line to just accept their calls. insecure = invite dtmfmode = rfc2833 disallow = all allow = ulaw
Now that the account has been defined, you must add some extensions in the dialplan to allow you to send calls to your service provider:
exten => _1NXXNXXXXXX,1,Dial(SIP/${EXTEN}@myprovider
)
Asterisk supports TLS for encryption of the SIP
signaling and SRTP for encryption of the media streams of a phone call. In this section
we will set up calls using SIP TLS and SRTP between two Asterisk
severs. The first step is to ensure the proper dependencies have
been installed. Ensure that you have both OpenSSL and LibSRTP installed. If either one of these was not installed,
reinstall Asterisk after installing these dependencies to ensure
that support for TLS and SRTP are included. Once complete, make sure
that the res_srtp
module was
compiled and installed. To install OpenSSL, the package is openssl-devel
on CentOS and libssl-dev
on Ubuntu. To install LibSRTP,
the package is libsrtp-devel
on
CentOS and libsrtp0-dev
on
Ubuntu.
Next we will configure SIP
TLS. You must enable TLS using the global tlsenable
option in the [general]
section of /etc/asterisk/sip.conf
on both servers.
You can optionally specify an address to bind to if you would like
to limit listening for TLS connections to a single IP address on the
system. In this example, we have the IPv6 wildcard address specified
to allow TLS connections on all IPv4 and IPv6 addresses on the
system:
[general] tlsenable = yes tlsbindaddr = ::
The next step is to get certificates in place. For the purposes of demonstrating the configuration and functionality, we are going to generate self-signed certificates using a helper script distributed with Asterisk. If you were setting this up in a production environment, you might not want to use self-signed certificates. However, if you do, there are a number of applications out there that help make it easier to manage your own certificate authority (CA), such as TinyCA.
The script that we are
going to use is ast_tls_cert, which is in the contrib/scripts/
directory of the
Asterisk source tree. We need to generate a CA certificate and two
server certificates. The first invocation of ast_tls_cert will generate the CA cert and
the server cert for serverA
. The
second invocation of ast_tls_cert
will generate the server cert for serverB
:
$
cd contrib/scripts
$
mkdir certs
$
./ast_tls_cert -d certs -C
serverA
-oserverA
$
./ast_tls_cert -d certs -C
serverB
-oserverB
-c certs/ca.crt -k certs/ca.key$
ls certs
ca.cfg ca.crt ca.key serverA.crt serverA.csr serverA.key serverA.pem serverB.crt serverB.csr serverB.key serverB.pem tmp.cfg
Now that the certificates
have been created, they need to be moved to the appropriate
locations on serverA
and serverB
. We will use the /var/lib/asterisk/keys/
directory to hold
the certificates. Move the following files to serverA
:
And move these files to
serverB
:
With the certificates in
place, we can complete the Asterisk configuration. We need to point
Asterisk to the server certificate that we just created. Since we’re
using self-signed certificates, we also need to point to the CA
certificate. In the [general]
section of /etc/asterisk/sip.conf
on serverA
, add these options:
[general] tlscertfile = /var/lib/asterisk/keys/serverA.pem tlscafile = /var/lib/asterisk/keys/ca.crt
Make the same changes to
sip.conf
on serverB
:
[general] tlscertfile = /var/lib/asterisk/keys/serverB.pem tlscafile = /var/lib/asterisk/keys/ca.crt
When you create the
server certificates, the Common Name field must match the hostname of
the server. If you use the ast_tls_cert script, this is the value
given to the -C
option. If
there is a problem verifying the server certificate when you make
a call, you may need to fix the Common Name field. Alternatively,
for the sake of testing you can set the tlsdontverifyserver
option to yes
in the [general]
section of /etc/asterisk/sip.conf
, and Asterisk
will allow the call to proceed even if it fails verification of
the server certificate.
In the section called “Connecting two Asterisk systems together with SIP”, we created the
configuration necessary to pass calls between serverA
and serverB
. We are now going to modify that
configuration so that Asterisk knows that the calls between the two
servers should be encrypted. The only change required is to add the
transport = tls
option to the
peer entry for the other server.
[serverB] type = peer host = 192.168.1.102 username = serverA secret = apples context = incoming disallow = all allow = ulaw transport = tls
[serverA] type = peer host = 192.168.1.101 username = serverB secret = apples context = incoming disallow = all allow = ulaw transport = tls
Now when you make a call
using Dial(SIP/serverA)
or
Dial(SIP/serverB)
, the SIP
signaling will be encrypted. You can modify the dialplan to force
outgoing calls to have encrypted signaling by setting the CHANNEL(secure_bridge_signaling)
function
to 1
:
[default] exten => 1234,1,Set(CHANNEL(secure_bridge_signaling)=1) same => n,Dial(SIP/1234@serverB)
On the side receiving the
call, you can check whether the signaling on an incoming call is
encrypted using the CHANNEL(secure_signaling)
dialplan
function. Consider the following example dialplan:
[incoming] exten => _X.,1,Answer() same => n,GotoIf($["${CHANNEL(secure_signaling)}" = "1"]?secure:insecure) same => n(secure),NoOp(Signaling is encrypted.) same => n,Hangup() same => n(insecure),NoOp(Signaling is not encrypted.) same => n,Hangup()
When a call is sent from
serverA
to serverB
using this configuration, you can
see from the output on the Asterisk console that the dialplan
determines that the signaling of the incoming call is
encrypted:
-- Executing [1234@incoming:1] Answer("SIP/serverA-00000000", "") in new stack -- Executing [1234@incoming:2] GotoIf("SIP/serverA-00000000", "1?secure:insecure") in new stack -- Goto (incoming,1234,3) -- Executing [1234@incoming:3] NoOp("SIP/serverA-00000000", "Signaling is encrypted.") in new stack -- Executing [1234@incoming:4] Hangup("SIP/serverA-00000000", "") in new stack
Now that SIP TLS has been
set up for calls between serverA
and serverB
, we will set up SRTP
so that the media streams associated with the call are encrypted as
well. Luckily, it is quite easy to configure, compared to what was
required to get SIP TLS working. First, make sure that you have the
res_srtp
module loaded in
Asterisk:
*CLI>
module show like res_srtp.so
Module Description Use Count res_srtp.so Secure RTP (SRTP) 0 1 modules loaded
To enable SRTP, set the
CHANNEL(secure_bridge_media)
function to 1
:
[default] exten => 1234,1,Set(CHANNEL(secure_bridge_signaling)=1) same => n,Set(CHANNEL(secure_bridge_media)=1) same => n,Dial(SIP/1234@serverB)
This indicates that encrypted media is required for an outbound call. When the call is sent out via SIP, Asterisk will require that SRTP be used, or the call will fail.
With all of these tools in place, you can ensure that calls between two Asterisk servers are fully encrypted. The same techniques should be applied for encrypting calls between Asterisk and a SIP phone.
The dialplan functions provide a mechanism for verifying the encryption status of an incoming call and forcing encryption on an outgoing call. However, keep in mind that these tools only provide the means for controlling encryption for one hop of the call path. If the call goes through multiple servers, these tools do not guarantee that the call is encrypted through the entire call path. It is important to carefully consider what your requirements are for secure calls and take all of the necessary steps to ensure that those requirements are respected throughout the entire call path. Security is complicated, hard work.
The Inter-Asterisk eXchange protocol, version 2 (most commonly known as IAX[80]) is Asterisk’s own VoIP protocol. It is different from SIP in that the signaling and media are carried in the same connection. This difference is one of the advantages of the IAX protocol, as it makes getting IAX to work across NAT connections much simpler.
One of the more unique features of the IAX protocol is IAX trunking. Trunking an IAX connection could be useful on any network link that will often be carrying multiple simultaneous VoIP calls between two systems. By encapsulating multiple audio streams in one packet, IAX trunking cuts down on the overhead on the data connection, which can save bandwidth on a heavily used network link.
The principal advantage of IAX encryption is that it
requires one simple change to the
/etc/asterisk/iax.conf
file:
[general] encryption = yes
For extra protection, you can set the following option to ensure that no IAX connection can happen without encryption:
forceencryption = yes
Both of these options can
be specified in the [general]
section, as well as in peer
/user
/friend
sections in iax.conf
.
[78] In traditional PBXs, the purpose of DIDs was to allow
connection directly to an extension in the office. Many PBXs could
not support concepts such as number translation or flexible digit
lengths, and thus the carrier had to pass the extension number as
the DID digits, rather than the number that was dialed (the DNIS
number). For example, the phone number 416-555-1234 might have been
mapped to extension 100, and thus the carrier would have sent the
digits 100
to the PBX instead of
the DNIS of 4165551234
. If you
ever replace an old PBX with an Asterisk system, you may find this
translation in place, and you’ll need to obtain a list of mappings
between the numbers that the caller dials and the numbers that are
sent to the PBX. It is also common to see the carrier only pass the
last four digits of the DNIS number, which the PBX then translates
into an internal number.
[79] There are many proprietary PBX systems in the market that have a basic configuration that will work right out of the box. Asterisk deployments are far more flexible, but seldom as simple.
[80] Pronounced “eeks.”