Voice-over-IP mit Asterisk und Telekom

Vorbemerkungen und Systembeschreibung

Mein hausinternes Telefoniesystem besteht aus einigen SNOM-Phones, die ich als Second-Hand-Geräte be EBay erstanden habe sowie aus einigen Softphones (MicroSip auf Windows 10). Alle Geräte hängen im Hausnetz und kommunizieren mit einem Asterisk-Server. Direkte Kommunikation von und nach extern ist aus Sicherheitsgründen blockiert.

Asterisk läuft in Version 14.x auf einem virtuellen Server (Ubuntu Linux), der in einer OpenStack-Cloud gehostet wird. Der Cloud-Server selbst hängt ebenfalls in meinem Hausnetz. Bei korrekter Konfiguration der Host-Umgebung spielt das eigentlich keine Rolle, relevant für den VoIP-Betrieb ist nur die Konfiguration von Asterisk selbst, und natürlich die der Netzwerkkomponenten (physisch oder virtuell), auf die ich hier aber nicht weiter eingehe und die ich als gegeben voraussetze.

Die Deutsche Telekom hält sich ja ziemlich zurück mit Angaben zur korrekten Konfiguration von VoIP-Geräten im Zusammenhang mit dem eigenen VoIP-Netz. Aus Provider-Sicht ist es auch durchaus verständlich, dass man für die Vielzahl freier und kommerzieller VoIP-Komponenten in all ihren Versionen keine Support leisten kann und stattdessen auf die eigenen Router und Produkte verweist, die man auch fernwartet und supportet. Wer vom Standard abweichen will, der muss dann eben auch die Verantwortung dafür tragen. Das ist überall so und auch niemandem vorzuwerfen.

Wie oben schon beschrieben, funktioniert die folgend beschriebene Konfiguration zum Zeitpunkt des letzten Updates dieser Seite (November 2016) auf meiner Anlage. Dazu aber noch folgende Hinweise:

  • Die Telekom arbeitet kontinuierlich an ihrer Technik. Das hat zur Folge, dass auch eigentlich korrekte Anlagenkonfigurationen von Zeit zu Zeit Aussetzer haben. Wenn man selbst einen Asterisk-Server betreibt, dann kann man durch einen Blick in die Logfiles meist schnell feststellen, woran es hakt. Eine entsprechende Meldung der SIP-Gegenstelle (z.B. fehlerhafte Autorisierung) deutet meist auf einen Fehler der eigenen Konfiguration hin. Ich habe aber auch schon erlebt, dass der Fehler bei der Gegenstelle lag. Solche zeitweisen Aussetzer treten bei mir ohne Vorwarnung auf, und verschwinden nach einiger Zeit auch von selbst wieder.
  • Ich habe auch schon dauerhafte Konfigurationsänderungen der Gegenstelle beobachtet, durch die eine vormals funktionierende Konfiguration nicht mehr lief. Das kann an Hand der Protokolle und Logfiles festgestellt und entsprechend in der eigenen Konfiguration nachjustiert werden. Mit etwas Glück sagt die Gegenstelle im SIP-Datenverkehr auch, woran es liegt und was man korrigieren muss (z.B. "Registration interval must be larger than xxx sec").
  • Die Asterisk-Pakete, die die Paketverwaltung des Ubuntu-Server bereitstellt, waren bei mir nicht in Ordnung. Es schien zwar alles zu laufen, ich habe jedoch regelmäßig einen Crash im SIP-Stack bei Annahme eines Anrufes erlebt, den ich nicht weiter lokalisieren oder beheben konnte. Eventuell ist das mittlerweile behoben worden. Ich habe jedoch Asterisk und den SIP-Stack PJSIP neu aus den offiziellen Quellen übersetzen müssen um ein stabiles System zu erhalten. Neuerdings integriert der Asterisk Source Code auch den PJSIP Source Code, ein separater Download ist nicht notwendig. Eine andere als die integrierte PJSIP Version führte bei mir auch zum Crash bei eingehenden Anrufen.

Im Normalfall wird man seinen Asterisk-Server hinter einer Firewall betreiben. Damit ankommende Anrufe von den SIP-Servern der Telekom auch den eigenen Asterisk erreichen, müssen einige Ports zum Asterisk weitergeleitet werden (Port-Forwarding). Die Telekom machte dazu früher auf den eigenen Seiten einige Angabe, mittlerweile wird jedoch nur noch auf die Dokumentation der eigenen Telefonieanlage verwiesen.

