Monthly Archive for May, 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

OpenSIPS: batch dialogs killer one-liner

Situation: VoIP ISP server suddenly became unavailable and you have some thousands of dialogs like this:

dialog::  ID=17580696317398
	state:: 3
	user_flags:: 0
	timestart:: 1556697836
	datestart:: 2019-05-01 13:03:56
	timeout:: 1556701436
	dateout:: 2019-05-01 14:03:56
	callid:: 7EB7F3F9-6B1E11E9-90F3C2ED-81742C80@XX.YY.168.28
	from_uri:: sip:ZZZXXX7146@XX.YY.168.28
	to_uri:: sip:NNNN902290@XX.YY.169.130
	caller_tag:: 8999291C-450
	caller_contact:: sip:ZZZXXX7146@XX.YY.168.28:5060
	callee_cseq:: 0
	caller_route_set:: <sip:XX.YY.169.130;lr=on;ftag=8999291C-450;did=dff3.a92b;nat=yes>
	caller_bind_addr:: udp:EE.FF.116.74:5060
	caller_sdp:: 
	CALLEES:: 
		callee:: 
			callee_tag:: as3d7dee61
			callee_contact:: sip:abc@EE.FF.116.62:5060;transport=udp
			caller_cseq:: 101
			callee_route_set:: 
			callee_bind_addr:: udp:EE.FF.116.74:5060
			callee_sdp:: 

To kill them in some seconds (not to wait when OpenSIPS will terminate them according to SIP timers), do:

for i in `opensipsctl fifo dlg_list | grep callid | grep \@XX.YY.168.28 | awk '{print $2}'` ; do opensipsctl fifo dlg_end_dlg $i ; done

In fact, the situation was as follows: VoIP software on the ISP side (we have a DID from it connected to our OpenSIPS cluster) had some problems and they suddenly started sending us a bunch of unique INVITES (with different Call-IDs) for any certain inbound call.

Very soon the total number of dialogs dramatically increased up to enormous values. And this is a theme of my next article!