Catégories
Système

FreePBX / Asterisk : filtrage d’appel avec MySQL

Version de FreePBX 15.0.16.75
Version d’Asterisk 16.2.1~dfsg-1+deb10u2
OS Debian Buster 10.6

L’objectif était de pouvoir autoriser des numéros de téléphones à appeler une ligne de notre serveur Asterisk. C’est en fait une whitelist qu’on a défini dans une base de données MySQL.

Quand on cherche à filtrer des appels en fonction de numéros appelant on tombe souvent sur la fonctionnalité de FreePBX Caller ID Lookup. Cette fonctionnalité permet en fait d’enrichir un appel avec le nom correspondant au numéro appelant qu’on peut trouver dans une table de correspondance. C’est comme un annuaire, qui affiche le nom de l’appelant plutôt que son numéro.

Dans FreePBX le menu Système/CID Lookup permet de définir la source de l’annuaire. On peut utiliser une URL qui va chercher dans un annuaire ou un requête MySQL, etc…. Ca fonctionne très bien, sauf que ça ne joue pas le rôle de filtre.

Le module Blacklist de FreePBX https://wiki.freepbx.org/display/FPG/Blacklist+Module+User+Guide fait exactement le contraire de ce qu’on cherche à faire.

D’autres manières de créer des whitelists passent par l’utilisation d’un masque de numéros sur les routes entrantes. On peut dire qu’on laisse passer tous les numéros qui commencent par 06 et 07, les mobiles avec une expression régulière telle que « _0[67]XXXXXXXX. » Le problème c’est qu’on ne peut pas définir une dizaine de numéros de mobiles avec une expression régulière de cette forme.

Quand on cherche de la documentation Asterisk et les posts sur le sujet, on voit qu’on peut définir des règles « custom ». Alors , pourquoi ne pas bloquer les appelants s’ils ne sont pas dans une table MySQL en utilisant cidlookup ?

Il suffit en théorie de créer un contexte cidlookup-custom dans le fichier /etc/asterisk/extensions_custom.conf

Sauf que le contexte est inclus, mais il n’est pas appelé. Et on ne voit pas bien comment l’appeler sans toucher le fichier /etc/asterisk/extensions_additional.conf. Le problème, c’est que dans ce cas, à chaque modification de FreePBX via l’interface graphique, le fichier extensions_additional.conf est écrasé !

La solution, c’est d’écraser le contexte cdi-lookup dans /etc/asterisk/extensions_override_freepbx.conf !!!

Procédure pour la mise en place du filtrage d’appelant sur une route entrante

Etape 1 : Création de la whitelist dans MySQL

Commencer par créer une table pour stocker les numéros de la whiteliste dans la base MySQL de FreePBX. On a créé 2 champs, le nom ou pentagramme dans notre cas particulier et le numéro de téléphone : phonenumber.

Se connecter à la base MySQL en ligne de commande, puis lancer la commande :

