# &adminguide;

## Overview

This module has been designed to offer an additional layer of security over our communications. To achieve this, the following features are available:

- Blacklist to block user agents, IP addresses, countries, domains and users.

- Whitelist to allow user agents, IP addresses, countries, domains and users.

- Blacklist of destinations where the called number is not allowed.

- SQL injection attacks prevention.

When a function is called, it will be searched in the whitelist. If the value is not found, then the blacklist will be searched.

All data will be loaded into memory when the module is started. There is an RPC reload command to update all the data from database. It is also possible to add new data to the blacklist or whitelist using other RPC commands.

## Dependencies

### &kamailio; Modules

The following modules must be loaded before this module:

- database -- Any db_* database module

### External Libraries or Applications

The following libraries or applications must be installed before running &kamailio; with this module loaded:

- none

## Parameters

### `db_url` (string)

Database URL.

Default value is ""

#### Set `db_url` parameter

    		...
    		modparam("secfilter", "db_url", "mysql://user:pass@localhost/kamailio")
    		...

### `table_name` (string)

Name of the table used to store the blacklisted and whitelisted values.

Default value is secfilter

#### Set `table_name` parameter

    		...
    		modparam("secfilter", "table_name", "secfilter")
    		...

### `action_col` (string)

Name of database column containing the type of list. The possible values are:

- 0 = blacklisted data
- 1 = whitelisted data
- 2 = blacklisted destination number

Default value is action

#### Set `action_col` parameter

    		...
    		modparam("secfilter", "action_col", "action")
    		...

### `type_col` (string)

Name of database column containing the type of values. The possible values are:

- 0 = user-agent (if action=0 or action=1)
- 0 = destination number (if action=2)
- 1 = country
- 2 = domain
- 3 = IP address
- 4 = user

Default value is type

#### Set `type_col` parameter

    		...
    		modparam("secfilter", "type_col", "type")
    		...

### `data_col` (string)

Name of database column containing blacklisted and whitelisted values.

Default value is data

#### Set `data_col` parameter

    		...
    		modparam("secfilter", "data_col", "data")
    		...

### `dst_exact_match` (integer)

This value is used in the destinations blacklist and corresponds to the numbers that we want to prevent calling. If the value is 1, the call will appear as blacklisted if the destination is exactly the same. If the value is 0, every destination whose number begins with a number appearing on the destination blacklist will be rejected.

Default value is 1

#### Set `dst_exact_match` parameter

    		...
    		modparam("secfilter", "dst_exact_match", 1)
    		...

### `reload_delta` (integer)

The number of seconds that have to be waited before executing a new RPC reload. By default there is a rate limiting of maximum one reload in five seconds. If set to 0, no rate limit is configured.

Default value is 5

#### Set `reload_delta` parameter

    		...
    		modparam("secfilter", "reload_delta", 1)
    		...

### `cleanup_interval` (integer)

The number of seconds that have to be wait before cleanup the previous values from memory after a RPC reload.

Default value is 60

#### Set `cleanup_interval` parameter

    		...
    		modparam("secfilter", "cleanup_interval", 120)
    		...

## Functions

### `secf_check_ip ()`

It checks if the source IP address is blacklisted. The search is approximate and data stored in the database will be compared as a prefix. For example, if we have blacklisted IP address 192.168.1. all messages from IPs like 192.168.1.% will be rejected.

Return values are:

- 2 = the value is whitelisted
- 1 = the value is not found
- -2 = the value is blacklisted

#### `secf_check_ip` usage

    		...
            secf_check_ip();
            if ($? == -2) {
                    xlog("L_ALERT", "$rm from $si blocked because IP address is blacklisted");
                    exit;
            }
    		...

### `secf_check_ua ()`

It checks if the user-agent is blacklisted. The search is approximate and the comparison will be made using the values of the database as a prefix. If we add to the user-agent blacklist the word sipcli, every message whose user-agent is named, for example, sipcli/1.6 or sipcli/1.8 will be blocked. It is very useful to block different versions of the same program.

