POSTFIX 文档

一、基本配置

介绍

postfix的main.cf文件支持上百个配置参数。幸运的是,所有的参数都有比较合理的默认值。在大多数情况下,你只需要配置2到3个参数值就可以启用postfix邮件系统了。下面的这个链接是postfix配置文件的简要介绍。

Postfix配置文件

接下来的内容假设你已经安装好Postfix系统,不管你是通过源码编译安装还是使用已编译好的版本安装的。

这 篇文档包括了postfix的基本配置。关于如何把postfix配置成一个邮件中转器(mailhub)或邮件防火墙或拨号的客户端等特定的应用,请参 见STANDARD_CONFIGURATION_README这个文件。在你掌握以下的基本参数之前,暂时可以不用去了解 STANDARD_CONFIGURATION_README的相关内容。

第一个参数是制定邮件系统的身份以及在网络中的作用

出站邮件的域名

接收什么域名的邮件

中继何种客户端的邮件

把中继邮件传递到什么目的地

传递的方法:直接还是间接

许多其他配置参数的默认值都是从这儿继承来的

下面的这个参数控制着何时将邮件传递到本地postmaster
什么错误发送错误报告给postmaster

如果你的postfix是在一个代理,NAT的后面或者你已启用了一个备份的MX,确保正确的设置下面的参数;
Proxy/NAT外部网络地址

Postfix守护进程运行在后台,把遇到的问题以及正常的活动记录到syslog日志中。这里有一些事情需要注意一下:
你需要postfix记录什么样的日志

如果你的postfix有强烈的安全需求,你可能想让postfix守护进程运行在chroot环境下
postfix守护进程运行在chroot下

如果你的postfix运行在一个虚拟的网络接口上,或者如果你的虚拟接口上还同时运行着其他的邮件服务,你将需要列在下面的参数:
主机名
域名
网络地址

postfix配置文件
默认情况下,postfix配置文件在/etc/postfix目录下。两个最重要的文件是main.cf和master.cf;这两个文件的所有者必须是root用户。赋予其他用户对main.cf或master.cf文件的写入权限意味着赋予了该用户root权限

在/etc/postfix/main.cf文件中,你将需要设置最少的参数,postfix配置参数个数类似于shell的变量,但有两个不同之处:第一个是postfix不能识别引号;

你能像下面的方式制定配置参数:

/etc/postfix/main.cf:
parameter = value

你也能在参数钱使用$符号
/etc/postfix/main.cf:
other_parameter = $parameter

你可以在$parameter被赋值前使用$parameter(这是postfix与unix脚本变量的第二个不同)。postfix配置参数使用了松散的赋值,直到该值被使用时才会被检查

postfix使用数据库文件来实现访问控制,地址重写等目的。DATABASE_README文件介绍了postfix怎样与Berkeley DB, LDAP or SQL 协同工作。这儿有一个通用的示例:

/etc/postfix/main.cf:
virtual_alias_maps = hash:/etc/postfix/virtual

当改变了main.cf或master.cf文件中的值时,一定要以root身份执行postfix reload命令来刷性邮件系统

# postfix reload

出站邮件使用什么域名
myorigin参数指定了邮件发送者的域名。默认情况下是使用本地的机器名($myhostname)。如果你运行的不是一个很小的邮件系统,你可能想改成$domain。

为了保证发送者和接受者地址的一致性,myorigin也应该为那些接受者地址不规范的邮件附加上域名

示例(只需要指定一个即可)
/etc/postfix/main.cf:
myorigin = $myhostname (以 “user@$myhostname”发送邮件,默认设置是这种形式)
myorigin = $mydomain (以 “user@$mydomain”发送邮件,推荐使用这个形式)

接收何种域名的邮件
mydestination参数指定:postfix把什么域名的邮件传送到本地,而不是其他的机器。默认情况下,postfix接收发往本机的邮件。VIRTUAL_README文件介绍了如何为postfix配置主域。

你能指定零个或过个域名,它们之间用空格或逗号隔开。/file/name的方式被它的内同代替;

重要提示:如果你的机器是整个域的邮件服务器,你必须指定$mydomain的值。

示例1:默认设置
/etc/postfix/main.cf:
mydestination = $myhostname localhost.$mydomain localhost

示例2:域范围的邮件服务器
/etc/postfix/main.cf:
mydestination = $myhostname localhost.$mydomain localhost $mydomain

示例3:多个A记录的主机
/etc/postfix/main.cf:
mydestination = $myhostname localhost.$mydomain localhost
www.$mydomain ftp.$mydomain

注意事项:为了避免邮件传递的循环,你必须列出机器的主机名,包括:$myhostname和localhost.$mydomain

什么客户端可以中继邮件
默认情况下,postfix将信任网络的邮件传递到任何目的地。信任网络定义在mynetworks参数中。postfix默认信任与postfix在同一个客户端。

重要提示:如果你的机器是连接到广域网中,你的默认信任网络范围将太广,容易被恶意中继

示例(仅需指定一行即可):
/etc/postfix/main.cf:
mynetworks_style = subnet (这是默认设置,信任postfix的网段)
mynetworks_style = host (最安全的,仅信任postfix本机)
mynetworks = 127.0.0.0/8 (最安全的,仅信任postfix本机)
mynetworks = 127.0.0.0/8 168.100.189.2/32 (这里指定了信任的网段)

你能在main.cf中指定信任的网络,或者你能让postfix为你工作。默认是让postfix工作。这个结果取决于mynetworks_style的参数值

·当postfix只传递本机的纸时使用”mynetworks_style = host”

·当postfix转发与postfix的IP同网段的邮件时,使用”mynetworks_style = subnet” 。在linux系统上,使用”ifconfig”来检查ip地址

·当postfix转发与postfix的ip在同一类网络(即A/B/C类网)中的邮件时,使用”mynetworks_style = class”,不要在拨号的postfix系统中使用该种方式,因为这会导致你的postfix信任ISP的整个网络。这种情况下,你可以使用 mynetworks参数明确的指出信任的网段

作为mynetworks_style的另外一种方式,你可以使用mynetworks手动指定信任的网络(注意:设置了mynetworks会导致postfix忽略mynetworks_style中指定的值)。如下面的示例:
/etc/postfix/main.cf:
mynetworks = 168.100.189.0/28, 127.0.0.0/8
你也可以在这里指定一个信任网络的文件地址。然后把信任的网络写入该文件。而不需要把信任的网络一个个的写入main.cf文件中。

中继邮件到什么目的地
默认情况下,postfix仅将陌生人的邮件传递到信任的远处目标域。信任的远处目标域定义在relay_domains参数中。默认是在mydestination中的所有域及其子域。

示例(仅需指定一个即可):
/etc/postfix/main.cf:
relay_domains = $mydestination (默认值)
relay_domains = (安全的,不转发任何陌生人的邮件)
relay_domains = $mydomain (转发mydomains及其子域的邮件)

传递的方法:直接或间接
默 认情况下,postfix直接把邮件传递到internet上。有些情况下,这是不可行的。例如,你的系统在非工作时间需要关闭,或者postfix在防 火墙的后面,或者你的网络提供者不允许你把邮件直接发送到internet上。在这些情况下,你需要配置postfix通过一个中继主机间接的传递邮件。

示例(仅需指定一个即可):
/etc/postfix/main.cf:
relayhost = (默认设置,直接传递)
relayhost = $mydomain (通过本地的邮件hub传递)
relayhost = [mail.$mydomain] (通过本地的邮件hub传递)
relayhost = [mail.isp.tld] (通过isp供应商的邮件hub传递)

这里使用中括号[]是为了忽略dns的mx记录查找。如果你不知道这个中括号的含义也没有关系,仅需确保为邮件hub主机名加上中括号[],否则会导致你的邮件被错误的传递

STANDARD_CONFIGURATION_README文件包含了更多关于防火墙和拨号网络的提示。

发送错误报告给postmaster
你应该为postmaster设置一个别名,以便错误报告发送到别名邮箱横中。postfix邮件系统必须要有postmaster地址存在,以便系统能够发送错误报告。当升级aliases(5)的时候,确保超级用户的别名存在。
/etc/aliases:
postmaster: you
root: you

在改变了aliases文件后,需执行“newaliases”命令。aliases文件默认在/etc目录下,你可以更改aliases的位置。使用postconf alias_maps找到该文件。

postfix系统把错误发送给postmaster。你可能只关心部分的错误,所以,需要配置错误报告的级别。默认只报告严重的错误(资源和软件错误)给postmaster:

默认设置:
/etc/postfix/main.cf:
notify_classes = resource, software

The meaning of the classes is as follows:
错误类型的解释如下:
(略)

代理/NAT外部网络地址
一些邮件服务器通过proxy/NAT连接到邮件服务器。这意味着Internet上的系统只能连接到NAT/proxy,而不是连接到邮件服务器上。NAT/proxy把外部的邮件连接重定向到邮件服务器上,但是postfix不知道这个连接重定向的过程。

如果你的postfix运行在proxy或者NAT后面,你需要配置proxy_interfaces参数,同时指定所有的外部proxy/NAT地址,以便postfix从这些地址接收邮件。你可以使用IP地址来代替主机名。

重要提示:你必须指定proxy/NAT的外部地址,当你的系统是一个备份的MX主机时,否则当主MX故障时,会出现邮件的循环。

示例:在NAT后的主机是备份的MX主机
/etc/postfix/main.cf:
proxy_interfaces = 1.2.3.4 (1.2.3.4是proxy/NAT的公网ip地址)

你需要知道哪些postfix日志内容
postfix 守护进程运行在后台,它通过syslog守护进程记录postfix出现的错误以及正常的活动。syslogd进程依据类别和严重性来筛选事件,然后把它 们添加到日志文件中去。日志文件的类别,级别和日志文件名通常是在/etc/syslog.conf文件中指定的。下面是最简单的日志文件
/etc/syslog.conf:
mail.err /dev/console
mail.debug /var/log/maillog

在改变syslog.conf文件后,发送一个”HUP”信号给syslogd进程。

重要提示: 许多的syslogd应用程序不会主动的创建文件。你必须在重启syslogd进程前创建相关的日志
文件。

重要提示: 在linux系统上,你需要在路径名前加一个”-“符号,例如:-/var/log/maillog,否则syslogd进程将会抢夺postfix的系统资源,最终影响postfix系统的运行效率。

