Friday, December 5, 2014

Kamailio: auth_db setup with IP restriction


In this example, I will share how to authenticate SIP REGISTER and SIP INVITE against a database containing username, password and IP address. I have kamailio configured to use auth_db, usrloc, ipops (for IP restriction).
Here are snippets from the main config script, kamailio.cfg:
...

modparam("auth_db|usrloc", "db_url", DB_URL)
modparam("auth_db", "use_domain", 1)
modparam("auth_db", "calculate_ha1", 1)
modparam("auth_db", "user_column", "extension")
modparam("auth_db", "domain_column", "domain_name")
modparam("auth_db", "password_column", "password")
modparam("auth_db", "load_credentials", "$var(ip)=ip_address")

...

      if (is_method("REGISTER")) {
              # auth user/pass
              if(!www_authenticate("$fd", "user_extension")) {
                      www_challenge("$fd", "1");
              }
              # apply IP auth
              if (ip_type("$var(ip)") && !is_in_subnet("$si", "$var(ip)")) {
                      sl_send_reply( "403", "IP forbidden" );
                      exit;
              }
              if (!save("sip_registration")) {
                      sl_reply_error();
              }
              exit;
      }

...

      if (is_method("INVITE")) {
              if (!proxy_authenticate("$fd", "user_extension")) {
                      proxy_challenge("$fd", "1");
                      exit;
              }
              if (ip_type("$var(ip)") && !is_in_subnet("$si", "$var(ip)")) {
                      sl_send_reply( "403", "IP forbidden" );
                      exit;
              }
              # INVITE authenticated at this point, 
              # continue processing packet in next lines
              #
              # ...

      }

...


Here is my database schema for postgresql:
--
--  CREATE THE AUTO-INCREMENT SEQUENCE FOR TABLE
--
DROP SEQUENCE IF EXISTS public.user_extension_id CASCADE;
CREATE SEQUENCE public.user_extension_id
 INCREMENT BY 1
 MINVALUE 1
 MAXVALUE 9223372036854775807
 START WITH 1
 CACHE 1
 NO CYCLE
 OWNED BY NONE;
ALTER SEQUENCE public.user_extension_id OWNER TO kamailio;

--
--  CREATE THE TABLE
--
DROP TABLE IF EXISTS public.user_extension CASCADE;
CREATE TABLE public.user_extension(
 user_extension_id integer NOT NULL DEFAULT nextval('user_extension_id'::regclass),
 domain_name VARCHAR(64) DEFAULT '' NOT NULL,
 extension text,
 password text,
 ip_address text,
 CONSTRAINT user_extension_pkey PRIMARY KEY (user_extension_id),
 CONSTRAINT user_extension_key UNIQUE (domain_name,extension)

);
ALTER TABLE public.user_extension OWNER TO kamailio;

--
-- INSERT EXAMPLE USER
--
INSERT INTO user_extension (domain_name, extension, password, ip_address) VALUES ('sip.domain', '1000', '1000TEST1000', '192.168.0.11');

Assuming you have everything else setup correctly in Kamailio, you should be able to register to the proxy using username '1000', password '1000TEST1000' and from only the IP address '192.168.0.11'

*Please note you can use CIDR notation to allow whole subnets like 192.168.0.0/24

Thursday, August 21, 2014

TUTORIAL: Compile bind9 on linux with Response Rate Limiting (to prevent DDoS DNS attacks)

This tutorial can easily be applied to most any linux system. I went through these steps on Debian 7 server.

First let's setup the environment, this tutorial assumes you have no previous install of bind on the server.


mkdir -p /var/local/cache/bind
mkdir -p /usr/local/etc/bind

groupadd -g 5005 bind
useradd -u 5005 -g 5005 -d /var/local/cache/bind -M -s /bin/false bind

Now let's download the bind9 source code. This tutorial assumes you have the required dependencies installed. The only one I found tricky to locate was libkrb5-dev (on Debian you can install it with apt-get install libkrb5-dev)

cd /usr/src

wget http://ftp.isc.org/isc/bind9/cur/9.9/bind-9.9.5-P1.tar.gz

tar zxvf bind-9.9.5-P1.tar.gz

cd bind-9.9.5-P1

./configure '--enable-threads' '--enable-largefile' '--with-libtool' '--enable-shared' '--enable-static' '--with-openssl=/usr' '--with-gssapi=/usr' '--with-gnu-ld' '--with-geoip=/usr' '--enable-ipv6' '--enable-rrl'

make

make install

wget --user=ftp --password=ftp ftp://ftp.rs.internic.net/domain/db.cache -O /usr/local/etc/bind/db.root

Last step is to install the configuration files and startup scripts.

rndc-confgen -a -c /usr/local/etc/bind/rndc.key

cat > /etc/named.conf <<EOT
include "
/usr/local/etc/bind/rndc.key";
include "/usr/local/etc/bind/named.conf";

EOT
cat > /usr/local/etc/named.conf <<EOT
#
controls {
        inet 127.0.0.1 port 953
        allow { 127.0.0.1; 192.168.1.100; } keys { "rndc-key"; };
};

options {
        directory "/var/local/cache/bind";
        allow-new-zones yes;
        transfers-in 500;
        empty-zones-enable yes;
        //forwarders { 8.8.8.8; 8.8.4.4; };
        recursion yes;
        //allow-transfer {"none";};
        allow-query { any; };
        allow-recursion { any; };

        dnssec-validation auto;

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };

        rate-limit {
            responses-per-second 5;
            #window 5;
            #log-only yes;
        };
};

zone "." {
        type hint;
        file "/usr/local/etc/bind/db.root";
};

EOT
 

chown bind:bind -R /var/local/cache/bind
chown bind:bind -R /usr/local/etc/bind

Please note the init.d scripts only work on Debian based systems. I do not have init.d scripts for any other distribution.

Download the init.d script here
Download the init.d default file here

Copy the init.d script to /etc/init.d/bind9
Copy the init.d default file to /etc/default/bind9


chmod +x /etc/init.d/bind9

/etc/init.d/bind9 start