Daily Archive for May 13th, 2019

OpenSIPS: ratelimit with dynamically changeable value

This note will instruct you how to protect each DID number connected to your OpenSIPS from SIP DDoS, limiting not the total amount of INVITE requests going to your OpenSIPS server, but only INVITEs to some certain RURI.

Check it out, I hope you like it!

This is useful when you have a plenty of SIP numbers (DIDs) connected to your server and each one accepts inbound calls, e.g. a call centre or a taxi ordering service, etc. And you have to check each destination and drop too much requests, without degradation of any other incoming calls.

This is a nice solution to prevent the situation seen on the graph in the previous post.

PS: clustering support is not described here.

    loadmodule "ratelimit.so"		     # no deps
    modparam("ratelimit", "window_size", 2)  # ban timeout, sec

Add start limit value to the startup_route:

    startup_route {
    	cache_store("local", "incoming:ratelimit", "15");
    }

Somewhere in the initial INVITE section:

# AntiDDoS for each inbound call
if($si !~ "^10\..*") {
    cache_fetch("local", "incoming:ratelimit", $var(rl));
        # $var(rl) invites/sec going to each $rU.
        # SBT is the most precise policy.
        if (!rl_check("pipe_$rU", "$(var(rl){s.int})", "SBT")) {          
            sl_send_reply("503", "Service Unavailable. AntiDDoS");
            xlog("L_INFO", "call $ci from $fU@$si:$sp to $oU@$Ri drp by rl");
            exit;
        };
};

Live statistics:

voip-sipgw01 opensips # opensipsctl fifo rl_list
PIPE::  id=pipe_9618688830 algorithm=SBT limit=8 counter=0
PIPE::  id=pipe_9020578345 algorithm=SBT limit=8 counter=0
PIPE::  id=pipe_9611157347 algorithm=SBT limit=8 counter=0
PIPE::  id=pipe_79190224444 algorithm=SBT limit=8 counter=0
...
PIPE::  drop_rate=581

Change the limit on the fly up to 10 INVITES to each $rU:

opensipsctl fifo cache_store local incoming:ratelimit 10