从 Sieve 脚本调用 Bash 脚本

从 Sieve 脚本调用 Bash 脚本

我不确定是否已经有人问过类似的问题。
我目前正在尝试将电子邮件移入或移出垃圾邮件文件夹时将其推送到我们的垃圾邮件过滤器,以便它可以将它们识别为垃圾邮件/火腿。为此,我遵循了本指南:https://workaround.org/ispmail/stretch/filtering-out-spam-with-rspamd在“从用户操作中学习”部分中。
sieve 脚本是按照说明创建的,它们已由 sievec 处理,并且已按照指南授予权限。两个shell脚本也已相应创建。唯一真正的区别是我们没有用户或组“vmail”。我将其设置为 dovecot:root ,它应该是我们系统的对应项。所以该文件夹看起来像这样:

drwxr-xr-x 2 dovecot root 4,0K Mai  7 10:52 .
drwxr-xr-x 3 root    root 4,0K Jul 29  2019 ..
-rw-r--r-- 1 dovecot root   85 Mai  7 10:47 learn-ham.sieve
-rw-r--r-- 1 root    root  246 Mai  7 10:47 learn-ham.svbin
-rw-r--r-- 1 dovecot root   86 Mai  7 10:47 learn-spam.sieve
-rw-r--r-- 1 root    root  250 Mai  7 10:47 learn-spam.svbin
-rw-r--r-- 1 dovecot root  509 Mär 16 13:57 mailfilter.sieve
-rw-r--r-- 1 root    root  398 Mai  6 18:02 mailfilter.svbin
-rwx------ 1 dovecot root   41 Mai  7 10:52 rspamd-learn-ham.sh
-rwx------ 1 dovecot root   42 Dez 14 10:42 rspamd-learn-spam.sh

当 sieve 脚本执行并应该调用 shell 脚本时,我收到以下错误:

Mai 12 17:16:28 mail dovecot[4119]: imap(user)<8778><xIGQ8nSlFMZ/AAAB>: Fatal: execvp(/etc/dovecot/sieve/global/rspamd-learn-spam.sh) failed: Permission denied
Mai 12 17:16:28 mail dovecot[4119]: imap(user)<8778><xIGQ8nSlFMZ/AAAB>: Error: write(program stdin) failed: Broken pipe
Mai 12 17:16:28 mail dovecot[4119]: imap(user)<8778><xIGQ8nSlFMZ/AAAB>: program `/etc/dovecot/sieve/global/rspamd-learn-spam.sh' terminated with non-zero exit code 84
Mai 12 17:16:28 mail dovecot[4119]: imap(user)<8778><xIGQ8nSlFMZ/AAAB>: Error: sieve: pipe action: failed to pipe message to program `rspamd-learn-spam.sh': refer to server log for more information. [2020-05-12 17:16:28]
Mai 12 17:16:28 mail dovecot[4119]: imap(user)<8778><xIGQ8nSlFMZ/AAAB>: sieve: left message in mailbox 'Junk'
Mai 12 17:16:28 mail dovecot[4119]: imap(user)<8778><xIGQ8nSlFMZ/AAAB>: Error: sieve: Execution of script /etc/dovecot/sieve/global/learn-spam.sieve failed

除了我不知道“服务器日志”指的是什么之外,我只是无法弄清楚问题到底是什么。当然,这看起来像是权限错误,但如何修复呢?

关于我们的系统:Debian 10.4 with dovecot 2.3.4.1 和piginghole 0.5.4
编辑:
我发现一个错误:我将 sieve_pipe_bin_dir 设置为错误的文件夹。它现在指向包含两个 .sh 文件的文件夹,但我仍然收到这些错误:

