Bannière

Métadonnées du document:
[ Auteur : Clockover ][ Création le : 01/11/2007 ][ Dernière modification le : 02/11/2007 ][ Version : 1.1 ]

Mise en place d'une infrastructure VoIP basée sur Asterisk

Introduction:

Cet article me permettra de vous présenter le projet de mise en place d'une infrastructure utilisant l'excellent logiciel qu'est Asterisk. J'ai volontairement passé les détails car de nombreuses sources d'informations sont disponibles sur Internet mais également car l'article deviendrait trop conséquent.

Tout d'abord, Asterisk permet de se servir d'un poste/serveur informatique comme d'un IPBAX (PABX sur IP). Il s'agit d'un logiciel libre diffusé sous Licence GPL et il peut fonctionner sur différentes plateformes comme *BSD, GNU/Linux et Windows.

Logo de Asterisk
Logo de Asterisk

Ce logiciel gère de nombreux protocoles de communication de Voix sur IP comme : H323, SIP, IAX/IAX2. Il peut également se servir de cartes d'extension de type PCI pour router des appels depuis ou vers une ligne analogique/numéris. Il offre de nombreuses fonctions comme la conférence téléphonique, la musique d'attente, les serveurs vocaux, ... C'est un outil qui offre une très grande souplesse, car rien ne nous empêche d'utiliser des scripts systèmes conjointement avec Asterisk ou encore de travailler avec des bases de données diverses.

Présentation du projet:

Le projet est inscrit dans un cadre d'une auto-formation personnelle. Il n'est jamais rentré en production (mais a été mis en place sous forme de maquette fonctionnelle).
Les deux idées initiatrices du projet étaient de pouvoir économiser de la bande passante sur ma liaison WAN de 1024/128 Kbps et de réduire les factures de GSM.

Pour cela, la solution la plus séduisante fut de mettre en place deux serveurs Asterisk:
flecheUn à la maison qui gérerait les appels internes, les boites vocales (sachant que le serveur de mail est en interne) et la défaillance de la connexion ADSL (par perte de synchronisation ou autre) en utilisant une interface vers le réseau téléphonique traditionnel (avec une gestion des priorités).
flecheL'autre sur un serveur dédié kimsufi chez OVH qui permettrait de gérer des callbacks pour les GSM et de répartir les différents appels sur plusieurs lignes SIP/IAX2. (La mise en place d'un serveur vocal qui permettait de rediriger directement les appels entrants vers le téléphone du destinataire aurait pu être réalisé très simplement à partir de là.)

Entre les deux serveurs Asterisk, une liaison trunkée IAX2 permettait d'économiser un maximum de bande passante, tout en évitant d'avoir des problèmes de translation d'adresse liés à la conception du protocole SIP (il fonctionne avec une liaison de contrôle et une de données). L'interconnexion peut être, en plus, chiffrée très simplement avec les nouvelles versions d'Asterisk.

Schéma récapitulatif
Schéma récapitulatif du projet
(1): Serveur Asterisk qui gère les callbacks, les appels entrants et les priorités de routage.
(2): Serveur Asterisk qui gère les postes internes et la messagerie vocale.

Présentation rapide d'Asterisk:

Sous Debian, la commande habituelle : apt-get install asterisk permet bien sûr d'installer tout ce qu'il faut.

1. Configuration

