Un proxy SIP pour le téléphone Livebox d'Orange

Auteur :  x0r Publié le   Nombre de commentaires : 26
Mots-clefs : sip orange livebox voip livephone hack cisco siproxd linphone paramètres

Mise à jour : RIP siproxd_orange :(

Moins d'une semaine après avoir publié mon dernier article, certaines personnes ont probablement déjà pu observer ma page BitBucket et voir que j'avais créé un nouveau dépôt public intitulé siproxd_orange.

Après avoir passé près de deux mois à analyser le fonctionnement du client SIP officiel d'Orange (j'ai nommé le Livephone), il n'y a rien de plus naturel que de valider le fruit de mes recherches en fabriquant une implémentation indépendante des mêmes extensions au protocole SIP.

Voici donc ma première deuxième release, la version 0.1.1 de ce plugin, qui est le fruit de maintenant presque trois mois d'intense recherches. Je vous le propose en téléchargement, tout en précisant néanmoins qu'il est très important de lire le fichier README qui l'accompagne.

Le résultat ? J'ai pu téléphoner via le numéro géographique (en 01) attribué pour ma Livebox, directement via Linphone et via un téléphone SIP Cisco 7960G. Le téléphone Cisco trône d'ailleurs fièrement sur mon bureau depuis que je l'ai acheté sur Leboncoin.

Cisco 7960 sur mon bureau
Faire mumuse avec du SIP est une bonne excuse pour faire de genre de craquages. C'est juste un peu moins "girlfriend-compliant".

Mon plugin se contente généralement de réécrire certains des paquets SIP qu'il reçoit. Comme Orange utilise des URI "tel:" dans certains de ses messages et que siproxd fait mal la vérification syntaxique lorsque de tels URI figurent dans les messages SIP (ils font pourtant l'objet de la RFC 3966), j'ai été parfois obligé de réécrire les messages avant même l'étape de parsing de siproxd. Ces réécritures modifiaient la longueur des paquets reçus et provoquaient un bug pour lequel j'ai soumis un patch, qui vient tout juste d'être accepté.

