Voice-over-IP using Asterisk on a Deutsche Telekom landline

Preliminary note and system description

My internal phone system comprises some SNOM-Phones bought second-hand at EBay and some soft phones (MicroSip on Windows 10). All devices are connected to my LAN and communicate with the Asterisk server. Any direct external VoIP communication is blocked for security reasons.

On my site Asterisk runs in version 14.x on a virtual server (Ubuntu Linux) which is hosted in my own OpenStack-Cloud. The cloud server is connected to my LAN as well. Provided a correctly configured hosting environment this doesn't play a role for the Asterisk configuration. Only the Asterisk configuration itself is relevant for a successful VoIP operation, and of course correctly configured networking components (physical or virtual). For the following I will just assume a properly configured and running network environment.

The Deutsche Telekom isn't too communicative regarding the configuration of VoIP clients to enable them to connect to their VoIP network. From a providers point of view this is absolutely understandable considering the huge number of free and commercial VoIP components in all their different versions and configurations out there. It is clear that a provider can and will only provide support for its own hardware. Whoever want's to deviate from the standard setup for whatever reason then has to take on his own responsibility. That's normal and nothing to complain about.

As mentioned above the configuration described below works for my setup at the time of the last update of this web page (November 2016). However, I'd like to make a few more comments:

  • The Telekom seems to continously make changes to its technical equipment and configuration. As a consequence even correctly configured local installations may stop working from time to time. When operating your own equipment you can easily check the log files to find out what's going on. A corresponding error message in the SIP trace (e.g. missing authorization) in most cases indicates a misconfiguration of the local installation. However, I also have observed errors caused by a misconfigured Deutsche Telekom counterpart. Errors of this type come without warning and may also silently disappear without any action required.
  • I also have observed configuration changes at the SIP counterpart (i. e. the Telekom side) which led to errors in a once working configuration. With a little luck the SIP trace will tell you details about the error and ways to correct it (e.g. "Registration interval must be larger than xxx sec").
  • The Asterisk packages provided by the Ubuntu package manager had some errors in my installation. I was able to configure and run Asterisk but observed regular crashes when SIP calls arrived. I wasn't able to localize the error and ended up with installing Asterisk and the PJSIP SIP stack myself from source. The current Asterisk release contains the PJSIP source code and the Asterisk source code so no separate download of PJSIP source is necessary. Trying to use a separately downloaded PJSIP source code resulted in a crash of the executable on an incoming call.

Normally a firewall will be between your Asterisk server and the internet. For incoming calls from the SIP servers of the Telekom to reach your Asterisk server a few ports have to be forwarded. The Telekom provided some information about the relevant ports but the page has been deleted recently and now simply refers the user to the documentation of his own telephony system.

An additional challenge for setting up an Asterisk server is the fact that the Deutsche Telekom operates several VoIP servers. Whereas outgoing SIP traffic from the Asterisk server always is to be sent to tel.t-online.de the incoming traffic originates from several different servers. The exact address range is not known to me. However all Telekom VoIP servers seem to be on the network Therefore the following filter/NAT ruleset on the firewall works for my installation (incoming calls):

  • SIP Signaling: IPv4 UDP, Source Source-Port any Destination own-WAN-IP Destination-Port 5060 → Destination asterisk-server-internal-ip Destination-Port 5060
  • RTP Voice Data: IPv4 UDP, Source Source-Port any Destination own-WAN-IP Destination-Port 30000-30100 → Destination asterisk-server-internal-ip Destination-Port 30000-30100

For outbound connections the firewall allows any IPv4 communication from the Asterisk server. This should be the default rule for most private firewalls.

The RTP port range for the firewall must match the corresponding setting in the rtp.conf configuration file of Asterisk


All other configuration options are commented out in rtp.conf.