Eine weitere Schwierigkeit aus Sicht des Asterisk-Betreibers liegt darin, dass die Telekom eine ganze Reihe von VoIP-Servern betreibt. Während der ausgehende Datenverkehr also immer an tel.t-online.de geht, so kann der ankommende Datenverkehr von ganz verschiedenen Servern kommen. Der genaue Adressbereich ist nicht ganz klar, die Server scheinen aber alle im Adressraum 217.0.0.0/13 zu leben. Bei mir funktioniert an der Firewall folgendes Filter/NAT-Ruleset (Incoming):

  • SIP-Signalisierung: IPv4 UDP, Source 217.0.0.0/13 Source-Port any Destination eigene-WAN-IP Destination-Port 5060 → Destination asterisk-server-internal-ip Destination-Port 5060
  • RTP-Gesprächsdaten: IPv4 UDP, Source 217.0.0.0/13 Source-Port any Destination eigene-WAN-IP Destination-Port 30000-30100 → Destination asterisk-server-internal-ip Destination-Port 30000-30100

In die Gegenrichtung (von innen nach aussen) erlaubt die Firewall dem Asterisk-Server jede IPv4-Kommunikation, das entspricht der Default-Einstellung der meisten privaten Firewalls.

In der rtp.conf von Asterisk muss der zu verwendende RTP-Portbereich entsprechend eingestellt werden

[general]
rtpstart=30000
rtpend=30100

Alle weiteren Einstellungen in der rtp.conf sind auskommentiert.

Dazu noch folgende Anmerkungen, die bei mir wesentlich zum Erfolg beigetragen haben.

  • Andere Ports habe ich nicht verwendet. Insbesondere weder den früher von der Telekom beschriebenen Port 5070, noch weitere Portbereiche 40000-41000 für die RTP-Daten, und auch keine STUN/ICE/...-Ports.
  • Die Telefone habe ich auf dieselben Portbereiche eingestellt. Da RTP direkt zwischen den Endpoints ausgetauscht wird, hielt ich es für sinnvoll, das auch bei den Telefonen so einzustellen und nicht nur bei Asterisk.
  • Als Firewall habe ich pfSense im Einsatz (folgendes gilt daher mit hoher Wahrscheinlichkeit auch für seine Forks, z.B. OPNSense). Hier gibt es einige spezielle Einstellungen zu beachten, die in der Dokumentation beschrieben sind. Zum einen muß fü den ausgehenden Datenverkehr (SIP und RTP) eine NAT-Regel eingerichtet werden, die verhindet, daß die Firewall die Ports in den Paketen manipuliert (static ports). Zum anderen muß das Management der State Tables auf conservative gesetzt werden. Andernfalls kam es zu Gesprächsabbrüchen weil die Firewall bestehende Verbindungen unterbrochen hat. Ich nehme an, daß andere Firewalls ähnliche Effekte produzieren können.

Asterisk verwendet mittlerweile den neuen SIP-Stack PJSIP anstelle des Vorgängers chan_sip. Nach meiner Erfahrung läuft der neue SIP-Stack deutlich stabiler und robuster als der alte. Die folgende Beschreibung der Konfiguration bezieht sich daher auf den neuen SIP-Stack (Konfigurationsdatei pjsip.conf), der bei mir im Einsatz ist.

Die Vorgängerversion dieser Beschreibung bezog sich noch auf den alten SIP-Stack. Für Leser, die noch mit dem alten SIP-Stack arbeiten, habe ich sie hier gesichert.

Die Konfigurationsdatei pjsip.conf gliedert sich in einzelne Abschnitte. Deren Name spielt allerdings meistens keine Rolle, sondern ist nur eindeutiger Bezeichner mit dem der Abschnitt an anderer Stelle referenziert wird. Was in dem Abschnitt konfiguriert wird, bestimmt der type = Eintrag. PJSIP unterscheidet hier global, transport, registration, out, endpoint, aor, identify, acl. Die meisten Abschnitte können mehrfach vorkommen. Bei mir sieht das in etwa so aus:

