Kamailio permission module

The permission module includes features and controls to create ACLs based on source IP, From, Request Uri. This allows to control who can do what, for example whether requests arriving from a certain source IP can be rotated to the destination, or whether a certain SIP Uri can be handled or must be rejected.

How to configure

The permission module is included by default in the Kamailio setup, therefore no further installation would be required. However, we will use a MySQL database to manage the access rules, and therefore we will also have to install the mysql module for Kamailio (e.g. kamailio-mysql-5.5.3 - package versions are available [here](https://rpm.kamailio .org/)).

To create the database schema for Kamailio, we can use the kamdbctl tool, and configure the required parameters in the /etc/kamailio/kamctlrc file, in particular the ** DBENGINE** in use, which in our case is 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"
	...

Run kamdbctl create to create the kamailio schema with its tables and the users kamailio and kamailioro.

Now all we have to do is configure Kamailio to be able to use the permission module, let’s see how.

In my scenario I want to check the traffic that arrives from a certain source IP and is directed to a certain SIP Uri, for example I want that the system accepts incoming calls from the address 54.171.127.192 and with the INVITE containing the number 0612345 in the SIP Uri, and rejects the others. To obtain this result we must insert the correct data into the trusted table of the kamailio schema and use the allow_trusted([src_ip_pvar, proto_pvar, furi_pvar]) function.

Add data into table

	insert into trusted (src_ip, proto, ruri_pattern, tag) values ('54.171.127.192', 'any', '[:]0612345[@]', 'my-first-rule');

Enable the permission module in the Kamailio configuration
To make the configuration readable I defined two global definitions, #!define WITH_MYSQL and #!define WITH_CUSTOMER_CHECK, the first used to configure access to the database and the second used to load the permission module and call the allow_trusted function.

	// Enable Customer IP-URI Number check
	#!define WITH_MYSQL
	#!define WITH_CUSTOMER_CHECK

Now configure the database access data, using the kamailio user (with its password) created previously.

	#!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

Load the modules.

	#!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

Manage the call in Kamailio’s routing logic

	####### 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;
	}
	...
	...

Upon receipt of an INVITE, the CUSTOMERCHECK route will check the source IP and the Request Uri via the allow_trusted() function and in case of a positive match on the trusted table it will return true and the processing logic will continue, in case of a negative match it will return false and Kamailio will return back a Response 503 Service Unavailable.