Some more comments might be added which turned out to be essential for success in my setup.

  • I haven't used any other ports. In case of the Telekom often ports 5070 or 40000-41000 for RTP have been mentioned but turned out to be not necessary in my case, not the often mentioned STUN/ICE/... ports.
  • I made sure to set the same port ranges also on the telephones. I considered this to be useful because RTP is transmitted directly from endpoint to endpoint so it makes sense to use the same endpoints also there and not only at the Asterisk.
  • I use pfSense as firewall (so the following probably also applies to its forks, e.g. OPNSense). A few special settings are required which are described in the documentation. First it is required to add a NAT rule also for the outgoing traffic (SIP and RTP) to ensure that the firewall does not manipulate the ports of the outgoing data packets (static ports). Second the management of the state tables must be set to conservative. Setting this to other values led to sudden interruptions of calls because the firewall decided to block traffic on existing connections. I assume that similar effects may also occur with other firewalls.

Asterisk now uses the new SIP stack PJSIP instead of its predecessor chan_sip. From my experience the new SIP stack seems to work more stable and robust than the old one. Therefore the configuration details given below refer to the new one (configuration file pjsip.conf) which is in use in my installation.

On the previous version of this page I had a similar configuration description for the old SIP stack. I've decided to keep it for a while for readers still working with the old SIP stack. You can find it here. However, it's available in German language only and I don't want to invest the time to translate this outdated information.

The configuration file pjsip.conf is structured into several sections. In contrast to other configuration files the name of the sections doesn't play a role in most cases. It is just a unique identifier that is used to reference a particular section from other sections. The actual meaning of the section is configured using a type = entry in that section. PJSIP knows the types global, transport, registration, out, endpoint, aor, identify, acll, and some others which I don't need in my installation. Most section types may appear several type, of course with different name and content. In my installation it looks like this:

Global Settings
  • user-agent is a string to be set as "User Agent" in SIP requests. The default is "Asterisk ...". This is sent to the Telekom when we are sending a SIP request, e.g. a phone call. We can set any other name here.
  • endpoint_identifier_order. For Asterisk an incoming SIP request simply is a UDP data packet. To actually process the data Asterisk has to know the endpoint (i.e. the telephone) the packet came from. Here we configure that Asterisk first should try to match the packets source IP address to known IP addresses in the configuration file. This will work for our internal telephones where the IP addresses are static and known. It will not work for calls incoming from the Deutsche Telekom VoIP servers because of unknown and changing source IP addresses. Therefore we configure the username as a second option for the matching process. By default Asterisk also has an anonymous activated here. For security reasons we don't want to match and handle anonymous calls and leave out the corresponding option. Note that anonymous calls here refers to the matching process of SIP packets. It is still possible for the caller not to send or to fake its own phone numer (CallerID).
  • default_from_user. This is what Asterisk will set as From User in SIP requests if no other value for this setting is available (e.g. the CallerID). We will set here our own phone number (without country code, including area code).


Here we configure UDP and TCP as available transports for Asterisk. Later on we only will use UDP which is sufficient for Asterisks SIP operation. At a later time we may want to have the option to also use TCP alternatively, so we keep this setting for the moment. It doesn't harm and we won't reference it in the proposed configuration.

  • bind configures the computer network port Asterisk/PJSIP is expected to listen on. Setting here configures Asterisk to listen on all port available.
  • local_net identifies the LAN IP address range and helps PJSIP to find out what is local an what is external. This might become relevant in NAT scenarios so we will configure this parameter although we probably don't need it in our setup. xxx.xxx.xxx.xxx/yy identifies the local IP network, e.g.
Outbound Registrations


This section tells PJSIP how to register with the Deutsche Telekom VoIP server. It is important to understand that registration has nothing to do with authentification or authorization. SIP registration just informs the Telekom VoIP server about our Asterisk server so that the Telekom servers will know where to forward calls coming in on the landline telephone number.

Of course we need an authorization to register our Asterisk server with the Telekom servers. It is important to note that at this point the authorization is required for the registration process itself only. We will need an additional and maybe different authorization if we want to make a call via the Telekom VoIP server. The Telekom uses the same username/password combination in both cases, but this might be different for other providers. Therefore for our setup we will reference this section several times in our configuration file.