Ce qui signifie que tant qu'une hypothétique version 0.8.3 de siproxd n'est pas encore sorti, il faudra compiler soi-même une version patchée du code source pour que le plugin fonctionne correctement. Cette restriction rend malheureusement la mise en œuvre de ma solution beaucoup plus difficile (et croyez-moi, j'ai vraiment voulu faire le plus de choses possibles sans devoir patcher siproxd ou libosip2), en attendant une éventuelle prochaine version 0.8.3. Cette procédure est néanmoins documentée (du mieux que je peux) sur la page du projet siproxd_orange. En attendant, le code source intégrant mon patch est déjà disponible (choisir une snapshot postérieure au 26 mai).

Est-ce que cela signifie qu'on peut désormais brancher son téléphone SIP préféré directement sur l'infrastructure d'Orange ? Tout à fait. Est-ce que cela signifie qu'on pourra débrancher définitivement le câble RJ11 à l'arrière de sa Livebox ? Je ne sais pas. C'est pourquoi je compte aussi sur vous afin de trouver les bugs que je n'aurais peut-être pas pu repérer moi-même.

(Note à moi-même : ça m'apprendra à faire des releases avant de tout tester correctement.)

Mise à jour du 23 janvier 2015 : correction factuelle sur la question de la mauvaise prise en charge par siproxd des URIs "tel:" ; merci aymeric !

Le SIP par Orange : analyse technique

Auteur :  x0r Publié le   Nombre de commentaires : 8
Mots-clefs : sip orange livebox voip livephone asterisk reversing téléphone paramètres

Mise à jour : Orange n'aime pas trop ça. Allez savoir.

Il y a SIP, et SIP par Orange.

Orange : not open !

Source image : trollab.org

En effet, l'opérateur historique a décidé de migrer une partie de ses clients ADSL et Fibre vers le protocole SIP pour la signalisation téléphonique de la téléphonie par Internet de la Livebox.

Orange propose ainsi trois manières d'exploiter la téléphonie par IP incluse dans ses connexions Internet :

  • on peut tout simplement brancher un bon vieux téléphone analogique (ou une interface FXO) en insérant la prise RJ11 à l'arrière de la Livebox ;
  • on peut aussi connecter directement des téléphones DECT compatibles à la box ;
  • enfin, et potentiellement le plus intéressant : on peut aussi utiliser l'application Livephone pour utiliser son PC comme un "softphone" qui a l'avantage de sonner lorsqu'un appelant externe compose le numéro fixe associé à la Livebox.

Cette application, uniquement disponible sous Windows malheureusement, n'est pas compatible avec toutes les connexions, et je conjecture qu'elle ne fonctionne qu'avec les abonnés utilisant la signalisation SIP pour le téléphone. Ce qui signifie qu'il serait théoriquement possible d'utiliser n'importe quel softphone avec ce service. Pour moi, cela me permettrait de m'affranchir du câble RJ11 entre mon serveur et la box, et de bénéficier d'une méthode plus élégante pour détecter le début et la fin d'un appel téléphonique.

Hélas, il n'en est rien ! Une analyse plus détaillée révèle en effet que le Livephone implémente une version modifiée du mécanisme d'authentification SIP, que je n'ai pu relever qu'après un long travail d'ingénierie inverse (légale, dans ce cas particulier). Ces modifications violent bien entendu la RFC 3261, cassant de fait la compatibilité avec les clients SIP autres que le Livephone.

Constatant que des demandes d'informations antérieures ont été infructueuses, j'ai donc été contraint de me lancer dans une analyse technique plus poussée. Les informations que je publie ici sont principalement des résultats d'analyses de trames réseau et de traces de débogueur ; néanmoins, j'ai également été amené à décompiler le programme pour comprendre entièrement le mécanisme d'authentification.

C'est dans une démarche d'interopérabilité que j'exposerai dans les grandes lignes le fonctionnement de l'authentification SIP par Orange. Nous constaterons très rapidement pourquoi un téléphone SIP conforme à la RFC ne pourra jamais utiliser en l'état le réseau SIP Orange, puis j'expliquerai dans une dernière partie une solution possible pour contourner ces modifications propriétaires.

Certains paragraphes seront délibérément vagues ou peu détaillés, par manque de recherches, ou afin d'éviter les ennuis (comme ceux que j'aurais pu avoir avec la SNCF il y a quelques temps et qui m'ont conduit à censurer des morceaux d'article).

Le SIP par Orange en trois étapes

Le schéma ci-dessous résume le processus d'authentification du Livephone auprès du proxy SIP Orange.

MSC décrivant l'authentification SIP Orange
Échange de messages entre le client et les différents serveurs

On voit déjà immédiatement que le processus est beaucoup plus compliqué qu'une simple requête REGISTER auprès du proxy. Reprenons chacune des trois étapes en plus de détails.

Login

Tout d'abord, le client envoie en HTTPS (mais sans vérifier le certificat, ce qui est bien pratique pour faire du sslstrip comme un gros dégueulasse) une requête au serveur d'authentification. On dirait que celui-ci reconnaît l'utilisateur en se basant sur l'IP source (du moins, je crois), mais substituer ses propres serveurs DNS à ceux d'Orange permet de "forcer" un downgrade vers une authentification par login et mot de passe. Il semblerait que la toute première authentification se fait toujours par login et mot de passe.

Récupération de la configuration

Si l'authentification passe, le client reçoit entre autres un token qui est une chaîne hexadécimale tellement longue qu'il faut trois segments TCP pour la transmettre. Il envoie ce token (concaténé à d'autres variables, comme le nom et les versions de l'OS et du client) à un serveur de paramètres par HTTPS lui aussi, cette fois pour récupérer une liste de paramètres SIP : nom du proxy SIP, URI SIP de l'utilisateur (de la forme +33123456789@orange-multimedia.fr) entre autres, mais aussi une étrange chaîne de caractères en base64 appelée AuthentData.

Enregistrement auprès du proxy SIP

Enfin, la troisième étape consiste à faire l'enregistrement du client auprès du proxy SIP. Cela se fait avec un message REGISTER, comme le décrit la RFC 3261. Comme on peut le voir, l'authentification se déroule par challenge-response, de la même manière que l'authentification HTTP Digest, décrite dans la RFC 2617.

En réalité, le calcul de la réponse au challenge est un peu compliquée. La seule différence est que le paramètre H(A1) n'est pas égal à md5("${username}:${realm}:${password}"). Il faut en effet (censuré).

En conclusion, j'ignore si cela a été fait sciemment ou par flemme, mais le résultat ressemble presque à un échange conforme à la RFC 2617, alors qu'il n'en est rien en réalité.

Récapitulatif

En résumé, on dégage les informations suivantes :

  • l'authentification se fait en trois étapes auprès de trois serveurs différents, au lieu du seul proxy SIP ;

  • un des paramètres pour le calcul de la réponse au challenge envoyé par le proxy SIP ne correspond pas à ce qui est prescrit par la RFC. Au lieu de ça, il s'agit d'un bloc binaire, récupéré depuis une source extérieure, et chiffré avec un algorithme dont je suis à peu près sûr que (censuré).

  • de fait, il est impossible de se passer des deux premières étapes de l'authentification car celles-ci permettent d'obtenir des informations essentielles à l'authentification SIP.

Se défaire des extensions propriétaires

Se pose maintenant la vraie question : quelle est la solution la plus simple pour assurer l'interopérabilité entre l'infrastructure SIP Livephone d'une part, dont on a vu qu'elle ne respecte pas les RFC, et l'ensemble des clients SIP d'autre part ?

Une première possibilité aurait été de mettre au point des patchs pour Asterisk, car c'était dans l'optique de faire fonctionner le Livephone avec ce serveur de téléphonie que je m'étais lancé dans ce travail.

Cependant, j'ai préféré privilégier la solution d'un proxy SIP, qui serait alors utilisable directement avec n'importe quel client SIP, y compris Asterisk, et éviterait à ceux qui souhaiteraient tenter la même chose d'être obligé d'installer Asterisk chez eux, et d'avoir juste besoin de ce proxy et d'Ekiga ou de Linphone.

Le proxy ne ferait que du bête forwarding de requêtes et de réponses entre les deux parties, sauf dans le cas du REGISTER qu'il intercepterait pour faire l'authentification « à la sauce Orange » à la place, tout en répondant "OK" au client si tout s'est bien passé.

Le seul problème restant est la dernière étape d'authentification. Cet aspect risque de rendre l'interopérabilité bien plus difficile à obtenir que ce que j'aurais espéré. La réalisation d'un proxy en devient à la limite de la légalité, car à part décompiler l'algo de hachage pour l'analyser plus en détail et voir avec quels paramètres il est appelé, je vois mal comment faire autrement.

Conclusion

Ces recherches sont incomplètes, dans la mesure où je n'ai pu valider mes analyses que partiellement à l'aide de preuves de concept incomplètes.

Bien que je puisse comprendre qu'Orange ait pu décider de fournir une méthode centralisée de distribution d'éléments de configuration (après tout, j'imagine qu'ils font la même chose pour la Livebox elle-même de toute façon), une modification aussi lourde au processus d'authentification SIP proprement dit (c'est-à-dire le challenge-response) a tout d'une action délibérée. Modification difficilement justifiable d'un point de vue technique, qui plus est.

