aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-02-14 10:23:54 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-02-14 10:23:54 +0000
commit6903ec48c4bdff1ad76ffd952c76c39adffa2db6 (patch)
tree82174c1fcbc6727ea69fda9e323a01c69d1edb75
parent4fb6e04bc74bb04c577a66765d83ee45b2ee788b (diff)
parentbab9f14abf2c2201a51c3f9e5932403095926c30 (diff)
downloadrspamd-6903ec48c4bdff1ad76ffd952c76c39adffa2db6.tar.gz
rspamd-6903ec48c4bdff1ad76ffd952c76c39adffa2db6.zip
Merge pull request #166 from fatalbanana/master
rbl.lua: Ignore private IP space
-rw-r--r--conf/modules.conf1
-rw-r--r--doc/markdown/modules/rbl.md4
-rw-r--r--src/plugins/lua/rbl.lua58
3 files changed, 57 insertions, 6 deletions
diff --git a/conf/modules.conf b/conf/modules.conf
index de125866a..2f291de79 100644
--- a/conf/modules.conf
+++ b/conf/modules.conf
@@ -87,6 +87,7 @@ rbl {
default_from = true;
default_received = false;
default_exclude_users = true;
+ default_exclude_private_ips = true;
rbls {
diff --git a/doc/markdown/modules/rbl.md b/doc/markdown/modules/rbl.md
index 41854c542..2c654c808 100644
--- a/doc/markdown/modules/rbl.md
+++ b/doc/markdown/modules/rbl.md
@@ -53,6 +53,10 @@ If set to false, do not yield a result unless the response received from the RBL
If set to true, do not use this RBL if the message sender is authenticated.
+- default_exclude_private_ips (false)
+
+If set to true, from/received RBL checks will ignore private IP address space.
+
RBL-specific subsection is structured as follows:
~~~nginx
diff --git a/src/plugins/lua/rbl.lua b/src/plugins/lua/rbl.lua
index 12b42f186..6950ab7cb 100644
--- a/src/plugins/lua/rbl.lua
+++ b/src/plugins/lua/rbl.lua
@@ -32,6 +32,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
local rbls = {}
local rspamd_logger = require "rspamd_logger"
+local rspamd_ip = require "rspamd_ip"
local function validate_dns(lstr, rstr)
if (lstr:len() + rstr:len()) > 252 then
@@ -46,6 +47,43 @@ local function validate_dns(lstr, rstr)
return true
end
+local private_ranges_v4 = {
+ {[1] = rspamd_ip.from_string("127.0.0.0"), [2] = 8},
+ {[1] = rspamd_ip.from_string("10.0.0.0"), [2] = 8},
+ {[1] = rspamd_ip.from_string("192.168.0.0"), [2] = 16},
+ {[1] = rspamd_ip.from_string("169.254.0.0"), [2] = 16},
+ {[1] = rspamd_ip.from_string("172.16.0.0"), [2] = 12},
+ {[1] = rspamd_ip.from_string("100.64.0.0"), [2] = 10},
+}
+
+local private_ranges_v6 = {
+ {[1] = rspamd_ip.from_string("fc00::"), [2] = 7},
+ {[1] = rspamd_ip.from_string("fe80::"), [2] = 10},
+ {[1] = rspamd_ip.from_string("fec0::"), [2] = 10},
+}
+
+local ipv6_loopback = rspamd_ip.from_string("::1")
+
+local function is_private_ip(rip)
+ if rip:get_version() == 4 then
+ for _, r in pairs(private_ranges_v4) do
+ if r[1] == rip:apply_mask(r[2]) then
+ return true
+ end
+ end
+ else
+ if rip == ipv6_loopback then
+ return true
+ end
+ for _r in pairs(private_ranges_v6) do
+ if r[1] == rip:apply_mask(r[2]) then
+ return true
+ end
+ end
+ end
+ return false
+end
+
local function ip_to_rbl(ip, rbl)
return table.concat(ip:inversed_str_octets(), ".") .. '.' .. rbl
end
@@ -161,7 +199,8 @@ local function rbl_cb (task)
end
if not havegot['from'] then
havegot['from'] = task:get_from_ip()
- if not havegot['from']:is_valid() then
+ if not havegot['from']:is_valid() or
+ (rbl['exclude_private_ips'] and is_private_ip(havegot['from'])) then
notgot['from'] = true
return
end
@@ -188,10 +227,12 @@ local function rbl_cb (task)
end
for _,rh in ipairs(havegot['received']) do
if rh['real_ip'] and rh['real_ip']:is_valid() then
- if (rh['real_ip']:get_version() == 6 and rbl['ipv6']) or
- (rh['real_ip']:get_version() == 4 and rbl['ipv4']) then
- task:get_resolver():resolve_a(task:get_session(), task:get_mempool(),
- ip_to_rbl(rh['real_ip'], rbl['rbl']), rbl_dns_cb, k)
+ if ((rh['real_ip']:get_version() == 6 and rbl['ipv6']) or
+ (rh['real_ip']:get_version() == 4 and rbl['ipv4'])) and
+ ((rbl['exclude_private_ips'] and not is_private_ip(rh['real_ip'])) or
+ not rbl['exclude_private_ips']) then
+ task:get_resolver():resolve_a(task:get_session(), task:get_mempool(),
+ ip_to_rbl(rh['real_ip'], rbl['rbl']), rbl_dns_cb, k)
end
end
end
@@ -213,6 +254,7 @@ if type(rspamd_config.get_api_version) ~= 'nil' then
rspamd_config:register_module_option('rbl', 'default_helo', 'string')
rspamd_config:register_module_option('rbl', 'default_unknown', 'string')
rspamd_config:register_module_option('rbl', 'default_exclude_users', 'string')
+ rspamd_config:register_module_option('rbl', 'default_exclude_private_ips', 'string')
end
end
@@ -245,8 +287,12 @@ end
if(opts['default_exclude_users'] == nil) then
opts['default_exclude_users'] = false
end
+if(opts['default_exclude_private_ips'] == nil) then
+ opts['default_exclude_private_ips'] = false
+end
+
for key,rbl in pairs(opts['rbls']) do
- local o = { "ipv4", "ipv6", "from", "received", "unknown", "rdns", "helo", "exclude_users" }
+ local o = { "ipv4", "ipv6", "from", "received", "unknown", "rdns", "helo", "exclude_users", "exclude_private_ips" }
for i=1,table.maxn(o) do
if(rbl[o[i]] == nil) then
rbl[o[i]] = opts['default_' .. o[i]]