Dans le répertoire /etc/asterisk/, nous trouverons différents fichiers de configuration (que nous reverrons d'une façon plus détaillée):
flecheiax.conf (Définition des postes ou liaisons IAX/IAX2)
flechesip.conf (Définition des postes ou liaisons SIP)
flecheh323.conf (Définition des postes ou liaisons H323)
flecheextensions.conf (Ce fichier permet de définir le routage des appels)
flechevoicemail.conf (Ce fichier gère la fonction de messagerie vocale)
flechezapata.conf (Gestion des différentes canaux physiques du serveur)

Il est à noter que si la configuration de Asterisk est modifiée, il faut la recharger manuellement soit via la console, soit en relançant le service. (Ceci peut être évité, si l'on se sert d'une base de données pour contenir les informations de configuration.)

Pour démarrer/stopper/redémarrer le serveur Asterisk, il suffit de faire:
/etc/init.d/asterisk start/stop/restart

2. La console

Pour gérer l'IPBAX Asterisk, il suffit de taper: asterisk -r ce qui nous fait rentrer dans sa console de gestion

Par défaut, les différentes erreurs apparaîtront en temps réel dans la console. Si pour une raison quelconque, l'on désire rendre cette remonté d'informations plus précises, il suffira de taper: asterisk -r -vv (plus le nombre de v sera élevé, plus il y aura d'informations)

La console ne sert évidemment pas qu'à afficher des événements, elle permet également d'afficher certaines informations comme : les connexions IAX2 actuelles (iax2 show peers), l'historique des dialogues SIP (sip show history)... ou encore d'effectuer certaines actions: transférer un appel (transfer), recharger la configuration (reload).

Toutes les commandes de la console Asterisk sont listées grâce à la commande: help.

Configuration du serveur interne:

Liaison IAX2 et clients (iax.conf)

Les fichiers iax.conf et sip.conf permettent de définir les clients qui pourront s'authentifier sur le serveur via les protocoles IAX/IAX2 et SIP respectivement. Ils sont quasiment identiques.

Certaines lignes seront expliquées à l'aide du symbole « ; » qui sert à insérer un commentaire. (mais là n'est pas le but de l'article)

;La section "general" correspond aux paramètres par défaut appliqués.
[general]
;Il s'agit du point d'entrée du client concerné dans la table de routage téléphonique.
context = default
language = fr
;Permet de rendre prioritaire le flux VoIP si vos équipements réseau le supporte.
tos = lowdelay

;INTERCONNEXION ENTRE LES DEUX SERVEURS ASTERISK
;1. En direction du serveur kimsufi (externe)
[to-kim]
;On ne peut que émettre avec ce type d'utilisateur 
type = peer
auth = md5
;Login et mot de passe identique du côté de l'autre serveur.
username = from-mail
secret = Mot de passe
;Si l'on veut chiffrer le trunk.
;encryption = aes128			
host = adresse IP ou nom d'hôte distant.
trunk = yes
;Permet d'avoir un status détaillé sur le client depuis la console d'Asterisk.
qualify = yes

;2. Venant du serveur kimsufi (externe)
[from-kim]
context = from-kim
;Ce type d'utilisateur ne fpeut que recevoir des appels.
type = user
auth = md5
secret = Mot de passe
trunk = yes
;encryption = aes128

;CLIENTS IAX2
;La partie concernant les postes internes a répété par numéros utilisés.
[Numéro]
context = client
;Ce type peut émettre et recevoir des appels.
type = friend
username = Login
secret = Mot de passe
callerid = Nom affiché 
host = dynamic
mailbox= numéro@default
qualify = yes

Plan de routage (extensions.conf)

Le fichier extensions.conf nous permet de programmer notre IPBAX. Avec lui, nous pourrons définir les actions à entreprendre dans les différentes situations.

;Définition d'une variable "GENERAL" qui permet d'éviter de retaper à chaque fois tous les numéros des postes internes.
[globals]
GENERAL=SIP/101&SIP/102&IAX2/103

;APPELS PROVENANT D'UN POSTE INTERNE
[client]
;APPELS INTERNES
;Si le numéro demandé est un numéro interne (dans ma maquette les numéros internes étaient 101,102,103...).
exten => _1XX,1,Dial(SIP/${EXTEN}&IAX2/${EXTEN},20,tr)
;Si pas de réponse, on redirige vers la boite vocale correspondante (201 pour poste 101, 202 pour poste 202...).
exten => _1XX,2,Voicemail(2${EXTEN:1}@default)
;Et on raccroche.
exten => _1XX,3,Hangup()

;MESSAGERIE
;Si le numéro composé commençait par 2 et possédait 3 chiffres en tout, on appelle la boîte vocale correspondante.
exten => _2XX,1,Answer()
exten => _2XX,2,Wait(1)
;On lance le serveur vocal de la boite vocale.
exten => _2XX,3,VoiceMailMain(${EXTEN}@default)
exten => _2XX,4,Hangup()

;APPELS SORTANTS
;Si on a composé un numéro qui commence par 9, on veut sortir.
;On vérifie que la communication est possible avec le kimsufi.
exten => _9.,1,ChanIsAvail(IAX2/to-kim) 
exten => _9.,2,Dial(IAX2/to-kim/${EXTEN},30,r)
exten => _9.,3,Congestion
;Sinon on tente la ligne de secours.
exten => _9.,104,Dial(Zap/1/${EXTEN},30,r)
exten => _9.,105,Congestion
;Sinon on avertit.
exten => _9.,206,SetLanguage(fr)
exten => _9.,207,Wait(1)
exten => _9.,208,Playback(all-circuits-busy-now)
exten => _9.,209,Hangup

;LOOPBACK DE TEST
;Petit numéro spécial pour débugger les téléphones IP (Micro/Haut-Parleur...).
exten => 99,1,Answer()
exten => 99,2,SetLanguage(fr)
exten => 99,3,Echo()
exten => 99,4,Playback(vm-goodbye)
exten => 99,5,Hangup()

;APPELS PROVENANT DU SERVEUR EXTERNE
[from-kim]
;Appel vers un numéro spécifique.
exten => _1XX,1,Dial(SIP/${EXTEN}&IAX2/${EXTEN},20,t)
exten => _1XX,2,Congestion
;Appel général.
exten => 100,1,Dial(${GENERAL},20,t)
exten => 100,2,Congestion

Messagerie vocale (voicemail.conf)

[general]
format = wav
attach = yes

;Adresse source de la notification par mail.
serveremail = asterisk@domaine.com
fromstring = Nom affiché

;Longueur d'un message vocal maximale (seconde).
maxmessage = 300

;Au bout de combien de seconde, l'enregistrement du message s'arrête-t-il ?
maxsilence = 10

;Nombre maximal d'erreur de mot de passe pour consulter la méssagerie vocale.
maxlogins = 3

;Sujet et corps du mail.
emailsubject=[PBX]: Nouveau message ${VM_MSGNUM} dans la boîte: ${VM_MAILBOX}
emailbody=Bonjour ${VM_NAME},\n\n\tNotification de réception d'un message vocal d'une durée de: ${VM_DUR}\\
(numéro ${VM_MSGNUM})\ndans la boîte vocale: ${VM_MAILBOX} de la part de: ${VM_CALLERID}, le: ${VM_DATE},\\
que vous pouvez consulter quand vous voudrez\nNe pas répondre à ce mail.  Merci!\n\n\t\t\t\t--Asterisk Service--\n

mailcmd = /usr/sbin/sendmail -t

[zonemessages]
paris24=Europe/Pars|'vm-received' Q 'digits/at' R

[default]
Numérodeboîte => Motdepasse,Nom,Adressemail

Compilation du module Zaptel

Pour se servir des interfaces téléphoniques matérielles, il faut disposer du module noyau approprié. Dans la majorité des cas, il suffira de se servir de votre gestionnaire de paquet pour installer le module précompilé. Dans mon cas, au moment de la maquette la machine tournait sur un noyau compilé par moi-même dont je ne disposais plus des sources. J'en profite donc pour indiqué une procédure dans ces cas là. Pour commencer, il faudra télécharger les sources de votre noyau et de Zaptel. Ensuite, faîtes:

cd /usr/src/
tar jxvf linux-version (Extraire les sources du noyau)
ln -s linux-version linux
cd linux
vi Makefiles (Pour modifier le champs EXTRAVERSION de façon à ce qu'il corresponde au résultat d'un uname -r)
make oldconfig && make prepare
make modules_prepare
tar zxvf zaptel-version (Extraire les sources de Zaptel)
cd zaptel-version
make linux26
make install

Interfaces matérielles (zaptel.conf)

Le fichier zaptel.conf permet d'initialiser les interfaces téléphoniques matérielles. Dans cet exemple, une carte clone d'une X100P a été utilisée. Il ne faudra pas oublier de lancer le module Zaptel avec la commande: modprobe wcfxo et pour vérifier que tout fonctionne correctement: ztcfg -vv.

loadzone=fr
defaultzone=fr
fxsks=1

Utilisation et configuration des interfaces (zapata.conf)

Ce Fichier permet lui de définir, associer et configurer les différentes interfaces physiques à Asterisk.

echocancel=yes
usecallerid=yes
context=incoming
signalling=fxs_ks
group = 2
channel => 1

Configuration du serveur externe

Liaison SIP et clients (sip.conf)

Pour gérés les différents provideurs VoIP, il faut se baser sur ce fichier. Sur la maquette, Free avait été utilisé ainsi que VoipBuster.

[general]
context = default
defaultexpirey = 1800
port = 5060
bindaddr = 0.0.0.0
language = fr
dtmfmode = inband

;Ouverture des sessions chez les différents provideurs.
register => login:motdepasse@nomd'hôte
register => login:motdepasse@nomd'hôte

;Définition des liaisons.
[Free]
context = free-in
type = peer
username = Votre numéro de téléphone
fromuser = Votre numéro de téléphone
secret = Mot de passe
host = freephonie.net
insecure = very
qualify = yes	

[voip]
type = peer
host = sip1.voipbuster.com
username = Login
fromuser = Login
secret = Mot de passe
qualify = yes

Liaison IAX2 et clients (iax.conf)

[general]
context = default
language = fr
tos = lowdelay

;INTERCONNEXIONS ENTRES LES DEUX SERVEURS ASTERISK
;1. Appels venant du serveur interne
[from-mail]
context = from-mail
type = user
auth = md5
secret = Mot de passe
trunk = yes
;encryption = aes128

;2. Appels vers le serveur interne
[to-mail]
type = peer
auth = md5
username = from-kim
secret = Mot de passe
;encryption = aes128
host = Adresse IP ou nom d'hôte
trunk = yes
qualify = yes

Plan de routage (extensions.conf)

;Cette partie peut être utilisé si on spécifie des clients directement sur le serveur externe.
;[client]
;Transférer au serveur interne.
;exten => _1XX,1,Dial(IAX2/to-mail/${EXTEN},30,tr)
;exten => _1XX,2,Voicemail(2${EXTEN:1}@default)
;exten => _1XX,3,Hangup()
;Inclure également le routage du contexte "from-mail".
;include => from-mail

;Venant du serveur interne.
[from-mail]
;Appels sortants.
exten => _90XXXXXXXXX,1,Dial(SIP/free/${EXTEN:1})
exten => _90XXXXXXXXX,1,Dial(SIP/voip/${EXTEN:1})
;D'autres extensions sont à prévoir pour les numéros spéciaux, urgences...

;Venant de la ligne free.
[free-in]
;1. Soit on redirige vers le serveur interne qui fera sonner les postes
;exten => s,1,Dial(IAX2/to-mail/${EXTEN},30,tr)
;2. Soit on utilise les callbacks (dans l'exemple l'authentification se fait sur le numéro de l'appelant,\\
;il est possible de mettre un système de code)
exten => s/numérodel'appelant,1,system(echo -e "Channel: SIP/free/${CALLERIDNUM}\\nMaxRetries: 2\\nRetryTime:\\
10\\nWaitTime: 20\\nContext: recall\\nExtension: s\\nPriority: 1" > /tmp/recall.call) 
exten => s/numérodel'appelant,2,system(sh /etc/asterisk/recall.sh &)
exten => s/numérodel'appelant,3,system(echo "${DATETIME} - ${CALLERID} - ${CHANNEL}" >> /tmp/recall.log)
exten => s/numérodel'appelant,4,Hangup()

;Callbacks
[recall]
exten => s,1,Wait(2)
exten => s,2,SetLanguage(fr)
exten => s,3,SIPDtmfMode(inband)
;Demande d'authentification (optionel vu que l'on vérifie le numéro de l'appelant).
;exten => s,4,Authenticate(Motdepasse)
;Demande de taper le numéro sur lequel être redirigé.
exten => s,5,Playback(vm-enter-num-to-call) 
exten => s,6,WaitExten()
;Si numéro interne, direction le serveur interne.
exten => _1XX,1,Dial(IAX2/to-mail/${EXTEN},30,r)
;Sinon, on ressort.
exten => _9.,1,Dial(SIP/voip/${EXTEN:1},30,r)

Script de callback

#!/bin/sh
#On crée un nom de fichier unique pour éviter les écrasements.
fn="/tmp/$$.`date +%s`"
mv /tmp/recall.call $fn
sleep 15
#On déplace l'appel dans la "queue" de sortie.
exec mv $fn /var/spool/asterisk/outgoing

Le mot de la fin

Et voilà, nous avons donc la maquette illustrée au début de l'article entièrement fonctionnelle.
J'espère que cet article vous a donné goût à ce système, qu'il vous montre un bon aperçu de ce qu'il est capable de faire mais également qu'il vous propose des idées sur lesquelles potasser pour obtenir ce que vous recherchez.
Je tiens à signaler que le script de callback n'est pas de moi (vous trouverez la source dans les liens plus bas).
Si vous trouvez une erreur dans cet article, merci de m'en faire part.

Pour aller plus loin

Bien sûr comme d'habitude, je vous invite à découvrir le manuel d'Asterisk (man asterisk).

Le site officiel d'Asterisk (US) : ici
Le site officiel du projet Asterisk pour Windows (US) : ici
AsteriskGuru (une mine d'informations avec de nombreux tutoriaux) (US) : ici
Asterisk-France (Site communautaire francophone au sujet d'Asterisk) (FR) : ici
Récapitulatif sur les différents codecs VoIP (US) : ici
SOS-Admin (Sujet: Asterisk et les callbacks) (FR) : ici
Calculer la bande passante nécessaire pour des canaux VoIP (suivants les codecs...) (US) : ici
Connaitre l'état de sa connexion pour la VoIP (US) : ici
(US) : ici

Il y a 0 commentaire(s) sur ce sujet.
L'intégralité du portail est placé sous licence Creative Commons License NC v2.0 (sauf mentions contraires indiquées sur les pages et/ou documents concernés !). Version: 4.2
Ce portail répond normalement aux critères de compatibilité XHTML v1.1 et CSS v2.0 du W3C:
Valid XHTML 1.1! Valid CSS 2.0!

Page générée en 0.006 secondes