Mai 22 15:40:06 mail dovecot[18547]: imap(user)<18686><57dcxDymXJ5/AAAB>: Fatal: execvp(/etc/dovecot/sieve/global/rspamd-learn-spam.sh) failed: Permission denied
Mai 22 15:40:06 mail dovecot[18547]: imap(user)<18686><57dcxDymXJ5/AAAB>: Error: write(program stdin) failed: Broken pipe
Mai 22 15:40:06 mail dovecot[18547]: imap(user)<18686><57dcxDymXJ5/AAAB>: program `/etc/dovecot/sieve/global/rspamd-learn-spam.sh' terminated with non-zero exit code 84
Mai 22 15:40:06 mail dovecot[18547]: imap(user)<18686><57dcxDymXJ5/AAAB>: Error: sieve: pipe action: failed to pipe message to program `rspamd-learn-spam.sh': refer to server log for more information. [2020-05-22 15:40:06]
Mai 22 15:40:06 mail dovecot[18547]: imap(user)<18686><57dcxDymXJ5/AAAB>: sieve: left message in mailbox 'Junk'
Mai 22 15:40:06 mail dovecot[18547]: imap(user)<18686><57dcxDymXJ5/AAAB>: Error: sieve: Execution of script /etc/dovecot/sieve/global/learn-spam.sieve failed

无论我设置哪个所有者(root:root或dovecot:root,唯一不是“人类用户”的其他用户将是类似_apt,bin,nslcd,daemon,dovenull或www-data)任何想法可能会导致那?

编辑2:
我现在改变了我的方法,尝试直接通过管道连接到 rspamc。这是我的 learn-spam.sieve 脚本:

require ["vnd.dovecot.pipe", "copy", "imapsieve"];
pipe :copy "rspamc" ["learn_spam"];

因此,我更改了 90-plugin.conf 以包含

sieve_pipe_bin_dir = /usr/bin/rspamc

rspamc 所在的位置。现在我收到错误了