Globale Einstellungen
[global]
type=global
user_agent=beliebiger-name
endpoint_identifier_order=ip,username
default_from_user=meine-Festnetznummer
  • user-agent ist ein string, der als "User Agent" in SIP-Requests gesendet wird. Als Default steht hier "Asterisk ..." drin. Das erfährt dann also die Telekom, wenn wir einen Sip-Request senden, z.B. einen Anruf tätigen. Wenn wir das nicht wollen, dann schreiben wir hier irgendeinen anderen Text rein.
  • endpoint_identifier_order. Ein SIP-Request ist für Asterisk einfach ein ankommendes UDP-Datenpaket. Für die weitere Verarbeitung muss Asterisk wissen, von welchem Endpoint (z.B. Telefon) das Paket kommt. Wir beschreiben hier, dass zunächst die IP-Adresse untersucht werden soll, denn die kennen wir zumindest von unseren internen Telefonen. Von der Telekom kenenn wir sie nicht, weshalb im zweiten Schritt nach dem username geschaut werden soll. Im Default von Asterisk wäre hier auch noch anonymous aktiviert, aber anonyme SIP-Requests lassen wir sicherheitshalber nicht zu. Es sei noch darauf hingewiesen, dass anonymous sich hier auf die Zuordnung von SIP-Paketen zu Endpoints bezieht. Das ist unabhängig davon, ob der Anrufer auch seine Telefonnummer mitsendet.
  • default_from_user. Das sendet Asterisk als From User in SIP-Requests, wenn es nichts besseres hat (z.B. eine CallerID). Wir schreiben hier unsere eigen Festnetznummer rein, mit Vorwahl und Rufnummer ohne Trennzeichen.
Transports
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0
local_net=xxx.xxx.xxx.xxx/yy

[transport-tcp]
type=transport
protocol=tcp
bind=0.0.0.0
local_net=xxx.xxx.xxx.xxx/yy

Wir konfigurieren zwei Transports, UPD und TCP. UDP alleine sollte genügen, aber wir wollen die Option haben auch per TCP mit Asterisk sprechen zu können.

  • bind konfiguriert den Netzwerkanschluss, an dem Asterisk/PJSIP arbeitet. Mit 0.0.0.0 lauscht Asterisk an allen verfügbaren Anschlüssen.
  • local_net identifiziert für PJSIP das lokale Netzwerk. Das wird in NAT-Szenarien relevant, wir konfigurieren das sicherheitshalber mal, xxx.xxx.xxx.xxx/yy bezeichnet das lokale Netzwerk, also z.B. 192.168.0.0/24.
Outbound Registrations
[telekom_meine-rufnummer]
type=registration
transport=transport-udp
outbound_auth=telekom_meine-rufnummer_auth
server_uri=sip:tel.t-online.de
client_uri=sip:+49meine-rufnummer-mit-vorwahl@tel.t-online.de
contact_user=meine-rufnummer
retry_interval=60
forbidden_retry_interval=300
expiration=480
auth_rejection_permanent=false

[telekom_meine-rufnummer_auth]
type=auth
auth_type=userpass
password=mein-passwort
username=meine-rufnummer
realm=tel.t-online.de

Mit diesem Abschnitt sagen wir PJSIP, dass wir uns bei der Telekom registrieren wollen. Dabei es ist wichtig zu verstehen, dass diese Registrierung nichts mit Autorisierung und Berechtigungen zu tun hat. Die SIP-Registrierung dient lediglich dazu, den eigenen Asterisk-Server bei den Telekom-Servern bekannt zu machen, damit diese wissen, wohin Anrufe geleitet werden sollen, die auf der eigenen Festnetznummer ankommen.

Zwar brauchen wir für die Registrierung eine Autorisierung. Die ist in diesem Zusammenhang aber nur für die Durchführung der Registrierung relevant. Wenn wir selbst einen Anruf machen wollen, dann brauchen wir dafür eine eigene zusätzliche Autorisierung. Dass dabei von der Telekom in beiden Fällen die gleiche Username/Password-Kombination verlangt wird, ändert nichts an der prinzipiellen Unterscheidung. Aber weil das für unsere Konstellation jedesmal dieselbe Authorisierung ist, wird dieser Abschnitt im folgenden noch mehrmals referenziert.

