مراية لـ
https://github.com/postalserver/postal.git
تم المزامنة 2025-12-01 05:43:04 +00:00
feat: support for using rspamd for spam filtering
هذا الالتزام موجود في:
@@ -102,6 +102,14 @@ rails:
|
|||||||
environment: production
|
environment: production
|
||||||
secret_key:
|
secret_key:
|
||||||
|
|
||||||
|
rspamd:
|
||||||
|
enabled: false
|
||||||
|
host: 127.0.0.1
|
||||||
|
port: 11334
|
||||||
|
ssl: false
|
||||||
|
password: null
|
||||||
|
flags: null
|
||||||
|
|
||||||
spamd:
|
spamd:
|
||||||
enabled: false
|
enabled: false
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ module Postal
|
|||||||
def inspectors
|
def inspectors
|
||||||
Array.new.tap do |inspectors|
|
Array.new.tap do |inspectors|
|
||||||
|
|
||||||
if Postal.config.spamd&.enabled
|
if Postal.config.rspamd&.enabled
|
||||||
|
inspectors << MessageInspectors::Rspamd.new(Postal.config.rspamd)
|
||||||
|
elsif Postal.config.spamd&.enabled
|
||||||
inspectors << MessageInspectors::SpamAssassin.new(Postal.config.spamd)
|
inspectors << MessageInspectors::SpamAssassin.new(Postal.config.spamd)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ module Postal
|
|||||||
extend ActiveSupport::Autoload
|
extend ActiveSupport::Autoload
|
||||||
eager_autoload do
|
eager_autoload do
|
||||||
autoload :Clamav
|
autoload :Clamav
|
||||||
|
autoload :Rspamd
|
||||||
autoload :SpamAssassin
|
autoload :SpamAssassin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
74
lib/postal/message_inspectors/rspamd.rb
Normal file
74
lib/postal/message_inspectors/rspamd.rb
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
require 'net/http'
|
||||||
|
|
||||||
|
module Postal
|
||||||
|
module MessageInspectors
|
||||||
|
class Rspamd < MessageInspector
|
||||||
|
|
||||||
|
class Error < StandardError
|
||||||
|
end
|
||||||
|
|
||||||
|
def inspect_message(inspection)
|
||||||
|
response = request(inspection.message, inspection.scope)
|
||||||
|
response = JSON.parse(response.body)
|
||||||
|
return unless response['symbols'].is_a?(Hash)
|
||||||
|
|
||||||
|
response['symbols'].values.each do |symbol|
|
||||||
|
next if symbol['description'].blank?
|
||||||
|
|
||||||
|
inspection.spam_checks << SpamCheck.new(symbol['name'], symbol['score'], symbol['description'])
|
||||||
|
end
|
||||||
|
rescue Error => e
|
||||||
|
inspection.spam_checks << SpamCheck.new("ERROR", 0, e.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def request(message, scope)
|
||||||
|
http = Net::HTTP.new(@config.host, @config.port)
|
||||||
|
http.use_ssl = true if @config.ssl
|
||||||
|
http.read_timeout = 10
|
||||||
|
http.open_timeout = 10
|
||||||
|
|
||||||
|
raw_message = message.raw_message
|
||||||
|
|
||||||
|
request = Net::HTTP::Post.new('/checkv2')
|
||||||
|
request.body = raw_message
|
||||||
|
request['Content-Length'] = raw_message.bytesize.to_s
|
||||||
|
request['Password'] = @config.password if @config.password
|
||||||
|
request['Flags'] = @config.flags if @config.flags
|
||||||
|
request['User-Agent'] = 'Postal'
|
||||||
|
request['Deliver-To'] = message.rcpt_to
|
||||||
|
request['From'] = message.mail_from
|
||||||
|
request['Rcpt'] = message.rcpt_to
|
||||||
|
request['Queue-Id'] = message.token
|
||||||
|
|
||||||
|
if scope == :outgoing
|
||||||
|
request['User'] = ''
|
||||||
|
# We don't actually know the IP but an empty input here will
|
||||||
|
# still trigger rspamd to treat this as an outbound email
|
||||||
|
# and disable certain checks.
|
||||||
|
# https://rspamd.com/doc/tutorials/scanning_outbound.html
|
||||||
|
request['Ip'] = ''
|
||||||
|
end
|
||||||
|
|
||||||
|
response = nil
|
||||||
|
begin
|
||||||
|
response = http.request(request)
|
||||||
|
rescue Exception => e
|
||||||
|
logger.error "Error talking to rspamd: #{e.class} (#{e.message})"
|
||||||
|
logger.error e.backtrace[0,5]
|
||||||
|
|
||||||
|
raise Error, "Error when scanning with rspamd (#{e.class})"
|
||||||
|
end
|
||||||
|
|
||||||
|
unless response.is_a?(Net::HTTPOK)
|
||||||
|
logger.info "Got #{response.code} status from rspamd, wanted 200"
|
||||||
|
raise Error, "Error when scanning with rspamd (got #{response.code})"
|
||||||
|
end
|
||||||
|
|
||||||
|
response
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
المرجع في مشكلة جديدة
حظر مستخدم