You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置Exim仅对入站邮件执行SpamAssassin扫描?

问题分析与解决

思路正确性

你的思路是正确的:通过区分入站/出站邮件,或者识别邮件列表发出的邮件来跳过SpamAssassin扫描,既避免了邮件列表群发时重复扫描的资源浪费,又能通过SPF验证拦截伪造Return-Path的垃圾邮件,方向没问题。

两个尝试的问题解析

1. eq{$received_protocol}{SMTP}无效的原因

Exim中,本地邮件列表软件发出的邮件也可能使用SMTP协议(比如通过本地SMTP端口提交),仅靠received_protocol为SMTP无法区分外部入站邮件和本地出站邮件。正确的区分逻辑应该结合邮件来源:

  • 外部入站邮件:sender_host_address是外部IP,非本地地址(127.0.0.1/::1/内部网段)
  • 本地出站邮件:sender_host_address为本地地址,或received_protocol为local(若邮件列表通过sendmail命令直接提交)

2. Return-Path条件写法的问题

你的条件存在三个关键错误:

  • 变量引用错误:header_return_path:是错误的变量名,Return-Path属于信封发件人,并非邮件头字段,应该使用Exim内置变量$return_path获取。
  • 存在性判断语法错误:判断变量是否存在的正确写法是def:return_path,不需要末尾的冒号。
  • 正则匹配冗余:^.*@list\.example\.com$可以简化为@list\.example\.com$,只需匹配域名后缀即可,无需额外匹配前缀内容。

修正后的条件写法:

accept  condition = ${if match{$return_path}{\N@list\.example\.com$\N}{1}{0}}

推荐的完整配置调整

在所有SpamAssassin相关规则最前面添加以下规则,直接跳过邮件列表发出的邮件扫描:

# 跳过邮件列表发出的邮件的SpamAssassin检查
accept  condition = ${if match{$return_path}{\N@list\.example\.com$\N}{1}{0}}

# 以下是原有的SpamAssassin规则...
# Bypass SpamAssassin checks if the message is too large (4 million).
warn    condition   = ${if >={$message_size}{4000000}{1}}
        add_header  = X-Spam-Note: SpamAssassin run bypassed due to message size
        add_header  = Subject: [L] $h_Subject:

# ...后续原有规则保持不变

如果你想基于邮件来源区分入站/出站,也可以用以下规则替代上述accept规则,仅对外部入站邮件执行扫描:

# 仅对外部入站邮件执行SpamAssassin扫描,跳过本地/内部邮件
accept  condition = ${if eq{$sender_host_address}{127.0.0.1}{1}{0}}
accept  condition = ${if eq{$sender_host_address}{::1}{1}{0}}
accept  condition = ${if isin{$sender_host_address}{192.168.0.0/16}{1}{0}}  # 替换为你的内部网段

内容的提问来源于stack exchange,提问作者Perdu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 17:56:29