Comme je le disais au-dessus, la prochaine étape consistera bien évidemment à concevoir et implémenter un proxy SIP faisant le lien entre un client SIP lambda, et l'infrastructure SIP propriétaire du Livephone. Ce proxy ne fonctionnera que sur la connexion Internet Orange de l'utilisateur, entre autres parce que beaucoup de noms de serveurs que j'ai pu voir passer dans tcpdump ne sont résolvables que par le biais des serveurs DNS Orange (rappelez-vous du serveur SMTP d'Orange, par exemple). Tous mes essais sont concluants jusqu'à maintenant, et si je parviens à implémenter un proxy qui fonctionne, le résultat fera bien entendu l'objet d'une autre publication sur ce site.

Étant donné que ces modifications protocolaires sont manifestement intentionnelles dans le but de casser la compatibilité avec les matériels et logiciels respectant les normes, cet effort de reverse engineering en est d'autant plus légitimisé.

Mise à jour du 4 mai : correction de quelques inexactitudes, notamment liés à l'authentification.

Mise à jour du 28 mai : faire un plugin pour siproxd : ça, c'est fait.

monrer.fr : ouverture à toutes les lignes Transilien SNCF

Auteur :  x0r Publié le   Nombre de commentaires : 8

Vous attendiez tous ce moment (ou pas), mais l'API Prochains Départs Transilien fournie par la SNCF a été ouverte aujourd'hui à toutes les lignes Transilien SNCF !

Ceci a pour conséquence principale que monrer.fr fournit désormais les horaires temps réel des prochains trains sur toutes les gares desservies par l'ensemble des lignes Transilien SNCF, à savoir les lignes Transilien C, D, E, H, J, K, L, N, P, R et U. Presque comme avant donc. Les lignes A et B, gérées par la RATP, sont encore exclues des horaires en temps réel pour le moment.

Il y a encore quelques gares pour lesquels je dois peaufiner l'accès API et la mutualisation de plusieurs sources de données, mais je résoudrai ces problèmes en temps et en heure.

