CallerID Blacklists en Asterisk

Pues el dia de hoy voy a exponer como hice para solucionar la siguiente situacion…

Problema:

Se requiere de un sistema capaz de recibir llamadas de la PSTN, y poder checar el CallerID (ANI) contra una lista en una base de datos, y si el CallerID coincide con alguno dentro de la lista, denegar la llamada… de lo contrario recibirla tal cual.

Descripcion de la solucion:

Servidor:

Asterisk usando una tarjeta Dual E1 (TE210P), uno de los E1’s con Telmex y el otro configurado como entrada para el PBX Interno (Siemmens).

Configuracion:

Configuracion de las Tarjetas E1:

Archivo /etc/zaptel.conf

# It must be in the module loading order
#TELMEX
span=1,1,0,cas,hdb3
cas=1-15:1101
cas=17-31:1101
#PBX Siemmens
span=2,1,0,cas,hdb3

cas=32-46:1101
cas=48-62:1101# Global data
loadzone        = us
defaultzone     = us

Archivo /etc/asterisk/unicall.conf

[channels]
usecallerid=yes
hidecallerid=no
callwaitingcallerid=yes
threewaycalling=yes
transfer=yes
cancallforward=yes
callreturn=yes
echocancel=yes
echocancelwhenbridged=yes
rxgain=0.0
txgain=0.0
callgroup=1
pickupgroup=1
immediate=yes
musiconhold=default
;loglevel=255
protocolclass=mfcr2
protocolvariant=mx,10,4
protocolend=cpe
group = 1
context= CalleridBlacklist-custom
;Telmex
channel = 1-15
channel = 17-31callgroup=5
pickupgroup=5
context= PBX-custom
protocolvariant=mx,10,12
;PBX
channel = 32-46
channel = 48-62

Configuracion de Asterisk:

Archivo /etc/asterisk/extensions.conf

[CalleridBlacklist-custom]
exten => _XX.,1,NoOp(el callerid es ${CALLERIDNUM})
;Checar el callerid contra la BD, usando un AGI script en PHP
exten => _XX.,n(agi_call),AGI(callerid_blacklist.php)
exten => _XX.,n,NoOp(blacklisted = ${blacklisted_cid})
exten => _XX.,n,GotoIf($[${blacklisted_cid} != ‘1’]?:colgar)
exten => _XX.,n,Goto(Entrada-Telmex-custom,${EXTEN},1)
exten => _XX.,n(colgar),Hangup[Entrada-Telmex-custom]
exten => _XX.,1,NoOp(El callerid es ${CALLERID})
exten => _XX.,2,Dial(Unicall/32/${EXTEN})
exten => _XX.,2+101,Dial(Unicall/33/${EXTEN})
exten => _XX.,2+102,Dial(Unicall/34/${EXTEN})
exten => _XX.,2+103,Dial(Unicall/35/${EXTEN})
exten => _XX.,2+104,Dial(Unicall/36/${EXTEN})
exten => _XX.,2+105,Dial(Unicall/37/${EXTEN})
exten => _XX.,2+106,Dial(Unicall/38/${EXTEN})
exten => _XX.,2+107,Dial(Unicall/39/${EXTEN})
exten => _XX.,2+108,Dial(Unicall/40/${EXTEN})
exten => _XX.,2+109,Dial(Unicall/41/${EXTEN})
exten => _XX.,2+110,Dial(Unicall/42/${EXTEN})
exten => _XX.,2+111,Dial(Unicall/43/${EXTEN})
exten => _XX.,2+112,Dial(Unicall/44/${EXTEN})
exten => _XX.,2+113,Dial(Unicall/45/${EXTEN})
exten => _XX.,2+114,Dial(Unicall/46/${EXTEN})
exten => _XX.,2+115,Dial(Unicall/48/${EXTEN})
exten => _XX.,2+116,Dial(Unicall/49/${EXTEN})
exten => _XX.,2+117,Dial(Unicall/50/${EXTEN})
exten => _XX.,2+118,Dial(Unicall/51/${EXTEN})
exten => _XX.,2+119,Dial(Unicall/52/${EXTEN})
exten => _XX.,2+120,Dial(Unicall/53/${EXTEN})
exten => _XX.,2+121,Dial(Unicall/54/${EXTEN})
exten => _XX.,2+122,Dial(Unicall/55/${EXTEN})
exten => _XX.,2+123,Dial(Unicall/56/${EXTEN})
exten => _XX.,2+124,Dial(Unicall/57/${EXTEN})
exten => _XX.,2+125,Dial(Unicall/58/${EXTEN})
exten => _XX.,2+126,Dial(Unicall/59/${EXTEN})
exten => _XX.,2+127,Dial(Unicall/60/${EXTEN})
exten => _XX.,2+128,Dial(Unicall/61/${EXTEN})
exten => _XX.,2+129,Dial(Unicall/62/${EXTEN})
exten => _XX.,3,Hangup

