我在用
Ubuntu 18.04 64 bit
dovecot 2.2.33.2
spamassassin 3.4.1
amavisd
目标是运行一个电子邮件服务器,我已经实现了。我可以使用 Thunderbird 和 imap 协议访问服务器上的电子邮件。
对于 Postfix 配置,我遵循了本教程:https://help.ubuntu.com/community/PostfixBasicSetupHowto而是使用 Maildir。
Dovecot 配置如下:
https://www.linuxbabe.com/mail-server/secure-email-server-ubuntu-16-04-postfix-dovecot https://help.ubuntu.com/community/Dovecot
此外,我还安装了fail2ban
,并已测试成功。
下一步是电子邮件过滤。以下https://help.ubuntu.com/lts/serverguide/mail-filtering.html.en效果很好。Spamassassin 会拦截所有垃圾邮件。但实际上我并不想拦截它,我只希望 spamassassin 将其标记为垃圾邮件,并将垃圾邮件重定向到我的垃圾邮件文件夹中。这只是为了防止某些非垃圾邮件被过滤掉。
为此我设置了/etc/amavis/conf.d/21-ubuntu_defaults
:
$final_spam_destiny = D_PASS;
并且主题被添加****SPAM****
下一步是 dovecot 自动将此邮件移至我的垃圾邮件文件夹。然后我就卡住了。我按照这个教程操作:https://workaround.org/ispmail/stretch/filtering-out-spam-with-rspamd
还有“将垃圾邮件发送到垃圾邮件文件夹”部分。但是它不起作用。我发现 sieve 不适用于 imap。但我找不到任何有关 imap_sieve 的教程或手册,无法解决我的问题。你们有人有想法吗?我也没有找到任何日志条目,其中可以看到 sieve 正在工作(或不工作)?
答案1
我的问题有点进一步:
通过设置 conf.d/10-logging.conf
mail_debug = yes
和 conf.d/90-sieve.conf
sieve_plugins = sieve_imapsieve
sieve_global_dir = /etc/dovecot/sieve/`
以及:
conf.d/90-plugin.conf`
plugin {
sieve_plugins = sieve_imapsieve sieve_extprograms
imapsieve_mailbox1_name = INBOX
imapsieve_mailbox1_after = file:/etc/dovecot/sieve/default.sieve
sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment
}
和 sieve/default.sieve: `
require ["fileinto", "mailbox", "imap4flags"];
if header :contains "subject" ["*SPAM*"] {
setflag "\\Seen";
#setflag "\\Deleted";
fileinto :create "Junk";
stop;
}
以及编译sievec sieve/default.sieve
我让垃圾邮件被复制到垃圾邮件文件夹。但不幸的是邮件仍然留在收件箱中。似乎只是复制了?
答案2
我通过另一种方法解决了这个问题。也许不是最好的解决方案,但对我来说很有效。我实现了一个 incronetab,只要 maildir 中有新电子邮件,它就会被触发。
`/home/myuser/Maildir/new/ IN_CREATE python3.6 /var/lib/SpamControl.py $@ $#`
SpamControl.py 如下所示:
import subprocess
import sys
import time
time.sleep(0.5)
path = sys.argv[1]
file = sys.argv[2]
base_path = path[0:len(path)-4]
new_path = base_path + "cur/"
new_file = file + str(r'\:2\,')
full_path = new_path + new_file
command = "head -n 50 " + full_path
e_mail = subprocess.check_output([command], shell=True)
e_mail = e_mail.decode('ascii')
e_mail = e_mail.splitlines()
spam = False
for iterator in range (0, len(e_mail)):
if "X-Spam-Flag: YES" in e_mail[iterator]:
spam = True
if spam is True:
new_path = base_path + "/.Junk/cur/" + new_file + "S"
command = "mv " + full_path + " " + new_path
subprocess.check_output([command], shell=True)
等待时间是必要的,因为 dovecot 会将邮件从 new 移到 cur。当邮件全部处于 new 状态时,代码速度不够快。
其余的代码检查电子邮件是否有垃圾邮件标记,如果有,则将其移至用户的垃圾邮件文件夹。阅读电子邮件的方式有点不寻常,但由于邮件名称中有“/”,我很难直接阅读它。当我将其移动到垃圾邮件时,我在文件名末尾添加了“S”,以便将其标记为已读。然后,thunderbird 就不会再用那里的新邮件来打扰我了。
请随意发表评论。
答案3
您遇到的问题在于筛选执行顺序。您必须将插件规则从重命名after
为before
plugin {
sieve_plugins = sieve_imapsieve sieve_extprograms
imapsieve_mailbox1_name = INBOX
imapsieve_mailbox1_before = file:/etc/dovecot/sieve/default.sieve
sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment
}
然后,如果主题中存在模式,您的消息将被继续default.sieve
并在正常传递之前停止。*SPAM*
我强烈建议使用名称,例如sieve_before before1.sieve
,而不是 ,因为它具有特殊含义。此外,最好在消息中添加一些特殊标题,例如 ,而不是主题操作。default.sieve
default.sieve
X-SPAM-DETECTED
更新
这是我的完整解决方案。我已将其用于exim
MTA 和dovecot
交付/筛选
exim
spamassassin
有一个调用来计算消息分数的ACL 。
如果分数高于阈值,则添加两个自定义标头:
acl_data:
warn spam = spamd
condition = ${if >{$spam_score_int}{49}}
add_header = X-Spam-Score: $spam_score_int
add_header = X-Spam-Ooops: Detected
accept
然后路由器将消息传递给传输:
local:
driver = accept
condition = <some site specific code>
transport = dovelda
传输很明显:
dovelda:
driver = pipe
user = mailnull
command = /long/path/deliver -d $local_part@$domain -f $sender_address
envelope_to_add
return_path_add
delivery_date_add
log_output
deliver
依赖于 dovecot 的配置:
plugin {
sieve_plugins = sieve_imapsieve sieve_extprograms
sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment
sieve_pipe_bin_dir = /usr/local/etc/dovecot
## Two sieves only - common and personal
sieve_before = /long/path/common.sieve
sieve_dir = /var/mail/%d/%n
sieve = /var/mail/%d/%n/user.sieve
. . . . . . .
}
common.sieve
很简单:
####
require "fileinto";
require "variables";
require "imap4flags";
if exists "X-Spam-Ooops"
{
fileinto "Junk";
stop;
}
elsif anyof (header :contains "From" "postmaster@")
{ ## postmaster's message should be delivered at any cost
setflag "flagvar" "\Flagged";
fileinto :flags "${flagvar}" "INBOX";
stop;
}
else
{
## Trigger to launch the next script in the sequence
keep;
}
####
就这样。任何分数高于允许分数的邮件都会被标X-Spam-Ooops
头标记并放入用户的Junk
子文件夹中。