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.