The registration also will not prevent other non-Telekom servers from sending SIP requests to our Asterisk server. Port 5060 has been forwarded to Asterisk in our firewall rules, so any UDP packet reaching our WAN IP address on this port will be sent to Asterisk no matter where it came from. We have a little bit of filtering implemented in the firewall rule set by restricting the allowed source address range to a valid Deutsche Telekom address range. But of course we do not know whether we really can trust all machines in this address range.

  • transport=transport-udp. The Deutsche Telekom will communicate via UDP only. transport-udp is the name of the corresponding type=transport configuration section defined above.
  • outbound_auth references the type=auth section. The name set here must be the name of the corresponding section a few lines below.
  • server_uri=sip:tel.t-online.de is the address of the Telekom SIP server.
  • client_uri is the URL we use to register with the Telekom. I've set this to the landline telephone number (including +<country code>, area code without 0 and phone number).
  • contact_user is the user identification. Here also the landline phone numer works (without country code, including area and phone number)
  • retry_interval=60. We will retry the registration every 60 seconds if it doesn't work (e.g. if there is a timeout).
  • forbidden_retry_interval=300. In case we receive a "forbidden" as response to our registration request we will pause for 5 minutes and then try again.
  • expiration=480. We will re-register every 8 minutes. Too short intervals are not allowed and we will receive a "forbidden" as response. Longer intervals are ok and will reduce data traffic. But in case our registration gets lost we will have to wait that long to re-register and to be able to receive calls again.
  • auth_rejection_permanent=false. If our registration attempt gets denied we will try it again. As mentioned above denials may happen from time to time due to maintenance work on the providers side. It would be fatal to give up registration in this case because we would not be able to receive calls anymore and we probably won't even notice.

The second section describes the authorization we have to send together with the registration request in order to be accepted and registered properly with the provider.

  • auth_type=userpass. This is Asterisks default setting. We configure this explicitely to make it clear that we will use the classic Deutsche Telekom username/password combination for authorization.
  • password. This is the password you receive from the provider (typically by snail mail) to connect via the provided line. For the Telekom this is xxxxxxxx:yyyyyyyyyyyy-zzzz@t-online.de. Here xxxxxxxx is the number of the personal password, yyyyyyyyyyyy the number from the connection data specification ("T-Online Nummer") and zzzz the user number (typ. 0001). The landline telephone number itself must be provided as a user name.
  • username is the username corresponding to the password. For Deutsche Telekom this is the provided landline telephone number (without country code, including areacode without 0 and phone number).
  • realm. The SIP realm for the local endpoint. The endpoint represents a Telekom landline connection, so the endpoint is in the realm tel.t-online-de.

This registration section must be repeated for every telephone number or SIP account to be registered with the provider, i.e. each phone number has to be registered separately.


The concept of an endpoint in PJSIP means an endpoint in a SIP communication, i.e. two endpoints communicate with eachother via the SIP protocol. An endpoint may be the home of several users. If for example an endpoint is physically represented by a SIP telephone several users may have an account on this telephone. The details have to be handled by the telephone itself, not by SIP/Asterisk. As phone calls connect users, Asterisk has to know the mapping between users and endpoints. In PJSIP this is configured using an Address-of-Record (AOR).

If Asterisk receives an incoming call (i.e. the corresponding SIP signaling) it will try to identify from the SIP signaling the user who is to receive this call. To forward the SIP packet to this user Asterisk has to know the endpoint the user resides on. So in the SIP packet Asterisk will look for an identification of the user (typically its name) and try to match it with an type=aor section with the users name. Then it will look for an endpoint related to this AOR. The final IP address of the endpoint is known to Asterisk as soon as the endpoint registers with Asterisk. Asterisk also knows the IP address of the sender from the incoming SIP request so it has all the information necessary to handle the call. By distinguishing users and endpoints a not binding them one-on-one a user is able to simply take his SIP account from one telephone to another.

There are some other options for this process. It is possible for example to tie an IP address to an endpoint so Asterisk will know how to reach the endpoint without having the endpoint to register first with Asterisk. In this case still it is required to specify which user is on this endpoint.

