如何配置后缀以将所有传入的电子邮件传递到脚本?


24

我希望使用后缀将所有传入的邮件发送到任何地址(包括未映射到本地用户的地址),以管道方式发送到脚本。我已经尝试mailbox_command在中进行配置/etc/postfix/main.cf

mailbox_command = /path/to/myscript.py

如果用户是本地用户,则此方法效果很好,但对于没有别名的“未知”用户,此方法将失败。我尝试设置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

脚本之后,该怎么办?这听起来像病毒扫描程序和垃圾邮件过滤器所做的那样,也许您可​​以找到配置其中之一并将其配置用于脚本的指南?
DerfK 2011年

消息将发送到Web应用程序。因此,脚本之后是:数据库,其他处理,其他内容,但不是普通邮件内容。关键问题是使未知用户不退信-这是在正常病毒/垃圾邮件情形之外的,在这种情况下,您将退回未映射的用户。
user67641 2011年

@ user67641嗨,我需要将邮件注入脚本中的后缀中,还是在master.cf中添加更多行
merveotesi 2013年

Answers:


32

好的,我刚刚完成了这项工作-尽管比我想象的要毛茸茸。我放下了maildir_command零件,然后去了transport_maps。关键是要做5件事:

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

(1)创建/etc/postfix/virtual_aliases以添加一个全包别名- localuser必须是现有的本地用户:

@mydomain.tld   localuser@mydomain.tld

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

mydomain.tld    mytransportname:

(3)接下来,双方transportvirtual_aliases需要被编译成Berkeley DB的文件:

$ sudo postmap /etc/postfix/virtual_aliases
$ sudo postmap /etc/postfix/transport

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

mytransportname   unix  -       n       n       -       -       pipe
  flags=FR user=localuser argv=/path/to/my/script.py
  ${nexthop} ${user}

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

  ...
  transport_maps = hash:/etc/postfix/transport
  virtual_alias_maps = hash:/etc/postfix/virtual_aliases

还有...很好!嘘。


1
极其有用的答案
merveotesi 2013年

1
不需要虚拟别名映射。您可以使用完成相同的操作relay_domains(在这种情况下,传输文件可以基于实际的To:地址进行过滤)。
Brilliand

我发现您可以使用virtual_transport = mailcaptcha:in main.cfmailcaptcha unix - n n - - pipe flags=FR user=vmail argv=/usr/bin/perl /usr/local/mail-captcha/verify.pl ${sender} ${recipient}in 将所有虚拟邮件路由到脚本master.cf。请参阅postfix.org/transport.5.htmlpostfix.org/VIRTUAL_README.html
Chloe,

(4)应该在一行中,对吗?也不需要a postfix restartreloador这样的东西吗?最后一件事:是否有一个日志文件来查看到达后缀的邮件?
巴斯基(Basj)'17

@Basj,日志文件为/var/log/mail.log
fiedl

4

我唯一一次使用过这样的东西是针对特定用户的邮箱。所需要做的就是用别名将用户名别名为管道和进程:

pong:“ | /usr/local/bin/gotit.pl”

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

gotit.pl(例如,不要因为糟糕的编程skillz =而选择我)。要做的是处理我发送到我们的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;
    }
}

是的,只需将@ mydomain.tld重定向到pong,mydomain.tld的所有传入main都将通过管道传输。
Zaar Hai

对于使用多个虚拟域的我们来说,不要忘记将其重定向到pong @ localhost,这样它就不会将默认域名附加到别名
therightstuff

0

我使用了旧式的“平面文件” Mailbox来接收所有邮件(如果maildir/文件很大,则每隔几个小时修剪一次),而不是使用现代的文件夹通过脚本来处理邮件。我想也可以对文件运行logrotate,以使其易于管理。

这样,您可以简单地将所有邮件作为本地用户复制到邮箱。


0

之后很多麻烦我放在一起该解决方案基于几个不同的来源,导致少得多的努力,关键的步骤,配置virtual_alias_domains以及virtual_alias_maps和确保虚拟映射是my-alias@localhost不是只是my-alias。在我的示例中,命令别名是将电子邮件通过管道传输到网站API端点,但是它也可以很容易地通过管道传输到其他终端。

这是您需要采取的步骤:

  • 设置您的域的A和MX记录,A记录@指向您将要在其上接收电子邮件的服务器的IP,MX则使用主机名@和值 10 mail.your-domain-name
  • sudo apt-get install postfix
  • 选择“ Internet站点”并输入您的域名(完全限定)
  • sudo vi /etc/postfix/main.cf
  • 将mail.your-domain-name添加到mydestination值列表中
  • 附加
virtual_alias_domains = hash:/etc/postfix/virtual_domains
virtual_alias_maps = hash:/etc/postfix/virtual

到文件末尾

  • sudo apt-get vi /etc/aliases
curl_email: "|curl --data-binary @- http://your-domain-name/email"
  • sudo newaliases
  • sudo apt-get vi /etc/postfix/virtual_domains
example.net   #domain
example.com   #domain
your-domain-name   #domain

(#domain字段禁止显示警告)

  • sudo postmap /etc/postfix/virtual_domains
  • sudo apt-get vi /etc/postfix/virtual
info@your-domain-name bob@gmail.com
everyone@your-domain-name bob@gmail.com jim@gmail.com
email_processor@your-domain-name curl_email@localhost
@your-domain-name catchall@whereveryouwant.com
ted@example.net jane@outlook.com
  • sudo postmap /etc/postfix/virtual
  • sudo /etc/init.d/postfix reload
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.