Diese Registrierung hindert auch keine fremden Server daran, uns SIP-Requests (z.B. Anrufe) zu senden. Da der Port 5060 von der Firewall an Asterisk weitergeleitet wird, kann prinzipiell jeder, der die externe IP-Adresse kennt, entsprechende Anfragen an Asterisk senden. Wir haben das bei der Konfiguration der Firewall lediglich ein bisschen eingeschänk, indem wir einen Filter auf einen Adressbereich der Telekom gesetz haben. Aber wir wissen natürlich nicht, ob uns tatsächlich alle Rechner in diesem Adressbereich wohlgesonnen sind.

  • transport=transport-udp. Die Telekom kommuniziert nur per UDP. transport-udp ist der Name des entsprechenden type=transport-Abschnittes, den wir oben definiert haben.
  • outbound_auth referenziert den Namen eines type=auth-Abschnittes. Der angegebene Name muss mit dem des Abschnittes (ein paar Zeilen darunter) übereinstimmen.
  • server_uri=sip:tel.t-online.de gibt den Namen des SIP-Servers der Telekom an.
  • client_uri gibt die URI an, mit der wir uns bei der Telekom melden. Ich verwende hier meine Telefonnummer (mit +49, Vorwahl ohne 0 und Rufnummer).
  • contact_user ist meine User-Identifikation. Hier funktioniert ebenfalls die eigene Telefonnummer (ohne +49, Vorwahl mit 0 und Rufnummer).
  • retry_interval=60. Wir versuchen es alle 60 Sekunden, wenn es nicht klappt (z.B. Timeout).
  • forbidden_retry_interval=300. Falls wir ein "Forbidden" zurückbekommen, dann probieren wir es in 5 Minuten nochmal.
  • expiration=480. Alle 8 Minuten neu registrieren. Das Intervall darf nicht zu kurz sein, sonst bekommen wir ein "Forbidden" zurück. Längere Intervalle sind OK und verringern den Datenverkehr. Falls andererseits unsere Registrierung verloren geht, dann können wir bis zur Neuregistrierung nicht angerufen werden. Zu lange wollen wir das Intervall also auch nicht machen.
  • auth_rejection_permanent=false. Falls unsere Registrierung abgelehnt wird, dann versuchen wir es trotzdem weiter. Wie beschieben kann das zeitweise vorkommen. Es wäre fatal, wenn wir aufgeben würden, denn dann könnten wir keine Anrufe mehr bekommen und würden das vermutlich gar nicht mal merken.

Der zweite Abschnitt enthält die Autorisierung, die wir bei der Registrierung mitsenden müssen, damit diese von der Telekom akzeptiert wird.

  • auth_type=userpass. Das ist der Asterisk-Default. Wir schreiben das trotzdem explizit hin um ganz klar zu machen dass wir hier die klassische Telekom-Username/Passwort-Kombination verwenden.
  • password. Das ist das klassische Telekom-Passwort, das man zu seinem Anschluss bekommt, also xxxxxxxx:yyyyyyyyyyyy-zzzz@t-online.de. Dabei ist xxxxxxxx die Ziffernkombination des persönlichen Kennwortes, yyyyyyyyyyyy die Nummer aus den Zugangsdaten (vormals T-Online Nummer) und zzzz die Mitbenutzernummer (typisch 0001). Die eigene Telefonnummer kommt als Benutzernamen in den folgenden Eintrag.
  • username ist der Telekom-Benutzername zum Passwort, normalerweise also die eigene Telefonnummer (ohne +49, Vorwahl mit 0 und Rufnummer).
  • realm. Der SIP-Realm zum eigenen Endpoint. Da dieser einen Telekom-Festnetzanschluss repräsentiert, liegt der Endpoint im Realm tel.t-online-de.

Dieser Registrierungsabschnitt muss für jede eigene Rufnummer wiederholt werden, jede eigene Rufnummer muss also separat registriert werden um angerufen werden zu können.

Endpoints

PJSIP hat das Konzept der Endpoints, was in etwa einen Endpunkt in einer SIP-Kommunikation meint. Es kommunizieren also normalerweise zwei Endpoints per SIP miteinander. Einem Endpoint können dabei mehrere Nutzer zugeordnet sein. Wenn der Endpoint ein Telefon ist, dann können auf diesem mehrere Benutzer angemeldet sein. Die Details sind dann Sache des Telefons, nicht von Asterisk. Welche Nutzer einem Endpoint zugeordnet sind, das wird in PJSIP mit einem Address-of-Record (AOR) ausgedrückt.

