在后缀中使用多个“myhostname”

dja*_*unz 6 postfix

postfix 是否允许动态更改“myhostname”?我 rtfmed 很多,但没有发现任何定性的东西。我的安装是后缀多域、多个 ip(在 master.cf 中调整)和多个 dkim sig 但不包括 master.cf 中的 myhostname 指令。

那种东西:

192.168.1.12:smtp inet n - n - - smtpd -o myhostname=mail.mail2.com -o smtpd_banner=mail.mail2.com -o smtp_helo_name=mail.mail2.com
Run Code Online (Sandbox Code Playgroud)

无论如何,banner 和 helo 都可以,但是 myhostname 仍然是 main.cf 中包含的那个

vio*_*313 10

Postfix 是高度可配置的。如此之多以至于 rtfming 似乎只比阅读源代码(只是开玩笑)稍微有利。

事实上,有多种方法可以动态覆盖静态配置。至少,需要对 Postfix 工作流程有一定的了解。这是在概述中

了解以下内容也很有用:

  • 不同的 Postfix 守护进程引用main.cf 静态配置的不同部分。
  • 大多数内置的 Postfix 服务都是可定制的;
  • 可以将临时定制服务(milters等)插入工作流程;
  • 如果一切都失败了,可以部署多个 Postfix 实例;每个都指的是单独的main.cfmaster.cf静态的配置


根据 OP,有条件地向某些外部收件人发送邮件:

感兴趣的方法是那些以以下任一条件为条件的方法:

  • smptd监听端口
  • 发件人域名

显然,在这方面,并且由于很快就会变得清晰的原因,Wietse Venema在 Postfix 2.7 中做了一些*关键的更改,以进行内容过滤等总结:

前缀 后缀 2.7 :

在未指定的情况下,默认的下一跳目标是 $myhostname(即:)localhost


后缀 2.7:

如果未指定,默认下一跳目标是收件人域。

通过使用开箱即用的方式支持以发件人域为条件的传输 sender_dependent_default_transport_maps