Return values are:

- 2 = the value is whitelisted
- 1 = the value is not found
- -1 = error
- -2 = the value is blacklisted

#### `secf_check_ua` usage

    		...
            secf_check_ua();
            if ($? == -2) {
                    xlog("L_ALERT", "$rm from $si blocked because UserAgent '$ua' is blacklisted");
                    exit;
            }
    		...

### `secf_check_country (string)`

Similar to secf_check_ua. It checks if the country (IP address) is blacklisted. Geoip module must be loaded to get the country code.

Return values are:

- 2 = the value is whitelisted
- 1 = the value is not found
- -1 = error
- -2 = the value is blacklisted

You can filter by blocking the IPs of messages coming from countries that are on the blacklist. Alternatively, you can block everything that is not explicitly on the whitelist.

#### `secf_check_country` usage

    		...
    	if (geoip2_match("$si", "src")) {
                    secf_check_country($gip2(src=>cc));
                    if ($? == -2) {
                            xdbg("$rm from $si blocked because Country '$gip2(src=>cc)' is blacklisted");
                            exit;
                    }
            }

    		...

            if (geoip2_match("$si", "src")) {
                    secf_check_country($gip2(src=>cc));
                    if ($? != 2) {
                            xdbg("$rm from $si blocked because Country '$gip2(src=>cc)' is not whitelisted");
                            exit;
                    }
            }
    		...

### `secf_check_from_hdr ()`

It checks if any value of from header is blacklisted. It checks if from name or from user are in the users blacklist or whitelist. It also checks if the from domain is in the domains blacklist or whitelist. The blacklisted value will be used as a prefix and if we block, for example, the user sipvicious, all users whose name starts with this word will be considered as blacklisted.

Return values are:

- 4 = from name is whitelisted
- 3 = from domain is whitelisted
- 2 = from user is whitelisted
- 1 = from header not found
- -1 = error
- -2 = from user is blacklisted
- -3 = from domain is blacklisted
- -4 = from name is blacklisted

#### `secf_check_from_hdr` usage

    		...
            secf_check_from_hdr();
            switch ($?) {
                    case -2:
                            xlog("L_ALERT", "$rm to $si blocked because From user '$fU' is blacklisted");
                            exit;
                    case -3:
                            xlog("L_ALERT", "$rm to $si blocked because From domain '$fd' is blacklisted");
                            exit;
                    case -4:
                            xlog("L_ALERT", "$rm to $si blocked because From name '$fn' is blacklisted");
                            exit;
            };
    		...

### `secf_check_to_hdr ()`

Do the same as secf_check_from_hdr function but with the to header.

Return values are:

- 4 = to name is whitelisted
- 3 = to domain is whitelisted
- 2 = to user is whitelisted
- 1 = to header not found
- -1 = error
- -2 = to user is blacklisted
- -3 = to domain is blacklisted
- -4 = to name is blacklisted

#### `secf_check_to_hdr` usage

    		...
            secf_check_to_hdr();
            switch ($?) {
                    case -2:
                            xlog("L_ALERT", "$rm to $si blocked because To user '$tU' is blacklisted");
                            exit;
                    case -3:
                            xlog("L_ALERT", "$rm to $si blocked because To domain '$td' is blacklisted");
                            exit;
                    case -4:
                            xlog("L_ALERT", "$rm to $si blocked because To name '$tn' is blacklisted");
                            exit;
            };
    		...

### `secf_check_contact_hdr ()`

Do the same as secf_check_from_hdr function but with the contact header.

Return values are:

- 3 = contact domain is whitelisted
- 2 = contact user is whitelisted
- 1 = contact header not found
- -1 = error
- -2 = contact user is blacklisted
- -3 = contact domain is blacklisted

#### `secf_check_contact_hdr` usage

    		...
            secf_check_contact_hdr();
            switch ($?) {
                    case -2:
                            xlog("L_ALERT", "$rm to $si blocked because Contact user '$ct' is blacklisted");
                            exit;
                    case -3:
                            xlog("L_ALERT", "$rm to $si blocked because Contact domain '$ct' is blacklisted");
                            exit;
            };
    		...