如果顺利的话,问题的数量比较小,但是在日志文件循环前运行下面的内容将是一个好的习惯。
# postfix check
# egrep ‘(reject|warning|error|fatal|panic):’ /some/log/file

第一个命令(及postfix check)将触发postfix报告文件的允许/所有不一致的地方。

第二个命令将查找postfix的错误报告,报告怎样更有效的阻止中继邮件和垃圾邮件。这个内容可能会很多。你可以根据这些信息过滤掉不期望的内容。

DEBUG_README文件描述了“警告”等错误标签的含义

运行postfix守护进程的chrooted
postfix守护进程可以运行在一个chroot环境下(这个在master.cf文件中配置)。这个进程将运行在一个固定的没有什么特权的环境下,访问postfix队列目录的权限(/var/spool/postfix)也被限制.这将有效的阻止黑客的入侵。

其他内容(略)

主机名
主机名参数使用FQDN的值.$myhostname将出现在postfix许多参数默认值里。

默认情况下,myhostname设置为本地机器名。如果你的本地机器名不是规范的FQDN,或者你在一个虚拟的接口上运行postfix,你将需要为postfix指定一个FQDN。

如果你在main.cf中指定了mydomain,那么postfix将会使用它的值为myhostname参数产生一个FQDN默认值

示例:

/etc/postfix/main.cf:
myhostname = host.local.domain (machine name is not FQDN)
myhostname = host.virtual.domain (virtual interface)
myhostname = virtual.domain (virtual interface)

域名
域名参数指定$myhostname的父域。默认情况下,它是$myhostname去掉第一个点号前的内容。

相反的,如果你在main.cf中指定了mydomain值,postfix将用该值为myhostname产生一个默认的FQDN。

示例:
/etc/postfix/main.cf:
mydomain = local.domain
mydomain = virtual.domain (virtual interface)

网络地址
inet_interfaces蚕食指定了postfix监听的网络地址;传递到user@[network address]的邮件会被传到本地,其效果等同于该地址列在了$mydestination中一样。

你能在master.cf预先设置一个ip地址,从未忽略inet_interfaces的设置
postfix默认监听所有活动的端口。如果你的postfix运行在虚拟的接口上,你需要指定监听的端口。

重要提示:如果你的MTAs运行在虚拟的接口上,你必须为这个MTAs明确的指定inet_interfaces值。

示例:默认的设置。
/etc/postfix/main.cf:
inet_interfaces = all

例如:主机运行了多个虚拟邮件服务器。对每个postfix实例,可以仅指定下面的一个
/etc/postfix/main.cf:
inet_interfaces = virtual.host.tld (virtual Postfix)
inet_interfaces = $myhostname localhost… (non-virtual Postfix)
注意:在更改inet_interfaces参数后,需要重启postfix服务器。

二、家庭办公环境的Postfix安装技巧和提示

概述
把家庭办公环境的postfix应用技巧和提示整合到这篇文档的目的是便于查找。这篇文档仅描述了邮件的发送。如 果你的postfix服务器不直接接收邮件(比如:它没有公网的域名和固定的IP),那么你将需要一个类似于“fetchmail”的解决方法–这超出 了postfix的文档范围

从STANDARD_CONFIGURATION_README文档中选择相关主题:
·基于internet主机的postfix安装
·基于Intranet主机的postfix安装
从SASL_README文档中选择相关主题:
·在postfix的smtp客户端启用SASL认证
·配置邮件发送者的SASL认证
关于这些主题的更详细的信息查看SASL_README 和 STANDARD_CONFIGURATION_README文档

基于Internet主机的postfix安装
postfix几乎在没有改变独立主机的设置的前提下就能被安装好。至少,当你下载postfix源码后知道如何安装postfix。

你可以用“postconf -n”命令查看main.cf中的哪些设置变更过。除了一些路径的设置和“基本配置”文档中的参数设置外,几乎没有什么申述需要在独立主机上设置:
/etc/postfix/main.cf
myhostname=ceshi.linux.com (其中ceshi.linux.com是机器的FQDN)
mydomain=linux.com
myorigin=$mydomain
mydestination=$myhostname localhost.$mydomain localhost
mail.$mydomain
inet_interfaces=all
mynetworks=127.0.0.1/8 192.168.1.0/24
proxy_interfaces=1.2.3.4
relayhost = [mail.$mydomain]
/etc/aliases:
postmaster: qq@linux.com
root: qq@linux.com

也可以参见“没有公网主机名的postfix安装”部分,如果它们对你的配置有帮助的话。

没有公网主机名的postfix安装
这部分是适用于那些没有internet主机名(即公网固定IP)的postfix主机。一般是那 些通过DHCP或者拨号获取公网动态IP地址的主机。postfix可以用一个不存在(fantasy)的名称为linux系统用户提供发送/接收邮件的 功能。但是当你在给internet用户发邮件时,不能在邮件地址中使用这个名称,因为internet用户将无法给你回复邮件。实际上,越来越多的站点 将拒绝域名不存在的邮件。

注意:下面的内容将随postfix版本不同而有所不同。查看postfix的版本,使用”postconf mail_version”命令

解决方法1:postfix2.2及以后的版本
postfix 2.2 使用通用的地址映射方法把本地邮件地址映射为internet上的有效地址。这个映射仅在邮件发送出postfix主机时才发生;当邮件在同一台机器的不同用户间传递邮件时,将不会使用地址映射功能。

下面的例子展现了一些附加的配置。你需要把这些附加的配置与该文档前半部分介绍的基本配置结合起来。

1 /etc/postfix/main.cf:
2 smtp_generic_maps = hash:/etc/postfix/generic
3
4 /etc/postfix/generic:
5 his@localdomain.local hisaccount@hisisp.example
6 her@localdomain.local heraccount@herisp.example
7 @localdomain.local hisaccount+local@hisisp.example

当邮件通过SMTP发送给公网的邮件服务器时:
第5,6行 左边是内部的邮件地址,右边的部分是公网的邮件地址

如果你的系统使用dbm文件来代替db文件的话,那么用dbm来代替hash。查看你的postfix支持哪些查询表,用”postconf -m”命令。

当你改变了通用查询表的内容时,需要执行一下”postmap /etc/postfix/generic”命令来重新生成该配置文件。

解决方法2: postfix 2.1及以前版本
老版本的postfix系统是使用有效地internet地址,并且让postfix把有效的internet地址映射为本地的地址。这样,你能发送邮件给internet用户和本地用户。

下面的例子展现了一些附加的配置。你需要把这些附加的配置与该文档前半部分介绍的基本配置结合起来。

1 /etc/postfix/main.cf:
2 myhostname = hostname.localdomain
3 mydomain = localdomain
4
5 canonical_maps = hash:/etc/postfix/canonical
6
7 virtual_alias_maps = hash:/etc/postfix/virtual
8
9 /etc/postfix/canonical:
10 your-login-name your-account@your-isp.com
11
12 /etc/postfix/virtual:
13 your-account@your-isp.com your-login-name

如果你的系统使用dbm文件来代替db文件的话,那么用dbm来代替hash。查看你的postfix支持哪些查询表,用”postconf -m”命令。

当你改变了canonical表的内容时,需要执行一下”postmap /etc/postfix/canonical”命令

当你改变了virtual表的内容时,需要执行一下”postmap /etc/postfix/virtual”命令

在postfix的smtp/lmtp客户端启用sasl验证
这个部分向你展示了一个典型的方案:postfix的smtp客户端经过邮件网关sasl验证后发送邮件。

问题解决提示:
如果你的sasl登陆失败,并在maillog日志文件里提示:sasl验证失败:没发现可用的验证机制。这个错误参见“postfix SMTP/LMTP客户端策略–SASL机制属性”。

对于一些模糊的sasl验证失败,参见“postfix SMTP/LMTP客户端策略–SASL机制名称”

为了是这个例子更可读,我们把它分成两个部分介绍。第一个部分关注基本的配置,第二个部分主要是设置用户名/密码信息。

/etc/postfix/main.cf:
smtp_sasl_auth_enable = yes
relayhost = [mail.isp.example]
# Alternative form:
# relayhost = [mail.isp.example]:submission
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

smtp_sasl_auth_enable设置决定是否启用客户端的验证。我们将在第二部分配置客户端的用户名和密码信息。

relayhost参数设置将强制postfix的SMTP把所有发往公网的邮件传递到指定的邮件网关,而不是直接把邮件发送到目的邮箱。

在relayhost参数设置中,中括号”[]”阻止postfix的smtp到mx记录中查找中括号中的名称。

relayhost的目的地可以指定一个非默认的tcp端口。例如:[mail.isp.example]:submission告诉postfix连接tcp的587端口–这是为email客户应用保留的端口。

postfix的smtp客户端要与smtp服务器使用一样的验证方法”AUTH=method….”以回应ehlo命令;这要求没有额外的postfix客户端配置。

postfix的smtp客户端不支持过期的”wrappermode”协议–在smtp服务器使用465端口。使用隧道,请参见TLS_README文档

使用smtp_sasl_password_maps参数,我们能配置postfix的smtp客户端发送用户名和密码信息给邮件网关服务器。 正如接下来要讨论的部分,postfix的smtp客户端支持多isp帐户。由于这个原因,用户名和密码存储在一个邮件网关服务器可以访问的表中

/etc/postfix/sasl_passwd:
# destination credentials
[mail.isp.example] username:password
# Alternative form:
# [mail.isp.example]:submission username:password

重要提示:
把sasl客户端的密码文件放在/etc/postfix目录中,确保只有root用户对该文件可读写。postfix的smtp客户端可以读取sasl客户端的密码。它在降低特权和使用chroot前,以root用户的身份打开该文件

当改变/etc/postfix/sasl_passwd之后,一定要使用postmap命令

如果在relayhost destination中指定了相关的值,必须在smtp_sasl_password_maps文件中使用相同的值

如果你在relayhost destination中指定了非默认的tcp端口(比如:”:submission” or “:587″),你必须在smtp_sasl_password_maps使用相同的端口

配置基于发送者的sasl验证机制
postfix为不同的发送地址提供不同的isp帐户(postfix 2.3版本之后)。当一个人使用同一台机器用于工作和生活时,或者当同一台postfix服务器使用不同的isp帐户时,这个设置将非常有用。