Another option would be to tie an user ("Contact") to an endpoint in advance. This also will remove the need for the user to register with Asterisk. We will use this type of configuration for outgoing calls via our Telekom SIP account. The Deutsche Telekom VoIP server will not register with our Asterisk server despite the fact that it expects us to register with the Telekom server. So we have to tell Asterisk in advance the endpoint our own landline telephone number ("Contact") is attached to to be able to place outgoing calls.

For security reasons we will distinguish incoming and outgoing calls via our landline in the configuration and configure separate endpoints (and dialplan contexts) for both directions. Taking everything together the configuration of an endpoint for outgoing calls looks like this:



The first part here describes the endpoint itself.

  • transport=transport-udp. The Telekom only communicates using UDP. transport-udp is the name of the corresponding type=transport section declared above.
  • context. Defines the context in the dialplan (extensions.conf) where incoming calls from this endpoint will be handled. Here we declare an unspecified context which we will also declare in the dialplan and leave it empty there. This is for security reasons to stop incoming calls on this endpoint (which is dedicated to outgoing calls only) as they might be a fraud and we therefore dont't want them to be connected to any endpoint via our Asterisk server.
  • disallow/allow. This specifies the codecs allowed on this endpoint. The Telekom uses alaw (ISDN) and nowaydays also g722 (better quality for language).
  • outbound_auth. References the authorization type=auth section with the same name defined above. It is normal that the Telekom requests our authorization for outgoing calls. We are authorized and we tell Deutsche Telekom.
  • aors=telekom_out. Refers to the AOR with the same name defined a few lines later. As already mentioned the Telekom will not register with our Asterisk server. By specifying this entry (and the corresponding AOR section) we tell Asterisk on which endpoint our landline telephone number (user, "Contact") actually resides.
  • callerid. This sets the CallerID of all outgoing calls via this endpoint to a fixed value. We use our own landline telephone number (without county code, including area code and phone number).
  • from_user. The "From User" in the SIP header also has to be our landline telephone number, same value as callerid.
  • from_domain must be tel.t-online.de for Deutsche Telekom.
  • timers are deactivated.
  • rtp_symmetric activates symmetric RTP. RTP voice data therefore wil be sent and received on the same ports on the endpoints. Because RTP data are transmitted directly from endpoint to endpoint without Asterisk in between also the telephones must be configured to use symmetric RTP.

The second section finally defines the "Contact" as our own landline telephone number for Asterisk to match our own phone number to the corresponding endpoint.

  • contact is the SIP URI format of our own landline telephone number (including +<country code>, areacode and telephone number).

This section must be repeated in case we own several telephone numbers we want to use to dial out of Asterisk, once for each number to be used on dial out

Next we will define an endpoint for incoming calls. We use this endpoint for all incoming calls from Deutsche Telekom no matter which phone number from our number portfolio actually has been called. We don't want to use this endpoint to dial out so we don't have to specify an AOR. This also means that dialing out via this endpoint is not possible or at least not easy to accomplish which further increases security level. Also incoming calls (on the landline) will be handled strictly separately from outgoing calls later in the dialplan.


  • transport=transport-udp. The Telekom only communicates using UDP. transport-udp is the name of the corresponding type=transport section declared above.
  • context=telekom_in is the dialplan context we will use to handle calls incoming on the landline.
  • disallow/allow. This specifies the codecs allowed on this endpoint. The Telekom uses alaw (ISDN) and nowaydays also g722 (better quality for language).
  • outbound_auth references the authorization section defined above which has already been referenced multiple times. It might seem confusing in this place because we configure this endpoint for incoming calls from Telekom only and Telekom will not send an authorization when calling our Asterisk. This however refers to incoming type of authorization and indeed is not configured here. The authorization configured here is an outbound authorization entry. This is necessary because Asterisk will send information about RTP data traffic to the Telekom server on incoming calls. The Telekom server however considers this information as incoming and will request an authorization before accepting these data. This is why we need outbound authorization on an incoming calls only endpoint.