Je n'ai pas encore eu le temps d'écrire d'autres posts ces derniers temps, car j'ai été très occupé pour des raisons diverses et variées. J'ai néanmoins pas mal avancé sur un petit projet de reverse engineering dont je serai certainement tenté de partager les résultats dans un futur proche.

Un répondeur multilingue avec Asterisk

Auteur :  x0r Publié le   Nombre de commentaires : 2
Mots-clefs : sip voip asterisk telephone fxo fxs

Ayant de la famille à l'étranger, je me souviens d'un incident où des membres de ma famille avaient tenté de m'appeler sur mon portable et qu'ils n'avaient pas compris qu'ils étaient tombés sur mon répondeur, probablement du fait de mon annonce en français.

C'est pourquoi j'ai toujours pensé qu'un répondeur qui sache diffuser son annonce dans la bonne langue, en la dérivant du numéro de l'appelant, serait fort appréciable.

Un tel service va généralement au-delà de ce que fournit un opérateur téléphonique. Je me suis donc dit que ce serait là un bon exercice pour mettre en place un serveur de téléphonie Asterisk. Ce faisant, cela me permettrait également de pallier d'autres lacunes de mon propre équipement ou tout simplement réaliser des applications plus ludiques plus tard.

Présentation d'Asterisk

On présente souvent Asterisk comme étant un IPBX, c'est-à-dire un autocommutateur téléphonique privé (aussi appelé PBX) qui fonctionne en voix sur IP. On trouve beaucoup d'autocommutateurs dans des entreprises ou institutions publiques : lorsqu'on appelle un numéro et qu'on entend une voix robotisée demander un numéro de poste, ou qu'on se retrouve face à un menu, c'est le PBX qui "répond".

Le volet "voix sur IP", quant à lui, signifie grosso modo qu'on peut utiliser Asterisk pour faire son Skype interne dont les communications ne passent pas par Microsoft (et probablement pas la NSA non plus mais je ne m'avancerai pas là-dessus, on sait jamais), tout en permettant les appels vers l'extérieur et l'utilisation aussi bien de téléphones analogiques (via les fameuses cartes dites "FXO/FXS", comme l'Openvox A400P) que des téléphones SIP (comme les Cisco qu'on voit à peu près partout) ou encore des logiciels comme Ekiga ou Linphone.

On peut donc utiliser Asterisk pour passer des appels externes depuis un PC muni d'un casque et d'un micro, à l'aide d'un logiciel appelé "softphone", ce qui est pratique lorsqu'on est amené à prendre beaucoup de notes pendant la conversation. Mais on peut aussi brancher directement un téléphone analogique dessus, faire sonner des softphones depuis celui-ci, ou faire sonner le téléphone analogique en composant des numéros internes.

L'architecture matérielle

Pour ce faire, nous partirons du principe qu'on dispose déjà d'un serveur et d'une carte FXO/FXS avec au moins :

  • 1 module FXS sur le port 1 (pour brancher un téléphone dessus et pouvoir le faire sonner), éventuellement plusieurs sur les ports 2 et 3 le cas échéant;
  • 1 module FXO sur le port 4, qui ira dans la prise FXS ("téléphone") de sa box ADSL ou directement dans le mur.

Enfin, nous nous munirons également d'un bon vieux téléphone analogique (c.à.d. conçus pour se brancher sur une prise en T ou sur une prise RJ11 murale et non pas sur un réseau Ethernet). Pas que ce soit forcément nécessaire, mais comme je disposais déjà d'un téléphone avant de migrer vers Asterisk, ce serait dommage de ne pas s'en servir.

Le plan de numérotation

Installer Asterisk implique déjà de réfléchir à un plan de numérotation. Même si ce n'est pas forcément obligatoire dans notre cas, cela facilitera grandement les tests. Chaque terminal susceptible de se connecter au serveur Asterisk (dans notre cas, un téléphone analogique) doit donc disposer d'un numéro.

Dans mon cas, comme la plage des numéros à 4 chiffres commençant par 4 n'est pas utilisée par France Télécom et que je souhaite que le reste des numéros composés soit redirigée vers l'extérieur (pas de 9 ou de 0 à composer avant d'obtenir une ligne externe), j'adopterai le plan suivant :

  • 4001 pour le téléphone analogique;
  • 4002 à 4099 pour d'autres téléphones, éventuellement ;
  • 4100 pour écouter ses messages vocaux ;
  • n'importe quelle autre plage de numéros valable et attribuée par l'ARCEP sera redirigée vers l'extérieur.

Ce plan donne donc le fichier extensions.conf suivant :

[trunkint]
;
; Appels téléphoniques internationaux
;
exten => _00.,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})