为了实现这个功能,postfix支持per-sender的sasl密码和per-sender中继主机。在下面的例子中,postfix的 smtp客户端将先通过发送者地址查找sasl密码文件,然后通过目的地址查找sasl密码文件。同样的,postfix的trivial- rewrite(8)守护进程将查找per-sender的中继主机文件,并使用默认的中继设置作为最后的办法。

/etc/postfix/main.cf:
smtp_sender_dependent_authentication = yes
sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
relayhost = [mail.isp.example]
# Alternative form:
# relayhost = [mail.isp.example]:submission
/etc/postfix/sasl_passwd:
# Per-sender authentication; see also /etc/postfix/sender_relay.
user1@example.com username2:password2
user2@example.net username2:password2
# Login information for the default relayhost.
[mail.isp.example] username:password
# Alternative form:
# [mail.isp.example]:submission username:password
/etc/postfix/sender_relay:
# Per-sender provider; see also /etc/postfix/sasl_passwd.
user1@example.com [mail.example.com]:submission
user2@example.net [mail.example.net]

如果你富有创造性,你能把两个表整合到mysql数据库中,并配置不同的postfix查询条件

如果你的系统使用dbm文件来代替db文件的话,那么用dbm来代替hash。查看你的postfix支持哪些查询表,用”postconf -m”命令。

当改变了sasl_passwd表时,执行”postmap /etc/postfix/sasl_passwd”命令

当改变了sender_relay表时,执行”postmap /etc/postfix/sender_relay”命令

三、postfix标准配置示例

这篇文档的目的
这篇文档展现了postfix的典型配置参数。在你按照《BASIC_CONFIGURATION_README》设置 完之后,应该回顾《postfix标准配置示例》这篇文档。需要注意的是,如果你的postfix还不能进行本地邮件发送和本地邮件传递,那么先安装好 postfix,在阅读下面的内容。

这篇文档的第一部分展现标准的配置,每一个内容都会解决一个特定的问题
•internet独立主机的postfix
•无客户端的postfix(即只发送邮件,不接收邮件)
•本地网络的postfix
•postfix的邮件网关/防火墙

这篇文档的第二部分对特定的网络环境进行附加的配置
•部分用户可以给internet发邮件
•在防火墙后面运行postfix
•为远程站点配置主/备份mx
•拨号主机的postfix配置
•没有公网地址的主机上配置postfix

internet独立主机的postfix
你能用”postconf -n”查看你的main.cf忽略了那些参数。

/etc/postfix/main.cf:
#可选参数:邮件以user@domainname代替user@hostname
#myorigin = $mydomain

#可选参数:指定NAT/proxy的ip地址
#proxy_interfaces = 1.2.3.4

#二选一的参数1:不中继其他主机的邮件
mynetworks_style = host
relay_domains =

#二选一的参数1:仅中继与postfix同一网段的客户端邮件
# mynetworks = 192.168.1.0/28
# relay_domains =

无客户端的postfix
无客户端的意思是只发送邮件不接收邮件。它不接收来自网络的任何邮件,也不把邮件投递到本地。空客户端的postfix典型应用环境是提供POP,IMAP或NFS。

在这个示例中,我们假设internet域名为:example.com,这个机器的名称为:nullclient.example.com。注:这个示例省略了默认的参数设置。

1 /etc/postfix/main.cf:
2 myorigin = $mydomain
3 relayhost = $mydomain
4 inet_interfaces = loopback-only
5 local_transport = error:local delivery is disabled
6
7 /etc/postfix/master.cf:
8 Comment out the local delivery agent entry
解释:
•第2行的意思:邮件以>user@example.com发送,而不是以user@nullclient.example.com发送。

•第3行的意思:转发所有example.com的邮件到这个邮件服务器。This prevents mail from getting stuck on the null client if it is turned off while some remote destination is unreachable.

•第4行的意思:不接收来自网络的邮件

•第5-8行的意思:关闭本地邮件投递。所有的邮件都到第三行指定的邮件服务器。
本地网络的postfix
这部分描述了一个主postfix服务器和其他邮件系统并存的局域网环境。我们仍然假设internet域名为:example.com。所有的系统都被配置为以>user@example.com发送邮件;所有的系统接收user@hostname.example.com的邮件。这个主服务器也接收>user@example.com的邮件。我们把这台机器命名为:mailhost.example.com。

以>user@example.com发送邮件的缺点是:root和其他系统帐户的邮件也发送到网关邮件服务器。这个缺点的解决办法参见“Delivering some but not all accounts locally”

这个示例仍展示除默认参数之外的所需参数

首先,我们展现没有mailhost的配置,因为这个相对简单点。这个邮件服务器以>user@example.com发送邮件,接收user@hostname.example.com的邮件。

1 /etc/postfix/main.cf:
2 myorigin = $mydomain
3 mynetworks = 127.0.0.0/8 10.0.0.0/24
4 relay_domains =
5 # Optional: forward all non-local mail to mailhost
6 #relayhost = $mydomain
解释:
•第2行:以>user@example.com发送邮件

•第3行:指定信任的网络

•第4行: 这个邮件服务器不中继不受信任网络的邮件

•第6行:如果邮件服务器没有公网的ip地址,参见下面的“防火墙后面的postfix”
接下来,我们展现含mailhost的配置。邮件服务器以>user@example.com发送邮件,接收>user@example.com和user@hostname.example.com的邮件

1 DNS:
2 example.com IN MX 10 mailhost.example.com.
3
4 /etc/postfix/main.cf:
5 myorigin = $mydomain
6 mydestination = $myhostname localhost.$mydomain localhost $mydomain
7 mynetworks = 127.0.0.0/8 10.0.0.0/24
8 relay_domains =
9 # Optional: forward all non-local mail to firewall
10 #relayhost = [firewall.example.com]

解释:
•第2行:发送给example.com域名的邮件全部传递到mailhost.example.com这台机器上。记住这行最后面的点号“.”
•第5行: 以>user@example.com发送邮件
•第6行:这个主机是发给example.com域的邮件的终点。
•第7行:指定信任的网络
•第8行:这个主机不中继不信任网络的邮件
•第10行:当mailhost需要通过防火墙上的邮件网关传递外部邮件时,需要设置这个参数。中括号“[]”是提示postfix不要进行mx查询。

在这样的环境中,用户以下面的某种方式访问他们的邮箱:
•通过NFS访问邮箱
•通过POP或者IMAP访问邮箱
•在用户倾向的机器上访问邮箱

在后面的示例中,每一个用户都有一个别名,从而把邮件转发到他们倾向的机器上。
/etc/aliases:
joe: joe@joes.preferred.machine
jane: jane@janes.preferred.machine

在某些系统上,alias数据库不是存放在/etc/aliases目录。使用”postconf alias_maps”命令查找alias数据库的位置。

在改变了aliases的文件后,使用”newaliases”命令重新生成alias数据库文件。

postfix邮件防火墙/网关
安装postfix防火墙/网关的目的是:把example.com的邮件转发到内部的网关,但是拒 绝”anything.example.com”的邮件。这儿仅有一个问题:使用relay_domains=example.com参数,防火墙也会接 收anything.example.com的邮件。

注意:这个示例要求postfix版本为2.0及以后的版本。使用”postconf mail_version”查看postfix的版本

这个解决方法出现在了许多地方。第一部分解决了在防火墙上的本地邮件投递,从而使得防火墙很难被攻破。

1 /etc/postfix/main.cf:
2 myorigin = example.com
3 mydestination =
4 local_recipient_maps =
5 local_transport = error:local mail delivery is disabled
6
7 /etc/postfix/master.cf:
8 Comment out the local delivery agent
解释:
•第2行:以>user@example.com发送邮件
•第3-8行:关闭防火墙上的本地邮件传递功能

出于技术正确性的考虑,防火墙必须能够接收postmaster@[firewall ip address]的邮件。这个解决方法的第二部分增加了对postmaster@[firewall ip address]的支持,同时也增加了 abuse@[firewall ip address]邮箱帐户。所有发给这两个地址的邮件全部被转发到内部的邮箱地址。

1 /etc/postfix/main.cf:
2 virtual_alias_maps = hash:/etc/postfix/virtual
3
4 /etc/postfix/virtual:
5 postmaster postmaster@example.com
6 abuse abuse@example.com

解释:
•由于mydestination参数的值为空(参见前文的设置),只有与$inet_interfaces或$proxy_interfaces匹配的地址才被认为是本地。所以localpart@[a.d.d.r]能够匹配为localpart in canonical(5) and virtual(5)。这样就不需要把防火墙的ip地址写到postfix配置文中去了。

这个解决方案的最后一部分没有邮件转发功能,而这是邮件防火墙的真正目的。

1 /etc/postfix/main.cf:
2 mynetworks = 127.0.0.0/8 12.34.56.0/24
3 relay_domains = example.com
4 parent_domain_matches_subdomains =
5 debug_peer_list smtpd_access_maps
6 smtpd_recipient_restrictions =
7 permit_mynetworks reject_unauth_destination
8
9 relay_recipient_maps = hash:/etc/postfix/relay_recipients
10 transport_maps = hash:/etc/postfix/transport
11
12 /etc/postfix/relay_recipients:
13 user1@example.com x
14 user2@example.com x
15 . . .
16
17 /etc/postfix/transport:
18 example.com smtp:[inside-gateway.example.com]
解释:
•第1-7行:接受来自$mynetworks的邮件,接受发给>user@example.com的邮件,但是不接受来自 user@anything.example.com的邮件。关键在第4-5行。

•第9,12-14行:定义可以接收来自internet邮件的example.com域邮件帐户。这将阻止邮件队列被未投递邮件系统塞满。如 果你没有维护有效的邮件接收者列表,那么你必须指定”relay_recipient_maps=”(即,一个空值),或者你必须在 relay_recipients表中指定一个”@example.com x”

•第10,17-18行:把发往example.com的邮件路由到内部的网关邮件服务器,用中括号[]提示postfix不要进行mx查询。

如果你的系统使用的是dbm文件,请指定dbm。使用”postconf -m”命令查看postfix支持哪些查询表

当relay_recipients的内容改变时,执行”postmap /etc/postfix/relay_recipients”命令

当传输表的内容改变时,执行”postmap /etc/postfix/transport”命令

