Retrouvez cet article dans : Linux Magazine Hors série 37
Parmi les lecteurs de GLMF, je suis sûr qu’une bonne partie a déjà entendu parler de la Voix sur IP ou VoIP dans le langage des lutins. Si ce n’est pas le cas, accrochez-vous bien, car vous êtes à quelques minutes de découvrir la liberté.
Pour faire de la publicité des discussions rincées de Gintonix, la VoIP est tout simplement le service de téléphonie offert par la majorité des FAI. De manière vulgarisée, votre BlahBox va s’authentifier via le net sur un serveur dit " registrar ", ce qui vous permettra ensuite de passer des appels en France, en Europe et ailleurs pour des prix variant de 0 à x (x étant indéterminable, mais tendant souvent vers 0).
Cet article a pour but de vous guider, tout au long de la mise en place de l’architecture nécessaire, sur votre serveur dédié, pour récupérer votre ligne de téléphone fixe où que vous soyez dans le monde. Cette installation consistera au couplage d’OpenVPN, qui nous servira à ériger un réseau privé chiffré, et d’Asterisk, qui fera de notre serveur un commutateur téléphonique.
|
1 |
Scénario |
Vous voilà parti sur la route de l’inconnu équipé bien entendu de votre joli portableee. Vous êtes bien trop loin de chez vous, vous allumez votre portable pour y transférer quelques photos, et là, *surprise*, il y a un lien wifi ouvert qui rôde dans les parages ! Merveilleux ! Vous vous y connectez, vous lancez OpenVPN (qui se connecte sur votre serveur dédié) et votre softphone préféré (qui se connecte sur votre Asterisk dédié), et vous voilà téléporté chez vous ! Vous pouvez alors appeler votre famille & vos amis de votre ligne fixe française. Magique !
Viennent alors les questions. Mais, tout ce système, je pourrais le mettre sur ma machine à la maison et m’y connecter quand je me déplace. Mais, qui a envie de laisser son ordinateur allumé 24h/24 pendant qu’il va gambader dans le monde à des centaines et des centaines de kilomètres de là ? Et si votre système prenait feu ? Et s’il y avait une coupure de courant ? Un dégât des eaux ? Une canicule qui fait surchauffer mon matériel ? Et j’en passe. La solution ultime qui, au-delà des problèmes de sécurité physique, règle aussi les problèmes de bande passante, est le serveur dédié.
Oui. Votre serveur dédié aura une bande passante bien supérieure (en débit montant et descendant), ainsi qu’une adresse IP fixe, et sera posé bien au frais dans une salle toute climatisée dans laquelle il se sentira si bien qu’il ne voudra pas se reposer une seule seconde. :)
|
2 |
Installation et configuration d’OpenVPN |
|
Note |
|
|
Étant donné que les *BSD et les Linux n’installent pas les ports ou packages selon la même arborescence, dans la suite de cette partie, j’emploierai la variable $PREFIX qui prendra les valeurs suivantes : Pour Linux : PREFIX="/etc/openvpn" Pour FreeBSD : PREFIX="/usr/local/etc/openvpn" |
Un des premiers bonheurs à mettre en place lorsqu’on configure un serveur dédié est de monter un réseau chiffré privé entre vos différentes machines à l’aide d’OpenVPN.
Cette partie de l’article décrit une configuration générique d’OpenVPN et peut donc être utile dans divers autres schémas d’utilisation que celui d’Asterisk.
Dans un premier temps, nous verrons la génération des clés et certificats liés à votre serveur et à vos clients. Puis, nous remplirons les fichiers de configurations de chacun.
Commençons tout d’abord par installer OpenVPN.
Sur une Debian (ou Ubuntu) :
|
sudo apt-get install openvpn |
Sous FreeBSD :
|
cd /usr/ports/security/openvpn && make install clean |
|
2.1 |
Installation & Génération des clés |
La première étape sera de créer les dossiers, qui vous serviront par la suite pour y mettre vos fichiers de configurations.
Pour Linux et/ou FreeBSD : mkdir $PREFIX && mkdir $PREFIX/work && mkdir $PREFIX/keys.
À ce moment précis, c’est avec grand plaisir que vous découvrirez qu’OpenVPN propose des scripts tous prêts qui vous serviront à générer les clés et certificats nécessaires à la sécurisation des échanges. Étant donnés les emplacements différents, une 2ème variable est nécessaire : $SCRIPTS.
Pour Debian (et Ubuntu) : SCRIPTS=”/usr/share/doc/openvpn/examples/easy-rsa/2.0”.
Pour FreeBsd : SCRIPTS=”/usr/local/share/doc/openvpn/easy-rsa/2.0”.
Copions alors ces fichiers dans le dossier $PREFIX/work que nous avons créé précédemment :
|
cp -Rv $SCRIPTS/* $PREFIX/work/ && cd $PREFIX/work/ |
Pour faciliter la tâche qui suit, nous allons commencer par éditer le fichier $PREFIX/work/vars qui sera lu lors des différentes générations. Voilà ce que vous avez à changer :
|
(...) export EASY_RSA="$PREFIX" (...) export KEY_SIZE=2048 # <- pour les paranos (...) export KEY_COUNTRY=FR export KEY_PROVINCE=NA export KEY_CITY=PARIS export KEY_ORG="Ghantoos OpenVPN" export KEY_EMAIL="ghantoos@ghantoos.org" |
Pour prendre en compte les nouvelles variables d’environnement définies dans le fichier vars, tapez :
source ./vars (Rappel : nous sommes là dans $PREFIX/work/)
|
./clean-all (au cas où) |
Commençons à tout calculer.
|
2.1.1 |
Certification Authority |
Une Certification Authority est une paire de clés publique/privée servant à signer les autres clés publiques générées (auto-certification) :
./build-ca (vous y trouverez les variables éditées dans le fichier //vars//)
|
2.1.2 |
Certificat du serveur |
Créons maintenant le certificat du serveur. La commande suivante ajoutera server.crt raoul-work.csr et raoul-work.key dans $PREFIX/work/keys/ :
|
./build-key-server server |
Ce certificat est bien sûr signé par le CA généré au-dessus.
|
2.1.3 |
Construction des paramètres Diffie Hellman |
Les paramètres Diffie Hellman nous fournissent un moyen de sécuriser la négociation initiale effectuée sur un lien non sécurisé. Cette commande peut durer quelques minutes :
|
./build-dh |
|
2.1.4 |
La clé TLS |
L’authentification TLS rajoute une signature HMAC à tous les packets de handshake afin de vérifier l’intégrité de ceux-ci :
|
openvpn --genkey --secret $PREFIX/keys/ta.key |
|
2.1.5 |
Les clés des clients |
Ce sera la dernière étape de préparation de notre sécurisation d’OpenVPN. À l’intention de chaque client qui se connectera sur votre VPN, vous allez devoir construire une clé :
|
./build-key pinpin ./build-key ghantoos ./build-key stariles |
|
2.1.6 |
Envoi des clés aux clients |
Afin d’accomplir cette tâche, on utilisera SCP. Pour le client pinpin, il vous faudra envoyer ca.crt pinpin.crt pinpin.key et ta.key :
|
cd $PREFIX/openvpn/keys/ && scp ca.crt pinpin.crt pinpin.key ta.key IP_de_pinpin:$PREFIX/ |
Maintenant que nous avons les clés en main, nous pouvons nous lancer dans la configuration de notre serveur et de nos clients.
|
2.2 |
Les fichiers de configuration d’OpenVPN |
|
2.2.1 |
Configuration du serveur dédié |
Pour configurer notre serveur, il nous faudra tenir compte de :
? nos clés et certificats générés dans la première partie de l’article ;
? l’IP et le port sur lequel le serveur VPN écoutera ;
? l’IP privée du serveur VPN ;
? l’intervalle d’IP allouées aux clients.
J’ai choisi de vous montrer la configuration de réseau " routé " d’OpenVPN, l’autre choix étant le mode " bridgé " [2]
Les autres options seront commentées dans le fichier de configuration type que voici :
|
# Server Config local xxx.xxx.xxx.xxx # mettre l’IP de votre serveur port 5050 # port de messagerie instantanée, souvent ouvert : ) proto tcp dev tun # mode routé server 10.10.10.0 255.255.255.0 # IP du serveur 10.10.10.1 # Sécurité & Certificats ca $PREFIX/keys/ca.crt cert $PREFIX/keys/server.crt key $PREFIX/keys/server.key dh $PREFIX/keys/dh2048.pem tls-auth $PREFIX/keys/ta.key 0 # Autre config keepalive 10 120 comp-lzo # compression LZO user nobody group nogroup persist-key # ne pas relire les clé en cas de perte de connectivité persist-tun # ne pas éteindre le tun en cas de perte de connectivité log openvpn.log verb 3 # Clients configuration client-config-dir ccd # dossier de configuration par client client-to-client # permet la communication entre clients # Routes annoncées par les clients route 192.168.50.0 255.255.255.0 # déclaration des route à venir (voir config client) |
|
2.2.2 |
Configuration des clients |
Maintenant que nous avons configuré notre serveur OpenVPN, nous allons configurer les différents clients qui auront accès à notre " réseau privé ". Cela pourra être votre ami en Chine, votre copain ou copine encore ailleurs ou bien tout simplement toutes vos différentes machines (bureau, maison, parents, etc.). Ainsi, vous aurez accès au service téléphonique de votre FAI où que vous soyez !
|
2.2.2.1 |
Chez le client |
Pour configurer notre client, il nous faudra tenir compte :
? des clés et certificats générés dans la première partie de l’article ;
? de l’IP et du port sur lequel nous nous connecterons au serveur VPN.
Les autres options seront commentées dans le fichier de configuration type que voici :
|
# Config client client dev tun # réseau routé proto tcp remote xxx.xxx.xxx.xxx 5050 # IP et port du serveur # Sécurité & Certificats ca /home/ghantoos/.openvpn/ca.crt cert /home/ghantoos/.openvpn/raoul-home.crt |
|
key /home/ghantoos/.openvpn/raoul-home.key tls-auth /home/ghantoos/.openvpn/ta.key 1 ns-cert-type server # Autres options comp-lzo resolv-retry infinite # reconnections automatiques "infinie" persist-key persist-tun verb 3 mute 20 # limitation des répétitions dans les logs ping 10 |
|
2.2.2.2 |
Sur le serveur dédié |
La configuration d’un client sur le serveur servira à :
? fixer son adresse IP privée ;
? lui permettre d’annoncer des routes qu’il connaît (vers son réseau local par exemple..) ;
? lui annoncer les routes privées d’autres clients OpenVPN.
Voici le fichier de configuration type. Celui-ci devra se placer dans le dossier $PREFIX/ccd et portera le même nom que notre client :
|
# IP statique # adresse IP fixe de pinpin: 10.10.10.20 ifconfig-push 10.10.10.20 10.10.10.21 # Les routes de mon réseau local iroute 192.168.50.0 255.255.255.0 # Les routes du réseau local d’autres clients: push "route 10.29.31.0 255.255.0.0" |
|
2.3 |
Démarrage d’OpenVPN |
Nous voilà donc en présence d’un serveur OpenVPN prêt à être utilisé lors de la deuxième partie de l’article.
Démarrons donc le serveur, puis le client.
Sur le serveur OpenVPN :
Linux :
|
/etc/init.d/openvpn start |
FreeBSD :
|
/usr/local/etc/rc.d/openvpn start |
Sur le client (je préfère démarrer le client dans un screen.. c’est bien plus pratique..) :
Linux :
|
/usr/bin/screen -dmS plop /usr/bin/screen -x plop /usr/sbin/openvpn /etc/openvpn/pinpin.conf |
FreeBSD :
|
/usr/local/bin/screen -dmS plop /usr/local/bin/screen -x plop /usr/local/sbin/openvpn /usr/local/etc/openvpn/pinpin.conf |
OpenVPN reste un monde à part entière dans lequel je vous conseille vivement de vous plonger. Le site officiel [1] est très riche en documentation et bien sûr un man OpenVPN pourra vous apporter des réponses et de nombreuses idées.
|
3 |
Installation et configuration d’Asterisk |
|
3.1 |
Un peu de théorie ne fait jamais de mal |
|
3.1.1 |
Architecture |
Ainsi que je l’ai annoncé au début de l’article, nous allons bâtir notre infrastructure autour du protocole de VoIP SIP. Voici l’architecture que nous voudrions mettre en place (voir Figure 1) :
? Un OpenVPN précédemment configuré pour avoir votre réseau privé chiffré (sur serveur dédié).
? Une patte de l’Asterisk ira s’enregistrer auprès de votre FAI (sur serveur dédié).
? Une patte de l’Asterisk écoutera sur l’IP OpenVPN pour enregistrer vos utilisateurs (sur serveur dédié).
? Trois utilisateurs seront configurés et enregistrés (sur machines clientes).
|
|
|
Figure 1 : Architecture |
|
3.1.2 |
Enregistrement |
Il est bien entendu qu’il faudra que vos utilisateurs s’enregistrent afin de passer ensuite leurs appels. Voyons comment cette authentification aura lieu.
Afin de ne pas envoyer votre mot de passe en clair à travers le réseau, la méthode d’authentification employée est le DIGEST over SIP (à l’image du DIGEST over HTTP) :
? L’utilisateur envoie un message REGISTER sans mot de passe.
? Le serveur lui renvoie une réponse 401 en lui donnant une clé de chiffrage.
? L’utilisateur fait alors un calcul " irréversible " à partir de la clé et de son mot de passe qu’il renvoie dans un nouveau REGISTER au serveur.
? Le serveur fait à son tour ce calcul, et le compare avec le contenu du message reçu. Si le résultat est identique, alors il vous renvoie un message 200 OK : vous êtes enregistrés.
Voici le callflow typique d’un enregistrement réussi :
|
|
|
Figure 2 : Enregistrement |
|
3.1.3 |
Appel sortant |
En dehors du message REGISTER que nous avons vu, voici la liste des messages SIP les plus fréquemment rencontrés : INVITE, 100 TRYING, 180 RINGING, BYE et 200 OK. Leurs noms résument assez bien leur fonction lors de l’établissement d’un appel.
Voici le callflow d’un appel allant de l’intérieur de notre VPN vers un numéro national :
|
|
|
Figure 3 : Appel sortant |
|
3.1.4 |
Appel entrant |
Dans notre configuration, 3 utilisateurs seront enregistrés sur notre Asterisk, mais seuls pinpin et ghantoos pourront recevoir des appels entrants. Ci-dessous, le callflow d’un appel entrant récupéré par ghantoos :
|
|
|
Figure 4 : Appel entrant |
|
3.1.5 |
La problématique du NAT |
Le problème du NAT dans la VoIP est un coup classique. En effet, le message SIP contient des informations relatives à l’adressage IP des clients. Quand A appelle B en passant par un serveur intermédiaire, le routage des messages de signalisation (SIP) se fait de manière classique. Jusqu’ici tout va bien, les téléphones sonnent, mais on n’entend rien. En fait, la destination (IP et port) des flux vocaux est donnée à l’intérieur du message SIP (plus précisément dans la SDP ou Session Description Protocol). Eh oui, vous voyez bien le souci.. Si B a une adresse publique et qu’il essaie de joindre A sur son adresse privée NATée (e. g. 10.10.10.10), la voix n’arrivera jamais à destination !
|
|
|
Figure 5 : Problématique NAT |
Afin de pallier cette complication, il est impératif que le registrar soit capable d’éditer les messages SIP et plus particulièrement la SDP des messages pour y modifier les données relatives à l’adressage IP. Il faut donc remplacer toutes les occurrences de 10.10.10.10 au niveau de la couche applicative en 99.99.99.99. Heureusement, Asterisk est capable de faire ce travail là. Il nous faudra tout simplement déclarer notre réseau privé. Ainsi, quand Asterisk recevra un message venant de la plage d’IP en question, il saura que faire. Cette configuration est d’une simplicité déroutante ! Voici la directive à renseigner dans le fichier sip.conf :
|
localnet=10.10.10.0/255.255.255.0 |
|
3.2 |
Modélisation |
Afin de pouvoir débuter la configuration de notre cher IPBX, il est nécessaire de poser les règles de numérotations que nous allons suivre.
Nous avons besoin de choisir :
? un préfixe de sortie (ou escape code) afin de contacter les numéros nationaux.
? les utilisateurs pouvant recevoir des appels de l’extérieur.
? les restrictions d’appel affectées aux utilisateurs.
Voici notre choix :
? préfixe de sortie : 9
? recevant les appels de l’extérieur : pinpin et ghantoos
? seul stariles aura des restrictions d’appel :
? interdiction d’appeler sur les mobiles (906).
? interdiction d’appeler à l’étranger (900).
|
3.3 |
Installation & Configuration |
|
Note |
|
Puisque que les *BSD et les Linux n’installent pas les ports ou packages selon la même arborescence, dans la suite de cette partie, j’emploierai la variable $PREFIX qui prendra les valeurs suivantes : Pour Linux : PREFIX="/etc/asterisk" Pour FreeBSD : PREFIX="/usr/local/etc/asterisk" |
Commençons tout d’abord par installer Asterisk.
Sur une Debian (ou Ubuntu) :
|
sudo apt-get install asterisk |
Sous FreeBSD :
|
cd /usr/ports/net/asterisk && make install clean |
|
3.3.1 |
Utilisateurs et registrar FAI |
La configuration de l’enregistrement auprès de votre FAI et celle de vos utilisateurs sur votre Asterisk se fait dans le fichier $PREFIX/sip.conf :
? Enregistrement sur le registrar du FAI :
? Utilisateur (et numéro de téléphone fixe) : 0912345678
? Mot de passe : votremotdepasse
? Domaine : fai_registrar.com
? Déclaration de l’utilisateur pinpin:
? mot de passe : lecodeestlibre
? nom de domaine : asterisk (ndd ou realm par défaut)
? context : monreseau (la configuration des context sera expliquée par la suite)
? Déclaration de l’utilisateur stariles :
? context : monreseau-restreint
Afin d’éviter d’écrire le mot de passe de pinpin en clair dans notre fichier de configuration, nous allons utiliser le paramètre md5secret.
Pour calculer le mot de passe en format md5secret, nous utiliserons la commande suivante :
Linux :
|
echo -n "utilisateur:nomd_de_domaine:motdepasse" | md5sum |
FreeBSD :
|
echo -n "utilisateur:nomd_de_domaine:motdepasse" | md5 |
Pour pinpin :
|
echo -n "pinpin:asterisk:lecodeestlibre" | md5 f52697913d853a7216428779d4631a1e - |
Nous pouvons alors remplir notre fichier de configuration :
|
[general] defaultexpirey=1800 ; timeout des enregistrements dtmfmode=auto ; gestion des DTMF qualify=yes ; vérification de présence avant l’envoi des appels bindaddr=10.10.10.1 ; IP d’écoute de la patte privée d’Asterisk bindport=5060 ; port d’écoute de la patte privée d’Asterisk localnet=10.10.10.0/255.255.255.0 ; déclaration de notre réseau local register => 0912345678:votremodepasse@fai_registrar.com ; e.g. freephonie.net ; On refuse tous les codecs à part ceux cités ci-dessous disallow=all allow=ulaw allow=alaw allow=speex allow=gsm [FAI-registrar-out] ; point d’accès SIP pour les appels sortants type=peer host=fai_registrar.com ; e.g. freephonie.net username=0912345678 fromuser=0912345678 secret=votremodepasse [FAI-registrar-in] ; point de sortie des appels type=peer ; déclaration du nœud avec votre FAI context=fromFAI ; utile pour le plan de numérotation & routage host=fai_registrar.com ; votre FAI [pinpin] type=friend ; "friend" autorise un dialogue bidirectionnel au contraire de "peer" username=pinpin md5secret=f52697913d853a7216428779d4631a1e callerid=Pinpin (GCU-Squad) host=dynamic context=monreseau ; utile pour le plan de numérotation & routage [ghantoos] (...) [stariles] type=friend username=stariles md5secret=36f3b2748cea3f5714d849889bb4a0c7 callerid=Stariles host=dynamic context=monreseau-restreint |
|
3.3.2 |
Numéros internes & appels sortants |
Dans la partie modélisation, nous avons vu qu’à la différence de pinpin et ghantoos, stariles avait des restrictions d’appel. Afin de mettre en place ces restrictions, nous allons créer 2 groupes d’utilisateurs :
? monreseau : pour pinpin et ghantoos ;
? monreseau-restreint : pour stariles.
Cette variable se fixe lors de la déclaration de l’utilisateur à l’aide du champ context.
Nous allons maintenant déclarer les groupes, fixer les numéros de téléphone des utilisateurs et leurs règles de numérotation :
|
[monreseau] exten => 10,1,Dial(SIP/pinpin) ; numero interne de pinpin: 10 exten => 11,1,Dial(SIP/ghantoos) ; numero interne de ghantoos: 11 exten => 12,1,Dial(SIP/stariles) ; numero interne de stariles: 12 ; tous les numéros commençant par 9 (d’où le _9) seront routés ; par FAI-registrar-out exten => _9.,1,Dial(SIP/FAI-registrar-out/${EXTEN:1}) [monreseau-restreint] exten => 10,1,Dial(SIP/pinpin) exten => 11,1,Dial(SIP/ghantoos) exten => 12,1,Dial(SIP/stariles) ; Restriction des appels vers les mobiles exten => _906.,1,Playback(invalid) exten => _906.,2,Hangup ; Restriction des appels 0800 exten => _908.,1,Playback(invalid) exten => _908.,2,Hangup ; Restriction des appels internationaux exten => _900.,1,Playback(invalid) exten => _900.,2,Hangup ; Les autres numéros commençant par 9 seront routé par FAI-registrar-out exten => _9.,1,Dial(SIP/FAI-registrar-out/${EXTEN:1}) |
|
3.3.3 |
Appels entrant v1 : routage direct |
Le modèle du routage direct peut s’avérer efficace si vous avez plusieurs téléphones dans la maison et/ou que vous voulez tout simplement faire sonner plusieurs téléphones en même temps lorsqu’un appel arrive (voir Figure 4). Lorsque votre Asterisk reçoit un appel entrant venant de votre FAI, il lui faudra router l’appel vers une ou plusieurs destinations.
La configuration d’un tel scénario est assez simple. Dans $PREFIX/extension.conf, il faudra rajouter :
|
[fromFAI] ; context utilisé par FAI-registrar-in dans sip.conf exten => s,1,Dial(SIP/pinpin&SIP/ghantoos) |
Ainsi, quand un appel arrive sur votre Asterisk, les téléphones de pinpin et ghantoos vont sonner en même temps. Le premier qui décroche aura gagné !
|
3.3.4 |
Appels entrants v2 : portail vocal |
Imaginez que lorsqu’on vous appelle, vous donnez le choix à l’appelant de composer l’extension de l’utilisateur qu’il cherche à joindre. La première extension pourra être votre box à la maison, la deuxième celle du bureau, la troisième celle d’un ami, etc. Avec ceci, vous êtes sûr que tout le monde vous enviera lors de vos soirées branchées dans le bistrot du coin ! Regardons techniquement parlant comment mettre en place un tel service.
Le routage via un serveur vocal interactif est très intéressant. Voici ce que nous allons faire :
? enregistrer un message d’accueil ;
? générer un menu basique qui sera joué à la réception des appels entrants ;
? utiliser les touches [DTMF] du téléphone pour router l’appel vers le bon destinataire.
|
3.3.4.1 |
Enregistrement du message d’accueil |
Il vous est possible d’enregistrer un fichier son en local en utilisant votre application préférée, puis de le convertir au format GSM. Il est possible d’utiliser l’application sox pour faire cette conversion [7] :
|
sox votre_message.wav -r 8000 -c 1 votre_message.gsm |
Après cette conversion, le fichier devra être envoyé sur votre serveur dédié dans le dossier :
Linux (Debian) : /usr/share/asterisk/sounds
FreeBSD : /usr/local/share/asterisk/sounds/
Ceci étant dit, Asterisk nous offre une solution bien plus élégante. En effet, nous allons premièrement mettre en place un SVI (Serveur Vocal Interactif) basique qui nous permettra d’enregistrer les annonces que nous utiliserons par la suite. Il vous suffira alors d’appeler sur votre numéro fixe pour enregistrer votre message d’accueil après le bip et de taper la touche [#] à la fin de votre message pour le réécouter :
|
[fromFAI] exten => s,1,Goto(menu_enregistrement,s,1) [menu_enregistrement] exten => s,1,Answer exten => s,2,Wait(2) exten => s,3,Background(hello-world) exten => s,4,Record(mes-enregistrements%d:gsm) exten => s,5,Wait(2) exten => s,6,Playback(${RECORDED_FILE}) exten => s,7,Wait(2) exten => s,8,Hangup |
Vous pourrez alors trouver les fichier enregistrés (mes-enregistrements0, mes-enregistrements1, etc.) dans le dossier sounds d’Asterisk (voir plus haut pour l’emplacement exact). Nous allons donc enregistrer 2 messages, le premier (mes-enregistrements0) donnera les choix qu’aura l’appelant en tombant sur notre SVI, le deuxième (mes-enregistrements1) préviendra l’utilisateur que la personne qu’il essaie de joindre n’est pas disponible. Vous voyez où je veux en venir. Quand, par exemple, l’appelant fera son choix de joindre pinpin, nous allons d’abord vérifier que pinpin est bien enregistré avant de transférer l’appel. Si ce dernier n’est pas joignable, un message sera joué, et l’utilisateur sera renvoyé au menu principal. :)
|
3.3.4.2 |
Notre SVI d’accueil |
Maintenant que nous avons enregistré nos messages, nous allons mettre en place un SVI (Serveur Vocal Interactif) qui accueillera tous nos appels entrant en donnant le choix suivant à l’appelant :
? Tapez 1 pour joindre pinpin.
? Tapez 2 pour joindre ghantoos.
? Tapez 4 pour joindre nos trois lutins.
? BONUS : Tapez 5 pour joindre le premier utilisateur enregistré.
Notre menu principal devra alors ressembler à ce qui suit :
|
[fromFAI] exten => s,1,Goto(menu_principal,s,1) [menu_principal] exten => s,1,Answer exten => s,2,Wait,2 exten => s,3,SetMusicOnHold(default) exten => s,4,Set(TIMEOUT(digit)=5) exten => s,5,Set(TIMEOUT(response)=5) exten => s,6,Background(mes-enregistrements0) exten => s,7,Goto(s,2) exten => 0,1,Directory(default|maison) ; On met le nom de l’utilisateur à joindre dans ; ${MYUSER} une variable globale (g), puis on ; envoie l’appel au testeur de "joingnabilité": [test_presence] exten => 1,1,Set(MYUSER="SIP/pinpin",g) exten => 1,2,Goto(test_presence,s,1) exten => 2,1,Set(MYUSER="SIP/ghantoos",g) exten => 2,2,Goto(test_presence,s,1) exten => 4,1,Dial(SIP/pinpin&SIP/ghantoos) ; BONUS: Dans ce cas là, c’est le premier utilisateur présent qui sonnera exten => 5,1,Set(MYUSER="SIP/pinpin&SIP/ghantoos",g) exten => 5,2,Goto(test_presence,s,1) [test_presence] ; Nous verifions la présence de ${MYUSER} exten => s,1,ChanIsAvail(${MYUSER}) ; Un "CUT" doit être fait pour récupérer le nom de l’utilisateur (sans son numéro ; de session) s’il est présent, dans le cas contraire, la variable sera vide. ; le "?5:3" signifie: si le "if" renvoie 1 aller à "s,5" => prévenir que l’utilisateur ; n’est pas joignable. Sinon aller à "s,3" => appeler l’utilisateur en question exten => s,2,GotoIf($["${CUT(AVAILCHAN,,1)}" = ""]?5:3) exten => s,3,Dial(${CUT(AVAILCHAN,,1)}) exten => s,4,Hangup exten => s,5,Playback(mes-enregistrements1) exten => s,6,Goto(mainmenu,s,1) |
|
3.4 |
Démarrage d’Asterisk |
Nous avons tout configuré sur notre serveur dédié afin de pouvoir recevoir des appels et appeler d’où qu’on soit via notre FAI. Il n’y aura plus aucune restriction géographique étant donné que la seule IP qui discutera avec votre FAI sera celle de votre serveur dédié. De votre côté, vous pourrez alors configurer autant d’utilisateurs que vous voulez en leur donnant les droits d’accès à votre réseau OpenVPN & Asterisk précédemment mis en place. Vive le serveur dédié et le Libre ! Mais attention à la facture quand même.
Quelques commandes utiles :
Linux :
? debug : /usr/sbin/asterisk -vvvc
? CLI : /usr/sbin/asterisk -r
? Default : /etc/init.d/asterisk start
FreeBSD :
|
Attention |
|
Ajoutez asterisk_enable="YES" dans /etc/rc.conf. |
? debug : /usr/local/sbin/asterisk -vvvc
? CLI : /usr/local/sbin/asterisk -r
? Default : /usr/local/etc/rc.d/asterisk start
|
4 |
Testons le tout |
Pour tester le tout, j’ai choisi d’utiliser le softphone Twinkle qui m’a semblé approprié et que j’utilise pour ma consommation personnelle. :) Pour installer Twinkle sur votre machine (pas sur le serveur dédié bien sûr !) :
Sur une Debian (ou Ubuntu) :
|
sudo apt-get install twinkle |
Sous FreeBSD :
|
cd /usr/ports/net/twinkle && make install clean |
Enregistrons alors notre utilisateur pinpin :
? registrar : 10.10.10.1 (la patte " OpenVPN " de notre Asterisk) ;
? utilisateur : pinpin ;
? domaine : asterisk ;
? mot de passe : lecodeestlibre.
|
|
|
Figure 6 : Configuration Twinkle Pinpin |
Voici les scénarios possibles, associés avec leur tcpdump vus dans wireshark, pour bien voir que non seulement c’est magique, mais c’est beau !
|
Note |
|
Afin d’éclaircir la lisibilité des traces, j’ai modifié le fichier /etc/hosts pour avoir dans les champs source et destination des adresses résolues. |
|
4.1 |
Pinpin -> Ghantoos |
pinpin compose le numéro interne de ghantoos : [11] (voir le fichier extension.conf). Les messages SIP ainsi que le RTP (la voix) sont alors relayés par le serveur dédié :
|
|
|
Figure 7 : tcpdump Pinpin ? Ghantoos |
|
4.2 |
Pinpin -> Mobile français |
Pinpin compose le numéro d’un mobile en prenant garde de taper [9] : 906xxxxxxxx. Les messages SIP et le RTP sont alors relayés par notre serveur dédié au registrar et proxy RTP de notre FAI :
|
|
|
Figure 8 : tcpdump Pinpin ? mobile |
|
4.3 |
Numéro publique -> Pinpin |
Un numéro public appelle sur notre ligne de téléphone, puis appuie sur la touche [1] pour joindre pinpin.
|
|
|
Figure 9 : Numéro public ? pinpin |
|
4.4 |
Numéro public -> tous nos utilisateurs |
Un numéro public appelle sur notre ligne de téléphone, puis appuie sur [4] pour faire sonner tous les utilisateurs actuellement enregistrés. Pinpin répond en premier.
|
|
|
Figure 10 : tcpdump Numéro public ? tout notre réseau |
Voici ce que montre le CLI d’Asterisk pendant cette manœuvre :
|
ghantoos@monserveur~# asterisk -r Asterisk 1.4.10, Copyright (C) 1999 - 2007 Digium, Inc. and others. Created by Mark Spencer <markster@digium.com> Asterisk comes with ABSOLUTELY NO WARRANTY; type ‘core show warranty’ for details. This is free software, with components licensed under the GNU General Public License version 2 and other licenses; you are welcome to redistribute it under certain conditions. Type ‘core show license’ for details. ========================================================================= Connected to Asterisk 1.4.10 currently running on monserveur (pid = 15853) Verbosity is at least 3 -- Executing [s@fromFAI:1] Goto("SIP/FAI-registrar-081ae468", "mainmenu|s|1") in new stack -- Goto (mainmenu,s,1) -- Executing [s@mainmenu:1] Answer("SIP/FAI-registrar-081ae468", "") in new stack -- Executing [s@mainmenu:2] Wait("SIP/FAI-registrar-081ae468", "2") in new stack -- Executing [s@mainmenu:3] SetMusicOnHold("SIP/FAI-registrar-081ae468", "default") in new stack -- Executing [s@mainmenu:4] Set("SIP/FAI-registrar-081ae468", "TIMEOUT(digit)=5") in new stack -- Digit timeout set to 5 -- Executing [s@mainmenu:5] Set("SIP/FAI-registrar-081ae468", "TIMEOUT(response)=5") in new stack -- Response timeout set to 5 -- Executing [s@mainmenu:6] BackGround("SIP/FAI-registrar-081ae468", "mes-enregistrements0") in new stack -- <SIP/FAI-registrar-081ae468> Playing ‘mes-enregistrements0’ (language ‘en’) == CDR updated on SIP/FAI-registrar-081ae468 -- Executing [4@mainmenu:1] Dial("SIP/FAI-registrar-081ae468", "SIP/pinpin&SIP/ghantoos&SIP/stariles") in new stack -- Called pinpin -- Called ghantoos -- SIP/pinpin-081b52b8 is ringing -- SIP/ghantoos-081b9a58 is ringing -- SIP/pinpin-081b52b8 answered SIP/FAI-registrar-081ae468 == Spawn extension (mainmenu, 4, 1) exited non-zero on ‘SIP/FAI-registrar-081ae468’ monserveur*CLI> |
On constate bien que les lignes du fichier extension.conf, plus précisément la partie [menu_principal], s’exécutent tour à tour. :)
|
5 |
Conclusion |
L’époque où il fallait débourser des milliers de francs pour mettre un place un réseau téléphonique privé/public est bel et bien révolue !
J’espère que cet article vous a été utile pour comprendre un peu plus comment fonctionnait la Voix sur IP, ainsi que la voie vers les diverses méthodes servant à monter une architecture saine et sécurisée afin d’en profiter où que vous soyez, moyennant une connexion au net, bien sûr. :)
Sur ce, à la prochaine,
Cheers !
|
Auteur : Ignace Mouzannar – ghantoos |
|
Ingénieur VoIP chez Comverse/NetCentrex, constructeur d’équipements de Voix sur IP. Crooner officiel du jardin magique GCU-Squad. |
|
Références |
|
? [1] http://openvpn.net/ ? [2] http://openvpn.net/index.php/documentation/howto.html#vpntype ? [3] http://www.asteriskguru.com/tutorials/extensions_conf.html ? [4] http://kevinbusque.com/?p=17 ? [5] http://www.voip-info.org/wiki-Asterisk+tips+IVR+menu ? [6] http://www.voip-info.org/wiki-Asterisk+cmd+Record ? [7] http://www.voip-info.org/wiki-Asterisk+cmd+GotoIf ? [8] http://www.voip-info.org/wiki-Asterisk+cmd+ChanIsAvail ? [9] http://nerdvittles.com/index.php?p=158 |
Retrouvez cet article dans : Linux Magazine Hors série 37