[trunknorm]

; Appels téléphoniques "locaux"
exten => _0[12345679]XXXXXXXX,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})
exten => _3XXX,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})

; Numéros Azur (prix appel local)
exten => _081XXXXXXX,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})

[trunknumverts]

; Numéros verts
exten => _080XXXXXXX,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})
exten => _10XX,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})

[trunknumsurtax]

; Numéros surtaxés
exten => _08[289]XXXXXXX,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})

; Services de renseignements à la con
exten => _118XXX,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})

[trunknumurg]
; SAMU
exten => 15,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})
; Police/gendarmerie
exten => 17,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})
; Pompiers
exten => 18,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})
; Numéro d'urgence européen
exten => 112,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})
; Personnes sourdes ou malentendantes
exten => 114,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})
; Urgences sociales ("SAMU social")
exten => 115,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})
; Enfants disparus
exten => 116000,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})
; Enfance maltraitée
exten => 119,1,Dial(${GLOBAL(OUT_PSTN)}/${EXTEN})

[phones]

include => internal

include => trunknorm
include => trunknumurg
include => trunknumsurtax
include => trunknumverts
include => trunkint


[internal]

exten => 4001,1,Dial(DAHDI/1,25,x)      ; téléphone analogique
  same => n,VoiceMail(${EXTEN},s)
  same => 101,VoiceMail(${EXTEN},s)

exten => 4100,1,NoOp()
  same => n,VoiceMailMain(${CALLERID(num)})

On déclare donc tout d'abord tous les numéros de téléphone pour lesquels on souhaite relayer l'appel vers l'extérieur. Il s'agit bien entendu de tous les numéros en zéro-quelque-chose à 10 chiffres, mais aussi tous les numéros courts en 4 chiffres (seuls ceux commençant par 1 et 3 sont attribués) et, très important, les numéros d'urgence.

La configuration du canal analogique

Il faut également configurer le fichier chan_dahdi.conf avec au moins les directives suivantes :

[channels]

signalling=fxo_ks
callerid="Votre nom ici" <4001>
mailbox=4001
group=0
context=phones
language=fr
channel => 1


signalling=fxs_ks
callerid=asreceived
group=1
context=incoming
busydetect=yes
busycount=3
busypattern=500,500
language=fr
channel => 4

Cette configuration est normalement en partie auto-générée, mais j'ai ajouté quelques éléments dans le bloc correspondant au "channel" 4 (i.e. le port 4, celui branché sur l'extérieur). J'ai ajouté busydetect=yes, busycount=3 et busypattern=500,500 parce que sinon, la carte ne sait pas quand l'interlocuteur a raccroché (ma Livebox ne fournit pas de signal spécifique lorsque la ligne a été libérée, en tout cas).

Enfin, pour que la suppression d'écho se fasse correctement, il faut charger le module wctdm (ou celui nécessaire pour votre carte) avec l'option opermode=TBR21 pour régler l'impédance de ligne à la valeur adaptée pour la France. Il suffit d'ajouter dans /etc/modprobe.d/dahdi.conf la ligne :

options wctdm opermode=TBR21

Redémarrer la machine, ou taper rmmod wctdm; modprobe wctdm en tant que root.

Les boîtes vocales

Avant de continuer, il faut savoir qu'Asterisk ne fournit pas automatiquement une boîte vocale par utilisateur ou numéro de téléphone, mais qu'il faut les configurer explicitement. Dans notre cas, on va simplement mettre en place une messagerie vocale pour le 4001. Il suffit d'ajouter dans voicemail.conf :

[default]
4001 => 1337,Téléphone,vous@example.com