在某些安装中,postfix的入站邮件和出站邮件处理是在两台机器上。入站的postfix实例有一个smtp服务–它用来监听外部防火墙 的接口;出站的postfix实例有一个stmp服务–它用来监听内部的接口。在这样的环境中,需要在每一个实例中配 置$inet_interfaces参数。

在大部分情况下,使用inet_interfaces将不会起作用,因为正如$inet_interfaces手册中所述的那样,smtp传输 代理对出站的连接,将使用特定的接口地址作为源地址,smtp传输代理将不能到达防火墙“另一边”的主机。出现的症状是防火墙将无法连接到此主机。关于推 荐的解决方法参见inet_interfaces参数。

部分用户可以给internet发邮件
以>user@example.com(而不是user@hostname.example.com)发送邮件的缺点是:发送给root和其他系统账号的邮件也被传递到了中心mailhost服务器上了。为了实现给这些账户的邮件在本机上传递,你可以按照下面的方法使用虚拟别名的办法:
1 /etc/postfix/main.cf:
2 virtual_alias_maps = hash:/etc/postfix/virtual
3
4 /etc/postfix/virtual:
5 root root@localhost
6 . . .
解释:
•第5行:正如virtual(5)手册中描述的那样:root匹配 root@site,当site等于$myorigin时,或者当site在$mydestination的之中,或者他与$inet_interfaces/$proxy_interfaces值匹配。

在更改了virtual的内容后,执行”postmap /etc/postfix/virtual”命令。

在防火墙后面的postfix
在防火墙后面安装postfix的最简单方法是:把所有的邮件发送给网关服务器,让邮件网关负责内外部邮件的转发。示例参见上文的本地网络部分。防火墙后面安装postfix更好的方法是:仅把发送到公网的邮件传递给邮件网关,发送到内部的邮件直接进行投递。
注意:这个例子要求postfix2.0及以后的版本。使用”postconf mail_version”查看postfix的版本

下面的示例展现了额外的配置。你需要把这些配置与第一部分已讨论的基本配置结合起来。

1 /etc/postfix/main.cf:
2 transport_maps = hash:/etc/postfix/transport
3 relayhost =
4 # Optional for a machine that isn’t “always on”
5 #fallback_relay = [gateway.example.com]
6
7 /etc/postfix/transport:
8 # Internal delivery.
9 example.com :
10 .example.com :
11 # External delivery.
12 * smtp:[gateway.example.com]
解释:
•第2,7-12行:要求内部的邮件直接进行投递,外部的邮件传递给邮件网关。这个例子假设使用内部DNS的MX记录。中括号[]提示postfix不要进行mx查找。

•第3行:重要:不要在main.cf中指定relayhost

•第5行:这组织邮件堵在队列中,当邮件服务器关机时。postfix将尽可能的直接传递邮件,然后把未送达邮件传递给邮件网关。

当系统使用dbm文件时,指定dbm。使用”postconf -m”查看postfix支持哪些查询表。

当改变了transport表的内容时,执行”postmap /etc/postfix/transport”命令。
配置postfix作为主/备份mx主机
这部分展现了额外的配置参数。你需要把它与该文档上半部分的基本配置参数结合起来。

当你的系统是备份的MX邮件主机时,参见下面的设置:

1 DNS:
2 the.backed-up.domain.tld IN MX 100 your.machine.tld.
3
4 /etc/postfix/main.cf:
5 relay_domains = . . . the.backed-up.domain.tld
6 smtpd_recipient_restrictions =
7 permit_mynetworks reject_unauth_destination
8
9 # You must specify your NAT/proxy external address.
10 #proxy_interfaces = 1.2.3.4
11
12 relay_recipient_maps = hash:/etc/postfix/relay_recipients
13
14 /etc/postfix/relay_recipients:
15 user1@the.backed-up.domain.tld x
16 user2@the.backed-up.domain.tld x
17 . . .

当你的系统是主MX的邮件主机时,你还需要接下来的设置(即1-22;如果是备份mx主机,只需设置到1-17即可)
18 /etc/postfix/main.cf:
19 transport_maps = hash:/etc/postfix/transport
20
21 /etc/postfix/transport:
22 the.backed-up.domain.tld relay:[their.mail.host.tld]
重要提示:
不要在mydestination,virtual_alias_domains和virtual_mailbox_domains中the.backed-up.domain.tld写进来。

• 第1-7行:把来自internet且发送给the.backed-up.domain.tld域的邮件转发给主MX记录的主机

•第10行:如果postfix通过NAT中继或proxy接收邮件时,这个设置是必须的。

•第12-16行:在the.backed-up.domain.tld域中定义有效的地址。这将保护你的邮件主机免于被未送达消息塞满。如果 你没有维护有效的收件人,那么你必须relay_recipient_maps的值设为空,或者在relay_recipients表中指定一个 @the.backed-up.domain.tld x

•第22行:中括号[]提示postfix不要进行mx查找

如果你的系统使用dbm,那么指定dbm

如果改变了transport的内容,执行”postmap /etc/postfix/transport”命令。

注意:当postfix为2.2之前的版本时,当为备份/主MX域中继邮件时,不要使用fallback_relay.否则,当目的服务器不可用时,邮件会在postfix的mx主机和fallback_relay主机间重复投递邮件。

•在main.cf中指定relay_transport = relay
•在master.cf中的relay入口的结尾指定”-o fallback_relay =”(不包括引号)
•在传输表中,指定”relay:nexthop…”(不包括引号)作为右边的内容。

在postfix 2.2及以后的版本中,上面的设置时默认的。
拨号主机上的postfix
这部分内容应用于拨号的主机(也指该主机经常不在线)。

这部分的配置参数要与该文档的上半部分基本配置参数相结合。

如果你没有公网的主机名和ip地址,那么你应该学习《Postfix on hosts without a real Internet hostname》这部分内容。

•把所有出站的邮件路由到你的ISP邮件网关。
如果你的邮件主机经常关机,postfix没有太多的机会把邮件投递到难以到达的某个internet角落。把这个邮件传递给那些一直在线的邮件服务器是一个很好的选择。在下面的例子中,中括号[]是为了告诉postfix不要进行mx查找。
/etc/postfix/main.cf:
relayhost = [smtprelay.someprovider.com]

•关闭自发的SMTP邮件传递
正常情况下,postfix将尝试以它便利的方式传递出站邮件。如果你的邮件主机使用使用了on-demand拨号IP,这将会导致你的邮件系统在发送新邮件时,自动拨号。为了阻止这样的拨号,禁用自发的SMTP邮件传递。
/etc/postfix/main.cf:
defer_transports = smtp (Only for on-demand dialup IP hosts)

•禁用SMTP客户端的DNS查询(仅适用于拨号的局域网)
/etc/postfix/main.cf:
disable_dns_lookups = yes (Only for on-demand dialup IP hosts)

•当internet连接建立时,清空邮件队列
把下面的命令复制到PPP或SLIP拨号脚本中:
/usr/sbin/sendmail -q (whenever the Internet link is up)

postfix的sendmail命令位置随linux版本的不同而不同。使用”postconf sendmail_path”命令查看postfix的sendmail命令的位置。

为了查看邮件队列是否被清空,使用下面的脚本:
#!/bin/sh

# Start mail deliveries.
/usr/sbin/sendmail -q

# Allow deliveries to start.
sleep 10

# Loop until all messages have been tried at least once.
while mailq | grep ‘^[^ ]*\*’ >/dev/null
do
sleep 10
done

如果你禁用了自发的SMTP邮件传递,你也可以每次连接到internet网络时运行”sendmail -q”。
没有公网主机名的postfix主机
这 部分适用于那些没有公网主机名的主机。一般情况是:这些主机通过ISP的DHCP获得动态的IP地址。postfix可以让你用假想(fantasy)的 名字来收发邮件系统帐户间的邮件。但是你不能用假想(fantasy)名字来收发公网的邮件,因为这会导致公网用户无法回复你的邮件。实际上,越来越多的 邮件系统会拒绝域名不存在的邮件。

注意:下面的内容将于postfix的版本相关。使用”postconf mail_version”来查看postfix的版本。

方案1:postfix 2.2及以后的版本
postfix 2.2使用通用的地址映射方法用internet有效地址来替换本地假想(fantasy)的邮件地址。这个地址映射仅当邮件出站时才会被使用;

下面的示例需要结合该文档的一部分基本参数设置。
1 /etc/postfix/main.cf:
2 smtp_generic_maps = hash:/etc/postfix/generic
3
4 /etc/postfix/generic:
5 his@localdomain.local hisaccount@hisisp.example
6 her@localdomain.local heraccount@herisp.example
7 @localdomain.local hisaccount+local@hisisp.example

当邮件通过SMTP传递到远程的邮件主机时:

•第5行:用ISP的邮件地址来代替his@localdomain.local

如果你的系统使用的是dbm文件,请指定dbm。使用”postconf -m”命令查看postfix支持哪些查询表

当改变了generic的内容时,执行”postmap /etc/postfix/generic”命令。

方案2:postfix 2.1及以前的版本
老版本的postfix解决方案是使用一个有效的internet地址,让postfix把有效的internet地址转换为本地的假想(fantasy)地址。你能给内网和公网用户发送邮件。

1 /etc/postfix/main.cf:
2 myhostname = hostname.localdomain
3 mydomain = localdomain
4
5 canonical_maps = hash:/etc/postfix/canonical
6
7 virtual_alias_maps = hash:/etc/postfix/virtual
8
9 /etc/postfix/canonical:
10 your-login-name your-account@your-isp.com
11
12 /etc/postfix/virtual:
13 your-account@your-isp.com your-login-name
解释:
•第2-3行:这里替换你的假想(fantasy)主机名。

•第5,9,10行:这三行把”your-login-name@hostname.localdomain”转换成”your-account@your-isp.com”。这部分是必须的。

 

•第7,12,13行:直接在本地传递给”your-account@your-isp.com”的邮件,不需要把它发送给ISP。这部分不是必须的,但是方便的。

 

如果你的系统使用的是dbm文件,请指定dbm。使用”postconf -m”命令查看postfix支持哪些查询表

四、postfix地址重写

当改变了canonical表的内容时,执行”postmap /etc/postfix/canonical”命令
当改变了virtual表的内容时,执行”postmap /etc/postfix/virtual”命令

 