### `secf_check_dst (string)`

It checks if the destination number is blacklisted. It must be user for INVITE messages. If the value of dst_exact_match is 1, the call will appear as blacklisted if the destination is exactly the same. If the value is 0, every destination whose number begins with a number appearing on the destination blacklist will be rejected.

Return values are:

- 2 (if the value is whitelisted)
- 1 (if the value not found)
- -2 (if the value is blacklisted)

#### `secf_check_dst` usage

    		...
    		if (is_method("INVITE")) {
    			secf_check_dst($rU);
    			if ($? == -2) {
    				xlog("L_ALERT", "$rm from $si blocked because destination $rU is blacklisted");
    				send_reply("403", "Forbidden");
    				exit;
    			}
    		}
    		...

### `secf_check_sqli_hdr (string)`

Search for illegal characters in the given value.

#### `secf_check_sqli_hdr` usage

    		...
            secf_check_sqli_hdr($ua);
            if ($? == -1) {
                    xlog("L_ALERT", "$rm from $si blocked because possible SQLi found in the user-agent header ($ua)");
                    exit;
            }

    		...

### `secf_check_sqli_all ()`

Search for illegal characters in several headers (user-agent, from, to and contact). If illegal characters are found the message will be dropped.

#### `secf_check_sqli_all` usage

    		...
    		secf_check_sqli_all();
    		...

## RPC commands

### `secfilter.reload`

Reload all blacklisted and whitelisted values from database.

#### `secfilter.reload` usage

    		...
    		&kamctl; rpc secfilter.reload
    		...

### `secfilter.print`

Print blacklisted and whitelisted values. Without parameters it will print all values. If you enter a type it will print this type values only.

Possible values are:

- (none) (show all data)
- ua (show blacklisted and whitelisted user-agents)
- country (show blacklisted and whitelisted countries)
- domain (show blacklisted and whitelisted domains)
- user (show blacklisted and whitelisted users)
- ip (show blacklisted and whitelisted IP addresses)
- dst (show blacklisted destinations)

#### `secfilter.print` usage

    		...
    		&kamctl; rpc secfilter.print
    		&kamctl; rpc secfilter.print ua
    		&kamctl; rpc secfilter.print country
    		&kamctl; rpc secfilter.print dst
    		...

### `secfilter.stats`

Print statistics of blocked and allowed messages.

#### `secfilter.stats` usage

    		...
    		&kamctl; rpc secfilter.stats
    		...

### `secfilter.stats_reset`

Reset all statistics.

#### `secfilter.stats_reset` usage

    		...
    		&kamctl; rpc secfilter.stats_reset
    		...

### `secfilter.add_dst`

Insert values into destination blacklist. These values will be checked with the function secf_check_dst to verify if the destination number can be called.

Parameters:

- number (number to add to the destination blacklist)

#### `secfilter.add_dst` usage

    		...
    		&kamctl; rpc secfilter.add_dst 555123123
    		...

### `secfilter.del_dst`

Delete value from destination blacklist.

Parameters:

- number (number to remove from the destination blacklist)

#### `secfilter.del_dst` usage

    		...
    		&kamctl; rpc secfilter.del_dst 555123123
    		...

### `secfilter.add_bl`

Insert values into blacklist.

Parameters:

- type (must be: ua, country, domain, user or ip)
- value (value to add to the blacklist)

#### `secfilter.add_bl` usage

    		...
    		&kamctl; rpc secfilter.add_bl ua friendly-scanner
    		&kamctl; rpc secfilter.add_bl user sipvicious
    		...

### `secfilter.del_bl`

Delete value from blacklist.

Parameters:

- type (must be: ua, country, domain, user or ip)
- value (value to remove from the blacklist)

#### `secfilter.del_bl` usage

    		...
    		&kamctl; rpc secfilter.del_bl ua friendly-scanner
    		&kamctl; rpc secfilter.del_bl user sipvicious
    		...