Wenn Asterisk also ein Telefongespäch (d.h. ein entsprechendes SIP-Paket) empfängt, dann versucht es herauszufinden, welchen Benutzer dieses Paket erreichen soll. Daher muss es wissen, auf welchem Endpoint dieser Nutzer zu finden ist, damit es die Kommunikation mit dem richtigen Endpoint aufnehmen kann. Im SIP-Paket sucht es dazu nach einer Identifikation des Empfängers (typisch der Name), dann nach einem type=aor-Abschnitt mit diesem Namen und dann nach einem Endpoint, dem dieser AOR zugeordnet ist. Die IP-Adresse des Endpoint erfährt Asterisk erst, wenn sich ein Nutzer bei Asterisk registriert. Denn dann weiß Asterisk sowohl die IP-Adresse des Absenders des SIP-Paketes, als auch den Namen des Nutzers aus dem Paketinhalt und damit die Zordnung zu einem Endpoint über des AOR-Eintrag. Auf diese Weise kann also ein Nutzer seinen SIP-Account von einem Telefon zum anderen "mitnehmen".

Alternativ kann die Zuordnung auch über die IP-Adresse gehen, indem man explizit bestimmte IP-Adressen bestimmten Endpoints zuordnet mittels eines type=identify-Abschnitts. Dann braucht es natürlich eine Zusatzinformation zum Nutzer, der dem Endpoint zugeordnet ist.

Daneben gibt es noch die Möglichkeit, einen Nutzer ("Contact") fest einem Endpoint zuzuordnen. Dies kann man verwenden, wenn man einen Nutzer anrufen möchte und auch weiß, auf welchem Endpoint der Nutzer zu finden ist, sich dieser Nutzer aber nicht bei Asterisk registriert hat. Dies wird für ausgehende Gespräche über den Telekom-Anschluss benötigt, denn die Telekom erwartet zwar von unserem Asterisk eine Registrierung, sendet unserem Asterisk selbst aber keine Registrierung, so dass Asterisk a priori nicht weiß welchem Endpoint die eigene Festnetznummer zugeordnet ist.

Aus Sicherheitsgründen unterscheiden wir ein- und ausgehende Gespräche auf der Festnetznummer und legen jeweils einen eigenen Endpoint dafür an. Das vorher Gesagt zusammengenommer sieht die Deklaration des Endpoints für ausgehende Gespräche so aus:

[telekom_out]
type=endpoint
transport=transport-udp
context=unspecified
disallow=all
allow=g722
allow=alaw
outbound_auth=telekom_meine-rufnummer_auth
aors=telekom_out
callerid=meine-rufnummer
from_user=meine-rufnummer
from_domain=tel.t-online.de
timers=no
rtp_symmetric=yes

[telekom_out]
type=aor
contact=sip:meine-rufnummer@tel.t-online.de

Der erste Teil beschreibt den eigentlichen Endpoint.

  • transport=transport-udp. Die Telekom kommuniziert nur per UDP. transport-udp ist der Name des entsprechenden type=transport-Abschnittes, den wir oben definiert haben.
  • context. Definiert den Context im Dialplan (extensions.conf), in den auf diesem Endpoint ankommende Gespräche geleitet werden. Wir definieren hier unspecified, den wir später auch im Dialplan anlegen und dort leer lassen. Damit ist sichergestellt, dass ein irrtümlich (oder in betrügerischer Absicht) hier ankommender Anruf nicht weitervermittelt wird. Das ist eine Sicherheitseinstellung.
  • disallow/allow. Geben die erlaubten Codecs an. Die Telekom spricht alaw (ISDN) sowie neuerdings g722 (bessere Sprachqualität).
  • outbound_auth. Referenziert den bei der Registrierung definierten gleichnamigen type=auth-Abschnitt. Die Telekom verlangt berechtigterweise für ausgehende Telefonate unsere Autorisierung, die wir hier mitteilen.
  • aors=telekom_out. Bezieht sich auf den gleichnamigen AOR, der ein paar Zeilen weiter definiert wird. Wie erwähnt registriert sich die Telekom nicht bei unserer Asterisk-Anlage. Mit diesem Eintrag (und dem AOR) teilen wir Asterisk mit, auf welchem Endpoint sich unsere eigene Festnetznummer befindet.
  • callerid. Das setzt eine feste CallerID für alle Anrufe, die über diesen Endpoint rausgehen. Die Telekom erwartet hier unsere eigene Festnetznummer (ohne +49, Vorwahl mit 0 und Rufnummer).
  • from_user. Der "From User" im SIP-Header muss ebenfalls unsere Festnetznummer sein, gleicher Wert wie bei callerid.
  • from_domain muss tel.t-online.de sein.
  • timers werden sicherheitshalber abgeschaltet.
  • rtp_symmetric aktiviert symmetrischen RTP Datenverkehr. Damit werden die RTP-Sprachdaten auf dem gleichen Port gesendet und empfangen. Da die RTP-Daten direkt zwischen den Endpoints versendet werden ohne Asterisk dazwischen, mu&Szlig; auch auf den Telefonen symmetrisches RTP eingestellt werden.

