{"id":1194,"date":"2018-05-23T09:17:28","date_gmt":"2018-05-23T04:17:28","guid":{"rendered":"http:\/\/alexeyka.zantsev.com\/?p=1194"},"modified":"2021-02-28T01:34:58","modified_gmt":"2021-02-27T20:34:58","slug":"opensips-clients-ip-address-blacklisting-with-iptables-rule-expiration","status":"publish","type":"post","link":"https:\/\/alexeyka.zantsev.com\/?p=1194","title":{"rendered":"SIP flood vs OpenSIPS armed with pike.so, exec.so, ipset and iptables"},"content":{"rendered":"<p>Preface: the <a href=\"http:\/\/www.opensips.org\/html\/docs\/modules\/2.4.x\/pike.html\" target=\"_blank\" rel=\"noopener noreferrer\">PIKE<\/a> module itself blocks SIP requests (just stops sending any replies) in case of flood. This article is about going on &#8211; adding flooding IP addresses to ipset for further rejecting any traffic to the OpenSIPS server using iptables.<\/p>\n<p>1. Create an ipset with auto removing addresses after 120 seconds and ability to add comments.<\/p>\n<pre>ipset create SIPFLOOD hash:ip timeout 120 comment\n<\/pre>\n<p>2. An iptables rule, which will drop incoming traffic from src IP addresses from created ipset table:<\/p>\n<pre>iptables -A INPUT -m set --match-set SIPFLOOD src -j DROP\n<\/pre>\n<p>3. Allow OpenSIPS&#8217; run-user (usually &#8216;opensips&#8217;) executing &#8216;ipset&#8217; command without a password (add this line to \/etc\/sudoers using &#8216;visudo&#8217; command):<\/p>\n<pre>opensips ALL= NOPASSWD: \/sbin\/ipset\n<\/pre>\n<p>4. OpenSIPS configuration.<\/p>\n<p>Part of modules section of config:<br \/><code><br \/>\n#### exec<br \/>\nloadmodule \"exec.so\"<\/code><\/p>\n<p><code><br \/>\n<\/code><\/p>\n<p><code>#### antiflood module<br \/>\nloadmodule \"pike.so\"<br \/>\nmodparam(\"pike\", \"sampling_time_unit\", 2)<br \/>\nmodparam(\"pike\", \"reqs_density_per_unit\", 10)<br \/>\nmodparam(\"pike\", \"remove_latency\", 120)<br \/>\n<\/code><\/p>\n<p>Part of OpenSIPS script, assuming that somebody sends us too much OPTIONS requests:<\/p>\n<pre>if(is_method(\"OPTIONS\")) {\n\n    pike_check_req();\n    switch($retcode) {\n        case -2:    # detected once - simply drop the request\n            exit;\n        case -1:    # detected again - ban the IP and drop request\n            exec(\"\/usr\/bin\/sudo ipset -exist add SIPFLOOD $si\");\n            exit;\n    }\n\n    sl_send_reply(\"200\", \"OK\");\n    exit;\n}\n<\/pre>\n<p>5. You may test all this with &#8216;sipp&#8217; tool.<\/p>\n<p>This is for generating 10 requests (-r) in 2 seconds (-rp 2000) and exiting sipp after sending 10 requests (-m):<\/p>\n<pre>sipp 172.16.0.222 -r 10 -rp 2000 -m 10 -sf OPTIONS.xml\n<\/pre>\n<p>This &#8211; for generating 70 requests (-r) in 2 seconds (-rp 2000) and exiting sipp after sending 70 requests (-m):<\/p>\n<pre>sipp 172.16.0.222 -r 70 -rp 2000 -m 70 -sf OPTIONS.xml\n<\/pre>\n<p>The OPTIONS.xml is as follows:<\/p>\n<p><a href=\"https:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2018\/05\/sipp.options.xml_.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1219\" src=\"http:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2018\/05\/sipp.options.xml_.png\" alt=\"\" width=\"505\" height=\"340\" \/><\/a><\/p>\n\n\n<p>UPD 2019-july-30: pike writes log messages (at least in automatic mode, but I&#8217;m sure that also in the manual ):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> Jul 30 06:59:05 ... \/opensips[15531]: PIKE - BLOCKing ip 46.166.151.117, node=0x7f6dec201c08<br> Jul 30 06:59:05 ... \/opensips[15533]: PIKE - UNBLOCKing node 0x7f6dec201b38<br> Jul 30 06:59:07 ... \/opensips[15531]: PIKE - BLOCKing ip 46.166.151.163, node=0x7f6dec201d40<br><\/pre>\n\n\n\n<p>If you do not need all these messages (in case of SIP flood it may be too many), just set the log_level for pike.so module:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">modparam(\"pike\", \"pike_log_level\", 3)<\/pre>\n\n\n\n<p>And then set the log_level for your OpenSIPS to be not so verbose (pike&#8217;s log_level must be greater than global):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">opensips-cli -x mi log_level 2<\/pre>\n\n\n\n<p>&#8230; or\/and in config file:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">log_level=2<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Preface: the PIKE module itself blocks SIP requests (just stops sending any replies) in case of flood. This article is about going on &#8211; adding flooding IP addresses to ipset for further rejecting any traffic to the OpenSIPS server using iptables. 1. Create an ipset with auto removing addresses after 120 seconds and ability to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[208],"class_list":["post-1194","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-opensips"],"_links":{"self":[{"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=\/wp\/v2\/posts\/1194","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1194"}],"version-history":[{"count":30,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=\/wp\/v2\/posts\/1194\/revisions"}],"predecessor-version":[{"id":3645,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=\/wp\/v2\/posts\/1194\/revisions\/3645"}],"wp:attachment":[{"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1194"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1194"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1194"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}