You may have noticed that an type=aor here is not necessary as explained above. We need however a type=identify section specifying the IP address range we have specified with the firewall filters. This will tell Asterisk that all incoming SIP traffic from this address range should be matched to this endpoint. It should be noted here again that this applies to all UDP traffic reaching our firewall from this address range and being forwarded to our Asterisk, be it from Deutsche Telekom VoIP servers or not.

  • endpoint=telekom_in references the endpoint declared above.
  • match= tells Asterisk to match every SIP packet from this address range to this endpoint.
More Phones

With the last configuration section we have completed the configuration of the communication between Asterisk and the Deutsche Telekom VoIP servers. Obviously this isn't sufficient to place and receive phone calls because now we only have communication between Asterisk and Deutsche Telekom and nothing else. To really make and receive calls we need at least one more telephone (one more endpoint). This telephone will be a physical SIP telephone in our home LAN so we consider it to be "secure" and don't worry about a distinction between incoming and outgoing calls. In addition we can configure it to register and authorize with Asterisk (which Telekom VoIP server never would do). The type=endpoint entry for this phone then looks like this:

mailboxes=as configured in voicemail.conf




These options configure how our telephone communicates with Asterisk. Therefore the telephone has to be configured properly to match what is specified here.

  • transport=transport-udp. In our LAN we use UDP for SIP communication.
  • context=internalsip Calls incoming on this endpoint (i.e. from our internal telephone to Asterisk) will be handled by Asterisk in the dialplan context specified here.
  • disallow/allow. Internally we use the same codec we also use for external communication with the Deutsche Telekom. This makes the system a little bit more robust, eliminates possible causes for trouble and removes the need to translate between different encodings when calling from on endpoint to another.
  • auth, aors references the corresponding sections a few lines further down.
  • mailboxes assigns a mailbox to this telephone. The mailbox itself is configured in voicemail.conf and simply referenced here.
  • username, password specifies a username/password combination to be used in the registration and communication of this telephone with Asterisk. You may specify whatever you like here, it just has to match the corresponding option in the configuration of the telephone itself.
  • realm defines our own SIP realm which has to match the corresponding entry in the telephones SIP configuration. In case you own a domain you may specify it here (e.g. rotherland.de in my case).
  • max_contacts=1 will allow only one single telephone on this endpoint.
  • remove_existing=true removes an existing contact if the same contact registers again. This entry is important to correctly handle multiple registration requests by the same telephone which otherwise would be denied by Asterisk.

The type=aor section is required to enable Asterisk to match an endpoint to a user specified by an incoming registration request so that Asterisk can call the correct endpoint (telephone) when it wants to call a specific user (contact). The type=identify section on the other hand is used by Asterisk to match SIP packets received from the IP address specified (the fixed IP address of the telephone in our LAN) to this endpoint.


To further improve the security of the installation the communication of Asterisk can be restricted to certain networks only.

; Deutsche Telekom
; own LAN

This section is quite self-explanatory. In the first line it denies communication with any other computer on the network. In the next lines it allows communication of Asterisk with the VoIP servers in the Deutsche Telekom network as well as with any telephones in our own LAN.

WOW !!!!! You've read up to this point and deserved my respect and a break before we continue with the configuration of the dialplan in the next section.

Compared to the pjsip.conf the dialplan extensions.conf is eays to configure. I'm going to explain a fictitious configuration similar to the one in my installation.

First some global settings:


The options have the following meaning:

  • static=yes and writeprotect=yes. We don't want any automatic modifications of the dialplan.
  • autofallthrough=yes is the default setting of Asterisk which we state here explicitely. Whenever a dialplan extension has finished processing Asterisk will hang up. I consider this more secure than the alternative.
  • extenpatternmatchnew=no. We only have a few extensions to handle so we stay with the classic pattern matching.
  • clearglobalvars=no. Keep global variables on dialplan reload.
  • userscontext=unspecified. This really is an important setting. It specifies a default dialplan context to be used if no other context matches an incoming call. We explicitely forward such calls to "unspecified" context which we will define later as empty or "not allowed". Asterisks default setting here is "default" and if a context with this name actually exists within the dialplan this might be a security risk because callers might try to fraud us by calling other number on our expense if there is a misconfiguration in this "default" context.