Der zweite Teil definiert einen "Contact", damit Asterisk unsere Festnetznummer (in Form eines SIP-URI) dem Endpoint zuordnen kann.

  • contact ist die SIP-Form der eigenen Festnetznummer (mit +49, Vorwahl ohne 0 und Rufnummer).

Wenn wir auf mehreren unterschiedlichen Rufnummern heraustelefonieren möchten, dann muss dieser Abschnitt entsprechend wiederholt werden.

Als nächstes kann der Endpoint für ankommende Gespräche definiert werden. Diesen Endpoint verwenden wir für alle ankommenden Gespräche aus Telekom-Netz. Da wir über diesen Endpoint nicht heraustelefonieren wollen, brauchen wir auch keinen AOR anzugeben. Das bedeutet auch, dass ein Heraustelefonieren über diesen Endpoint nicht einfach möglich ist, was wiederum der Sicherheit dient und die ankommenden Gespräche auch später im Dialplan klar von den ausgehenden trennt.

[telekom_in]
type=endpoint
transport=transport-udp
context=telekom_in
disallow=all
allow=g722
allow=alaw
outbound_auth=telekom_meine-rufnummer_auth

[telekom_in]
type=identify
endpoint=telekom_in
match=217.0.0.0/13
  • transport=transport-udp. Die Telekom kommuniziert nur per UDP. transport-udp ist der Name des entsprechenden type=transport-Abschnittes, den wir oben definiert haben.
  • context=telekom_in ist der Dialplan-Kontext an den die ankommenden Gespräche weitergeleitet werden.
  • disallow/allow. Geben die erlaubten Codes an. Die Telekom spricht alaw (ISDN) sowie neuerdings g722 (bessere Sprachqualität).
  • outbound_auth referenziert den bereits mehrfach verwendeten Autorisierungsabschnitt. Das mag an dieser Stelle verwirren, denn die Telekom selbst sendet uns keine Autorisierung mit, wenn sie uns anruft (wenngleich sie selbiges von uns erwartet, wenn wir SIP-Daten an die Telekom senden). Dies wäre jedoch eine inbound-Autorisierung, die hier tatsächlich nicht angegeben ist. Die hier genannte outbound-Autorisierung ist notwendig, weil Asterisk beim Vermitteln des ankommenden Gesprächs ("Bridging") Anweisungen zum RTP-Datenverkehr an die Telekom sendet. und prompt erwartet diese dafür wieder eine Autorisierung.

Ein type=aor-Abschnitt ist hier tasächlich nicht notwendig. Dafür aber ein type=identify-Abschnitt mit dem IP-Adressbereich, den wir auch bei den Filtern der Firewall angegeben haben. Dieser sorgt dafür, dass Asterisk alle ankommenden SIP-Anfragen aus diesem Addressbereich dem genannten Endpoint zuordnet. Es sei wiederholt, dass das jeglichen SIP-Datenverkehr aus diesem Adressbereich betrifft. Das sind die SIP-Server der Telekom, aber es gibt keine Garantie, dass die ankommenden SIP-Pakete ausschließlich von diesem kommen.

  • endpoint=telekom_in referenziert den vorstehend deklarierten Endpoint.
  • match=217.0.0.0/13 erklärt Asterisk, dass jedes SIP-Paket aus dem genannten Adressbereich dem genannten Endpoint zugeordnet werden soll.
Weitere Telefone

Mit dem letzten Eintrag ist die Konfiguration der Kommunikation Asterisk-Telekom abgeschlossen. Das reicht natürlich nicht zum Telefonieren, denn bisher kann nur Asterisk mit der Telekom sprechen. Zum Telefonieren brauchen wir noch ein Telefon (einen weiteren Endpoint). Da sich dieses in unserem Hausnetz befindet, betrachten wir es als "sicher" und verzichten auf die Unterscheidung ankommender und ausgehender Gespräche. Zudem können wir es so konfigurieren, dass es sich bei Asterisk registriert und autorisiert, so wie es eigentlich auch sein sollte. Der Eintrag für das Telefon sieht dann so aus:

