You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

asn.lua 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. --[[
  2. Copyright (c) 2022, Vsevolod Stakhov <vsevolod@rspamd.com>
  3. Copyright (c) 2016, Andrew Lewis <nerf@judo.za.org>
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. ]]--
  14. local rspamd_logger = require "rspamd_logger"
  15. local rspamd_regexp = require "rspamd_regexp"
  16. local lua_util = require "lua_util"
  17. local N = "asn"
  18. if confighelp then
  19. return
  20. end
  21. local options = {
  22. provider_type = 'rspamd',
  23. provider_info = {
  24. ip4 = 'asn.rspamd.com',
  25. ip6 = 'asn6.rspamd.com',
  26. },
  27. symbol = 'ASN',
  28. check_local = false,
  29. }
  30. local rspamd_re = rspamd_regexp.create_cached("[\\|\\s]")
  31. local function asn_check(task)
  32. local function asn_set(asn, ipnet, country)
  33. local descr_t = {}
  34. local mempool = task:get_mempool()
  35. if asn then
  36. if tonumber(asn) ~= nil then
  37. mempool:set_variable("asn", asn)
  38. table.insert(descr_t, "asn:" .. asn)
  39. else
  40. rspamd_logger.errx(task, 'malformed ASN "%s" for ip %s', asn, task:get_from_ip())
  41. end
  42. end
  43. if ipnet then
  44. mempool:set_variable("ipnet", ipnet)
  45. table.insert(descr_t, "ipnet:" .. ipnet)
  46. end
  47. if country then
  48. mempool:set_variable("country", country)
  49. table.insert(descr_t, "country:" .. country)
  50. end
  51. if options['symbol'] then
  52. task:insert_result(options['symbol'], 0.0, table.concat(descr_t, ', '))
  53. end
  54. end
  55. local asn_check_func = {}
  56. asn_check_func.rspamd = function(ip)
  57. local dnsbl = options['provider_info']['ip' .. ip:get_version()]
  58. local req_name = string.format("%s.%s",
  59. table.concat(ip:inversed_str_octets(), '.'), dnsbl)
  60. local function rspamd_dns_cb(_, _, results, dns_err, _, _, serv)
  61. if dns_err and (dns_err ~= 'requested record is not found' and dns_err ~= 'no records with this name') then
  62. rspamd_logger.errx(task, 'error querying dns "%s" on %s: %s',
  63. req_name, serv, dns_err)
  64. task:insert_result(options['symbol_fail'], 0, string.format('%s:%s', req_name, dns_err))
  65. return
  66. end
  67. if not results or not results[1] then
  68. rspamd_logger.infox(task, 'cannot query ip %s on %s: no results',
  69. req_name, serv)
  70. return
  71. end
  72. lua_util.debugm(N, task, 'got reply from %s when requesting %s: %s',
  73. serv, req_name, results[1])
  74. local parts = rspamd_re:split(results[1])
  75. -- "15169 | 8.8.8.0/24 | US | arin |" for 8.8.8.8
  76. asn_set(parts[1], parts[2], parts[3])
  77. end
  78. task:get_resolver():resolve_txt({
  79. task = task,
  80. name = req_name,
  81. callback = rspamd_dns_cb
  82. })
  83. end
  84. local ip = task:get_from_ip()
  85. if not (ip and ip:is_valid()) or
  86. (not options.check_local and ip:is_local()) then
  87. return
  88. end
  89. asn_check_func[options['provider_type']](ip)
  90. end
  91. -- Configuration options
  92. local configure_asn_module = function()
  93. local opts = rspamd_config:get_all_opt('asn')
  94. if opts then
  95. for k,v in pairs(opts) do
  96. options[k] = v
  97. end
  98. end
  99. local auth_and_local_conf = lua_util.config_check_local_or_authed(rspamd_config, N,
  100. false, true)
  101. options.check_local = auth_and_local_conf[1]
  102. options.check_authed = auth_and_local_conf[2]
  103. if options['provider_type'] == 'rspamd' then
  104. if not options['provider_info'] and options['provider_info']['ip4'] and
  105. options['provider_info']['ip6'] then
  106. rspamd_logger.errx("Missing required provider_info for rspamd")
  107. return false
  108. end
  109. else
  110. rspamd_logger.errx("Unknown provider_type: %s", options['provider_type'])
  111. return false
  112. end
  113. if options['symbol'] then
  114. options['symbol_fail'] = options['symbol'] .. '_FAIL'
  115. else
  116. options['symbol_fail'] = 'ASN_FAIL'
  117. end
  118. return true
  119. end
  120. if configure_asn_module() then
  121. local id = rspamd_config:register_symbol({
  122. name = 'ASN_CHECK',
  123. type = 'prefilter',
  124. callback = asn_check,
  125. priority = 8,
  126. flags = 'empty,nostat',
  127. })
  128. if options['symbol'] then
  129. rspamd_config:register_symbol({
  130. name = options['symbol'],
  131. parent = id,
  132. type = 'virtual',
  133. flags = 'empty,nostat',
  134. score = 0,
  135. })
  136. end
  137. rspamd_config:register_symbol{
  138. name = options['symbol_fail'],
  139. parent = id,
  140. type = 'virtual',
  141. flags = 'empty,nostat',
  142. score = 0,
  143. }
  144. else
  145. lua_util.disable_module(N, 'config')
  146. end