Kamailio permission module
Il modulo permission rende disponibili una serie di funzionalità e controlli per implementare ACL basate su IP sorgente, From, Request Uri. Questo ci permette di controllare chi può fare cosa, ad esempio se richieste che arrivano da un certo IP sorgente possono essere ruotate a destinazione, oppure se una certa SIP Uri può essere gestita o deve essere rifiutata.
Come usare il modulo permission
Il modulo permission è presente di default nel setup di Kamailio, pertanto non sarebbe necessaria alcuna installazione ulteriore. Noi però useremo un database MySQL per gestire le regole di accesso, e quindi dovremo installare anche il modulo mysql per Kamailio (e.g. kamailio-mysql-5.5.3 - le versioni dei pacchetti sono disponibili qui).
Per creare lo schema database necessario al funzionamento di Kamailio possiamo usare il tool kamdbctl, e configurare i parametri necessari all’utilizzo del database nel file /etc/kamailio/kamctlrc, in particolare il DBENGINE da utilizzare, che nel nostro caso è MySQL.
...
## database type: MYSQL, PGSQL, ORACLE, DB_BERKELEY, DBTEXT, or SQLITE
## by default none is loaded
##
## If you want to setup a database with kamdbctl, you must at least specify
## this parameter.
DBENGINE=MYSQL
## database host
DBHOST=localhost
## database port
DBPORT=3306
## database name (for ORACLE this is TNS name)
DBNAME=kamailio
## database path used by dbtext, db_berkeley or sqlite
# DB_PATH="/usr/local/etc/kamailio/dbtext"
## database read/write user
DBRWUSER="kamailio"
## password for database read/write user
DBRWPW="MyKamPwd101"
## database read only user
DBROUSER="kamailioro"
## password for database read only user
DBROPW="MyKamPwd101"
...
Eseguiamo quindi il comando kamdbctl create che andrà a creare lo schema kamailio con le sue tabelle e gli utenti kamailio e kamailioro.
Ora non ci resta che configurare Kamailio per poter utilizzare il modulo permission, vediamo come.
Nel mio scenario io voglio andare a controllare il traffico che arriva da un certo IP sorgente ed è destinato ad una certa SIP Uri, ad esempio voglio che il sistema gestisca chiamate in arrivo dall’indirizzo 54.171.127.192 per le quali l’INVITE contenga nella SIP Uri il numero di destinazione 0612345, rifiutando le altre. Per ottenere questo risultato dobbiamo inserire i dati corretti nella tabella trusted dello schema kamailio ed utilizzare la funzione allow_trusted([src_ip_pvar, proto_pvar, furi_pvar]).
Inseriamo i dati nella tabella
insert into trusted (src_ip, proto, ruri_pattern, tag) values ('54.171.127.192', 'any', '[:]0612345[@]', 'my-first-rule');
Abilitiamo il modulo permission nella configurazione di Kamailio
Per rendere leggibile la configurazione ho definito due global defines, #!define WITH_MYSQL e #!define WITH_CUSTOMER_CHECK, la prima mi serve per configurare l’accesso al database e la seconda per caricare il modulo permission e chiamare la funzione allow_trusted.
// Enable Customer IP-URI Number check
#!define WITH_MYSQL
#!define WITH_CUSTOMER_CHECK
Configuriamo i dati di accesso al database, utilizzando l’utente kamailio (con la sua password) creato in precedenza.
#!ifdef WITH_MYSQL
# - database URL - used to connect to database server by modules such
# as: auth_db, acc, usrloc, a.s.o.
#!trydef DBURL "mysql://kamailio:MyKamPwd101@localhost/kamailio"
#!endif
Carichiamo i moduli che ci servono.
#!ifdef WITH_MYSQL
loadmodule "db_mysql.so"
#!ifdef WITH_CUSTOMER_CHECK
loadmodule "auth.so"
loadmodule "auth_db.so"
loadmodule "permissions.so"
#!endif
#!endif
#!ifdef WITH_CUSTOMER_CHECK
modparam("permissions", "db_url", DBURL)
modparam("auth_db", "db_url", DBURL)
#!endif
Gestiamo la chiamata nella logica di routing di Kamailio
####### Routing Logic ########
/* Main SIP request routing logic
* - processing of any incoming SIP request starts with this route
* - note: this is the same as route { ... } */
request_route {
# Activate Dialog manage
if (!is_method("OPTIONS")) {
xlog("L_INFO","<$mb>\n");
# activate dialog manage
dlg_manage();
}
# customer check
route(CUSTOMERCHECK);
...
...
}
...
...
# Handle Customer IP - URI check
route[CUSTOMERCHECK] {
#!ifdef WITH_CUSTOMER_CHECK
if (is_method("INVITE")) {
xlog("L_INFO","allow_trusted: source IP $si, fromURI $fu, requestURI $ru\n");
if (!allow_trusted()) {
xlog("L_INFO","allow_trusted: $si - $ru not allowed\n");
$dlg_var(sipcode) = "503";
$dlg_var(sipmsg) = "Service Unavailable";
$dlg_var(errordsc) = "Customer not allowed";
send_reply("503", "Service Unavailable");
exit;
}
else {
xlog("L_INFO","allow_trusted: $si - $ru allowed\n");
}
}
#!endif
return;
}
...
...
La route CUSTOMERCHECK alla ricezione di un INVITE effettuerà il controllo dell’IP sorgente e della Request Uri tramite la funzione allow_trusted() e in caso di match positivo sulla tabella trusted ritornerà true e la logica di processing andrà avanti, in caso di match negativo ritornerà false e Kamailio restituirà una Response 503 Service Unavailable.