postfix地址重写的目的:
地址重写是postfix邮件系统的核心。postfix出于许多不同的目的需要重写地址。一些是为了管理或使用上的方便,而另一些是为了把正确格式的邮件传递到正确的目的地。下面是postfix地址重写的例子:

•把不完全的邮件地址补全为完整的邮件地址。例如:把username补全为username@example.com或者把username@hostname补全为username@hostname.example.com

• 替换邮件地址。例如:当发送邮件的时候用firstname.lastname@example.com替换useranme@example.com; 当接收邮件的时候用useranme@example.com替换firstname.lastname@example.com

•用一个外部地址来替换内部的邮件地址。例如:当内部用户给公网发邮件时,用isp-account@isp.example替换掉内部的username@localdomain.local来发邮件

•用多个地址来替换一个地址。例如:用alias中的地址来替换一个别名地址

•对特定的邮件地址,决定邮件怎样传递以及传递到哪儿。例如:使用smtp(8)传递代理来传递username@example.com的邮件,并传递到DNS中的example.com域mx记录指向的主机上。

尽 管postfix目前没有地址重写语言,但是通过表查询,地址重写拥有强大的地址控制能力。一般情况下,postfix使用固定字符串表查询的方法把一个 地址匹配为一个或多个地址;使用正则表达式把多个地址匹配为一个或多个地址。固定字符串表查询采用本地文件形式,或者是NIS,LDAP或SQL形式。 DATABASE_README文档介绍了关于postfix查询表的内容。

这篇文档的主题包括:
重写消息头,或者标记为无效
postfix地址重写总述
接收邮件时的地址重写
•标准邮件格式的地址重写
•权威地址映射
•地址伪装
•自动的BCC接收者
•虚拟映射
传递邮件时的地址重写
•Resolve address to destination
•邮件传递交换
•重定位的用户表
远程传递的地址重写
•出站邮件的通用映射
本地传递的地址重写
•本地别名数据库
•本地per-user转发文件
•本地catch-all地址
调试你的地址控制

重写消息头或者标记为无效
postfix 2.1及以前的版本总是重写消息头的地址,把postfix的域名附加到那些不完全的邮件地址中去。为来自本地的邮件重写消息头是正常的,但是为来自网络的邮件重写消息头就可能会出错:

•消息头地址重写被邮件地址标准格式所困扰(be frowned upon)
•附加postfix自己的域名会产生一些不正确的结果
•附加postfix自己的域名会产生好像来自本地用户的垃圾邮件

postfix 2.2及以后的版本给出了一个选项,让你决定是不重写来自远程邮件的消息头还是把这样的消息头标记为无效的地址。下面是它的工作原理:

•postfix 总是重写来自本地和postfix中sendmail命令的消息头地址,用自己的域名不全那些不完整的邮件地址。 local_header_rewrite_clients参数控制postfix认为哪些smtp客户端是本地客户端(默认情况下,来自本地网络接口地 址的邮件被认为是本地邮件)

•当remote_header_rewrite_domain参数值为空时(这个值默认为空),postfix从不重写来自远程smtp客户端邮件的消息头。

• 如果remote_header_rewrite_domain的值不为空,那么postfix将用 remote_header_rewrite_domain的值来重写那些来自远程smtp客户端并且邮件地址不完整的消息头。可以为 remote_header_rewrite_domain指定一个类似于domain.invalid的值,这样不完整的邮件地址就不会被误认为是本地 地址了。

postfix地址重写总述
下面这张图是地址重写的过程。

下面这个表总述了所有的postfix地址控制。如果你第一个阅读这篇文档,请先阅读完“接收邮件的地址重写”部分。一旦你阅读完了这篇文档,下面的这个表将帮助你迅速的找到你需要的内容

接收邮件的地址重写
cleanup(8)服务接收来自postfix之外的邮件,同时也接收来自内部的邮件,比如:转发的邮件,反弹至发送者的未送达邮件和关于邮件系统的postmaster提示邮件

cleanup(8) 服务把发送者,接收者和消息内容变成一个标准的邮件格式,然后放到入站队列中(incoming queue)。邮件服务器整理消息头和信封中的发送者和接受者邮件地址。并在消息头中添加下面的内容:Form: , Date:(这是邮件标准格式要求的);移除信息头中的Bcc。cleanup(8)服务把更复杂的地址控制交给trivial-rewrite(8)来 实现。

这个阶段的地址控制如下:
•把地址重写为标准的邮件地址格式
•权威地址映射
•地址伪装
•自动的BCC接收者
•虚拟别名

把地址重写为标准的邮件地址格式
在 cleanup(8)守护进程通过地址映射表查询管理地址前,它首先通过把地址发送给rewrite(8)守护进程来把地址重写为标准的邮件地址格式 (如:user@fully.qualified.domain)。把邮件地址重写为标准格式的目的是缩小查询表中的条目数量。

postfix的trivial-rewrite(8)守护进程进行下面的硬编码地址控制:

把”@hosta,@hostb:user@site”重写为”user@site”

上面的地址格式叫做路由邮件地址,指定邮件通过hosta和hostb主机到达user@site邮箱。这种邮件格式已经被废弃很久了。除非去除地址的路由部分,否则postfix无法处理这样的路由地址

注 意:postfix 2.2及以后的版本将重写来自远程smtp客户端的消息头地址,只要这个smtp客户端与local_header_rewrite_clients参数 的值匹配,或者remote_header_rewrite_domain参数指定了一个非空值。postfix 2.2之前的版本指定local_header_rewrite_clients = static:all,即可重写远程的smtp地址

把site!user重写为user@site
这个功能是由swap_bangpath布尔参数来控制的(默认值为yes)。这个功能的目的是把UUCP形式的地址重写为域地址形式。当你通过UUCP接收邮件时,这个功能是有用的。

把user%domain重写为user@domain
这个功能是有allow_percent_hack布尔参数控制的(默认值为yes)。一般情况下,这是为了处理像”user%domain@otherdomain”这样的地址的

把user重写为user@$myorigin
这个功能是由append_at_myorigin布尔参数控制的(默认值为yes)。你不能关闭这个这个功能,因为许多postfix组件期望所有的邮件地址都是user@domain这种形式的

如 果你的服务器不是$myorigin的主服务器,而且你希望一些用户不经过主服务器直接投递邮件,这时需要在虚拟别名表中把user@$myorigin 重定向为user@$myhostname。更详细的内容参见STANDARD_CONFIGURATION_README文档的”delivering some users locally”部分

把user@host重写为user@host.$mydomain
这个功能是由append_dot_mydomain布尔参数控制的。这个功能的目的是:对相同主机名的不同形式采用一致的处理方式。

有些人认为把host重写为host.domain是不好的做法。这是关闭该功能的原因。

把user@site.重写为user@site(结尾没有点号)
结尾的点号将自动的被移除。但是,一个地址如果在结尾有多个点号,postfix将认为该地址无效。

权威地址映射
cleanup(8)进程使用canonical(5)表把消息头和信封的地址重写。默认情况下,所有的消息头和信封地址都被重写;这个是由canonical_classes参数来控制的

这中映射对使用firstname.lastname的地址形式来代替登陆名形式的地址是有用的。对清除由邮件系统产生的无效的域也是有帮助的

权威映射默认是被禁用的。通过编辑main.cf文件中的canonical_maps参数来启用,当有多个值时,用空格或逗号隔开。

示例:
/etc/postfix/main.cf:
canonical_maps = hash:/etc/postfix/canonical

/etc/postfix/canonical:
wietse Wietse.Venema

静态的映射表如上面的示例所示,查询表可以用hash,ldap,mysql或pgsql。对于动态的映射表,你可以使用正则表达式。这要求你非常熟悉regexp_table(5), pcre_table(5)和canonical(5)的内容

除了权威映射表可以用于发送者和接收者,你还能单独指定应用于发送者或者接收者的权威映射表。

示例:
/etc/postfix/master.cf:
127.0.0.1:10026 inet n – n – – smtpd
-o receive_override_options=no_address_mappings
注意:在等号两边不要有空格

地址伪装
地址伪装是隐藏邮件网关后面的邮件主机的一个方法。通过这个伪装,使得邮件就好像从邮件网关发过来的一样。

地 址伪装默认是被禁用的,它是由cleanup(8)来控制的。通过编辑main.cf中的masquerade_domains参数来启用它,当 masquerade_domains有多个值时,用空格或逗号隔开。当postfix要伪装一个域时,postfix将从左到右的方式来处理列表,遇到 第一个匹配的时候停止。

示例:
/etc/postfix/main.cf:
masquerade_domains = foo.example.com example.com

上面的masquerade_domains会把any.thing.foo.example.com变为foo.example.com;但是吧any.thing.else.example.com为example.com

当一个域名前以!开头意味着不伪装这个域和它的子域
/etc/postfix/main.cf:
masquerade_domains = !foo.example.com example.com

不把”any.thing.foo.example.com”改为”foo.example.com”, 但是把”any.thing.else.example.com”改为”example.com”.

masquerade_exceptions参数指定哪些用户名不受地址伪装的影响。当指定一个或多个用户名时,用空格或逗号隔开。

示例:
/etc/postfix/main.cf:
masquerade_exceptions = root
默认情况下,postfix不做任何例外。

Subtle point:默认情况下,地址伪装仅应用于消息头和信封的发件人地址,不应用于信封的收件人地址。这允许你在邮件网关上使用地址伪装,并且仍然可以把来自外部的邮件传递到内部的邮箱用户上。

为了伪装信封收件人地址,指定(postfix 1.1及以后的版本):

/etc/postfix/main.cf:
masquerade_classes = envelope_sender, envelope_recipient,
header_sender, header_recipient

如果你像这样重写了收件人地址,postfix将不能给内部的邮件服务器发送邮件

地址伪装可以通过smtpd(8), qmqpd(8)或者pickup(8)对接收的邮件进行有选择的关闭–master.cf中的设置优先于main.cf中的设置。这个功能在postfix 2.1及以后的版本中生效。

示例:
/etc/postfix/master.cf:
127.0.0.1:10026 inet n – n – – smtpd
-o receive_override_options=no_address_mappings
注意:等号两边不要有空格