Jun 03 09:48:34 mail dovecot[1536]: imap(user)<10486><xVI6QSmnpLN/AAAB>: Error: sieve: pipe action: failed to pipe message to program: program `rspamc' not found
Jun 03 09:48:34 mail dovecot[1536]: imap(user)<10486><xVI6QSmnpLN/AAAB>: sieve: left message in mailbox 'Junk'
Jun 03 09:48:34 mail dovecot[1536]: imap(user)<10486><xVI6QSmnpLN/AAAB>: Error: sieve: Execution of script /etc/dovecot/sieve/global/learn-spam.sieve failed

什么地方出了错?或者pidgeonhole管道命令只能调用shell脚本?

答案1

看来我发现了什么不起作用:由于某种原因,dovecot 似乎没有 shell 脚本的执行权限。所以解决方案实际上是sudo -u dovecot chmod +x *.sh
在我的情况下正确的文件权限如下所示:

/etc/dovecot/sieve/global # ls -la
insgesamt 44K
drwxr-xr-x 2 dovecot root 4,0K Jul  8 07:33 .
drwxr-xr-x 3 root    root 4,0K Jul 29  2019 ..
-rw-r--r-- 1 dovecot root  144 Jun  5 10:06 learn-ham.sieve
-rw-r--r-- 1 root    root  306 Jun  5 10:07 learn-ham.svbin
-rw-r--r-- 1 dovecot root   86 Jun 17 15:45 learn-spam.sieve
-rw-r--r-- 1 root    root  250 Jun 17 15:45 learn-spam.svbin
-rw-r--r-- 1 dovecot root  509 Mär 16 13:57 mailfilter.sieve
-rw-r--r-- 1 dovecot root  462 Jul 29  2019 mailfilter.sieve~
-rw-r--r-- 1 root    root  398 Mai  6 18:02 mailfilter.svbin
-rwxrwxr-x 1 dovecot root   41 Jun  5 10:25 rspamd-learn-ham.sh
-rwxrwxr-x 1 dovecot root   42 Jul  8 07:33 rspamd-learn-spam.sh

答案2

检查您的sieve_pipe_bin_dir设置是否90-plugin.conf在 中被覆盖90-sieve-extprograms.conf。如果是这种情况,您可以从 中取消注释90-sieve-extprograms.conf,或者从 中删除它并使用来自(例如)90-plugin.conf 的默认目录90-plugin.conf/usr/lib/dovecot/sieve-pipe/

sieve_pipe_bin_dir应该设置为目录名称,就像您最初的目录名称一样,而不是可执行文件的文件名。

Permission denied执行程序时可能意味着 dovecot 没有读取或执行程序的权限 - 无论是可执行文件还是父目录。您可以使用stat $file或检查可执行文件的权限ls -l $filechmod +x $file将使其可执行(所有用户)。您可以尝试通过运行来测试 dovecot 是否可以执行该程序sudo -u dovecot $file(假设如果以这种方式运行,脚本不会做任何坏事)。 $file是例如/etc/dovecot/sieve/global/rspamd-learn-spam.sh

答案3

作为参考,以下是我为实现此目的所遵循的步骤:

  1. 在目录中创建脚本(即mail_processor.py/usr/lib/dovecot/sieve-execute/

    #!/usr/bin/python3
    from sys import stdin
    with open('/var/log/mail_processor.log', 'a') as logfile:
        for line in stdin:
            print(line.rstrip(), file=logfile)
    
    • 确保您的脚本和目标文件具有正确的权限:

      $ chmod +rx /usr/lib/dovecot/sieve-execute/mail_processor.py
      $ chmod 0777 /var/log/mail_processor.log
      
  2. 启用sieve_extprograms插件:

    • 使用以下内容修改 的\etc\dovecot\conf.d\90-sieve.conf插件部分:

      sieve_extensions = +vnd.dovecot.execute
      sieve_plugins = sieve_extprograms
      sieve_execute_bin_dir = /usr/lib/dovecot/sieve-execute
      
    • 重新加载鸽舍:

      $ service dovecot restart
      
  3. 创建筛过滤器(即在 Roundcube 中 goto settings-> filters-> actions-> edit filter set):

    require ["vnd.dovecot.execute"];
    # rule:[mail processing]
    if true
    {
        execute :pipe "mail_processor.py";
    }
    

现在,使用此筛选器传递到任何邮箱的所有邮件都将通过管道进行mail_processor.py操作。

Pigeonhole Sieve:Extprograms 插件以供参考

答案4

我使用常见示例遇到了类似的问题:pipe :copy "dovecot-lda"

第一:告诉 Dovecot 管道可执行文件所在的位置。在您的 00-zzzzz.conf 文件中,sieve_pipe_bin_dir = /usr/lib/dovecot/sieve-pipe.这仅适用于 Sieve 脚本中的“管道”命令。 HyperActive 的答案是“执行”命令。 .conf 文件并不重要,只要 dovecot.conf 或其他地方有一个 !include 来拉入 .conf 文件即可。 (90-sieve.conf、90-sieve-extprograms.conf 等)

第二:重新启动 Dovecot,以便加载该设置。

第三:创建该文件夹。 mkdir /usr/lib/dovecot/sieve-pipe 我以 root 身份执行此操作。为了确保其他用户可以访问,请对该文件夹执行 chmod 755。

第四:将您将通过管道输入的任何 CLI 命令的可执行文件放入该文件夹中。
dovecot-lda 已经有一个符号链接,“deliver”。这是一个通用参考,可以让我们避免硬编码到 dovecot-lda。所以我将 /usr/lib/dovecot/deliver 复制到 /usr/lib/dovecot/sieve-pipe。

第五:检查权限 dovecot-lda 可执行文件本身的权限为 755。“deliver”上的权限显示为 777,但目标的实际权限可以通过 看到ls -LaAFl /usr/lib/dovecot/deliver。 755 非常适合此目的。

概括:

  • 你的筛子脚本说pipe :copy
  • 这些指令通过require ["vnd.dovecot.pipe", "copy"....
  • :copy 后面的任何命令都需要在由 :copy 标识的文件夹中定义sieve_pipe_bin_dir在活动的 Dovecot .conf 文件中,设置该变量后需要重新启动 Dovecot。
  • 对于OP,这意味着/usr/lib/dovecot/sieve-pipe 中需要有一个指向“rspamc”的符号链接,指向/usr/bin/rspamc。

好吧,晚了几年,但这是写给其他偶然发现这个问答的人的。

相关内容