这种区别是有问题的,因为仍然有人坚持 2.7 之前的 Postfix 安装。例如:对于一些依赖官方 rpms 的 Red Hat 用户,例如,用户仍然使用 centOS 5x => Postfix 2.3 & 对于 centOS 6x => Postfix 2.6(但我可能错了,dyor 等


后缀 2.7:

事情变得容易了!下面是几种方法。

第一种方法涉及设置几个smtpd监听不同非标准端口的守护进程,并根据smtpd我们将出站电子邮件提交到哪个端口使用自定义传输:

  • 端口 10026 => custom1_smtp
  • 端口 10027 => custom2_smtp

这是通过动态定义自定义过滤器服务并覆盖smtpd服务中的content_filter指令来实现的。过滤器是一个假人。我们不会真正编写和部署我们自己的自定义过滤器服务。相反,我们只是劫持一个 postfix服务实例,其唯一目的是在电子邮件最终被发布到野外之前获得对指令的访问和动态覆盖。smtpmyhostname

这只能发生在 Postfix 2.7(可能还有上面的后续版本)中,因为指定传输的默认 nexthop 目的地被定义为接收域。在低于 Postfix 2.7 的版本中,它被定义为$myhostname因此电子邮件循环回到 Postfix,导致它陷入困境。


第二种方法是书上写的,它使用sender_dependent_default_transport_maps有条件地将我们的出站电子邮件路由到几个自定义的传输;并取决于发件人的域名:

  • parrots.tld => custom3_smtp:
  • penguins.tld => custom4_smtp:

sender_dependent_default_transport_maps像动作sender_dependent_relayhost_maps但不是从一个指定的发送者域路由的发送邮件到指定目的地的域,sender_dependent_default_transport_maps被用来在内部路由发送邮件从一个指定的发送器(域名)到指定的(自定义的)传输中所定义master.cf


我们将以下指令添加到/etc/postfix/main.cf

sender_dependent_default_transport_maps = hash:/etc/postfix/sender_transports
Run Code Online (Sandbox Code Playgroud)


然后创建映射文件/etc/postfix/sender_transports

@parrots.tld    custom3_smtp:
@penguins.tld   custom4_smtp:
Run Code Online (Sandbox Code Playgroud)

&构建数据库使用postmap

postmap hash:/etc/postfix/sender_transports
Run Code Online (Sandbox Code Playgroud)


然后我们定义我们所有的自定义传输/etc/postfix/master.cf

custom4_smtp      unix  -       -       n       -       -        smtp
             -o myhostname=mailer.external.penguins.tld
             -o smtp_bind_address=m.n.o.p
             -o smtp_helo_name=penguins.tld


custom3_smtp      unix  -       -       n       -       -        smtp
             -o myhostname=mailer.external.parrots.tld
             -o smtp_bind_address=i.j.k.l
             -o smtp_helo_name=parrots.tld


custom2_smtp      unix  -       -       n       -       -        smtp
             -o myhostname=mailer.external.cats.tld
             -o smtp_bind_address=e.f.g.h
             -o smtp_helo_name=cats.tld


custom1_smtp      unix  -       -       n       -       -        smtp
             -o myhostname=mailer.external.dogs.tld
             -o smtp_bind_address=a.b.c.d
             -o smtp_helo_name=dogs.tld



# our main internal entry for the dogs site; all outgoing dogs traffic is
# sent to this (non-standard) port and routed to our custom1_smtp transport
10026             inet  n      -        n       -       -        smtpd
             -o myhostname=mailer.internal.dogs.tld
             -o content_filter=custom1_smtp:  


# our main internal entry for the cats site; all outgoing cats traffic is
# sent to this (non-standard) port and routed to our custom2_smtp transport
10027             inet  n      -        n       -       -        smtpd
             -o myhostname=mailer.internal.cats.tld
             -o content_filter=custom2_smtp:  


# default smtpd entry;  outgoing traffic sent to this port (25) will get routed 
# subject to the conditions in our sender_dependent_default_transport_maps file
smtp              inet  n      -        n       -       -        smtpd
             -o myhostname=mailer.internal.tld


# hoorah.
#
Run Code Online (Sandbox Code Playgroud)


在 Postfix 2.7 之前:

Postfix pixies 通常建议的方法是设置多个 Postfix 实例。

但这里是对 Postfix 工作流的理解派上用场的地方.. 因为通过设计自定义定义的 Postfix 服务链,它也可以通过单个 Postfix 实例实现。没有什么main.cf需要改变的。静态配置可以从我们在 中定义的自定义服务链中动态覆盖master.cf

每个服务读取它自己的位于main.cf配置中的所有指令的子集。因此,随着我们在自定义服务链上的进展,我们可以覆盖链中每个 Postfix 服务中可能允许的任何设置。

(另外,请注意,我们甚至可以为任何默认的 Postfix 守护进程编写我们自己的自定义替换。这非常酷)。


/etc/postfix/master.cf

# each Postfix service reads it's own subset of directives from main.cf config.
# many settings can be dynamically overridden as we move thro the service chain..
# here we override the $myhostname setting depending upon which port we send our 
# outgoing smtp email to.

# custom2  cats service chain 
custom2_cleanup   unix  n       -       -       -       0        cleanup             -o queue_service_name=custom2_qmgr
custom2_qmgr      fifo  n       -       n       300     1        qmgr                -o rewrite_service_name=custom2_rewrite
custom2_rewrite   unix  -       -       n       -       -        trivial-rewrite     -o default_transport=custom2_smtp:
custom2_smtp      unix  -       -       n       -       -        smtp
             -o myhostname=mailer.external.cats.tld
             -o smtp_bind_address=e.f.g.h
             -o smtp_helo_name=cats.tld


# custom1 dogs service chain 
custom1_cleanup   unix  n       -       -       -       0        cleanup             -o queue_service_name=custom1_qmgr
custom1_qmgr      fifo  n       -       n       300     1        qmgr                -o rewrite_service_name=custom1_rewrite
custom1_rewrite   unix  -       -       n       -       -        trivial-rewrite     -o default_transport=custom1_smtp:
custom1_smtp      unix  -       -       n       -       -        smtp
             -o myhostname=mailer.external.dogs.tld
             -o smtp_bind_address=a.b.c.d
             -o smtp_helo_name=dogs.tld


# our main internal entry for the dogs site; all outgoing dogs traffic is
# sent to this (non-standard) port and routed to our custom1 service chain
10026             inet  n      -        n       -       -        smtpd
             -o myhostname=mailer.internal.dogs.tld
             -o cleanup_service_name=custom1_cleanup
           # NB: attempting to override the content_filter directive 
           # *will not work* in postfix < 2.7 since an unspecified nexthop 
           # destination defaults to localhost and causes the email to loop
           # -o content_filter=custom1_smtp:  


# our main internal entry for the cats site; all outgoing cats traffic is
# sent to this (non-standard) port and routed to our custom2 service chain
10027             inet  n      -        n       -       -        smtpd
             -o myhostname=mailer.internal.cats.tld
             -o cleanup_service_name=custom2_cleanup

# yeehar! acu ;)
#
Run Code Online (Sandbox Code Playgroud)


注意1:需要注意的是:
虽然配置参数记录了诸如cleanup_service_name和 之rewrite_service_name 类的指令,但它们似乎没有记录为任何 Postfix守护进程的可配置选项参数?!

因此,至少这似乎是一种未记录的方法,因此很可能在官方圈子中不受欢迎,甚至可能被视为邪恶。〜我不知道,因为我永远无法形成一个足够有说服力的问题来勇敢面对postfix-users@postfix.org官方邮件列表!


注意2
有一些人试图以其他富有想象力的方式来做这种事情,例如设置 header_checks FILTER 以localhost通过动态制作一个完整的来克服默认的下一跳目的地transport:recipient-domain-destination

/etc/postfix/master.cf

custom2_smtp      unix  -       -       n       -       -        smtp
             -o myhostname=mailer.external.cats.tld
             -o smtp_bind_address=e.f.g.h
             -o smtp_helo_name=cats.tld

custom2_cleanup   unix  n       -       -       -       0        cleanup 
             -o header_checks=regexp:/etc/postfix/custom2_header_checks

#conditional processing contingent upon entry via some non-standard port
10027             inet  n      -        n       -       -        smtpd
             -o myhostname=mailer.internal.cats.tld
             -o cleanup_service_name=custom2_cleanup
Run Code Online (Sandbox Code Playgroud)


然后在 中/etc/postfix/custom2_header_checks,使用正则表达式将收件人域从标头字段中拉出,并将其提供给过滤器指令,如下所示:

/^To:.*@(.*)$/      FILTER    custom2_smtp:$1
Run Code Online (Sandbox Code Playgroud)

虽然这看起来是个好主意,并且部分有效,但它确实是一个可怕的黑客;如果/当外发电子邮件包含多个收件人时,它可能不安全并且至少会失败。呸!


注意3
如果以上都没有任何意义,那么您可能需要做更多的 rtfming ;)