Therefore we define our "unspecified" context for all incoming calls from unknown or unwanted callers. We may consider such a call as an attack and write an entry to the log file.

; whoever gets here either has a wrong configuration or no rights to use our system

exten => _X.,1,Answer()
exten => _X.,2,Verbose(D E F A U L T ==> ${CALLERID(num)} called at ${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)} and reached the UNSPECIFIED context as he tried to call ${EXTEN}.)
exten => _X.,3,Hangup()

Next we have to specify the contexts we have referenced in pjsip.conf. Calls from our internal telephones will get to this context:

; Calls from internal telephones will come here

; directly call other internal users
exten => contact_name1,1,Dial(PJSIP/contact_name1)
exten => contact_name2,1,Dial(PJSIP/contact_name2)

; call the mailbox, we don't need a PIN because it's a purely internal call
exten => mailboxname,1,VoiceMailMain(mailboxname@mailboxcontext,s)

The names contact_name1, contact_name2 and mailboxname may be called directly from the SIP telephone because SIP also can dial names (not just numbers). Calling individual internal users is used for internal communication from one telephone to another (e.g. from first floor to second floor in the house). No external communication is involved here. The same applies to the communication from internal telephones to the mailbox.

For external communication via the landline and the corresponding telephone number we might use:

;national, dialed with +49
exten => _+49X.,1,Dial(PJSIP/telekom_out/sip:0${EXTEN:3}@tel.t-online.de,60)
exten => _+49X.,n,Hangup()

;we don't allow international calls for security reasons
exten => _+X.,1,Hangup() 
exten => _00X.,1,Hangup() 

;national, dialed with leading 0
exten => _0Z.,1,Dial(PJSIP/telekom_out/sip:${EXTEN}@tel.t-online.de,60)
exten => _0Z.,n,Hangup() 

; local area
exten => _Z.,1,Dial(PJSIP/telekom_out/sip:local-area-number-including-0${EXTEN}@tel.t-online.de,60)
exten => _Z.,n,Hangup() 

; emergency calls always are possible
exten => 110,1,Dial(PJSIP/telekom_out/sip:110@tel.t-online.de,60)
exten => 110,n,Hangup() 
exten => 112,1,Dial(PJSIP/telekom_out/sip:112@tel.t-online.de,60)
exten => 112,n,Hangup()

The entries are more or less self-explanatory. Please note that they are specific for Germany (+49) and Deutsche Telekom as SIP provider and must be adapted accordingly. The first configuration block will allow to dial out on national numbers if dialed with leading +49. The second block denies international calls for security reasons. The third block will dial out national numbers if dialed with leading 0. The fouth block will dial out local area numbers if dialed without area code by adding the local area code and translating them to standard national numbers. The fourth entry explicitely specifies emergency phone numbers (valid for Germany, replace by emergency numbers in your country/area).

Finally we need one more context to handle calls incoming on our landline. We just forward those calls to our internal telephones.

; Calls from landline via Deutsche Telekom VoIP come in here
; ring internal telephone for 30 seconds
exten => my-phonenumber,1,Dial(PJSIP/my-telephone,30) 
; then forward the caller to the mailbox
exten => my-phonenumber,n,VoiceMail(mailboxname@mailboxcontext)
exten => my-phonenumber,n,Hangup()

Here my-phonenumber is my own landline telephone number (without +<country code>, including area code with 0 and phone number). Deutsche Telekom will set this as the extension on calls incoming on the landline. We simply forward the call to the telephone my-telephone. This is the name of the corresponding endpoint configured in pjsip.conf earlier. If nobody answers the call on the telephone within 30 seconds Asterisk will forward the call to the mailbox which is configured in voicemail.conf.

updated 2017-12-03 Sitemap