自动的BCC接收者
在应用了权威映射和地址伪装后,cleanup(8)守护进程能产生一个可选的BCC(blind carbon-copy)。postfix提供3种机制:

always_bcc = address
传递所有邮件的拷贝到指定邮箱。在postfix 2.1之前的版本,这个功能是通过smtpd(8), qmqpd(8)或者pickup(8)来实现的。

sender_bcc_maps = type:table
用信封发送者的地址来查找”type:table”查询表。postfix 2.1及以后的版本支持该功能。

recipient_bcc_maps = type:table
用信封接收者的地址来查找”type:table”查询表。postfix 2.1及以后的版本支持该功能。

注意:自动BCC接收者仅对新邮件起作用。为了避免邮件的死循环,自动BCC接收者不接收postfix内部转发的邮件,也不接收postfix自己生成的邮件。

自动BCC接收者(包括alway_bcc)能够通过smtpd(8), qmqpd(8)或者pickup(8)对接收的邮件进行有选择的关闭。postfix 2.1及以后的版本支持该功能。

示例:
/etc/postfix/master.cf:
127.0.0.1:10026 inet n – n – – smtpd
-o receive_override_options=no_address_mappings
注意:等号两边不要有空格

虚拟别名
在 把接收者写入队列文件前,cleanup(8)守护进程使用可选的virtual(5)别名表重定向接收者的邮件。这个映射过程仅影响信封接收者地址;它 不影响消息头地址和信封发送者地址。虚拟别名查询对把虚拟别名域的邮件重定向到真实的用户邮箱是有用处的。它对重定向不存在的域邮件也是有用处的。虚拟别 名查询能用于把”firstname.lastname”的邮件地址转换回unix登录名的形式,尽管这个功能使用本地别名更合适。关于postfix虚 拟域的方法总述参见VIRTUAL_README这篇文档。

默认情况下,虚拟别名是禁用的。通过编辑main.cf文件中的virtual_alias_maps参数值来来启用。当virtual_alias_maps有多个值时,用空格或逗号隔开。

示例:
/etc/postfix/main.cf:
virtual_alias_maps = hash:/etc/postfix/virtual

/etc/postfix/virtual:
Wietse.Venema wietse

虚拟别名地址表中的地址受虚拟别名影响,但是它们不受权威映射影响,这样是为了避免邮件的循环。

正如上个示例的静态映射表所示,查询表可以使用hash:,ldap:,mysql:或者pgsql:。对于动态的映射表,可以使用正则表达式。这要求你熟悉regexp_table(5), pcre_table(5) 和 virtual(5)中的内容。

虚拟映射能够通过smtpd(8), qmqpd(8)或者pickup(8)对接收的邮件进行有选择的关闭。postfix 2.1及以后的版本支持该功能。

示例:
/etc/postfix/master.cf:
127.0.0.1:10026 inet n – n – – smtpd
-o receive_override_options=no_address_mappings
注意:等号两边不要有空格

这时,信息将进入postfix的入站队列。

传递邮件时的地址重写
postfix 队列管理器依据邮件的目的地址将邮件进行分类,并把邮件交给postfix的投递代理,像:local(8), smtp(8) 和 lmtp(8)。就像cleanup(8)一样,postfix队列管理器把复杂的地址控制交给trivial-rewrite(8)来处理。

这个阶段的地址控制主要有:
•把地址解析目的地址
•邮件传递交换
•重定位用户表

每一个postfix投递代理都尽力把邮件直接投递到目的地,而如何压缩发送者,接收者和信息内容则依据smtp,lmtp等协议的规则。当邮件无法投递到目的地时,该邮件将退给邮件发送者或者被移入延迟队列,稍后再试。

当邮件通过smtp(8)传递代理时的地址控制:
•smtp出站邮件的通用映射

当邮件通过local(8)传递代理时的地址控制:
•本地别名数据库
•本地用户.forward文件
•本地全部(catch-all)地址

该文档的接下来部分将以更详细的方式展现每一步的地址控制,主要是以示例的方式。

把地址解析成目的地址
psotfix的qmgr(8)队列管理器从入站队列选取新邮件或者从延迟队列选择被延迟的邮件;然后询问trivial-rewrite(8)地址重写和解析进程来确定邮件应该被投递到哪儿。

postfix 2.0以后的版本区别4种主要的地址类型。每一种类型都有它自己的域名,传递方法。更详细的内容参见ADDRESS_CLASS_README文章。postfix 2.0之前的版本只区别本地传递。

邮件传递交换
一 旦trivial-rewrite(8)进程确定了默认的传递方法,它会到可选的transprot(5)表中查询(overrides the message destination and/or delivery method)这样的信息。transport(5)表最常用的功能是发送邮件到没有连接到internet网络的系统,或者是为特定需求的客户端配置特 定的smtp客户端。更详细的内容参见STANDARD_CONFIGURATION_README 和 UUCP_README文档,示例参见transport(5)手册。

传输表查询默认是禁用的。通过编辑main.cf中的transport_maps参数来启用,对多个值的,用空格或逗号隔开。

示例:
/etc/postfix/main.cf:
transport_maps = hash:/etc/postfix/transport

重定位的用户表
trivial- rewrite(8)进程通过relocated(5)数据库来处理每一个接收者。这个数据库提供了处理不存在邮箱地址和不存在域的办法。当邮件发送给 relocalted(5)数据库中列出的地址时,postfix将会在原来邮件的基础之上附加一些信息,然后退给邮件发送者。

在查询完 transport(5)表后查找relocated(5)数据库,in anticipation of transport(5) tables that can replace one recipient address by a different one

重定位用户查询默认是禁用的。通过修改main.cf中的relocated_maps参数来启用,当为多个值时,用空格或逗号隔开。

示例:
/etc/postfix/main.cf:
relocated_maps = hash:/etc/postfix/relocated

/etc/postfix/relocated:
username@example.com otheruser@elsewhere.tld

postfix2.0以后的版本,重定位用户的邮件将会被smtp服务器以“用户移动到otheruser@elsewhere.tld”理由而拒绝。老版本的postfix先会接收邮件,然后以同样的理由发送一份不可达报告给发送者。

出站smtp邮件的通用映射
一些主机没有有效的internet域名,它们的域名类似于localdomain.local。当你想给internet上邮箱发送邮件时,就会产生问题,因为许多邮件服务器拒绝来自无效域名的邮件地址。

通 过smtp_generic_maps参数,你能指定generic(5)查询表(这个表的作用是用有效的internet邮件地址来代替本地邮件地 址),当邮件通过smtp进入internet时。generic(5)映射表代替信封和消息头地址时不可逆的。当邮件在本地postfix上的不同用户 间传递时,generic(5)映射不会发生。

这个功能在postfix 2.2及以后的版本可用。

例如:
/etc/postfix/main.cf:
smtp_generic_maps = hash:/etc/postfix/generic

/etc/postfix/generic:
his@localdomain.local hisaccount@hisisp.example
her@localdomain.local heraccount@herisp.example
@localdomain.local hisaccount+local@hisisp.example

当邮件通过smtp发送给远程的邮件主机时,会用isp的邮件地址代替his@localdomain.local。

本地别名数据库
当 邮件被传递到本地时,local(8)传递代理通过aliases(5)数据库管理每一个本地接收者。这个映射不影响消息头中的邮件地址。本地别名一般用 于分发列表,或者用于把类似于postmaster这类标准别名重定向到真实的邮箱地址。这个表也能用于把firstname.lastname转换为登 录名。

别名查询默认是启用的。这个默认配置依赖于操作系统的环境,但是通常是下面的一种:

/etc/postfix/main.cf:
alias_maps = hash:/etc/aliases
alias_maps = dbm:/etc/aliases, nis:mail.aliases

alias数据库文件的位置是由alias_database参数来控制的。
/etc/postfix/main.cf:
alias_database = hash:/etc/aliases (4.4BSD, LINUX)
alias_database = dbm:/etc/aliases (4.3BSD, SYSV<4)
alias_database = dbm:/etc/mail/aliases (SYSV4)

aliases(5) 文件能够指定邮件是传递到本地文件,还是传递一个命令通过标准的输入流来接收信息。基于安全的考虑,命令和文件目的地的传递是用别名数据库所有者权限来执 行的。默认的userid和default_privs被用于传递所有者为root的别名文件中的命令或文件。

本地用户的.forward文件
通过local(8)传递代理的传递,用户通过指定家目录中.forward文件的目的地来控制他们自己的邮件传递。除了alias(查询值和冒号)左边没有之外,.forward文件的语法与local aliases(5)的语法结构在其他方面都一样。

本地所有的(catch-all)地址
当local(8)传递代理发现邮件接收者不存在时,正常情况下,邮件会退给发送者。有时,postfix管理者希望吧这些接收者不存在的邮件传递到另外一个邮件服务器。基于这样的目的,你能通过luser_relay参数指定一个专用的邮件地址来接收这些邮件。

另外一种办法:通过指定fallback_transport参数,把接收者不存在的邮件委派给其他传输。更详细的内容参见local(8)传输代理文档。

注意:如果你使用了luser_relay功能以便接收非unix帐户的邮件,那么必须指定:
/etc/postfix/main.cf:
local_recipient_maps =

(即:空值)在main.cf文件中,否则,postfix的smtp服务器将用“本地接收者表中的未知用户”来拒绝非unix账户的邮件。更详细的内容参见LOCAL_RECIPIENT_README.

luser_relay能指定一个地址。它受$name的影响。
示例:
$user@other.host
没有扩展地址的username,后缀为@other.host。例如:把发送给username+foo的邮件发给username@other.host

$local@other.host
例如:把发送给username+foo的邮件发送给username+foo@other.host

sysadmin+$user
例如:把发送给username+foo的邮件发送给sysadmin+username

sysadmin+$local
例如:把发送给username+foo的邮件发送给sysadmin+useranme+foo

调试地址控制功能
postfix 2.1及以后的版本会产生基于调试目的的邮件传递报告。这些报告不仅显示地址重写,别名扩展/转发后的发送者/接收者地址,而且这些报告也显示传递到邮箱的信息,非postfix命令的传递信息,应答远程smtp服务器的信息等等。

postfix产生两种邮件传输调试报告:

•what-if:报告发生了什么,但是没有真正的传递邮件。这种运作模式要求:
$ /usr/sbin/sendmail -bv address…
邮件传递状态报告将被发送到登陆帐户的邮箱中。