Ceci crée une boîte vocale pour le 4001, avec comme mot de passe 1337 et comme nom d'utilisateur "Téléphone". Les e-mails seront envoyés à vous@example.com. Tant qu'on y est, modifions la variable emailbody pour que le message soit en français (oui c'est sur une seule ligne) :

emailbody=${VM_NAME},\n\n${VM_CALLERID} vous a ${IF($["${VM_CIDNUM}" =
"${ORIG_VM_CIDNUM}"]?laissé:transféré)} un message de longueur ${VM_DUR}\ndans
votre boîte vocale ${VM_MAILBOX} le ${VM_DATE}.\n${IF($["${VM_CIDNUM}" =
"${ORIG_VM_CIDNUM}"]?:Ce message a été laissé par ${ORIG_VM_CALLERID} le
${ORIG_VM_DATE}.)}\nVous pouvez l'écouter en appelant le 4100 depuis un
téléphone de l'appartement ou en téléchargeant\nla pièce jointe.\n

Les appels entrants

Cette configuration permet d'émettre des appels depuis un téléphone interne, mais pas d'en recevoir !

Comme on peut le voir, décrocher son téléphone analogique le place dans le contexte "phones" depuis lequel on peut appeler les numéros externes et internes. Cependant, un signal de sonnerie de l'extérieur place l'appelant dans le contexte "incoming", que nous n'avons pas encore paramétré.

L'idée principale étant que tout appel arrivant dans le contexte incoming sera simplement relayé vers le téléphone analogique. C'est là-dedans que nous allons faire le changement de langue.

On en profite tout d'abord pour envoyer bouler les appels masqués avec PrivacyManager, parce qu'il s'agit généralement de personnes indésirables. Cette application invite l'interlocuteur à composer son propre numéro de téléphone, qui sera ensuite affiché sur les téléphones lorsqu'ils sonnent. Une mesure temporaire, car j'envisage de remplacer cela par une invite qui demande à la personne de s'identifier oralement.

Le principe est simple : tout ce qui a "0031" comme 4 premiers caractères vient des Pays-Bas, et on change donc la langue en néerlandais ; tout ce qui commence par 0049 (Royaume-Uni) ou 001 (États-Unis/Canada) déclenche un changement de langue en anglais (y compris le Québec, mais je vous laisserai trouver les indicatifs correspondants vous-mêmes). Dans le cas contraire, on laisse en français.

On fait sonner le téléphone sur le port 1 de la carte pendant 25 secondes, puis on passe au répondeur.

[incoming] 

include => internal

exten => s,1,PrivacyManager()
  same => 2,Set(MYLANGUAGE=DEFAULT)
  same => 3,Set(MYLANGUAGE=${IF($[ ${CALLERID(num):0:4} = 0031 ] ? nl)})
  same => 4,Set(MYLANGUAGE=${IF($[ ${CALLERID(num):0:4} = 0049 ] ? en)})
  same => 5,Set(MYLANGUAGE=${IF($[ ${CALLERID(num):0:3} = 001 ] ? en)})
  same => 6,Set(MYLANGUAGE=${IF($[ ${MYLANGUAGE} = DEFAULT ]) ? fr})
  same => 7,Set(CHANNEL(language)=${MYLANGUAGE})
  same => 8(privmgr-passed),NoOp(${CHANNEL(language)})
  same => 9,Dial(DAHDI/1,25,x)
  same => 10,Playback(cust-vm-intro)
  same => 11,VoiceMail(4001,s)
  same => 12,Playback(vm-nobodyavail)
  same => 13,Hangup()
  same => 109,Playback(cust-vm-intro)
  same => 110,VoiceMail(4001,s)
  same => 111,Hangup()

Il suffit ensuite d'enregistrer deux exemplaires de l'annonce répondeur, en WAV 16 bits mono 8 kHz, et de les placer dans /usr/share/asterisk/sounds/<LANGUE>/cust-vm-intro.wav. Normalement, cela suffit. L'option s de VoiceMail() désactive l'annonce par défaut pour le répondeur et laisse uniquement le bip sonore.

Pour enregistrer ses annonces vocales, le plus simple est de mettre en place un numéro "virtuel" dans le contexte internal, qui active la boîte vocale du téléphone analogique. Il suffit d'enregistrer une annonce par ce biais et récupérer le message envoyé par e-mail :

exten => 4102,VoiceMail(4001,s)

Ainsi, en composant le 4102 depuis le téléphone, on entendra juste un bip sonore, puis à vous d'enregistrer les annonces pour votre répondeur, un par un. Une fois que vous avez récupéré les pièces jointes, composez le 4100 pour accéder à votre répondeur et supprimer les annonces que vous venez d'enregistrer.

Une fois que tout est en place, il suffit tout simplement de relancer Asterisk.

Le résultat final est qu'en cas de non-réponse, l'annonce cust-vm-intro est lue dans la bonne langue, puis l'appelant entendra un bip et pourra enregistrer son message. Si, au contraire, on tombe sur la messagerie vocale de la Livebox par exemple, il faut régler celui-ci pour que le répondeur se déclenche au bout de 9 sonneries (au lieu de 5), et s'arranger pour qu'Asterisk réponde avant.

Et en bonus, on reçoit également un exemplaire du message vocal par e-mail, en pièce jointe, ce qui est totalement la classe.

Conclusion

Tout cela paraît peut-être un peu tordu juste pour ajouter une seule fonctionnalité, mais on peut imaginer beaucoup d'autres possibilités. Le fait que le langage des plans de numérotation soit Turing-complet permet à n'importe qui de mettre en place son système téléphonique avec ses besoins spécifiques. Ce projet ne m'aura coûté que 220 euros pour la carte FXO/FXS, ce qui paraît un peu cher à première vue, mais reste tout à fait respectable pour le service que cela rend.

Il y a peut-être des choses que je pourrais améliorer dans mon plan de numérotation, mais j'ai essayé de vous montrer le strict minimum nécessaire pour utiliser une ligne téléphonique analogique avec Asterisk.

Comme ma ligne est derrière une Livebox, une idée connexe consisterait à laisser Asterisk s'enregistrer lui-même auprès du serveur de téléphonie Orange ; après tout, j'ai déjà pu voir comment ça marche. Ceci serait fort appréciable pour ceux qui souhaiteraient utiliser leur propre matériel au lieu de leur Livebox tout en conservant le téléphone.

Enfin, pour plus d'informations sur comment fonctionne Asterisk ou le téléphone, je vous conseille de lire l'excellent Asterisk™: The Future of Telephony disponible en PDF.

Surveiller sa Livebox 3 avec Nagios

Auteur :  x0r Publié le   Nombre de commentaires : 7
Mots-clefs : orange livebox nagios monitoring surveillance alerte

Ça fait quelques temps déjà que je me suis mis en tête de surveiller ma propre petite infrastructure réseau. Avec mon serveur chez moi qui fournit le NFS, le DNS, pas mal de petits sites Web et tout plein d'autres choses, ma jail FreeBSD qui héberge ce site ainsi que monrer.fr, mon routeur et mes onduleurs, on n'a pas forcément toujours le temps de vérifier soi-même si tout marche, alors que certaines choses feraient mieux de ne pas être cassées trop longtemps.

Pour ce faire, j'ai choisi Nagios, comme beaucoup de monde le ferait. Mais je me suis rapidement rendu compte qu'il me manquait quelque chose : en effet, bien que je surveille ma Livebox, il lui arrive parfois de répondre au ping alors que la connexion Internet ne fonctionne pas (lors d'un renouvellement d'un bail DHCP par exemple, ou pour toute autre raison). Je voulais donc pouvoir distinguer le cas où ma jail FreeBSD est dans les choux du cas où c'est la connexion Internet elle-même qui ne marche plus.

C'est pourquoi j'ai codé quelques plugins Nagios que vous pourrez récupérer sur mon dépôt BitBucket. Ils se connectent tous sur l'interface d'administration de la Livebox pour récupérer l'état de la connexion Internet, mais aussi du téléphone et de la télévision.

Cet article s'applique uniquement à la Livebox 3, qui est le dernier modèle au moment où j'écris cet article et qui est fournie à chaque nouvel abonnement fibre chez Orange.

L'interface d'administration : du HTML mais pas de texte

Tout d'abord, si vous allez sur l'interface d'administration de votre Livebox (http://192.168.1.1 par défaut) et que vous regardez le code source de la page, vous trouverez beaucoup de balises <span> mais pas un seul mot de texte. Par exemple, la partie qui nous intéresse pour l'état de la connexion Internet est (moyennant le whitespace ajouté pour plus de clarté) :

<span class="translation Translations.general.label.internet"></span>
<br>
<span style="color:#3caa0a;"
    class="translation Translations.general.label.available display"
    id="Services.InternetConnection"
    name="Services.InternetConnection">
</span>

Ce bout de HTML est censé donner ça :

État des services de la Livebox

Il s'agit donc bien de la partie de l'interface qui affiche une icône verte et le texte « disponible ». En fait, la page contient un bout de JavaScript qui insère le texte dans la bonne langue au bon endroit (au lieu de tout simplement honorer l'en-tête Accept-Language du protocole HTTP). C'est pas très élégant, mais cela nous permettra au moins de nous affranchir de problèmes liés aux différentes langues dans lesquelles les Livebox seraient fournies.

Donc pour obtenir la disponibilité de la connexion Internet, il suffit de regarder l'attribut class de l'élément HTML dont l'identifiant est Services.InternetConnection.

L'état de la TV et du téléphone : AJAX à la rescousse

La première version de mon script se contentait tout simplement de récupérer cette page HTML de temps en temps. Cependant, un petit coup de Firebug m'a rapidement montré que l'état des services TV et téléphone sont récupérés par des appels AJAX et ne sont pas affichés directement sur la page HTML.

Sous peine de fausses alertes Nagios (le HTML indiquant que la TV et le téléphone sont down par défaut), il nous faut donc faire un peu plus de travail pour récupérer l'état de ces services.

Pour l'état de la téléphonie, c'est à l'URL suivante que ça se passe :

http://192.168.1.1/sysbus/VoiceService/VoiceApplication:listTrunks

Il suffit d'envoyer une requête POST avec comme données {"parameters":{}} (un GET ne suffit pas et renverrait une erreur), et on obtient une réponse qui renferme en sus beaucoup d'informations intéressantes :

{
  "status": [
    {
      "name": "SIP-Trunk",
      "signalingProtocol": "SIP",
      "enable": "Enabled",
      "trunk_lines": [
        {
          "name": "LINE1",
          "groupId": "Group1",
          "enable": "Enabled",
          "status": "Up",
          "statusInfo": "",
          "directoryNumber": "+33123456789",
          "uri": "+33123456789@orange-multimedia.fr",
          "authUserName": "CENSURAIDE@orange-multimedia.fr",
          "authPassword": "",
          "event_subscribe_lines": [
            {
              "eventSubscribeEvent": "message-summary",
              "eventSubscribeAuthUserName": "",
              "eventSubscribeAuthPassword": ""
            }
          ]
        }
      ],
      "sip": {
        "proxyServer": "",
        "proxyServerPort": 5060,
        "registrarServer": "",
        "registrarServerPort": 5060,
        "outboundProxyServer": "81.253.172.17",
        "outboundProxyServerPort": 5060,
        "userAgentDomain": "orange-multimedia.fr",
        "userAgentPort": 5060,
        "subscriptionInfo": [
          {
            "event": "message-summary",
            "notifyServer": "voicemail.orange-multimedia.fr",
            "notifyServerPort": 5060
          }
        ]
      },
      "h323": {

      }
    },
    {
      "name": "H323-Trunk",
      "signalingProtocol": "H.323",
      "enable": "Disabled",
      "trunk_lines": [
        {
          "name": "LINE3",
          "groupId": "Group1",
          "enable": "Disabled",
          "status": "Disabled",
          "statusInfo": "",
          "directoryNumber": "",
          "uri": "",
          "authUserName": "",
          "authPassword": "",
          "event_subscribe_lines": [

          ]
        }
      ],
      "sip": {

      },
      "h323": {
        "gatekeeper": "",
        "gatekeeperPort": 1719
      }
    }
  ]
}

Le numéro de téléphone des attributs directoryNumber et uri est bien entendu le numéro de téléphone de votre Livebox. En tout cas, cela montre que ma Livebox utilise le protocole SIP.

Le paramètre authUserName me semble un peu plus abscons cependant. Il s'agit en réalité d'un identifiant de 10 caractères composé uniquement de lettres majuscules et qui ne correspond avec aucun des identifiants qu'Orange m'a fournis.

Hélas, je ne parviens pas à trouver plus d'informations concernant la possibilité de bénéficier de son accès VoIP avec autre chose qu'une Livebox. Peut-être faudra-t-il que je fasse un jour l'expérience en sniffant les communications entre la Livebox et le GPON sur le bon VLAN. De toute façon, là n'est pas l'objet de l'article. (Edit : ça, c'est fait).

Passons à l'état de la télévision. Il y a un peu moins de choses rigolotes à glaner dans le JSON renvoyé par l'URL correspondante, mais en POSTant {"parameters":{}} sur l'URL http://192.168.1.1/sysbus/NMC/OrangeTV:getIPTVStatus, on obtient :

{"status":null,"data":{"IPTVStatus":"Available"}}

Simple et efficace.

Conclusion

Cela fait quelques semaines que j'ai ajouté ces plugins Nagios à mon service de monitoring, mais je n'ai pas encore eu d'alertes à propos d'éventuelles coupures de service.

En tout cas, si vous aussi voulez vous laisser tenter, vous pouvez récupérer le code source sur la page BitBucket correspondante. Il suffit de copier les scripts dans /usr/lib/nagios/plugins (ou là où sont les autres plugins Nagios sur votre système), ajouter les commandes correspondantes et c'est parti.