[mein-telefon]
type=endpoint
transport=transport-udp
context=internalsip
disallow=all
allow=g722
allow=alaw
auth=mein-auth-eintrag
aors=mein-aor-eintrag
mailboxes=wie in voicemail.conf definiert

[mein-auth-eintrag]
type=auth
auth_type=userpass
password=mein-eigenes-passwort
username=mein-eigener-username
realm=mein-eigener-realm

[mein-eigener-username]
type=aor
max_contacts=1
remove_existing=true

[mein-eigener-username]
type=identify
endpoint=mein-telefon
match=ip-adresse-mein-telefon

Diese Einträge definieren, wie unser Telefon mit Asterisk kommuniziert. Die Konfiguration des Telefons muss also zu dem passen, was hier eingetragen wird.

  • transport=transport-udp. Auch hausintern nutzen wir UDP.
  • context=internalsip Auf diesem Endpoint eingehende Anrufe (d.h. von unserem internen Telefon an Asterisk) werden von Asterisk in diesem Dialplan-Kontext vermittelt.
  • disallow/allow. Wir halten uns da an die Codes, wie sie auch die Telekom verwendet. Es macht das System eutlich robuster, wenn zwischen den Endpoints nicht auch noch zwischen verschiedenen Codecs übersetzt werden muß.
  • auth, aors referenzieren die entsprechenden Abschnitte ein paar Zeilen weiter.
  • mailboxes ordnet dem Telefon eine Mailbox zu. Diese wird in voicemail.conf definiert und hier referenziert.
  • username, password vergibt eine Username/Password-Kombination, mit der sich das Telefon bei Asterisk registrieren kann und die das Telefon angeben muss, wenn Asterisk eine Autorisierung fordert. Der Eintrag kann frei gewählt werden, er muss nur mit dem zusammanpassen, was im Telefon selbst konfiguriert wird.
  • realm definiert einen eigenen SIP-Realm, den man beim Telefon einträgt. Hier kann man z.B. die eigene Domain einsetzen (z.B. rotherland.de in meinem Fall).
  • max_contacts=1 erlaubt nur ein einziges Telefon an diesem Endpoint.
  • remove_existing=true entfernt einen vorhandenen Kontakt, wenn sich derselbe Kontakt erneut registriert. Der Eintrag ist notwendig, weil sonst erneute Registrierungen mit Verweis auf den bereits existierenden Kontakt abgelehnt würden.

Der type=aor-Abschnitt ist notwendig, damit Asterisk bei einer Registrierung eines Nutzers dieses Namens ("sicher") diesen dem Endpoint zuordnen und dann anrufen kann (ausgehende Gespräche zu diesem Telefon). Der type=identify-Abschnitt dagegen beschreibt die Zuordnung ankommender SIP-Pakete an Hand der festen IP-Adresse dieses Telefons in unserem Hausnetz zu dem genannten Endpoint.

ACLs

Um die Sicherheit noch ein bisschen zu steigern, kann man die erlaubten Netzwerke festlegen, die mit Asterisk kommunizieren dürfen.

[acl]
type=acl
deny=0.0.0.0/0.0.0.0
; Telekom
permit=217.0.0.0/13
; eigenes LAN
permit=eigene-LAN

Der Eintrag ist selbsterklärend. Er verbietet zunächst alle Rechnern im Netz die Kommunikation und erlaubt dann gezielt Verbindungen zu den VoIP-Servern im Telekom-Netz sowie den Telefonen im hausinternen LAN.

WOW !!!!! Sie haben bis hierher gelesen und sich meinen Respekt und eine Pause verdient, bevor Sie im nächsten Abschnitt den Dialplan konfigurieren.

Im Vergleich zur pjsip.conf ist der Dialplan extensions.conf relativ einfach zu konfigurieren. Ich gebe hier eine Beispielkonfiguration an, die sich an meine anlehnt. Der Phantasie sind natürlich keine Grenzen gesetzt.

Zunächst einige globale Einstellungen:

[general]
static=yes
writeprotect=yes
autofallthrough=yes
extenpatternmatchnew=no
clearglobalvars=no
userscontext=unspecified