•what happened:传递邮件,报告成功,失败与否,包括远程smtp服务器的应答。这种运作模式要求:
$ /usr/sbin/sendmail -v address…
邮件传递状态报告将被发送到登陆帐户的邮箱中。

这些报告包括postfix传输代理产生的信息。因为它们以守护进程的身份运行,不直接的与用户交互,结果是以邮件的形式发送给测试消息的发送者。这些报告的格式实际上与未送达报告的格式是一样的。

例 如:下面是用”sendmail -bv postfix-users@postfix.org”产生的传递报告。这个报告的第一部分包含了人工可读的信息。在这种情况下,邮件将通过 mail.cloud9.net传递,smtp服务器将回复一个”250 ok”。其他的报告可能显示了到mailbox的传递,或者到feipostfix命令的传递。

Content-Description: Notification
Content-Type: text/plain

This is the mail system at host spike.porcupine.org.

Enclosed is the mail delivery report that you requested.

The mail system

<postfix-users@postfix.org>: delivery via mail.cloud9.net[168.100.1.4]: 250 2.1.5 Ok

报告的第二部分是机器可读的形式,包括了下面的信息:

•信封发送者的地址(wietse@porcupine.org)
•信封接收者的地址(postfix-users@postfix.org)。如果接收者的地址被postfix改变,那么postfix也包含原始的接收者地址。
•传递状态

一些信息取决于postfix的版本。下面的示例适用于postfix 2.3及以后的版本。

Content-Description: Delivery report
Content-Type: message/delivery-status

Reporting-MTA: dns; spike.porcupine.org
X-Postfix-Queue-ID: 84863BC0E5
X-Postfix-Sender: rfc822; wietse@porcupine.org
Arrival-Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)

Final-Recipient: rfc822; postfix-users@postfix.org
Action: deliverable
Status: 2.1.5
Remote-MTA: dns; mail.cloud9.net
Diagnostic-Code: smtp; 250 2.1.5 Ok

报告的第三部分包含了postfix传递的信息,包括:form:,to:,信息头,你能在这儿看到地址重写对邮件传递的影响。用”sendmail -bv”提交的邮件没有正文,所有下面的例子中没有任何内容。

Content-Description: Message
Content-Type: message/rfc822

Received: by spike.porcupine.org (Postfix, from userid 1001)
id 84863BC0E5; Sun, 26 Nov 2006 17:01:01 -0500 (EST)
Subject: probe
To: postfix-users@postfix.org
Message-Id: <20061126220101.84863BC0E5@spike.porcupine.org>
Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)
From: wietse@porcupine.org (Wietse Venema)

 

五、Postfix虚拟域名主机

 

这篇文档的目的
这篇文档要求postfix 2.0及以后的版本

这篇文档总述了:postfix怎样承载多个internet域;一些域是邮件传递的最终目的域,另一些域是出于转发目的地域。

这篇文档不仅描述了postfix内建的传输机制,而且给出了使用非postfix邮件传递软件的建议。

这篇文档涉及以下主题:

权威域对宿主域对其他域
本地文件对网络数据库
共享域,Unix系统账号
postfix虚拟别名示例:独立域,unix系统账号
postfix虚拟邮箱示例:独立域,非unix账号
非postfix邮箱存储:独立域,非unix账号
邮件转发域
邮件列表
自动回复

权威域对宿主域对其他域
大部分的postfix系统都是域的最后目的地。这些域包括了postfix主机的FQDN和IP地址,有时也 包括了主机名的父域。这篇文档接下来的部分将把这些域看作是权威域(即权威域是postfix主机名的域,如:postfix的FQDN为 mail.linux.com,那么linux.com就是这台postfix的权威域)。

除了权威域,postfix可以被配置为非权威的额外域的最后目的地。这些域叫做宿主域,因为他们与postfix主机名无关。宿主域一般与虚拟别名域或虚拟邮箱域为同一类,具体的定义参见ADDRESS_CLASS_README文件。

postfix还可以被配置为其他域的备份mx主机。在这种情况下,postfix不是这些域的最后目的地。当postfix主mx主机down机时,它接收邮件放在队列中。这个功能与中继域地址类别相同,具体定义在ADDRESS_CLASS_README文件中。

最后,postfix被配置为传递主机,它把邮件传递到internet上。很明显,postfix不是这些邮件的最后目的地。这个功能仅对授权的客户端和用户生效;它与默认域地址类别相同,具体定义在ADDRESS_CLASS_README文件中。

 

 

 

本地文件对网络数据库
这里的示例使用了本地文件的表查询,如:DBM或Berkeley DB。用postmap命令很容易调试:
示例:
postmap -q info@example.com hash:/etc/postfix/virtual

 

用数据库来代替本地文件,参见LDAP_README, MYSQL_README 和 PGSQL_README 。强烈建议读者在先把本地文件调试正常后,在迁移到网络数据库上。使用postmap命令查询网络数据库的查询结果是否与本地文件查询结果一致。

 

 

示例:
postmap -q info@example.com ldap:/etc/postfix/virtual.cf

 

共享域,unix系统帐户
宿主额外域最简单的方法是:把域名添加到postfix的mydestination参数中去,然后把用户名添加到unix密码文件中去。

权威域与宿主域之间没有区别。用户能接收没有域的邮件。

在下面的例子中,我用example.com作为这台postfix的宿主域。
/etc/postfix/main.cf:
mydestination = $myhostname localhost.$mydomain … example.com

这个方法的缺陷是:

 

 

 

发送给info@my.host.name的邮件也会传递给info@example.com
用户存放在unix密码文件中,大量用户的维护将变得困难。

 

下面的例子对这两个缺陷提供了解决方法。

postfix虚拟别名示例:独立域,unix系统账号
使用这部分描述的方法,每一个宿主域有它自己的邮件地址。但是,它仍然使用系统帐户进行本地邮箱投递。

使用虚拟别名与,每一个宿主邮件地址的别名为一个本地unix系统帐户,或者为一个远程的邮件地址。下面的例子显示了example.com怎样使用这种机制。

 

 

 

1 /etc/postfix/main.cf:
2 virtual_alias_domains = example.com …other hosted domains…
3 virtual_alias_maps = hash:/etc/postfix/virtual
4
5 /etc/postfix/virtual:
6 postmaster@example.com postmaster
7 info@example.com joe
8 sales@example.com jane
9 # Uncomment entry below to implement a catch-all address
10 # @example.com jim
11 …virtual aliases for more domains…

 

注意:

 

第2行:virtual_alias_domains设置告诉postfix:example.com是一个虚拟别名域。如果你省略了这个设置,postfix会拒收邮件(中继访问被拒绝),或者无法投递邮件(发给example.com的邮件产生死循环)

 

不要把虚拟别名域写入mydestination参数中去。

 

 

第3-8行:/etc/postfix/virtual文件包含了虚拟别名。上面的这个示例,发给postmaster@example.com的邮件会转发给本地的postmaster,而发给info@example.com的邮件会转发给joe系统帐户。

 

第10行:一个全部的(catch-all)虚拟别名接收在虚拟别名文件中example.com没有列出的地址的邮件。这存在一定的风险。垃 圾邮件制造者可能给可能的用户名发邮件,所以,一个所有的(catch-all)邮箱可能会接收到许多垃圾邮件。许多垃圾邮件的反弹邮件是以anything@example.com发送的。

 

在改变了virtual的内容后,执行”postmap /etc/postfix/virtual”命令,然后用”postfix reload”重载main.cf文件

注意:虚拟别名既可以解析为一个本地地址,也可以解析为一个远程地址。他们不需要一定解析到本地的unix系统帐户上

更多关于虚拟别名文件的信息参见virtual(5)手册。

虚拟别名解决了一个问题:它允许每一个域有它自己的邮件地址。但是,仍然有一个缺陷:每一个虚拟地址都会映射到unix系统帐户上。随着虚拟地址的增加,unix系统账号也会相应的增长。接下来的部分将解决这个问题。

postfix虚拟邮箱示例:独立域,非unix帐户
随着域和用户的增长,unix/linux系统不可能给每一个用户分配一个系统帐户。

通过postfix的virtual(8)邮箱投递代理,每一个接收者地址都能有它自己的虚拟邮箱。不想虚拟别名域,虚拟邮箱域不需要把每一个接收者地址笨拙的转换为一个系统帐户地址。

postfix的virtual(8)邮箱传递代理通过接收者的邮箱地址查询存放用户信息的表,找到用户的邮箱路径名,uid和gid。maildir方式的传递是在邮箱路径名的结尾加上个”/”。

如果你感觉多个表比较烦,可以把这些信息存放到sql数据库中去。这个可以参见本文前面的”本地文件对数据库”

这儿有个虚拟邮箱域”example.com”的示例:

 

 

 

1 /etc/postfix/main.cf:
2 virtual_mailbox_domains = example.com …more domains…
3 virtual_mailbox_base = /var/mail/vhosts
4 virtual_mailbox_maps = hash:/etc/postfix/vmailbox
5 virtual_minimum_uid = 100
6 virtual_uid_maps = static:5000
7 virtual_gid_maps = static:5000
8 virtual_alias_maps = hash:/etc/postfix/virtual
9
10 /etc/postfix/vmailbox:
11 info@example.com example.com/info
12 sales@example.com example.com/sales/
13 # Comment out the entry below to implement a catch-all.
14 # @example.com example.com/catchall
15 …virtual mailboxes for more domains…
16
17 /etc/postfix/virtual:
18 postmaster@example.com postmaster

 

注意:

第2行:virtual_mailbox_domains设置告诉postfix:postfix是虚拟邮箱域。如果你忘了这个设置,postfix将会拒绝邮件(中继访问也拒绝),或者无法传递(发给example.com的邮件产生自循环)

不要把虚拟邮箱域名列在mydestination参数值中!

不要把虚拟邮箱域名列在virtual_alias_domains的参数值中!

第3行:virtual_mailbox_base参数为所有的虚拟邮箱路径指定了一个共同的前缀。这是一个安全的机制,以免某些人做错。这可以阻止邮件被传递到所有的文件系统上。

 

 

 

