如何配置 postfix 以将所有传入电子邮件通过管道传输到脚本?

use*_*641 28 scripting postfix

使用 postfix,我希望将所有传入邮件发送到任何地址(包括那些未映射到本地用户的地址)通过管道传输到脚本。我试过配置mailbox_command/etc/postfix/main.cf

mailbox_command = /path/to/myscript.py
Run Code Online (Sandbox Code Playgroud)

如果用户是本地用户,这很有效,但对于没有别名的“未知”用户则失败。我尝试设置luser_relay为本地用户,但这会抢占mailbox_command,因此该命令不会运行。我尝试设置local_recipient_maps=(空字符串),但消息仍然被退回(未知用户)。

是否有我可以使用的魔术调用来让所有已知和未知用户也转到脚本?

完整/etc/postfix/main.cf如下——它是默认的 Ubuntu 10.04,除了以下mailbox_command行:

# See /usr/share/postfix/main.cf.dist for a commented, more complete version


# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname

smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

readme_directory = no

# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.

myhostname = ... snip ...
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = sassafras, ... snip ...,localhost.localdomain, localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

mailbox_command = /path/to/my/script.py
Run Code Online (Sandbox Code Playgroud)

use*_*641 37

好的,我刚刚开始工作 - 虽然比我想象的要多。我放弃了这个maildir_command部分,然后去了transport_maps。关键是做好5件事:

  1. 设置一个 db 文件来处理别名(并添加一个包罗万象的别名)
  2. 设置 db 文件以将相关域的“传输”映射到特殊处理程序。
  3. 将 db 文件编译成 postfix 想要的 berkeley db 格式。
  4. 将处理程序设置/etc/postfix/master.cf为通过管道将邮件发送到脚本。
  5. 设置/etc/postfix/main.cf为对 使用传输数据库,为 使用transport_maps别名数据库virtual_alias-maps

(1) 创建/etc/postfix/virtual_aliases添加一个包罗万象的别名——localuser需要是现有的本地用户:

@mydomain.tld   localuser@mydomain.tld
Run Code Online (Sandbox Code Playgroud)

(2) 创建/etc/postfix/transport添加传输映射。“mytransportname”可以是任何你想要的;它在下面使用master.cf

mydomain.tld    mytransportname:
Run Code Online (Sandbox Code Playgroud)

(3)接下来,transport和 都virtual_aliases需要编译成berkeley db文件:

$ sudo postmap /etc/postfix/virtual_aliases
$ sudo postmap /etc/postfix/transport
Run Code Online (Sandbox Code Playgroud)

(4) 将传输添加到/etc/postfix/master.cf

mytransportname   unix  -       n       n       -       -       pipe
  flags=FR user=localuser argv=/path/to/my/script.py
  ${nexthop} ${user}
Run Code Online (Sandbox Code Playgroud)

(5) 在/etc/postfix/main.cf

  ...
  transport_maps = hash:/etc/postfix/transport
  virtual_alias_maps = hash:/etc/postfix/virtual_aliases
Run Code Online (Sandbox Code Playgroud)

而且……好!嘘。


Gre*_*ort 5

我唯一一次使用类似的东西是针对特定用户的邮箱。所需要的只是将该用户名别名为别名中的管道和进程:

乒乓球:“| /usr/local/bin/gotit.pl”

这会将发往“pong@mymailserver.com”的流量发送到我编写的用于处理它的 Perl 脚本。

gotit.pl(例如,不要因为我蹩脚的编程技巧而指责我=)。它的工作是处理我发送到 Exchange 服务器的电子邮件(通过一些 VB 代码自动回复),以验证 Exchange 是否及时处理电子邮件。如果没有,邮件服务器会向我们的寻呼机发送一封警报电子邮件并写入一个锁定文件,这样我们就不会经常收到垃圾邮件。

#! /usr/bin/perl -w
use vars qw ( $mung $sent $tvalue $remainder $delta $fout );
$mung = time;
while (<STDIN>) {
    ($sent, $tvalue, $remainder ) = split /: /, $_, 3;
    $tvalue =~ s/(\D+)//g;
    chomp($tvalue);
    $delta = $mung-$tvalue;
    if ( $sent =~ "Sent" ) {
        $fout = "/var/spool/mailcheck/$tvalue";
        next unless ( -e $fout );
        open (TMP, "> $fout") or die "Couldn't open output file: $!\n";
        print TMP "Received in: $delta seconds.\n";
                close TMP;
        last;
    }
}
Run Code Online (Sandbox Code Playgroud)