### `secfilter.add_wl`

Insert values into whitelist.

Parameters:

- type (must be: ua, country, domain, user or ip)
- value (value to add to the whitelist)

#### `secfilter.add_wl` usage

    		...
    		&kamctl; rpc secfilter.add_wl country es
    		&kamctl; rpc secfilter.add_wl user trusted_user
    		...

### `secfilter.del_wl`

Delete value from whitelist.

Parameters:

- type (must be: ua, country, domain, user or ip)
- value (value to remove from the blacklist)

#### `secfilter.del_wl` usage

    		...
    		&kamctl; rpc secfilter.del_wl country es
    		&kamctl; rpc secfilter.del_wl user trusted_user
    		...

## Installation

### Database setup

Before running &kamailio; with the secfilter module, it is necessary to set up the database table where the module will read the blacklist data from. In order to do that, if the table was not created by the installation script or you choose to install everything by yourself you can use the secfilter-create.sql SQL script in the database directories in the kamailio/scripts folder as a template. Database and table name can be set with module parameters so they can be changed, but the name of the columns must match the ones in the SQL script. You can also find the complete database documentation on the project webpage, &kamailiodbdocs;.

#### Example database content - secfilter table

    		...
    		+----+-----------+-----------+------------------+
    		| id | action    | type      | data             |
    		+----+-----------+-----------+------------------+
    		|  1 | 0         | 2         | 1.1.1.1          |
    		|  2 | 0         | 0         | friendly-scanner |
    		|  3 | 0         | 0         | pplsip           |
    		|  4 | 0         | 0         | sipcli           |
    		|  5 | 0         | 4         | sipvicious       |
    		|  6 | 0         | 1         | ps               |
    		|  7 | 0         | 3         | 5.56.57.58       |
    		|  8 | 1         | 0         | asterisk pbx     |
    		|  9 | 1         | 2         | sip.mydomain.com |
    		| 10 | 2         | 0         | 555123123        |
    		| 11 | 2         | 0         | 555998776        |
    		+----+-----------+-----------+------------------+
    		...

Action values are:

- 0 (blacklist)
- 1 (whitelist)
- 2 (destination)

Type values are:

- 0 (user-agent)
- 1 (country)
- 2 (domain)
- 3 (IP address)
- 4 (user)

## Some examples

### Print data

#### kamctl rpc secfilter.print ua

    		...
    {
            User-Agent: {
                    Blacklisted: {
                            Value: friendly-scanner
                            Value: pplsip
                            Value: sipcli
                            Value: sundayddr
                            Value: iWar
                            Value: sipsak
                            Value: VaxSIPUserAgent
                            Value: SimpleSIP
                            Value: SIP Call
                            Value: Ozeki
                            Value: VoIPSec
                            Value: SIPScan
                            Value: Conaito
                            Value: UsaAirport
                            Value: PortSIP VoIP SDK
                            Value: zxcvfdf11
                            Value: fdgddfg546df4g8d5f
                            Value: siptest
                            Value: Nmap NSE
                    }
                    Whitelisted: {
                            Value: my custom ua
                    }
            }
    }
    		...

### Statistics

#### kamctl rpc secfilter.stats

    		...
    {
            Blacklist: {
                    User-Agent: 1256
                    Country: 45
                    From-Domain: 0
                    To-Domain: 0
                    Contact-Domain: 1
                    IP-Address: 2552
                    From-Name: 0
                    To-Name: 0
                    Contact-Name: 0
                    From-User: 316
                    To-User: 0134
                    Contact-User: 0
            }
            Whitelist: {
                    User-Agent: 0
                    Country: 478
                    From-Domain: 0
                    To-Domain: 0
                    Contact-Domain: 0
                    IP-Address: 0
                    From-Name: 0
                    To-Name: 0
                    Contact-Name: 0
                    From-User: 0
                    To-User: 0
                    Contact-User: 0
            }
            Other: {
                    Destination: 0
                    SQL-Injection: 213
            }
    }
    		...