Dabei bedeuten:

  • static=yes und writeprotect=yes. Wir verzichten auf alle automatischen Änderungen am Dialplan.
  • autofallthrough=yes ist die Default-Einstellung, die wir hier explizit nochmal auflisten. Wenn ein Dialplan für eine Extension abgelaufen ist, dann legt Asterisk in jedem Fall auf. Das halte ich für sicherer.
  • extenpatternmatchnew=no. Wir bleiben beim Klassiker, da wir nur relativ wenige Extensions haben.
  • clearglobalvars=no. Globale Variablen behalten, wenn der Dialplan neu geladen wird.
  • userscontext=unspecified. Eine wirklich wichtige Einstellung, die einen Default-Kontext für eingehende Anrufe definiert, für die kein anderer Kontext gefunden werden kann. Wir leiten solche Anrufe explizit nach "unspecified" und definieren diesen Kontext auch als leer bzw. "nicht erlaubt". Der Standardwert wäre "default" und wenn tatsächlich ein gleichnamiger Kontext definiert wäre, dann könnte der unerwünsche Anrufer eventuell auf unsere Kosten telefonieren.

Daher defnieren wir als nächstes einen Kontext, in den wir alle Anrufer umleiten, die wir nicht kennen und nicht haben wollen. Das werten wir als Angriffsversuch und erzeugen einen Eintrag im Log:

[unspecified]
; wer hier landet ist entweder schlecht konfiguriert oder hat keine "Rechte"

exten => _X.,1,Answer()
exten => _X.,2,Verbose(D E F A U L T ==> ${CALLERID(num)} kam um ${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)} in UNSPECIFIED an als er versuchte die Nummer ${EXTEN} anzurufen.)
exten => _X.,3,Hangup()

Als nächstes müssen wir die Kontexte anlegen, die wir in pjsip.conf referenziert haben. Für Anrufe von unseren internen Telefonen landen wir hier:

[internalsip]
; in den Kontext gelangt man, wenn man einen Call
; von den internen Telefonen startet

; direkt einzelne User anwaehlen
exten => contact_name1,1,Dial(PJSIP/contact_name1)
exten => contact_name2,1,Dial(PJSIP/contact_name2)

;Mailboxabfrage von intern ohne PIN
exten => mailboxname,1,VoiceMailMain(mailboxname@mailboxcontext,s)

Die Namen contact_name1, contact_name2 und mailboxname kann man von SIP-Telefonen direkt anwählen, denn SIP kann auch Namen wählen und nicht nur Nummern. Die Anwahl einzelner User dient der internen Kommunikation von einem Telefon zum anderen (z.B. vom Keller ins Dachgeschoß), dabei geht keine Kommunikation nach außen. Gleiches gilt für die Abfrage der Mailbox.

Für die Kommunikation nach Außen über unsere Festnetznummer verwende ich:

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

;international lassen wir nicht zu
exten => _+X.,1,Hangup() 
exten => _00X.,1,Hangup() 

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

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

; Notrufe gehen immer
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()

Die Einträge sind im Wesentlichen selbsterklärend. Der erste Block wählt nationale Nummern, die mit +49 gewählt werden, ins nationale Netz. Internationale Anrufe lassen wir sicherheitshalber nicht zu, zweiter Block. Danach folgen nationale Nummern, die mit 0 gewählt werden, sowie Ortsnetznummern, bei denen Asterisk noch die Vorwahl ergänzt. Zum Schluß folgen sicherheitshalber noch explizit die Notrufnummern.

Zuletzt brauchen wir noch den Kontext für eigehende Anrufe von extern, die wir einfach auf unsere internen Telefone weiterschalten:

[telekom_in] 
; Anrufe von extern via Telekom
; 30 Sekunden klingen
exten => meine-rufnummer,1,Dial(PJSIP/mein-telefon,30) 
; danach auf die Mailbox umleiten
exten => meine-rufnummer,n,VoiceMail(mailboxname@mailboxcontext)
exten => meine-rufnummer,n,Hangup()

Dabei ist meine-rufnummer die eigene Festnetznummer (ohne +49, Vorwahl mit 0 und Rufnummer). Diese wird von der Telekom als Extension mitgesendet. Wir leiten den Anruf dann einfach an das Telefon mein-telefon weiter. Das ist der Name, mit dem wir den zugehörigen Endpoint in pjsip.conf konfiguriert haben. Falls am Telefon niemand abnimmt, dann leiten wir nach 30 Sekunden auf die Mailbox weiter, die wir in voicemail.conf definiert haben.

updated 03.12.2017 Sitemap