{"id":1109,"date":"2017-10-12T14:30:12","date_gmt":"2017-10-12T09:30:12","guid":{"rendered":"http:\/\/alexeyka.zantsev.com\/?p=1109"},"modified":"2021-02-28T01:37:27","modified_gmt":"2021-02-27T20:37:27","slug":"opensips-register-vs-permissions-module","status":"publish","type":"post","link":"https:\/\/alexeyka.zantsev.com\/?p=1109","title":{"rendered":"OpenSIPS battle: REGISTER requests vs permissions module"},"content":{"rendered":"<p>UPDATE: this post restricts access based on source IP address. A new article shows <a href=\"http:\/\/alexeyka.zantsev.com\/?p=1348\" target=\"_blank\" rel=\"noopener noreferrer\">how to restrict access (registrations) based on username<\/a>.<\/p>\n<p>Sutuation: you have to check the source address of REGISTER messages, going to your OpenSIPS server and decide wether to allow them or to deny.<\/p>\n<p>Use <a href=\"http:\/\/www.opensips.org\/html\/docs\/modules\/2.3.x\/permissions.html\" target=\"_blank\" rel=\"noopener noreferrer\">permissions<\/a> module for this.<\/p>\n<p>You can use it in two variants:<\/p>\n<p><strong>1.<\/strong> with OpenSIPS&#8217; text config files register.allow and register.deny (similar to Unix hosts.allow and hosts.deny).<br \/>\nIn this case you should use module&#8217;s function &#8216;<a href=\"http:\/\/www.opensips.org\/html\/docs\/modules\/2.3.x\/permissions.html#idp5645408\" target=\"_blank\" rel=\"noopener noreferrer\">allow_register<\/a>&#8216;<\/p>\n<p>Example of blocking REGISTERs from 10.145.13.49 IP address:<\/p>\n<p>register.deny file:<\/p>\n<pre>ALL : \"^sip:.*10\\.145\\.13\\.49\"\nALL : \"^sip:.*0*10\\.145\\.0*13\\.0*49\"   # this is to prevent bypassing\n                                       # by the insertion of one or more '0' in the IP address\n<\/pre>\n<p>register.allow file is empty (allow everything except those in .deny file).<\/p>\n<p>OpenSIPS script snippet:<\/p>\n<pre>\tif ( is_method(\"REGISTER\") ) {\n\t\tif (allow_register(\"register\")) {\n\t\t\tsave(\"location\");\n\t\t\texit;\n\t\t} else {\n\t\t\tsl_send_reply(\"403\", \"Forbidden registration from your IP v2\");\n\t\t\texit;\n\t\t}\n\t}\n<\/pre>\n<p>But this method has one big disadvantage &#8211; you need to restart OpenSIPS each time you edit register.allow\/register.deny.<br \/>\nOpenSIPS &#8216;permissions&#8217; module has a MI function &#8216;<a href=\"http:\/\/www.opensips.org\/html\/docs\/modules\/2.3.x\/permissions.html#idp5696288\" target=\"_blank\" rel=\"noopener noreferrer\">address_reload<\/a>&#8216; but it reloads the table (see below), not the allow\/deny files.<br \/>\nSo, it&#8217;s more cool to use the second variant, go on reading!..<\/p>\n<p><strong>2.<\/strong> with DB table &#8216;<a href=\"http:\/\/www.opensips.org\/Documentation\/Install-DBSchema-2-3#GEN-DB-ADDRESS\" target=\"_blank\" rel=\"noopener noreferrer\">address<\/a>&#8216;.<br \/>\nIn this case you should use modules&#8217; function &#8216;<a href=\"http:\/\/www.opensips.org\/html\/docs\/modules\/2.3.x\/permissions.html#idp5671920\" target=\"_blank\" rel=\"noopener noreferrer\">check_address<\/a>&#8216;<\/p>\n<p>&#8211; register.allow and register.deny files are empty.<br \/>\n&#8211; add entries to &#8216;address&#8217; table. In our case we&#8217;re using not real SQL DB but <a href=\"http:\/\/www.opensips.org\/html\/docs\/modules\/2.3.x\/db_text.html\" target=\"_blank\" rel=\"noopener noreferrer\">dbtext<\/a>. So, this is how &#8216;\/etc\/opensips\/dbtext\/address&#8217; file looks like:<\/p>\n<pre>voip-pbx-sbc ~ # cat \/etc\/opensips\/dbtext\/address \nid(int,auto) grp(int) ip(string) mask(int) port(int) proto(string) pattern(string,null) context_info(string,null)\n1:0:10.84.2.0:24:0:any\n2:0:10.145.13.5:32:0:any\n3:0:10.145.13.49:32:0:any\n4:0:10.145.14.0:24:0:any\n<\/pre>\n<p>WARNING: every time you add any new table, do not forget to add it&#8217;s version to another table &#8216;version&#8217;:<\/p>\n<pre>voip-pbx-sbc ~ # cat \/etc\/opensips\/dbtext\/version \ntable_name(string) table_version(int) \ndispatcher:8\nload_balancer:2\naddress:5\n<\/pre>\n<p>Firstly, I haven&#8217;t done it, and that&#8217;s why OpenSIPS could not start and I had this message in the system log:<\/p>\n<pre>ERROR:core:db_check_table_version: invalid version 0 for table address found, expected 5\n<\/pre>\n<p>So, the script snippet with the &#8216;check_address&#8217; function:<\/p>\n<pre>\tif ( is_method(\"REGISTER\") ) {\n\n\t\tif(check_address(\"0\",\"$si\",\"0\",\"any\")) {\n\t\t\tsave(\"location\");\n\t\t\texit;\n\t\t} else {\n\t\t\tsl_send_reply(\"403\", \"Forbidden registration from your IP v2\");\n\t\t\texit;\n\t\t}\n\n\t}\n<\/pre>\n<p>And here&#8217;s the magic! You may add IP-addresses or subnets to your DB or dbtext file and then run a MI command &#8216;<a href=\"http:\/\/www.opensips.org\/html\/docs\/modules\/2.3.x\/permissions.html#idp5696288\" target=\"_blank\" rel=\"noopener noreferrer\">address_reload<\/a>&#8216; without restarting your high-loaded OpenSIPS.<\/p>\n<p>Now the policy is &#8220;if address is in the table &#8211; allow it, otherwise block&#8221;. Look at the images below.<\/p>\n<p>IP is not in the table &#8211; REGISTER is forbidden:<br \/>\n<a href=\"https:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2017\/10\/perm.deny_.1.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" src=\"http:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2017\/10\/perm.deny_.1.png\" alt=\"\" width=\"500\" \/><\/a><\/p>\n<p><a href=\"https:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2017\/10\/perm.deny_.2.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" src=\"http:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2017\/10\/perm.deny_.2.png\" alt=\"\" width=\"500\" \/><\/a><\/p>\n<p>IP has been added to dbtext table and table reloaded &#8211; registrations passed successfully:<br \/>\n<a href=\"https:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2017\/10\/perm.allow_.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" src=\"http:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2017\/10\/perm.allow_.png\" alt=\"\" width=\"500\" \/><\/a><\/p>\n<p>You can also look the table&#8217;s contents with MI commands &#8216;opensipsctl fifo <a href=\"http:\/\/www.opensips.org\/html\/docs\/modules\/2.3.x\/permissions.html#idp5700208\" target=\"_blank\" rel=\"noopener noreferrer\">address_dump<\/a>&#8216; and &#8216;opensipsctl fifo <a href=\"http:\/\/www.opensips.org\/html\/docs\/modules\/2.3.x\/permissions.html#idp5703888\" target=\"_blank\" rel=\"noopener noreferrer\">subnet_dump<\/a>&#8216;.<br \/>\n<a href=\"https:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2017\/10\/perm.mi_.commands.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" src=\"http:\/\/alexeyka.zantsev.com\/wp-content\/uploads\/2017\/10\/perm.mi_.commands.png\" alt=\"\" width=\"500\" \/><\/a><\/p>\n<p>UPD: OpenSIPS core developer&#8217;s answer to my question http:\/\/lists.opensips.org\/pipermail\/users\/2017-October\/038169.html .<\/p>\n","protected":false},"excerpt":{"rendered":"<p>UPDATE: this post restricts access based on source IP address. A new article shows how to restrict access (registrations) based on username. Sutuation: you have to check the source address of REGISTER messages, going to your OpenSIPS server and decide wether to allow them or to deny. Use permissions module for this. You can use [&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,137,151],"class_list":["post-1109","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-opensips","tag-permissions","tag-register"],"_links":{"self":[{"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=\/wp\/v2\/posts\/1109","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=1109"}],"version-history":[{"count":34,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=\/wp\/v2\/posts\/1109\/revisions"}],"predecessor-version":[{"id":3647,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=\/wp\/v2\/posts\/1109\/revisions\/3647"}],"wp:attachment":[{"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1109"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1109"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alexeyka.zantsev.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1109"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}