Nummern en masse
Ein paar Telefone trägt man mal schnell in Asterisks Konfigurationsdateien ein. Mit ein paar hundert Geräten sieht das schon anders aus - zumal, wenn dafür anderswo gespeicherte Informationen zu duplizieren sind.
- Thilo Rößler
Prinzipiell erweist sich die Einrichtung von SIP-Accounts in einer Textdatei wie der sip.conf meist als einfach. Nicht so einfach ist jedoch unter Umständen das Bearbeiten dieser Daten im großen Stil und deren Verknüpfung mit verwandten Informationen. Beispielsweise gehört ein Telefon fast immer zu einer bestimmten Person im Unternehmen. Informationen über diese befinden sich vorzugsweise in einer Datenbank oder einem Verzeichnisdienst - sie in der Asterisk-Konfiguration zu wiederholen ist aufwendig und fehlerträchtig.
Konsequent durchdacht ist also die Speicherung der sip.conf-Daten in einem Verzeichnisdienst wünschenswert. Zwar bietet Asterisk im Lieferzustand keinen Zugriff auf LDAP-Verzeichnisse, er lässt sich aber nachrüsten. Dazu muss man jedoch in den sauren Apfel beißen und den Server neu kompilieren.
Unter www.asterisk-ev.org/astirectory.php sind Patches des Astirectory-Projekts von Eric Sesterhenn und Norbert Graf zu finden, sowohl für die produktive Version 1.0.9 als auch für den aktuellen Entwicklungszweig. Wie bislang wird es hier nur um Erstere gehen. Nach dem Entpacken des Asterisk-Quellcodes und dem Wechsel in das dabei entstehende Verzeichnis spielt patch -p1 < Patchdatei den Patch ein. Zum erfolgreichen Übersetzen sind neben den im ersten Artikel beschriebenen Voraussetzungen die LDAP-Bibliotheken erforderlich. Suse-Linux stellt sie im Paket openldap2-devel zur Verfügung, andere Distributionen bieten Ähnliches.
Im Folgenden kommt OpenLDAP als Verzeichnisdienst zum Einsatz. Die benötigte Schema-Datei ist ebenfalls unter der weiter oben angegebenen URL zu finden, dazu existiert eine kleine Beispieldatei im LDIF-Format, die als Basis für eigene Daten dienen kann.
Zur Nutzung von LDAP muss sip.conf die relevanten Verbindungsdaten enthalten:
[general]
context=default
port=5060
bindaddr=0.0.0.0
srvlookup=yes
ldaphost=10.1.1.2
ldapuser=cn=Manager,dc=example,dc=com
ldappass=secret
ldapbasedn=dc=example,dc=com
ldaphost ist die IP-Adresse oder der Name des anzusprechenden LDAP-Servers. Lauscht er nicht auf dem Standard-Port, muss die Portnummer durch einen Doppelpunkt getrennt folgen. Der als ldapuser angegebene „Distinguished Name“ (DN) muss entweder im Verzeichnisdienst existieren oder in der OpenLDAP-Konfigurationsdatei slapd.conf als rootdn definiert sein. Das zugehörige Passwort ist analog im Verzeichnisdienst oder in der Konfigurationsdatei gesetzt. ldapbasedn heißt ein Knoten im Baum des Verzeichnisdienstes, von dem an die Suche nach den benötigten Informationen erfolgt.
Da bei der Anmeldung eines SIP-Geräts das Ändern von Attributen nötig ist, kommt an dieser Stelle die immer zum Schreiben berechtigte rootdn zur Anwendung. Im Produktivbetrieb sollte man dieses Vorgehen aus Sicherheitsgründen vermeiden. Beim bloßen Testen erspart es allerdings das Anlegen eines geeigneten Benutzers samt zugehöriger Rechtevergabe.
LDAP-Schema fĂĽr Asterisk-Daten
Die Namen der Objektklassen und Attributtypen entsprechen soweit möglich den aus den Asterisk-Konfigurationsdateien bekannten. Kennzeichnend ist das jeweilige Präfix ast. Zwar lassen sich die eigentlichen Daten per Kommandozeile pflegen, allen, die einen grafischen Editor bevorzugen, sei jedoch Luma wärmstens ans Herz gelegt (luma.sourceforge.net).
Einen Beispieleintrag im Verzeichnisdienst zeigt Listing 1. Das Objekt ist eine Instanz der Klassen inetOrgPerson (organizationalPerson und person sind deren Vorgänger in der Vererbungshierarchie) und astSipFriend (auch hier mit den Vorgängern in der Hierarchie). Die Informationen über eine Person und das zugehörige Telefon verwaltet OpenLDAP somit zusammen in einem Objekt. Das Attribut displayName ist zwar nicht zwingend erforderlich, wird aber in Kürze hilfreich sein.
Listing 1
Statt in sip.conf kann man Telefondaten zusammen mit den ĂĽbrigen Benutzerinformationen in LDAP-Verzeichnissen ablegen.
dn: cn=Hugo Schulz, dc=example,dc=com
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: astSipGeneric
objectClass: astSipPeer
objectClass: astSipFriend
sn: Schulz
cn: Hugo Schulz
displayName: H. Schulz (Marketing)
astName: 100
astUsername: 100
astSecret: 123456
astHost: dynamic
astContext: default
Sind diese Informationen im Verzeichnisdienst vorhanden, sollte Asterisk ein SIP-Gerät authentifizieren können, das sich mit dem Namen „100“ und dem Kennwort „123456“ anmeldet. Das CLI-Kommando sip show peers zeigt den so angelegten SIP-Account allerdings nicht, da es seine Werte aus einer einmalig beim Asterisk-Start oder beim Neuladen der Konfigurationsdateien generierten Liste bezieht. Die konkrete Frage nach einem speziellen Peer mit sip show peer 100 bringt jedoch den gewünschten Erfolg. Nun sollte das Endgerät erreich- und benutzbar sein.
Mit dem Zusatzprogramm LDAPget lässt sich der beim Angerufenen im Display angezeigte Name aus dem Verzeichnisdienst auslesen. Seine Quellen sind unter www.mezzo.net/asterisk/app_ldap.html zu finden. Nach ihrem Entpacken genügt es im Allgemeinen, als root make install auszuführen. Ist Asterisk nicht im Standardpfad installiert, muss man vorher den Modulpfad im makefile eintragen. Nach der korrekten Installation sollte der CLI-Befehl show application LDAPget Informationen zu LDAPget ausgeben.
Wie LDAPget arbeitet, hängt von der Datei ldap.conf im Asterisk-Konfigurationsverzeichnis ab. Sie könnte zum Beispiel so aussehen:
[getCallerIDName]
host = 10.1.1.2
user = cn=Manager,dc=example,dc=com
pass = secret
base = dc=example,dc=com
filter = (&(objectClass=inetOrgPerson)(astName=%s))
attribute = displayName
Der Suchfilter legt fest, dass LDAPget bei Verwendung des Musters getCallerIDName nach Objekten der Klasse inetOrgPerson sucht, bei denen das Attribut astName den beim Aufruf von LDAPget im Wählplan übergebenen Wert hat. Der Wählplan bekommt in diesem Fall das LDAP-Attribut displayName zurückgeliefert, weil es in jedem Objekt nur einmal vorkommen darf - anders als Attribute wie sn und cn. displayName kann außerdem eine verkürzte oder umgangssprachliche Version des Namens einer Person enthalten.
Namen statt Nummern anzeigen
LDAPget verwendet anders als aktuelle OpenLDAP-Installationen noch die Version 2 des LDAP-Protokolls. Daher muss es durch die Zeile allow bind_v2 in slapd.conf das Recht zur Nutzung dieses Protokolls bekommen. Danach ist ein Neustart von OpenLDAP erforderlich.
Eine kleine Ergänzung in extensions.conf stellt sicher, dass der Name des Anrufers im Display erscheint:
[macro-anrufintern]
exten => s,1,LDAPget(CALLERIDNAME= getCallerIDName/${CALLERIDNUM})
exten => s,2,Dial(SIP/${MACRO_EXTEN},${RINGTIME})
exten => s,3,Goto(s-${DIALSTATUS},1)
exten => s-NOANSWER,1,Voicemail(u${ARG1})
exten => s-BUSY,1,Voicemail(b${ARG1})
exten => _s-.,1,Goto(s-NOANSWER,1)
Bevor nun ein SIP-Telefon klingelt, wird der Variablen CALLERIDNAME der vom Abschnitt getCallerIDName ermittelte Wert aus dem Verzeichnisdienst zugewiesen. Dazu bekommt das Script die CALLERIDNUM (die Nummer des Anrufenden) übergeben. Beim Aufbau des Gesprächs sendet Asterisk den Inhalt von CALLERIDNAME als Name des Anrufenden an das SIP-Gerät. Wer in seinem Verzeichnisdienst Informationen und Telefonnummern von Kunden pflegt, kann analog auch deren Namen anzeigen lassen.
Zur Ablage von Informationen bringt Asterisk eine kleine Datenbank zum Speichern von Schlüssel-Wert-Paaren mit. Jedes Paar kann zu einem Bereich gehören. Mit dieser Datenbank lässt sich etwa eine eigene Wahlwiederholung unabhängig vom eingesetzten Endgerät definieren. Zum Setzen und Auslesen der Daten dienen DBput und DBget, die beide im Wählplan verwendbar sind.
[default]
exten => _ZXX,1,Macro(anrufintern,${EXTEN})
exten => *5,1,DBget(toCall=redial/${CALLERID})
exten => *5,2,Macro(anrufintern,${toCall})
exten => *5,102,Hangup()
[macro-anrufintern]
exten => s,1,LDAPget(CALLERIDNAME=getCallerIDName/${CALLERIDNUM})
exten => s,2,DBput(redial/${CALLERIDNUM}= ${ARG1})
exten => s,2,Dial(SIP/${ARG1},${RINGTIME})
exten => s,3,Goto(s-${DIALSTATUS},1)
exten => s-NOANSWER,1,Voicemail(u${ARG1})
exten => s-BUSY,1,Voicemail(b${ARG1})
exten => _s-.,1,Goto(s-NOANSWER,1)
Diese Zeilen erweitern das Macro anrufintern so, dass es vor dem Verbinden zur Gegenstelle mit dem DBput-Programm das Paar CALLERIDNUM/Rufnummer in den Bereich redial schreibt. Bereiche mĂĽssen vor ihrer Verwendung nicht explizit deklariert werden.
Zum Auslesen der so festgehaltenen Informationen mit DBget dient die Durchwahl *5 (Durchwahlen mĂĽssen nicht numerisch sein). Ihre Wahl veranlasst Asterisk, aus dem Bereich redial den Wert zu ermitteln, der dem aktuellen Anrufer zugeordnet ist, und in toCall zu schreiben. Die ermittelte Nummer ruft er im Anschluss per Macro an. Existiert kein passender Wert in der Datenbank, legt Asterisk auf.
Im vollständigen Artikel der Printausgabe ist außerdem zu lesen, wie man zwei Asterisk-Systeme verbindet und wie externe Skripte für mehr Komfort sorgen.
iX-TRACT
- Konfigurationsdaten fĂĽr einzelne Telefone kann Asterisk mit einem Patch aus LDAP-Verzeichnissen beziehen.
- Zwei APIs ermöglichen den Einsatz von Scripts für ein- und ausgehende Anrufe, beispielsweise zur Anzeige der Anrufernamen.
- Mehrere Asterisk-Server lassen sich untereinander per IAX2-Protokoll vernetzen, etwa fĂĽr die Verbindung von Filialen mit der Zentrale.
Teil I: EinfĂĽhrung, Installation, Anbindung von Softphones.
Teil II: Komplexe Wählpläne, ISDN-Anbindung, Anrufbeantworter und Berechtigungen. (ck)