postfix 是否允许动态更改“myhostname”?我进行了很多研究,但没有发现任何定性内容。我的安装是 postfix 多域、多 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
无论如何,banner 和 helo 都没问题,但是 myhostname 仍然是 main.cf 中包含的那个。
答案1
Postfix 具有高度可配置性。因此,rtfming 似乎只比阅读来源(只是开个玩笑)。
事实上,有很多方法可以动态覆盖静态配置。至少需要对 Postfix 工作流程有所了解。概述。
了解以下内容也很有用:
- 不同的 Postfix 守护进程引用
main.cf
静态配置的不同部分。 - 大多数内置的 Postfix 服务都是可定制的;
- 特别定制服务(米尔特斯等)可以插入到工作流程中;
- 如果一切都失败了,多个 Postfix 实例可以部署;每个都指的是单独的
main.cf
静态master.cf
配置
按照 OP 的说法,有条件地发送邮件给某些外部收件人:
感兴趣的方法是基于以下任一条件的方法:
- 监听
smptd
端口 - 发件人域名
显然,正是在这方面,出于希望很快就能清楚的原因,Wietse Venema做了一些*关键改变在 Postfix 2.7 中内容过滤总结一下:
Postfix 2.7 之前版本:
如果未指定,默认的下一跳目的地是 $myhostname (即:)
localhost
。
Postfix 2.7:
如果未指定,则默认的下一跳目的地是收件人域。
通过使用
sender_dependent_default_transport_maps
这种区别是有问题的,因为仍然有人停留在 2.7 之前的 Postfix 安装上。例如:对于一些依赖官方 rpm 的 Red Hat 用户,例如,仍然使用 centOS 5x => Postfix 2.3 的用户和使用 centOS 6x => Postfix 2.6 的用户(但我可能是错的,dyor 等)
Postfix 2.7:
事情变得更容易了!下面是几种方法。
第一种方法是设置几个smtpd
监听不同非标准端口的守护进程,并根据smtpd
我们将出站电子邮件提交到哪个端口来使用自定义传输:
- 端口 10026 => custom1_smtp
- 端口 10027 => custom2_smtp
这是通过动态定义定制过滤服务content_filter
&覆盖邮件传输协议服务。过滤器是一个虚拟的。我们实际上不会编写和部署我们自己的自定义过滤服务。相反,我们只是劫持了一个 postfixsmtp
服务实例,其唯一目的是myhostname
在电子邮件最终被推送到外面之前获得访问权限并动态覆盖指令。
这只能发生在 Postfix 2.7(也可能是后续版本)中,因为指定传输的默认下一跳目的地被定义为收件人域在 Postfix 2.7 以下的版本中,它被定义为$myhostname
,因此电子邮件会循环回到 Postfix,从而导致其崩溃。
第二种方法是按书本和用途sender_dependent_default_transport_maps有条件地将我们的出站电子邮件路由到几个更多自定义的传输;并取决于发件人的域名:
- parrots.tld => custom3_smtp:
- 企鹅.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
然后创建映射文件/etc/postfix/sender_transports
:
@parrots.tld custom3_smtp:
@penguins.tld custom4_smtp:
使用以下方式建立数据库postmap
:
postmap hash:/etc/postfix/sender_transports
然后我们在以下位置定义所有自定义传输/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.
#
Postfix 2.7 之前版本:
Postfix 小精灵通常建议的方法是设置多个 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 ;)
#
注释1: 需要注意的是:
虽然诸如cleanup_service_name
和之类的指令rewrite_service_name
是记录在配置参数,它们似乎没有被记录为任何 Postfix 的可配置选项参数守护进程?!
所以至少这看起来是一个未记录的方法,因此在官方圈子里很可能会遭到反对,甚至被视为邪恶。〜我不知道,因为我从来没有能够提出一个足够有说服力的问题来勇敢地进入[email protected]
官方邮件列表!
笔记2:
有一些人试图以其他富有想象力的方式来做这种事情,例如设置 header_checks FILTER 以便localhost
通过动态编写完整的内容来克服默认的 nexthop 目的地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
然后在中/etc/postfix/custom2_header_checks
,使用正则表达式将收件人域从标头字段中拉出,并将其提供给过滤器指令,如下所示:
/^To:.*@(.*)$/ FILTER custom2_smtp:$1
虽然这看起来是个好主意,并且部分可行,但它无疑是一种可怕的黑客攻击;具有潜在的不安全性,并且至少在发送的电子邮件包含多个收件人时会失败。咄!
注释3:
如果以上内容都没有任何意义,那么您可能需要做更多的 rtfming ;)
但说真的,我知道这里有很多东西。由于各种我无法控制的原因,这生意停留在 Postfix 2.3 上,我需要花超过 5 分钟的时间来整理他们的要求;以至于我的小时费率已经下降到哥斯达黎加菠萝采摘者(只有我不要受益于他们的哥斯达黎加生活)。所以我试着趁着记忆犹新的时候把这一切都说清楚,而不是鹦鹉学舌地重复官方文件;希望这样可以帮助下一个走上这条特殊道路的可怜人;)
答案2
经过大量测试,我必须得出结论,您无法做到这一点。可以动态更改 myhostname,但它不会影响 Received 标头。
使用 $myhostname 进行横幅测试后,我可以看到当我使用时它会发生变化
-o myhostname=test.test.test
但收到的标头却没有。
我尝试在 main.cf 中使用
mydomain=test.test.test
myhostname=$mydomain
这确实会影响已接收标头和横幅。但尝试覆盖 $mydomain
-o mydomain=test.test.test
只会再次影响横幅。
因此,似乎 Received 标头中使用的变量是由 $myhostname 填充的前从命令行参数覆盖 $myhostname。