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.