[PBX-custom]
exten => _XX.,1,Dial(Unicall/g1/${EXTEN})
exten => _XX.,2,Hangup

Archivo /var/lib/asterisk/agi-bin/callerid_blacklist.php

Lo mas interesante de este script, es que es capaz de checar no solo un numero por si solo (ej. 555 2312122) sino tambien acepta el uso de caracteres especiales ( un punto . y las X) que sirven para hacer patterns de numeros (ej 55. cualquier numero que empiece con 55 sera rechazado). Si ya haz usado el plan de marcacion de Asterisk, ya estas familiarizado con estos simbolos…

#!/usr/bin/php -q
<?
require ‘phpagi.php’;
$agi = new AGI();

$number=preg_replace(“#[^0-9]#”,””,$agi->request[agi_callerid]);//remove any non numeric characters
$db = ‘continental_development’;
$dbuser = ‘root’;
$dbpass = ‘mydbpassword’;
$dbhost = ‘localhost’;

function create_pattern($arg) {
//We will replace all the X for [0-9], so that we can use it as a pattern
$pattern = preg_replace(“/[.]/”, “.*”, $arg);
$pattern = preg_replace(“/[Xx]/”, “[0-9]”, $pattern);
$pattern = “/^” . $pattern . “$/”;
return $pattern;
}

mysql_connect($dbhost,$dbuser,$dbpass);
mysql_select_db(“$db”); //or die(“could not open database”);
$row=mysql_query(“SELECT * FROM blacklists WHERE active=’1′ AND (expression LIKE ‘%$number%’ OR expression LIKE ‘%.%’ OR expression LIKE ‘%X%’)”);

while ($get_info = mysql_fetch_array($row)){

$expression=create_pattern($get_info[expression]);
//echo “\n” . $expression . ” like ” . “$number” . “\n”;
if (preg_match($expression,$number) || $number == null) {
$agi->stream_file(‘ss-noservice’);
$agi->set_variable(“blacklisted_cid”, 1);
exit();
}
else {
$agi->set_variable(“blacklisted_cid”, 0);
}

}

?>

NOTA: En el script anterior se esta haciendo uso de la libreria phpagi, asi que debe de estar instalada en la misma direccion que este script….

Tabla de la Base de Datos:

Puedes hacer tu propia tabla con los datos que necesites… pero para que te des una idea… esta es la estructura de la tabla que se uso…

mysql> describe blacklists;
+————-+————–+——+—–+———+—————-+
| Field       | Type         | Null | Key | Default | Extra          |
+————-+————–+——+—–+———+—————-+
| id          | int(11)      |      | PRI | NULL    | auto_increment |
| expression  | varchar(255) | YES  |     | NULL    |                |
| active      | tinyint(1)   | YES  |     | NULL    |                |
| description | text         | YES  |     | NULL    |                |
| created_at  | datetime     | YES  |     | NULL    |                |
| updated_at  | datetime     | YES  |     | NULL    |                |
+————-+————–+——+—–+———+—————-+

Eso es todo… a testear se ha dicho….

3 thoughts on “CallerID Blacklists en Asterisk

  1. lo hiciste muy complicado yo lo puedo resolver con estas lineas

    [ Context ‘blacklist’ created by ‘pbx_config’ ]
    ‘s’ => 1. noop(${CALLERID}) [pbx_config]
    2. lookupblacklist(j) [pbx_config]
    3. goto(from-pstn|s|1) [pbx_config]

    y la base de datos que puedes usar es la astdb comando database put

    • Que tal Juan… En realidad es complicado precisamente por que el objetivo es que el usuario final, tenga una administracion grafica, en la cual pueda dar de alta y borrar numeros telefonicos de la base de datos, asi como tambien expressiones regulares… (por ejemplo, denegar todos los numeros que cumplan con algun criterio espeficico… como alguna lada por ejemplo)….

  2. Buenas… estoy buscando algún módulo o algo por el estilo, para armar una lista de números permitidos a los cuales realizar llamadas (una whitelist de llamdas salientes). Es esto posible? Desde ya muchas gracias.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s