MariaDB [asterisk]> CREATE TABLE cidlookup ( 
  pentagramme varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL, 
  phonenumber varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL, 
  PRIMARY KEY (pentagramme),
  UNIQUE KEY phonenumber_unique (phonenumber)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ;
MariaDB [asterisk]>

Ajouter quelques enregistrements correspondants aux numéros que vous voulez laisser passer.

MariaDB [asterisk]> insert into cidlookup (pentagramme, phonenumber) values ('alard', '0634000001');
Query OK, 1 row affected (0.004 sec)
MariaDB [asterisk]> 

Vérifiez le contenu de la whitelist

MariaDB [asterisk]> select * from cidlookup;
+-------------+-------------+
| pentagramme | phonenumber |
+-------------+-------------+
| paabo       | 0634000003  |
| ancha       | 0634000002  |
| alard       | 0634000001  |
+-------------+-------------+
3 rows in set (0.000 sec)

MariaDB [asterisk]> 

Etape 2 : Création d’une source de CID Lookup dans FreePBX

Allez dans le menu Admin/CIDLookup Source

Cliquez sur le bouton pour ajouter une source « + CIDLookup Source » et remplir les champs du formulaire

Enregistrer le formulaire et appliquer la configuration.

Etape 3 : Affectation de la whitelist à une route entrante

Allez dans le menu Inbound routes et choisir la ligne que vous voulez filtrer. En modification, dans l’onglet « Other », vous pouvez sélectionner « Whitelist » dans la liste déroulante dans CIDLookup Source. Vous pouvez enregistrer le formulaire et appliquer la configuration.

A cette étape, vous avez appliqué la configuration, si vous appelez le numéro entrant à partir d’un des numéros de votre whitelist, il ne se passe rien de particulier. Peut-être voyez vous le nom de l’appelant à la place du numéro. C’est l’objectif de la fonction CIDLookup.

Etape 4 : Mise en place du filtrage

Nous allons modifier le comportement par défaut, afin de bloquer les appels dont le numéro ne se trouve pas dans la whitelist. Il faut créer, s’il n’existe pas déjà, le fichier /etc/asterisk/extensions_override_freepbx.conf en ajoutant un contexte [cidlookup] qui va écraser celui qui se trouve dans /etc/asterisk/extensions_additional.conf

Pour créer le contexte dans extensions_override_freepbx.conf, le plus simple est de le recopier depuis extensions_additional.conf

Contexte [cdilookup] dans extensions_additional.conf

[cidlookup]
include => cidlookup-custom
exten => cidlookup_2,1,MYSQL(Connect connid localhost user_read user_password asterisk)
exten => cidlookup_2,n,MYSQL(Query resultid ${connid} SELECT pentagramme FROM cidlookup WHERE phonenumber LIKE '%${CALLERID(num)}%')
exten => cidlookup_2,n,MYSQL(Fetch fetchid ${resultid} CALLERID(name))
exten => cidlookup_2,n,MYSQL(Clear ${resultid})
exten => cidlookup_2,n,MYSQL(Disconnect ${connid})
exten => cidlookup_2,n,Return()

exten => cidlookup_return,1,ExecIf($["${DB(cidname/${CALLERID(num)})}" != ""]?Set(CALLERID(name)=${DB(cidname/${CALLERID(num)})}))
exten => cidlookup_return,n,Return()

;--== end of [cidlookup] ==--;

qu’on recopie et qu’on modifie dans le fichier /etc/asterisk/extensions_override_freepbx.conf comme suit :

; Fichier qui écrase les contextes créés par FreePBX et qui n'est pas écrasé par un restart !

; Si le num n'est pas dans la BDD on interdit l'appel
[cidlookup]
include => cidlookup-custom
exten => cidlookup_2,1,MYSQL(Connect connid localhost user_read user_password asterisk)
exten => cidlookup_2,n,MYSQL(Query resultid ${connid} SELECT pentagramme FROM cidlookup WHERE phonenumber LIKE '%${CALLERID(num)}%')
exten => cidlookup_2,n,MYSQL(Fetch fetchid ${resultid} CALLERID(name))
exten => cidlookup_2,n,MYSQL(Clear ${resultid})
exten => cidlookup_2,n,MYSQL(Disconnect ${connid})
; ligne supplémentaire par rapport au contexte [cidlookup] de FreePBX defini dans extensions_additional.conf
exten => cidlookup_2,n,ExecIf($[${fetchid} = 0]?Gosub(action-forbidden,s,1()))
exten => cidlookup_2,n,Return()

exten => cidlookup_return,1,ExecIf($["${DB(cidname/${CALLERID(num)})}" != ""]?Set(CALLERID(name)=${DB(cidname/${CALLERID(num)})}))
exten => cidlookup_return,n,Return()

;--== end of [cidlookup] ==--;

; les fichiers de son se trouvent dans /usr/share/asterisk/sounds/fr/
[action-forbidden]
exten => s,1,Playback(sorry-cant-let-you-do-that)
 same => n,Playback(vm-goodbye)
 same => n,Macro(hangupcall,)

;--== end of [action-forbidden] ==--;

Une fois que vous avez créé ce fichier, il faut le charger dans Asterisk.
Lancer la commande :

# asterisk -vrx 'dialplan reload'

Lorsque vous appelez la ligne entrante et que votre numéro n’est pas dans la whitelist vous devriez entendre le message
« Désolé, je ne peux vous laisser faire cela,
au revoir. » et Asterisk raccroche !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.