diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 21:30:40 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 21:30:40 +0000 |
commit | 133a45c109da5310add55824db21af5239951f93 (patch) | |
tree | ba6ac4c0a950a0dda56451944315d66409923918 /src/plugins/lua/asn.lua | |
parent | Initial commit. (diff) | |
download | rspamd-133a45c109da5310add55824db21af5239951f93.tar.xz rspamd-133a45c109da5310add55824db21af5239951f93.zip |
Adding upstream version 3.8.1.upstream/3.8.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/plugins/lua/asn.lua')
-rw-r--r-- | src/plugins/lua/asn.lua | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/plugins/lua/asn.lua b/src/plugins/lua/asn.lua new file mode 100644 index 0000000..24da19e --- /dev/null +++ b/src/plugins/lua/asn.lua @@ -0,0 +1,168 @@ +--[[ +Copyright (c) 2022, Vsevolod Stakhov <vsevolod@rspamd.com> +Copyright (c) 2016, Andrew Lewis <nerf@judo.za.org> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +]]-- + +local rspamd_logger = require "rspamd_logger" +local rspamd_regexp = require "rspamd_regexp" +local lua_util = require "lua_util" +local N = "asn" + +if confighelp then + return +end + +local options = { + provider_type = 'rspamd', + provider_info = { + ip4 = 'asn.rspamd.com', + ip6 = 'asn6.rspamd.com', + }, + symbol = 'ASN', + check_local = false, +} + +local rspamd_re = rspamd_regexp.create_cached("[\\|\\s]") + +local function asn_check(task) + + local function asn_set(asn, ipnet, country) + local descr_t = {} + local mempool = task:get_mempool() + if asn then + if tonumber(asn) ~= nil then + mempool:set_variable("asn", asn) + table.insert(descr_t, "asn:" .. asn) + else + rspamd_logger.errx(task, 'malformed ASN "%s" for ip %s', asn, task:get_from_ip()) + end + end + if ipnet then + mempool:set_variable("ipnet", ipnet) + table.insert(descr_t, "ipnet:" .. ipnet) + end + if country then + mempool:set_variable("country", country) + table.insert(descr_t, "country:" .. country) + end + if options['symbol'] then + task:insert_result(options['symbol'], 0.0, table.concat(descr_t, ', ')) + end + end + + local asn_check_func = {} + asn_check_func.rspamd = function(ip) + local dnsbl = options['provider_info']['ip' .. ip:get_version()] + local req_name = string.format("%s.%s", + table.concat(ip:inversed_str_octets(), '.'), dnsbl) + local function rspamd_dns_cb(_, _, results, dns_err, _, _, serv) + if dns_err and (dns_err ~= 'requested record is not found' and dns_err ~= 'no records with this name') then + rspamd_logger.errx(task, 'error querying dns "%s" on %s: %s', + req_name, serv, dns_err) + task:insert_result(options['symbol_fail'], 0, string.format('%s:%s', req_name, dns_err)) + return + end + if not results or not results[1] then + rspamd_logger.infox(task, 'no ASN information is available for the IP address "%s" on %s', + req_name, serv) + return + end + + lua_util.debugm(N, task, 'got reply from %s when requesting %s: %s', + serv, req_name, results[1]) + + local parts = rspamd_re:split(results[1]) + -- "15169 | 8.8.8.0/24 | US | arin |" for 8.8.8.8 + asn_set(parts[1], parts[2], parts[3]) + end + + task:get_resolver():resolve_txt({ + task = task, + name = req_name, + callback = rspamd_dns_cb + }) + end + + local ip = task:get_from_ip() + if not (ip and ip:is_valid()) or + (not options.check_local and ip:is_local()) then + return + end + + asn_check_func[options['provider_type']](ip) +end + +-- Configuration options +local configure_asn_module = function() + local opts = rspamd_config:get_all_opt('asn') + if opts then + for k, v in pairs(opts) do + options[k] = v + end + end + + local auth_and_local_conf = lua_util.config_check_local_or_authed(rspamd_config, N, + false, true) + options.check_local = auth_and_local_conf[1] + options.check_authed = auth_and_local_conf[2] + + if options['provider_type'] == 'rspamd' then + if not options['provider_info'] and options['provider_info']['ip4'] and + options['provider_info']['ip6'] then + rspamd_logger.errx("Missing required provider_info for rspamd") + return false + end + else + rspamd_logger.errx("Unknown provider_type: %s", options['provider_type']) + return false + end + + if options['symbol'] then + options['symbol_fail'] = options['symbol'] .. '_FAIL' + else + options['symbol_fail'] = 'ASN_FAIL' + end + + return true +end + +if configure_asn_module() then + local id = rspamd_config:register_symbol({ + name = 'ASN_CHECK', + type = 'prefilter', + callback = asn_check, + priority = lua_util.symbols_priorities.high, + flags = 'empty,nostat', + augmentations = { lua_util.dns_timeout_augmentation(rspamd_config) }, + }) + if options['symbol'] then + rspamd_config:register_symbol({ + name = options['symbol'], + parent = id, + type = 'virtual', + flags = 'empty,nostat', + score = 0, + }) + end + rspamd_config:register_symbol { + name = options['symbol_fail'], + parent = id, + type = 'virtual', + flags = 'empty,nostat', + score = 0, + } +else + lua_util.disable_module(N, 'config') +end |