Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

rbl.lua 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. --[[
  2. Copyright (c) 2022, Vsevolod Stakhov <vsevolod@rspamd.com>
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ]]--
  13. local ts = require("tableshape").types
  14. local lua_maps = require "lua_maps"
  15. local lua_util = require "lua_util"
  16. -- Common RBL plugin definitions
  17. local check_types = {
  18. from = {
  19. connfilter = true,
  20. },
  21. received = {},
  22. helo = {
  23. connfilter = true,
  24. },
  25. urls = {},
  26. content_urls = {},
  27. emails = {},
  28. replyto = {},
  29. dkim = {},
  30. rdns = {
  31. connfilter = true,
  32. },
  33. selector = {
  34. require_argument = true,
  35. },
  36. }
  37. local default_options = {
  38. ['default_enabled'] = true,
  39. ['default_ipv4'] = true,
  40. ['default_ipv6'] = true,
  41. ['default_unknown'] = false,
  42. ['default_dkim_domainonly'] = true,
  43. ['default_emails_domainonly'] = false,
  44. ['default_exclude_private_ips'] = true,
  45. ['default_exclude_users'] = false,
  46. ['default_exclude_local'] = true,
  47. ['default_no_ip'] = false,
  48. ['default_dkim_match_from'] = false,
  49. ['default_selector_flatten'] = true,
  50. }
  51. local return_codes_schema = ts.map_of(
  52. ts.string / string.upper, -- Symbol name
  53. (
  54. ts.array_of(ts.string) +
  55. (ts.string / function(s)
  56. return { s }
  57. end) -- List of IP patterns
  58. )
  59. )
  60. local return_bits_schema = ts.map_of(
  61. ts.string / string.upper, -- Symbol name
  62. (
  63. ts.array_of(ts.number + ts.string / tonumber) +
  64. (ts.string / function(s)
  65. return { tonumber(s) }
  66. end) +
  67. (ts.number / function(s)
  68. return { s }
  69. end)
  70. )
  71. )
  72. local rule_schema_tbl = {
  73. content_urls = ts.boolean:is_optional(),
  74. disable_monitoring = ts.boolean:is_optional(),
  75. disabled = ts.boolean:is_optional(),
  76. dkim = ts.boolean:is_optional(),
  77. dkim_domainonly = ts.boolean:is_optional(),
  78. dkim_match_from = ts.boolean:is_optional(),
  79. emails = ts.boolean:is_optional(),
  80. emails_delimiter = ts.string:is_optional(),
  81. emails_domainonly = ts.boolean:is_optional(),
  82. enabled = ts.boolean:is_optional(),
  83. exclude_local = ts.boolean:is_optional(),
  84. exclude_private_ips = ts.boolean:is_optional(),
  85. exclude_users = ts.boolean:is_optional(),
  86. from = ts.boolean:is_optional(),
  87. hash = ts.one_of { "sha1", "sha256", "sha384", "sha512", "md5", "blake2" }:is_optional(),
  88. hash_format = ts.one_of { "hex", "base32", "base64" }:is_optional(),
  89. hash_len = (ts.integer + ts.string / tonumber):is_optional(),
  90. helo = ts.boolean:is_optional(),
  91. ignore_default = ts.boolean:is_optional(), -- alias
  92. ignore_defaults = ts.boolean:is_optional(),
  93. ignore_whitelist = ts.boolean:is_optional(),
  94. ignore_whitelists = ts.boolean:is_optional(), -- alias
  95. images = ts.boolean:is_optional(),
  96. ipv4 = ts.boolean:is_optional(),
  97. ipv6 = ts.boolean:is_optional(),
  98. is_whitelist = ts.boolean:is_optional(),
  99. local_exclude_ip_map = ts.string:is_optional(),
  100. monitored_address = ts.string:is_optional(),
  101. no_ip = ts.boolean:is_optional(),
  102. process_script = ts.string:is_optional(),
  103. random_monitored = ts.boolean:is_optional(),
  104. rbl = ts.string,
  105. rdns = ts.boolean:is_optional(),
  106. received = ts.boolean:is_optional(),
  107. received_flags = ts.array_of(ts.string):is_optional(),
  108. received_max_pos = ts.number:is_optional(),
  109. received_min_pos = ts.number:is_optional(),
  110. received_nflags = ts.array_of(ts.string):is_optional(),
  111. replyto = ts.boolean:is_optional(),
  112. requests_limit = (ts.integer + ts.string / tonumber):is_optional(),
  113. require_symbols = (
  114. ts.array_of(ts.string) + (ts.string / function(s)
  115. return { s }
  116. end)
  117. ):is_optional(),
  118. resolve_ip = ts.boolean:is_optional(),
  119. return_bits = return_bits_schema:is_optional(),
  120. return_codes = return_codes_schema:is_optional(),
  121. returnbits = return_bits_schema:is_optional(),
  122. returncodes = return_codes_schema:is_optional(),
  123. selector = ts.one_of { ts.string, ts.table }:is_optional(),
  124. selector_flatten = ts.boolean:is_optional(),
  125. symbol = ts.string:is_optional(),
  126. symbols_prefixes = ts.map_of(ts.string, ts.string):is_optional(),
  127. unknown = ts.boolean:is_optional(),
  128. url_compose_map = lua_maps.map_schema:is_optional(),
  129. url_full_hostname = ts.boolean:is_optional(),
  130. urls = ts.boolean:is_optional(),
  131. whitelist = lua_maps.map_schema:is_optional(),
  132. whitelist_exception = (
  133. ts.array_of(ts.string) + (ts.string / function(s)
  134. return { s }
  135. end)
  136. ):is_optional(),
  137. checks = ts.array_of(ts.one_of(lua_util.keys(check_types))):is_optional(),
  138. exclude_checks = ts.array_of(ts.one_of(lua_util.keys(check_types))):is_optional(),
  139. }
  140. local function convert_checks(rule)
  141. local rspamd_logger = require "rspamd_logger"
  142. if rule.checks then
  143. local all_connfilter = true
  144. local exclude_checks = lua_util.list_to_hash(rule.exclude_checks or {})
  145. for _, check in ipairs(rule.checks) do
  146. if not exclude_checks[check] then
  147. local check_type = check_types[check]
  148. if check_type.require_argument then
  149. if not rule[check] then
  150. rspamd_logger.errx(rspamd_config, 'rbl rule %s has check %s which requires an argument',
  151. rule.symbol, check)
  152. return nil
  153. end
  154. end
  155. rule[check] = check_type
  156. if not check_type.connfilter then
  157. all_connfilter = false
  158. end
  159. if not check_type then
  160. rspamd_logger.errx(rspamd_config, 'rbl rule %s has invalid check type: %s',
  161. rule.symbol, check)
  162. return nil
  163. end
  164. else
  165. rspamd_logger.infox(rspamd_config, 'disable check %s in %s: excluded explicitly',
  166. check, rule.symbol)
  167. end
  168. end
  169. rule.connfilter = all_connfilter
  170. end
  171. -- Now check if we have any check enabled at all
  172. local check_found = false
  173. for k, _ in pairs(check_types) do
  174. if type(rule[k]) ~= 'nil' then
  175. check_found = true
  176. break
  177. end
  178. end
  179. if not check_found then
  180. -- Enable implicit `from` check to allow upgrade
  181. rspamd_logger.warnx(rspamd_config, 'rbl rule %s has no check enabled, enable default `from` check',
  182. rule.symbol)
  183. rule.from = true
  184. end
  185. return rule
  186. end
  187. -- Add default boolean flags to the schema
  188. for def_k, _ in pairs(default_options) do
  189. rule_schema_tbl[def_k:sub(#('default_') + 1)] = ts.boolean:is_optional()
  190. end
  191. return {
  192. check_types = check_types,
  193. rule_schema = ts.shape(rule_schema_tbl),
  194. default_options = default_options,
  195. convert_checks = convert_checks,
  196. }