第4,10-15行:virtual_maibox_maps参数指定了用mailbox(或者maildir)路径名的查询表,它通过vuni邮件地址进行索引。在下面的这个示例中,发给info@example.com的邮件将会被放到/var/mail/vhost/example.com/info,而发给sales@example.com的邮件将会被放在/var/mail/vhosts/exampe.com/sales/目录下。

 

第5行:virtual_minimum_uid为mailbox/maildir所有者的UID指定了一个最小值。这是一个安全机制,以免出错。这阻止邮件写到敏感的文件中去。

第6,7行:virtual_uid_maps和virtual_gid_maps参数指定了所有虚拟邮箱的所有者的uid和gid的值为5000。如果你不希望uid和gid是固定值,可以指定一个查询表。

 

 

 

第14行:该注释项显示了如何使用所有的(catch-all)虚拟邮箱地址。它被用户接受垃圾邮件,也用于以anything@example.com的名义发送垃圾邮件的反弹邮件。

 

不要把虚拟邮箱通配符放到虚拟别名文件中去!!

第8,17,18行:这可能是虚拟别名与虚拟邮箱的混合使用。我盟使用这个功能把发给example.com的postmaster的邮件转发到本地的postmaster。你能使用同样的机制转发一个地址到远程地址上去。

第18行:这个示例假设:main.cf中的$myorigin值列在了mydestination参数设置中。如果不是这种情形,请在虚拟别名表的右边明确的指定一个域名,否则邮件将会被投递到错误的域中。

当virtual文件的内容改变后,执行”postmap /etc/postfix/virtual”命令。当改变了vmailbox文件的内容,执行”postmap /etc/postfix/vmailbox”命令。当改变了main.cf的内容,执行”postfix reload”命令。

注意:邮件投递是以virtual_uid_maps和virtual_gid_maps中指定的接收者uid/gid身份进行的。 postfix 2.0以前的版本无法在可写的父目录中创建maildir;你必须在使用前先创建这些目录。postfix在父目录可写的情况下可以自己创建 mailbox,但事先创建文件更安全点。

关于虚拟邮箱投递代理的更详细的信息,参见virtual(8)手册。

非postfix邮箱存储:独立域,非unix帐户
这是在postfix虚拟邮箱基础上的进一步改进。每一个宿主邮箱地址有它自己独立的邮箱。

当非postfix软件用于最后的投递时,仍需要一些postfix概念以便邮件顺利发送。

这部分的内容描述了:从postfix的角度,这应该是什么样的。关于cyrus/courier的maildrop的信息,参见CYRUS_README 或者 MAILDROP_README

下面是宿主域example.com投递邮件给非postfix投递代理的示例:

 

 

 

1 /etc/postfix/main.cf:
2 virtual_transport = …see below…
3 virtual_mailbox_domains = example.com …more domains…
4 virtual_mailbox_maps = hash:/etc/postfix/vmailbox
5 virtual_alias_maps = hash:/etc/postfix/virtual
6
7 /etc/postfix/vmailbox:
8 info@example.com whatever
9 sales@example.com whatever
10 # Comment out the entry below to implement a catch-all.
11 # Configure the mailbox store to accept all addresses.
12 # @example.com whatever
13 …virtual mailboxes for more domains…
14
15 /etc/postfix/virtual:
16 postmaster@example.com postmaster

 

注意:

第2行:为了投递给宿主域的非postfix邮箱存储,virtual_tranport参数需要指定一个postfix的LMTP客户端,或者通过管道投递代理执行非postfix软件。下面是典型的示例(仅使用一个就可以了):

virtual_transport = lmtp:unix:/path/name (uses UNIX-domain socket)
virtual_transport = lmtp:hostname:port (uses TCP socket)
virtual_transport = maildrop: (uses pipe(8) to command)

postfix已经做好支持LMTP的准备了。maildrop投递方法的示例已经定义在了默认的master.cf文件中了,更详细的内容参见MAILDROP_README文档。

第3行:virtual_mailbox_domains设置告诉postfix:example.com通过 virtual_transport来投递邮件。如果你忘了virtual_mailbox_domains参数的设置,postfix将拒收邮件,或者 无法传递邮件。

不要把虚拟邮箱的域名列在mydestination中!

不要把虚拟邮箱的域名列在虚拟别名与中!

 

 

 

第4,7-13行:virtual_mailbox_maps参数指定了包含所有有效接收者地址的查询表。查询结果只被postfix忽略。在上面的例子中,info@example.com和sales@example.com列 在了有效地址中;其他给example.com的邮件都被postfix的smtp服务器用”未知的用户”所拒绝。这是留给非postfix投递代理用以 拒绝本地提交的不存在接收者。如果你准备用LDAP,MySQL或者PgSQL来代替本地文件,请了解本文档的”本地文件对数据库”的内容。

 

第12行:这个注释项显示了怎样让postfix知道所有的有效邮件地址。擦汗讯结果会被postfix忽略

不要把虚拟邮箱通配符放在虚拟别名文件中!!

注意:如果你在virtual_mailbox_maps中指定了通配符,那么你需要配置非postfix邮箱存储来接收那个域的任何邮件。

 

 

 

第5,15,16行:同时使用虚拟别名与虚拟邮箱是可能的。我们使用这个功能把postmaster@example.com重定向到本地的postmaster中。你也可以使用同样的机制重定向邮件到本地或远程箱

 

第16行:这个示例假设:main.cf中的$myorigin值列在了mydestination参数设置中。如果不是这种情形,请在虚拟别名表的右边明确的指定一个域名,否则邮件将会被投递到错误的域中。

当virtual文件的内容改变后,执行”postmap /etc/postfix/virtual”命令。当改变了vmailbox文件的内容,执行”postmap /etc/postfix/vmailbox”命令。当改变了main.cf的内容,执行”postfix reload”命令。

邮件转发域
一些宿主域没有或者只有部分本地邮箱。这些域的目的是把邮件转发到其他其他。下面的示例展示了如何安装example.com作为邮件转发域:

 

 

 

1 /etc/postfix/main.cf:
2 virtual_alias_domains = example.com …other hosted domains…
3 virtual_alias_maps = hash:/etc/postfix/virtual
4
5 /etc/postfix/virtual:
6 postmaster@example.com postmaster
7 joe@example.com joe@somewhere
8 jane@example.com jane@somewhere-else
9 # Uncomment entry below to implement a catch-all address
10 # @example.com jim@yet-another-site
11 …virtual aliases for more domains…
Notes:

 

第2行:virtual_alias_domains设置告诉postfix:example.com是虚拟别名域。如果你忘记这个设置,postfix将拒收邮件,或者无法投递邮件。

不要把虚拟别名的域名列在mydestination中!

 

 

 

第3-11行:/etc/postfix/virtual文件包含了虚拟别名。在上面的示例中,发给postmaster@example.com的邮件会转发到本地的postmaster中去,而发给joe@example.com的邮件转发到远程的邮件地址–joe@somewhere;发送给jane@example.com的邮件被转发到jane@somewhere邮箱。发送给example.com的其他邮件都会被postfix以”未知用户”而拒绝

 

第10行:注释项显示了jim@yet-another-site邮箱接收所有发给在example.com域中不存在的邮箱地址。这存在一定的风险。现在的垃圾邮件发送者尝试非可能存在的用户名发送邮件。catch-all邮箱可能接收许多垃圾邮件,许多垃圾邮件的反弹邮件会以anything@example.com的名义发送。

 

当virtual的文件内容改变时,执行”postmap /etc/postfix/virtual”命令。当main.cf的文件改变时,执行”postfix reload”命令。

更多关于虚拟别名文件的信息参见virtual(5)手册。

邮件列表

前面的一些示例已经展现了如何把虚拟域的postmaster邮件转发到本地postmaster中去。你能用同样的方法把任何一个地址的邮件转发本地或远程地址

这里有一个重要的限制:虚拟别名和虚拟邮箱不能直接传递邮件列表管理器,如:majordomo。这个限制的解决办法是安装一个虚拟别名–通过它把虚拟地址导向本地传输代理:

/etc/postfix/main.cf:
virtual_alias_maps = hash:/etc/postfix/virtual

 

 

 

/etc/postfix/virtual:
listname-request@example.com listname-request
listname@example.com listname
owner-listname@example.com owner-listname

 

/etc/aliases:
listname: “|/some/where/majordomo/wrapper …”
owner-listname: …
listname-request: …
T
这个示例假设:main.cf中的$myorigin值列在了mydestination参数设置中。如果不是这种情形,请在虚拟别名表的右边明确的指定一个域名,否则邮件将会被投递到错误的域中。

更多关于postfix的本地投递代理信息,参见local(8)手册。

为什么这个示例使用一个复杂的虚拟别名来代替间接地传输映射呢?这个理由是:发送给虚拟邮件列表的邮件会以”不存在的用户”原因而被拒绝。为了确保传输映射的正常工作,postfix需要很多虚拟别名表或者虚拟邮箱表

在虚拟别名域的情形中,需要有一个从每一个邮件列表地址到自身的身份映射
在虚拟邮箱域的情形中,对每个邮件列表地址需要有个假的邮箱。

自动回复
为了给虚拟接收者配置一个自动回复,到虚拟别名表中设置一个规则:

/etc/postfix/main.cf:
virtual_alias_maps = hash:/etc/postfix/virtual

 

 

 

/etc/postfix/virtual:
user@domain.tld user@domain.tld, user@domain.tld@autoreply.mydomain.tld

 

传递邮件给接收者,同时发送一份邮件的副本给产生自动回复邮件的邮件地址。这个地址可以工作在不同的计算机上,或者通过配置一个传递映射项服务于本地系统–这个传输映射项把所有发给autoreply.mydomain.tld的邮件传递给一个自动回复的脚本。

不要把autoreply.mydomain.tld列在mydestination中!

/etc/postfix/main.cf:
transport_maps = hash:/etc/postfix/transport

/etc/postfix/transport:
autoreply.mydomain.tld autoreply:

/etc/postfix/master.cf:
# =============================================================
# service type private unpriv chroot wakeup maxproc command
# (yes) (yes) (yes) (never) (100)
# =============================================================
autoreply unix – n n – – pipe
flags= user=nobody argv=/path/to/autoreply $sender $mailbox

这个是用发送者地址和the user@domain.tld的接收者地址来调用/path/to/autoreply

更详细的信息查看pipe(8)手册,这内容在master.cf文件中。