但说真的,我知道这里有很多东西......由于各种我无法控制的原因,业务停留在 Postfix 2.3 上,我需要花费超过 5 分钟的时间来整理他们的需求;在某种程度上,我的时薪已经减少到哥斯达黎加菠萝采摘工的时薪(只有我没有从他们的哥斯达黎加生活中受益)。所以我试图把这一切都说出来,而这在我的脑海中是新鲜的,而且不仅仅是模仿官方文档;希望这可以帮助下一个在这条特殊道路上发生的可怜的灵魂;)


小智 2

经过大量测试后,我必须得出结论,你不能这样做。可以动态更改 myhostname,它只是不影响 Received 标头。

通过使用横幅使用 $myhostname 的测试,我可以看到当我使用时它会发生变化

-o myhostname=test.test.test
Run Code Online (Sandbox Code Playgroud)

但收到的标头却没有。

我尝试在 main.cf 中使用

mydomain=test.test.test
myhostname=$mydomain
Run Code Online (Sandbox Code Playgroud)

这确实会影响已接收标头和横幅。但试图覆盖 $mydomain

-o mydomain=test.test.test
Run Code Online (Sandbox Code Playgroud)

仅再次影响横幅。

因此,在从命令行参数覆盖 $myhostname之前, Received 标头中使用的变量似乎是从$myhostname 填充的。