POSTFIX安装的默认目录:
/etc/postfix/ 配置文件与查询表
/usr/libexec/postfix/ postfix的各个服务器程序
/var/spool/postfix/ 队列文件
/usr/sbin/ postfix的工具程序
此外,还需要创建一个POSTFIX虚拟账户与一个postdrop组,而且这组账户与组专供postfix系统使用,不做任何其他用途。
第一次启动postfix
第一次启动postfix之前,必须先完成两项准备工作。第一件工作是确定系统本身的标示,也就是你的机器在INTERNET上的完整主机名称,因为postfix的myhostname配置参数需要设定成这个名称。只要postfix知道系统的完整主机名称,它就可以推算出其他重要参数的默认值,例如mydomain。如果你没有明确设定myhostname参数,postfix的默认值是使用本机系统回复的结果。使用unix的hostname命令可查出系统的主机名称。
完整主机名称由两部分构成,在第一个点号之前的部分是主机本身的名称,其后是“网域名称”。如果你的系统已设定好完整的主机名称,就可以不修改myhostname参数。然而,有些系统只设定了简名,而没有设定完整名称。
在这种情况下,postfix无法自己推算出完整的网域名称,所以你必须先明确设定myhostname参数。postfix提供了一个专门用来设定配置参数的工具程序:postconf,利用此工具,你可以查阅或修改postfix系统的各项参数的设定值。例如,若要设定myhostname参数:postconf -e myhostname=mail.example.com -e选项是“编辑”之意,即postconf将指定的参数设定成=之后的值。
启动postfix之前的第二项准备工作,是确定系统的别名数据库(aliases database)的格式是否正确。在你的邮件服务器被使用之前,必须事前设定几个必要的“别名”(如postmaster、info等),好让别人可找到相关程序的管理员。我们稍候会讨论aliases文件的详细格式,现在,你只要知道它是一个文本文件,可用来产生适合查询的索引数据库。你的系统上现有的别名数据库不见得符合postfix的默认格式,所以必须使用newaliasese命令重建别名数据库:
# newaliases
这个命令不需要任何自变量,它不会修改你的aliases文本文件,但会依据文本文件的内容重建新的别名数据库文件。
完成了上述两项准备工作之后,就可使用下列命令来启动postfix:
#postfix start
如果postfix在启动过程中遇到问题,它会回复错误信息---可能出现在终端机画面,也可能被记录到系统上的邮件日志(随实际的unix系统环境而定)。无论如何,只要能够顺利启动,postfix会立刻“脱离”终端机,将所有信息导入系统邮件日志(通常是/var/log/maillog),也就是说,在终端机画面上看不到任何信息。所以每次你启动或是重新加载postfix时,请务必检查日志文件,看看有没有任何警告或错误信息。
绝大部分情况下,postfix都可以顺利启动而不遇到任何问题,所以,你现在应该已经成为一台正在运作中的全功能postfix server的名誉管理人。但是,在你真正担任此一职务之前,还必须为你的用户做两件事。第一件事,让你的用户不需要邮件服务器系统的shell账户也能收信。第二件事,确定远程系统确实能通过DNS找到你的postfix server。
配置文件
postfix的配置文件全部都集中在/etc/postfix/目录下,其中最重要的两个文件是master.cf与main.cf。为了安全起见,这两个文件的拥有者都应该是root,而且只有root拥有write权限,但是其read权限可以开放给任何人。每当你改变这些文件的内容后,都必须重新加载postfix一次,则所作的改变才会生效。
#postfix reload
但是如果你修改了inet_interfaces参数,则需要重新启动(restart)postfix,而不可只重新加载(reload)。
整个postfix系统由多个具有不同功能的daemon构成,这些daemon之所以能够相互配合,是依靠master daemon居中控制管理。master依据master.cf配置文件来决定如果启动其他postfix daemon。master.cf配置文件里每一行分别描述一种postfix服务或传送程序的工作参数,参数行有统一的格式,各字段的意义都有规定,所以各参数必须按照顺序排列。一般而言,默认的master.cf足以应付大多数状况,所以你通常不必修改它。
main.cf配置文件
postfix的主要配置参数都集中在main.cf文件中,几乎所有的配置参数的改变都是发生在这个文件。默认的main.cf大约包含三百个参数,虽 然大部分的参数都不必修改,但是它们也提供了让你自主调整的空间,当你需要修改POSTFIX的行为时,这些预设的参数提供了相当大的灵活性。 POSTFIX的配置参数相当多,为了方便查找,不同用途的参数被分别放在不同的样本配置文件。这些样本文件存放在sample_directory参数 所指定的目录下(通常与main.cf文件位于相同目录)。POSTFIX包随附的main.cf与样本文件都含有详细的注释,这些注释有助于你了解各个 参数的意义、语法以及注意事项。
POSTFIX提供了一个让你可在命令行中编辑修改main.cf配置文件的工具---postconf,事实上,只要你遵守POSTFIX的配置文件的 语法,任何你惯用的文本编辑器程序(例如vi,emacs,jed,pico等)都可以用来直接编辑main.cf或任何配置文件。POSTFIX配置文 件的内容可以包含空白行、注释行、参数行。空白行的含义非常明白不需赘述。注释行是开头字符为#的文本行。如果有多行注释,则每一行开头都要有一个#符 号。对软件而言,空白行与文字行没有作用,postfix只会解毒参数行;但对管理人员而言,它们有重要的参考价值。每项参数都至少有一个参数名称,其后 是一个=符号,然后是一个或多个参数值。简单来说,参数行的格式如下:
parameter = value
在=符号左右两边的空格是可有可无的。
最常犯的一种错误,是将注释与参数放在同一行。这类错误有时候很难追查,因为你认为是注释的部分,可能被postfix当成参数值。另一种常犯的错误,是 在参数值的前后加注引号。不管是单引号还是双引号,在postfix配置文件里都没有任何特殊意义,所以它们也会被当成参数值的一部分,而不是里想要的结 果。
多行参数值
第一个字符为空格(tab或space)的文本行,被视为前一行的延续。当参数值太多而无法放在同一行时,这种格式让我们将参数值分散在不同行。
配置变量
在参数名称之前加上一个$符号,表示引用该参数的设定值。这种语法的好处是你只要修改一个地方,其他相关参数即可统一修改,而不会遗漏。被引用的参数并不一定要先定义,即顺序颠倒也无所谓。
多参数值
有许多参数可以同时拥有一个以上的值。参数值之间可以用逗号(,)、空格(space与tab)或换行字符隔开。记住,当你将参数值放在不同行时,参数值之前必须要有空格,以表示它们与之前一行是连续的。
有时某些参数的值太多以至不适合直接放在main.cf配置文件里,则可将参数值写在另一个文本文件,而把文件名提供给参数。任何以/字符的字符串,都会 被视为文件名。举例来说,假设我们的系统要受理来自许多网域的邮件,则可以将这些网域名称写在另一个文本文件,然后让mydestination参数指向 该文件:
mydestination = /etc/postfix/destinations
原则上,可接受多个参数值而且参数值顺序不甚重要的参数,就可以使用外部文件。例如mynetworks,mydestination和relay_domains都可以接受外部文件。如果不正确特定参数是否支持外部文件,请查阅说明文件。
如果参数值多达上千个,或是参数值本身具有“key-value“的形式,这时候使用查询表(lookup table)会是比较好的选择,因为查询表有较高的查询效率。
每次修改main.cf之后,都必须重新加载postfix才能使改变生效:
postfix reload
查询表
MTA时常需要做各式各样的转换与查询,比方说,改写邮件地址、判断客户端是否来自授权网络等。对于这类工作,sendmail要使用复杂的改写规则或样 式转换,而postfix采用比较简单也比较有灵活性的查询表(lookup table)来实现。有许多重要参数都需要能够查询其对应关系,例如,用于改写邮件地址的canonical_maps参数。举例来说,有一家公司,他们 内部使用账户名称来做邮件地址,但是他们希望公开给外界的任何地址,都必须是一致的[email protected]格式。因此,若某人的实 际邮件地址是[email protected],则外界看到的邮件地址应该是[email protected]。很显然,因main.cf本 身的格式限制,我们无法描述这样的对应关系。在这种情况下,最好的办法就是将所有对应关系另外写在一个文件--也就是“查询表”中,而main.cf中的 canonical_maps参数只要指向这个文件即可。
查询表让postfix可从一个“索引键”(例如[email protected])查出其“对应值” ([email protected])。索引值(key)通常来自postfix于运行时得到的信息,如邮件里的邮件地址、客户端的IP地址或 主机名称等;而对应值(value)可能是一段信息(例如邮件地址),也可能是影响邮件处理流程的动作关键字(例如REJECT)。有许多postfix 参数都需要查询表,维护查询表是管理员的重要职责之一,所以有必要详加说明查询表的文件格式。
查询表的格式
postfix支持多种格式的查询表,最常见的格式是unix数据库文件,这是一种含有索引表的二进制文件,特别适合用于快速的“key-value”查 询。查询表的原始数据来自简单的文本文件,文本文件里的每一行定义一组“key-value”对应关系,key与value之间以空格隔开;
同一个查询表里的每一个key,都必须独一无二,不可重复。“key”通常被称为LHS,而“value”被称为RHS。查询表的LHS不区分大小写。如 同main.cf的格式,查询表也可以包含空白行与注释行,而且开头为空格的行也被视为前一行的延伸;引号在查询表里也同样没有特殊意义。
将所有对应关系都编入文本文件之后,必须使用postmap来创建做实际查询之用的数据库文件:
postmap /etc/postfix/canonlcal
每次修改文本文件之后,都必须运行postmap来重建它的数据库文件。
postmap不仅可以用来创建数据库文件,也可以用来查询。使用“-q”选项指定你要查询的LHS,它会显示出对应的RHS:
postmap -q [email protected] /etc/postfix/canonical
数据库格式
不同类型的unix数据库文件,有不同的内部格式。你的系统支持哪些类型的数据库,要看你的系统上安装了哪些数据库的函数库。通常,postfix至少支持 btree,dbm与hash这三种类型中的一种,不过,你的系统实际支持的类型可能更多。搞清楚你的系统支持哪些类型的数据库是非常重要的。 postconf的"-m"选项,可帮助你搞清楚你的postfix支持哪些类型的查询表:
postconf -m
此命令会显示出你的postfix支持的所有查询表类型以及各种形式的信息变量。但无论如何,你应该至少能找到btree,dbm或hash这三种数据库类型中的一种。
postfix默认的数据库类型,定义在default_database_type参数
使用postmap时,如果没特别指定某一数据库类型,它会将查询表(文本文件)转换成default_database_type参数所指定的数据库类型。然而,当你将查询表赋值给相关参数时,你必须指出查询表的数据库类型。
当你将一个查询表赋值给某参数时,必须同时注明查询表的“类型”与“名称”。指定查询表的语法如下:
parameter = type:name
这里的type是变量的访问方法,而name是含有“key-value”对应关系的资源的名称。对于索引式数据库的查询表,name等于查询表的完整路径名。
你 可以同时指定多个查询表给同一个参数。POSTFIX会依照你给定的顺序来搜索查询表,并且在找到符合条件的项目时立刻停止。某些参数支持“递归式查询 表”(recursive lookup table),如canonical_maps参数。使用递归查询时,系统一旦找到一个符合条件的对应值,postfix会尝试将值与所有的索引键再比对 一次,直到找出一个相符的索引键。
你或许已经注意到了,使用postmap编制索引文件之后,它会创建额外的文件。你可能会发现系统上多了一个. db文件,或是多了一对.dir与.pag文件(随你所用的数据库类型而定)。注意,指定查询表给参数时,只需指出查询表的类型以及文本查询表的完整路径 名称即可――――不需包含扩展名,因为扩展名是由数据库系统决定。
对比顺序
有许多参数的查询表,其索引键为邮件地址---有可能是完整地址,也可能只有人名部分,或是只有网域部分。例如canonical_maps参数的查询 表,其索引键只有人名部分有意义;而transport_maps参数的查询表,其索引键只有网域部分有意义。对于不同类型的查询表,postfix采取 的比对顺序也略有不同。如果你想知道特定参数的查询表的比对顺序,请参阅相关查询表的在线说明。
原则上,对于canonical_maps,relocated_maps与virtual_alias_maps这种只有人名部分有意义的参数而言,其查询表的比对顺序如下:
1、完整的地址,例如 [email protected]
2、只含人名部分的地址,例如kdent
3、以@开头的网域部分,例如@example.com
另一方面,对于只有“网域部分”才有意义的参数,例如transport_maps,postfix采用以下对比次序
1、完整的地址,例如[email protected]
2、只有网域本身的地址,例如example.com
3、以“."字符开头的网域地址,例如.example.com这表示任何子网域都符合条件。
如果你希望网域名称涵盖其下的所有子网域(比方说,“example.com“代表example.com与其所有子网域),你可以利用parent_domain_matches_subdomains参数来简化查询表的内容。此参数的默认值包含许多查询表。
查询表与简易列表
某些参数通常只需要一份简易列表,但是也容许你指定一个查询表,例如mydestination。使用简易列表时,只需要列出索引键即可:如果使用查询 表,则必须为每一个索引键都配对一个(无意义的)对应值。通常,只有在你想写给自己看的注释时,或者列表里有上千个项目的时候,你才要这样做。将长串列表 独立到一个简单的文字文件,不仅可以简化配置文件,在效率上也比较理想。举例来说,如果你的POSTFIX要服务的网络客户(定义在mynetworks 参数)不是集中在某个子网络(不能用简单的network/mask语法来表示),而必须分别列出个别网络客户的ip地址时,查询表可能会是比较理想的选 择。
模式表
除了支持与key-value配对关系的查询表之外,POSTFIX还支持一种更有灵活性的特殊表,让你可以用正则表达式来描述一组共同特征。正则表达式 又称为“模式”,许多unix工具应用它们来比对“具有描述的共同特征”的字符串。postfix支持两种风格的正则表达式,随你的系统所安装的函数库而 定。
默认情况下,postfix使用“posix扩展正则表达式”,我们简称为“regexp”。posix的全名是portable operating system interface,这是为了促进操作系统兼容的标准,regexp是其中关于正则表达式语法的标准规范。postfix也支持perl兼容正则表达式。 如果你习惯使用perl风格的正则表达式,你也会发现它与regexp的语法有点小差异如果你希望POSTFIX支持pcre,在编译postfix时, 必须链接pcer函数库才行。pcre不仅在语法功能上不同于regexp,在效率上也略胜regexp一筹。如果你不确定自己系统上的postfix是 否支持pcer,请使用postconf的“-m"选项来检查。
倘若pcre出现在postconf"-m"显现出支持类型中,则你的模式表可以使用perl风格的正则表达式。但如果你的系统不支持pcrc,那也不必 急着重新编译POSTFIX,因为默认的regexp已经足以应付管理员在正则表达式方面的需求,除非里确实需要perl正则表达式特有的功能。
对POSTFIX与perl两种风格的正则表达式,都可以找到很详尽的说明。任何关于PERL的书籍,都应该会提到它的正则表达式,如果里的系统上已经安 装了PERL,请参阅perlre在线说明书。关于regexp的说明,通常出现在re_format现在说明书,如果你的系统上没有这份文件,请去 INTERNET上搜索。
要使用模式表,除了要指定文件名之外,还必须注明其表示法为regexp或pcre;
body_checks = regexp:/etc/postfix/re_body_checks
模式表(此例中的re_body_checks)里的每一行,都分成“模式”与“值”两部分。模式是放在一对“/"符号之间的regexp或pcre正则表达式,“值”是该正则表达式所对应的字符串。“模式”与“值”之间以若干空格隔开:
/pattern/ value
模式表在postfix系统上最主要的应用,是用来过滤掉烦人的垃圾邮件:将垃圾邮件的标题与正文的特征写入两个样式表。
其他格式
POSTFIX也可以将其他后台系统当成查询表使用,例如mysql,ldap,nis等。当里使用这类外界资源时,应当先从最简单的数据库入手,例如dbm或hash,等确定该设定方法确实有效之后,再改用外界资源,并比较前后效果是否相同。
postmap提供了一个重要的选项:“-q",让你测试任何种类的查询表。例如,当你使用mysql数据库时,下面两个命令应该返回相同的值:
postmap -q hash:/etc/postfix/transport
postmap -q mysql:/etc/postfix/transport.cf
别名文件
别名文件(alias file)是postfix查询表中的特例,因为它使用一种兼容于sendmail的格式。传统上,别名文件的文件名为aliases,而且其实际存放位置随系统平台类型而定,但通常是在/etc/或/etc/mail/这两个目录中的一个。postfix默认使用系统原有的aliases文件,以便原本使用sendmial的系统,可以继续沿用原有的别名文件。
别名文件的位置
基于沿革因素,邮件系统只使用一个别名文件数据库。但是postfix没有这样的限制,你可以使用多个别名文件来组织你的配置信息。一般而言,当你要设定多组邮件列表(mailing list)时,你会想要将它们分别设定在各自的别名文件。aliase_maps参数显现出你有哪些别名文件。
如果你的系统支持NIS,postfix的默认行为会搜索NIS所提供的别名信息。因此,默认的alias_maps参数如下:
aliase_maps = hash:/etc/aliases, nis:mail.aliases
倘若你的系统提供NIS服务,但是你不想使用它,你可以修改aliae_maps参数,让它只包含别名文件:
alias_maps = hash:/etc/aliases
别名文件的位置既然都该了,别名数据库的位置也要修改:
alias_database = hash:/etc/postfix/aliasese
重建别名数据库文件
由于别名文件的格式不用于其他POSTFIX查询表,所以不能使用postmap来重建别名数据库文件。你应该使用postfix提供的另一个工具:postalias。此工具命令行的语法与postmap相同,你可用它将使用文字符号的别名文件转换成实际查询用的别名数据库:
postalias /etc/aliasese
另一个为了与sendmail兼容而设计的命令行工具是newaliases,这个工具的作用其实与postalias完全相同,但是其用法被刻意设计成兼容与sendmial包里的同名工具。所以你可以直接下达newaliases命令而不提供任何选项,也不必指定文本别名文件的位置,它就会自动产生别名数据库。
当你运行newaliase时,它是依据alias_database参数来决定源别名文件的位置。alias_maps与alias_database这两个参数的主要差异,在于前者可包含其他类型的别名信息,而后者只能包含“unix数据库”这一种来源。注意,newaliases是依据default_database_type参数来决定unix数据库的格式。
别名文件的格式
用于产生别名数据库的别名文件,其内容格式类似postfix的查询表,唯一差别在于别名的定义。别名文件同样也可以有空白行与注释行,注释行同样是以#符号开头,也同样不能与别名定义摆在同一行。一个别名的定义可以跨越多行,以空格开头的行,被视为前一行的延续。
别名的定义格式,最左侧是别名本身,其后一个冒号与若干空格,然后是一个或多个“目标”,目标之间以逗号隔开。别名与目标如果包含空格或任何特殊字符(#:、@),则必须以一对双引号界定其范围。简单来说,别名的定义格式如下:
alias: target1, target2, ....
冒号左侧的alias一定是一个本地地址,所以不能包含网域部分。冒号右侧的target通常是一个或多个邮件地址,有下列四种可能性:
邮件地址
任何符合RFC 2822规范的地址都可以。这表示target可以是本地地址或是需要转递到另一台主机的外地地址。
文件名
本机文件的完整路径。新邮件会被添加到指定文件的末端,也就是将该文理积案当成本地邮箱使用。
命令
一个竖线字符(|)与一个外部命令的完整路径。例如:
info: "| /usr/local/bin/autoreply"
:include: file
引入一个含有额外目标的文件。原则上,该文件里的目标可以是前述的任何有效目标,但是在默认情况下,“文件名”与“命令”这两种目标是禁止的。例如:
info: :include: /usr/local/mail/info_list
正常来说,当postfix投递本地邮件时,它会先使用收件人的身份,以获得将邮件写入收件人邮箱的权限;但如果收件人地址是一个别名,则postfix会使用别名文件拥有者的身份。不过,如果别名文件拥有者是特权用户,则postfix使用default_privs参数所指定的非特权身份。
别名目标限制
利用别名文件的“目标”可以做甚多事。你可以用allow_mail_to_commands与allow_mail_to_files来容许哪几种“目标”出现在别名文件里。有效的别名机制包括:alias(别名文件)、include与forward。
基于安全考虑,这两个参数的默认值都是“alias,forward”,也就是说,只有别名文件与.forward文件的目标可以设定为“文件”与“命令”,而引入文件的目标不可以是“文件”与“命令”。如果你想完全禁止邮件内容被递送到外部命令与文件,那就将这两个参数都设定为空白:
allow_mail_to_commands =
allow-mail_to_files =
相反,如果你希望所有别名机制都可以将邮件递送到外部文件与命令,则可以这样设定:
allow_mail_to_commands = alias, forward, include
allow_mail_to_files = alias, forward, include
这样的设定效果与sendmail的默认行为相同。这样做可能使得邮件列表管理系统(mailing-list manager, MLM)成为窥视目标,因为黑客提供的“文件名”或“命令”可能会被MLM当成一般目标地址而被写入别名文件,进而使得系统安全出现隐患。如果你不需要额外的include选项,那就接受postfix的默认值。
重要的别名
postfix包随附的别名文件模板,已经预先设定了一组系统别名。习惯上,这些系统报名最后都是指向root账户。如果你想要定期阅读root的邮件,最好的办法不是直接以root身份登录系统,而是另外设置一个root别名,将其邮件转到另一个你平常用来收信的邮箱。
RFC 2142定义了一组所有网域都应该具备的别名,你可以按实际提供的Internet的网络服务类型来决定要设置哪些别名。但无论如何,最起码要设置一个postmaster别名,好让其他网域的邮件管理员知道怎么联络你。请详细阅读RFC 2142,决定你需要创建哪些别名
设定MTA的标示
不管你的postfix要做何种用途,你都必须决定MTA的标识,也就是其主机名称与网域名称。这方面的参数共计有四个,分别是myhostname,mydomain/myorigin以及mydestination。
myhostname与mydomain
本章一开始就曾经讨论过myhostname参数的用途与重要性。如果你没指定myhostname, postfix使用gethostname()函数来查询系统的主机名称。如果你的系统已经事先设定好正确的主机名称,则gethostname()能正确返回完整的主机名称,倘若改名称确实就是你想要的,则你不一定要设定myhostname参数的值。但如果gethostname()函数返回的名称不完整或是不是你想要的名称,则你应该明确赋予myhostname参数一个完整主机名称,或是将mydomain参数设定成系统所属的网域的完整名称。当mydomain参数的值为手动设定时,postfix会依据gethostname()回复的本地主机名称以及管理员指定的mydomain参数值,自动推算出myhostname参数的值。
如果你将myhostname设定成系统的完整主机名称,但是省略了mydomain,则postfix扣掉myhostname的值的第一个点之前的部分,借此推算出mydomain的值。即若myhostname被设定成mail.example.com,则postfix会自动推算出mydomain的值为example.com---除非你自己刻意将mydomain设定成其他网域名称。类似的,如果你的系统不能正确回复它自己的完整网域名称,而你也没有设定mydomain和myhostname参数值,则当你启动postfix时,它会将问题记录在你的日志文件里。
myorigin
当用户通过postfix系统发出邮件,但是其信封与标头里的邮件地址都没注明网域名称时,postfix会自动使用myorigin参数定义的网域名称来补齐缺少的信息。mydomain的默认值等于myhostname的值。举例来说,若运行postfix的主机的名称为mail.example.com,当用户通过这台主机寄出一封“From:kdent”邮件时,postfix在实际寄出邮件之前,会将它改写成“from:[email protected]“。由于大多数用户只希望出现网域名称(例如[email protected])而不要出现主机名称,所以myorigin参数通常设定成$mydomain:
myorigin = $mydomain
mydestination
mydestination参数列出了postfix应该将其视为“本地网域”的所有网域名称。在默认情况下,postfix只会收下送给$myhostname与localhost.$mydomain的邮件,也就是说,postfix的默认行为只接受送给系统能够主机的邮件。如果你的postfix要代整个网域上的所有主机收信,则应该将$mydomain加入mydestination的参数行:
mydestination = $myhostname, localhost, $mydomain, $mydomain
现在,你的邮件服务器刻意成为整个网域的网关器,代该网域的所有主机收下邮件。
转发控制
除了为本地用户服务之外,postfix也刻意转发其他系统的邮件。规定哪些对象刻意使用你的系统的转发服务是非常重要的事。一般而言,局域网上的主机或用户需要你有能转寄信到任何地方的能力,但是你会愿意将同样的服务提供给局域网之外的网络。在邮件管理上,转发控制是非常重要的功能,因为这是防止垃圾邮件的首要控制手段。spammer最常用的一种手段,就是找出有固定连接而且能为他们转发垃圾邮件的服务器,通过这些无辜的服务器来滥发垃圾邮件,借此隐藏自己真正的行踪。你应该禁止非授权对象使用你的邮件系统来转发邮件。如果你将系统设定成open relay,这不仅只是助长垃圾邮件滥发问题而已,而是终有一天,你会发现自己的系统被列入黑名单,被其他邮件系统当成垃圾邮件的来源地,而成为他们的拒绝往来者,到最后,你甚至无法寄出自己的正常邮件。
限制转发访问
psotfix的默认配置不是open relay,mynetworks_style与mynetworks这两个参数决定客户端必须具备怎样的资格,才可以通过postfix来寄出邮件。默认配置仅容许相同IP子网络上的其他主机使用转发服务。你可以使用mynetworks_style参数来紧缩或放宽服务的地址范围:如果你只愿意让服务器自己能使用转发服务,则可将mynetworks_style设定成host;你也可以将mynetworks_style设定成class,让任何与服务器位于同一级ip网络的主机都可以使用转发服务。不过,对于大部分网络而言,使用class配置等于将服务器开放给许多不相干客户端。如果你不熟悉ip地址的分级方式,建议你使用默认的subnet,或是更严格的host。
或者,你也可以使用mynetworks参数明确指出哪些主机可以享受转发服务。mynetworks参数的效力高于mynetworks_style,如果你设定了前者,后者自动失效。你可以逐一列出个别的ip地址,或是使用network/mask表示法来指定一段子网络。mynetworks的方便之处,在于你可以提供转发服务给一组特定的ip地址群,而不管它们是否与服务器位于同一个子网络。例如,假设你是总公司的网管,你想提供转发服务给分公司办公室里的同事,而分公司位于另一个子网络,有固定的ip地址。在这种情况下,你可将分公司网络的ip地址纳入mynetworks,让他们可使用你的postfix server来寄信。不过,要是你想服务的对象没有固定ip地址,则你必须采取某种smtp身份验证机制。
smtp身份验证
所有能配合smtp协议进行身份验证的技术都比较复杂。在你挑选任何一种验证技术之前,最好再想想看,还有没有比较简单的选择。比方说,有没有可能让远程用户得到固定的ip地址?远程用户是否可改用另一台smtp server?或许远程用户的isp正好就提供smtp代转服务。
有人可能会想到,为何不利用控制垃圾邮件的技术,设置一条“寄件人地址是否为本地网域”的检查规则,借此决定是否可代为转发邮件?答案是绝不要这样做!因为寄件人地址太容易造假了,而垃圾邮件发送者绝对懂得如何伪装寄件人地址――――这简直是他们的专长。如果你真的使用了这种管制技术,你将会很快发现,你的邮件服务器已经成为open relay,你不仅会收到“看起来很像自己人寄出的垃圾邮件”,别人也会收到“看起来像是从你家寄出的垃圾邮件”。
因应动态ip地址的解决方案
sasl是规范server与client之间如何交换身份证书的一种通用协议。你的smtp server必须链接额外的函数库才能使用sasl。除了sasl之外,还有三种类似的解决方案,分别是pop-befre-smtp、DRAC以及WHOSON。这些方案都是针对没有固定ip地址的客户端而机设的。这些技术要求用户必须先登录pop/imap server,借它提供客户端当前的ip地址给你的系统。smtp server得到客户端的ip地址之后,便批准客户端可以使用转发服务一段时间。这项技术的优点在于用户几乎感觉不到有何不同,唯一差别是他们必须先检查新邮件,然后才能寄出新邮件。
DRAC和pop-before-smtp两者与postfix的合作方式,都是借由动态修改postfix查询表;当用户成功登录pop/imap server之后,将客户端当时的地址填入查询表,在超过预定期限之后,删除先前填写的地址。postfix不需要增加任何额外的函数库,唯一需要设定的是依据pop/imap server修改的那个查询表来决定是否提供转发服务,但pop/imap server 本身则需要修改、重新编译。DRAC不同于pop-before-smtp之处,在于它可以通过网络来访问smtp server,而pop-before-smtp则要求pop/imap server必须与smtp server安装在同一台系统上。
WHOSON实际上是一种让pop/imap与smtp两种服务器可以交互的接口协议。你可以在网络上架设一台whoson server,然后取得一个修补文件让postfix支持一种新型的查询表。在修补源程序并重新编译好postfix之后,它就可以与whoson server通信,借此判断特定客户端ip地址是否有权使用转发服务。
身份证书
另一种可以考虑的方案,是采用“客户端身份证书”,我们通常将证书当成保密通信的一种手段,其实证书也是最理想的身份验证法。然而,证书的审核与管理需要不少功夫,而且你的postfix必须支持TLS协议才行。
这些额外的支持机制都不是理想方案,因为你可能要重新编译、链接现有的服务器程序,并开放某些系统文件的写入权限给这些服务器程序。此外,它们也加重了系统管理员的工作负担。如果你不能使用先前所说的非验证式技术,或是你的smtp server必须满足“每一位”用户的转发要求--不管他们到底是在Internet上的哪个角落,那么,sasl或许是最可靠、也最灵活的身份验证方案。
管理
维护邮件服务器是一件长期的工作。你不能只是启动postfix,之后就不再管理。有一些例行性的管理工作必须靠你完成,而你也应该经常检查自己的系统是否有任何问题。
postfix的postfix工具提供了一个check命令,可帮助你检查当前的postfix配置是否有问题、文件与目录的拥有权是否正确,甚至帮你创建任何遗失的目录。运行方式如下:
postfit check
这个检查程序秉持“没有消息就是好消息”的Unix优良传统。如果你的系统一切无误,它不会出现任何信息;否则,它会将查出来的问题显示在屏幕上,并同时记录在日志文件里。
日志记录
postfix是一个长期运行的程序,你应该定期检查日志文件,看看有没有什么警告或异常的信息。有可能改变系统的事件,都可能会连带影响postfix,因此,几乎所有postfix的活动--不管成功与否,都会被记录在日志文件。每次你启动或重新加载postfix时,最好检查一下日志文件,确定postfix已经完成你要求的活动。
postfix的日志记录是通过系统的syslog daemon来代为完成。不管是哪一种版本的unix,系统日志都是管理工作上非常重要的一环。
一般而言,syslog daemon从各种系统进程中接收信息,并将信息写到它们的最终目的地。syslogd对于日志信息的分类方式,主要是依据信息本身的重要性以及产生信息的应用程序或机制。/etc/syslog.conf配置文件决定syslogd应该将各种类型的信息写到何处。postfix所使用的记录机制是“mail”。如果你不知道postfix产生的信息到底是记录在哪个日志文件,/etc/syslog.conf能提供正确的线索。某些操作系统是所有信息都记录在同一个日志文件中,像/var/log/syslog;而有些操作系统采取比较细腻的分类方式,它们可依据应用程序或服务类型,将信息分别记录在专属的日志文件中,对于这个系统,postfix日志信息可能会出现在/var/log/maillog文件--如果改系统的/etc/syslog.conf是像下面这样设定的话:
mail.* -/var/log/maillog
顺利找出邮件日志文件的位置之后,请务必定期检查它。你应该依据服务器的邮件量以及先行的日志轮替模式,决定至少每隔多久要检查一次,当然,决定权在你,多检查几次总是好事,重要的是要持之以恒,养成习惯。
要如何检查日志文件?这是一项需要练习的技巧。举例来说,如果想查出postfix曾经发生哪些值得注意的事,你可以这样做
egrep '{reject|warning|error|fatal|panic}:' /var/log/maillog
这个命令假设日志文件位于/var/log/maillog,如果不是,请换成实际使用的日志文件路径。
postfix的启动、关闭与重新加载
我们已经介绍过如何使用postfix命令来启动postfix
postfix start
在postfix持续运行的过程中,如果你修改了main.cf或master.cf,则postfix必须重新加载配置参数:
postfix reload
此命令会等待运行中的进程完成工作后才结束它们,然后重新读取配置参数,继续运行。当你下达此命令时,如果postfix正好在收信,发信方不会感受到任何异样或停顿。
在start或reload之后,最重要的事是检查日志文件,看看postfix是否回复任何错误或警告信息。
如果要关闭postfix,请使用postfix的stop命令:
postfix stop
同样,postfix会等待进程完成未完成的工作,然后才结束它们。对于reload就足够应付的事,就不应该先stop然后立刻start。此外,尽量避免频繁的start,stop,reload,因为这些动作都会严重影响服务器的运行效率。
master.cf
postfix的所有服务器程序,都是由master daemon在必要时才予以启动的。这些服务器程序的运行参数,全部都定义在master.cf配置文件。
master.cf的基本格式与postfix得其他配置文件一样:#符号代表注释,空白行与注释行没有作用,开头为空格的文字行被视为前一列的延续。
服务名称(service name)
服务器组件的名称。实际的命名规则,随该服务的传送类型而定。
传送方式(transport type)
传送服务所用的通信方法。有效的传送方式包括inet、unix与fifo。
inet方法表示服务可通过“网络套件字”(network socket)来访问,这类服务的对象可以是同系统上的其他进程,或是网络上其他主机的客户端进程。网络套接字服务的名称,是用服务方的“ip地址”(主机名称也可以)与“通信端口”(数值或/etc/service定义的端口符号名称)的组合来表示,例如:192.168.1.2:25、localhost:smtp。如果服务方恰好位于本地主机上,则“ip地址”与冒号都可以省略。
unix代表“unix domain socket”, 而fifo代表“命名管道”(named pipe)。两者都是同机器不同进程之间的通信机制,而且同样使用特殊文件为通信中介。unix与fifo服务的名称与unix标准文件名的命名规则相同,但是不包含目录路径的部分。postfix使用服务名称来创建通信中介用的特殊文件。 unix domain socket与命名通道两者都是unix的标准“进程间通信机制”(interprocess communications,通常简称为ipc)。
私有的(private)
某些服务组件仅供postfix系统自己使用,不开放给postfix之外的其他软件使用。如果本栏标示为y,表示私有访问(默认值);n代表开放公共访问。inet类型的组件必须标示为n,否则外界就无法访问该组件,毕竟网络套接字本身的用意,就是要开放给其他进程访问。
非特权的(unpriv)
是否使用非特权账户。默认为y,标示服务组件运行时,只需使用mail_owner参数指定的非特权账户(默认值为postfix),即以完成任务所需的最低限度来提供服务。大部分postfix组件都可以使用非特权账户。对于需要root特权的服务组件,此栏必须设定为n。
改变根目录(chroot)
是不是改变组件的工作根目录,借此提升额外的安全性。工作根目录的位置由main.cf的queue_directory参数决定。此栏的默认值为y(标示要改变工作根目录),大部分的postfix组件也都可以在chroot环境下运作。不过,标准的安装方式是让所有组件都在正常环境下运行。讲服务组件放在chroot环境下,添加了许多额外的复杂事情,你应该先通盘了解chroot所带来的保障,然后再决定这样的额外安全性是不是值得你多费一番设定与维护的功夫。
唤醒间隔(wakeup)
某些组件必须每隔一段时间被唤醒一次,定期执行它们的任务。pickup daemon就是这样的一个例子。其默认休眠间隔是60秒,master daemon每隔一分钟就唤醒pickup一次,要求它检查maildrop队列是否收到新邮件。qmgr和flush daemon也是需要被定期唤醒的服务组件。在时间值之后尾随一个问号(?),标示只有在需要该组件时才予以唤醒;0表示不必唤醒。此栏的默认值为0,因为目前只有三个组件需要被定期唤醒。postfix包预先为这三个组件设定的唤醒间隔时间,应该足以应付大部分情况,其他服务组件都不需要master的定期唤醒。
进程数上线(maxproc)
可以同时运行的进程个数的上线。如果没指定,则以main.cf的default_process_limit参数为准(其默认值为100)。如果设定为0,表示没有任何限制。如果服务器系统的资源有限,或是想让系统在某方面的表现特别好,你可以调整maxproc的值。
命令(command)
最后一栏是运行服务的实际命令。命令中的“程序文件名”部分不必包含路径信息,因为master daemon假设所有程序文件都放在daemon_directory参数所指定的目录下(默认目录为/usr/libexec/postfix/)。postfix的所有程序皆提供“-v”选项,可用来提高日志信息的详细程度,当我们需要解决问题时,经常利用这种方法来获得更多、更有用的调试信息,此外,你可以使用-d选项,让postfix程序产生调试信息给调试程序。
每一个postfix daemon都有自己的命令行选项。关于各个服务组件的选项。请参阅它们的在线说明书。请注意,只有postfix提供的服务器程序才可以放在命令栏,如果你想要运行自己的命令,请使用postfix提供的pipe daemon。
时间单位
postfix有一些与时间相关的参数,为了方便描述其值,postfix提供了一组简写代号来表示时间单位:s(秒)、m(分)、h(时)、d(天)、w(周)。如果没明确注明时间单位,各时间参数以自己的默认时间单位来解读你给的值。虽然从在线说明书可以查到所有时间参数的默认单位,但是谨慎的管理员不应贸然留下模糊的解释空间,而应该明确标示给定时间的单位。
某些服务器组件会参考main.cf提供的参数值,但同时也提供了“-o”命令行选项,让你可以在master.cf中强制设定你要的参数值。举例来说,若要创建一个特殊的smtp服务,你可将下面内容加入master.cf配置文件:
smtp-quick unix - - n - - smtp
-o smtp_connect_timeout=5s
参数名称、等号与设定值可以紧接在一起,不必留空格。在加入本例这样的设定之后,你的系统就多了一个特殊的smtp-quick服务,当它寄信时,如果对方服务器5秒内没有响应,就会自动断线。但是,遵照main.cf设定值的那个smtp服务,则使用不同的smtp_connect_timeout参数值。
收信限制
smtpd daemon可以对外来邮件强加一些限制,包括邮件的大小、同一封邮件的收件人数、邮件内容每一行的长度上线,甚至是同一个客户端可以容许在发生多少次错误后予以断线。这些限制决定于main.cf配置文件的几个参数。
smtpd_recipient_limit参数决定一封邮件最多可以有几位收件人,默认值是1000,就一般的邮件系统而言,这是很宽松的限制。
message_size_limit参数限制单封邮件的容量上线。默认值为10MB。如果想节约磁盘空间或内存,建议你降低此值。但如果你的用户经常夹带大的图像文件,则应该考虑适度扩大此值。
如果同一个客户端频繁出错,那通常是有问题或被攻击的征兆。postfix能累计客户端曾经发生错误的次数,对于可疑的客户端,postfix会主动延迟响应的时间,而且错误次数越多,延迟时间就越长。这样的延迟效果可保护你的系统,以免被错乱的客户端搞垮(不管对方是无心还是恶意)。初次的延迟时间由smtpd_error_sleep_time参数决定(默认为1秒钟),当客户端累积了smtpd_soft_error_limit次错误之后,往后每发生一次错误,postfix就多延迟1秒钟,当错误次数超过smtpd_hard_error_limit时,postfix就放弃该客户端,并主动断线。
举例来说,若网络远程有一个恶意程序连接到你的邮件服务器,试图发出垃圾命令来搞垮你的服务器。则这种垃圾命令会被postfix视为一种错误,并会开始怀疑客户端是否心怀不轨。假设你设定了下列延迟参数:
smtpd_error_sleep_time = 1s
smtpd_soft_error_limit = 10
smtpd_hard_error_limit = 20
则一开始,每次客户端出错之后,postfix都只会延迟1秒钟(smtpd_error_sleep_time),在历经10次试探之后,postfix开始延长每次延迟的时间。在第11次错误时,postfix等待11秒;第12次则等待12秒,依此类推。当总错误次数到达20次,postfix便有充分理由认定对方另有所图,所以会立刻切断连接。如果对方再次连接,而且试图制造同样的麻烦,则他势必再经历一回漫长的等待。
改写地址格式
postfix会尝试修正邮件标头里的邮件地址,使其符合RFC 2822标准的格式。有两种显而易见的错误格式,postfix会自动予以修正。
第一种情况是只有人名而没有网域部分,另一种情况是网域部分只有主机简明而没有域名。对于前者,postfix会将myorigin的值附加到人名之后;对于后者,则是将mydomain的值附加到主机简明之后。
规范地址
除了自动补齐不完整的邮件地址之外,postfix还提供另一种改写地址的功能,让你可将毫无共同点的地址,替换成整齐统一的格式。canonical_maps参数指向
关闭地址自动补齐
postfix自动补齐不完整邮件地址的行为,有时候会造成用户的混淆。假设你的postfix系统代理example.com网域的电子邮件,有一天,系统从外界收到一封邮件,但是其FROM:字段所含的地址不完整,如下:
from:marketing
to:[email protected]
postfix运行它的例行修正工作,所以上述字段现在变成这样:
from:[email protected]
to:[email protected]
类似本例这种不完整的地址,其实是发送垃圾邮件者惯用的伎俩之一。天真的用户看到调整后的地址,往往误以为垃圾邮件源自发送服务器。你当然可以设定postfix,要求它不要主动附加网域名称到不完整的地址,然而,除非你的服务器纯粹为“邮件网关”,没有任何邮件是从机器本身的MUA产生,才可以放心的关掉postfix的自动补齐功能。有许多应用程序都要求邮件地址必须符合RFC 2822标准格式,如果邮件中所含的地址格式不合规定,可能会遭到不少麻烦。
要避免postfix擅自将myorigin或mydomain附加到不完整的邮件地址,你可以修改append_at_myorigin和append_dot_mydomain这两个参数。
大部分情况下,你不会想要这样做。因为postfix自己假设邮件地址总是以正确格式出现,而许多处理邮件信息的应用程序也是如此认为。比较妥当的解决方法,是决绝接收邮件地址不完整的邮件。
定义地址对应关系的查询表,称为规范表(canonical map)。如果你的网络上有多个不同的邮件系统,分别产生了不同样式的地址,你可以将所有邮件都导到一个postfix网关,由它将各式各样的地址转换成标准格式。规范表通常用于将邮件地址从内部格式转换成公共格式,像这样:
/etc/postfix/canonical
[email protected] [email protected]
[email protected] [email protected]
甚至也可以连同网域部分一起转换;
在main.cf将canonical_maps参数指向规范表:
canonical_maps = hash:/etc/postfix/canonical
让你的规范表运行一次postmap,并在修改main.cf之后重新加载postfix;
canonical_maps参数会影响所有地址,包括信封与标头里的地址。每当postfix发现邮件地址符合规范表的某索引键,便会将它改写成对应值。如果你只想修改收件人或发信者的地址,postfix提供了额外的参数:sender_canonical_maps与recipient_canonical_maps。这两个参数的工作方式与canonical_maps相同,但是只会影响相关地址。如果你同时设定了这三个参数,postfix会依照下列顺序来改写地址;先是sender_canonical_maps,然后是recipient_canonical_maps,最后才是canonical_maps。
伪装主机名称
地址伪装的用意,在于隐藏内部主机的名称,让邮件看起来就像是从网关系统发出去的一样。假设你的postfix server需要转发内部网络主机寄出的邮件,当内部主机送出邮件时,发信者地址含有完整的主机名称,但是你希望只出现网域名称。masquerade_domains参数用来将主机名称转换成较简单的网域名称,你只要将一个网域名称赋值给它:
masquerade_domains = example.com
masquerade_domains参数可以接收多个网域名称,甚至是子网域名称。postfix会按照你给定的顺序来比对邮件中的地址。想像一个含有两个子网域只出现它们各自的子网域名称,而来自任何其他网域或网络主机的邮件,都只出现上层网域名称,则你可以这样设定:
masquerade_domains = acct.example.com hr.example.com example.com
如果你想保留某个原本会被换掉的网域名称,你可以在该网域名称之前注明一个感叹号:
masquerade_domains = !it.example.com example.com
这表示来自it.example.com网域的邮件地址不会被改写。
postfix甚至容许我们排除特定的账户。举例来说,假设我们希望[email protected]与[email protected]这样的地址保留原样,则我们可将这些账户名称列入masquerade_exceptions参数
masquerade_exceptions = admin, root
使用地址伪装功能时,标头与信封上的所有地址都会受到影响,唯一例外是信封上的收件人地址。这使得写给特定主机的邮件,仍可通过邮件网关器送到该主机,而同时又能伪装成由该主机寄出的邮件。如果你希望所有类型的地址都被伪装,那就将postfix能认出的所有地址类型全部都列在masquerade_classes参数中,请注意,如果你像上面这样设定masquerade_classes,则邮件网关系统将不知道如何投递原本应该送到[email protected]的邮件,因为该地址已经被改成[email protected]
改变投递地址
当用户更改邮件地址,而你不愿意服务器继续帮他们代收邮件时,你可以用一个查询表定义这些用户的新旧地址对应关系,并让relocated_maps参数指向此查询表。
relocated_maps = hash:/etc/postfix/relocated
查询表的每一行各记录一个“旧地址--新地址”的对应关系。每当收到要送给旧地址的邮件或是旧网域的任何人发的邮件,postfix会拒收,并将对应的新地址发送给寄信方。
那么,每当有smtp client要求postfix将邮件送到[email protected]或[email protected]时,postfix皆会予以拒收,而smtp client可从响应的错误信息中知道新地址。
除了个人地址变迁之外,postfix也能应付整个网域搬迁的情况。如果将下列对应关系加入/etc/postfix/relocated查询表:
@example.com oreilly.com
则每当postfix遇到要寄给example.com的邮件,不管收件人是谁,都一律予以拒收,并告知对方,邮件应该送到oreilly.com才对。
不明用户
对应该收下的本地邮件,如果收件人地址的人名部分在任何查询表、别名表、系统账户都查不出来,这个人即被视为“不明用户”。正常情况下,postfix会 拒收写给不明用户的信;如果你想收这类邮件,你可以将local_recipient_maps参数设成空,避免postfix拒收不明用户的邮件,然后 使用luser_relay参数将这类邮件集中到特定邮箱:
local_recipient_maps =
luser_relay = catchall
这里假设catchall是系统上的一个有效地址(别名或实际账户),可用与接收寄给不明用户的邮件。请注意,使用luser_relay有潜在的风险。 首先,你会因此而收到大量垃圾邮件。因为发送垃圾邮件者经常采用“字典攻击”,也就是将常见的人名与你的网域名称结合一起,企图蒙混过关。当你设定了 luser_relay之后,原本会被postfix挡掉的邮件,会全部都集中在你指定的邮箱中。另一个问题,如果不明邮件是因为寄件人打错字所造成的, 对方会误以为邮件已经顺利寄出,而没有发现错误的机会。这样你必须天天检查这些被拦截下来的邮件(包括大量烦人的垃圾邮件),并承担潜在的道德风险(私看 别人的邮件不是合法行为,除非得到授权)。
改变根目录(chroot)
postfix提供多层次的安全防护措施,其中一个层次是让你可将大部分的postfix服务局限在chroot环境下运作。chroot是unix操作 系统特有的一种安全措施,其作用是将进程环境的根目录,从平常的“/“改成文件系统上的另一个子目录,将进程的文件系统限制在该子目录下;也就是说,被 chroot的进程,无法访问该子目录之外的文件系统。
对于必须与外界通信的服务器进程而言,chroot特别有用,因为今日的Internet到处充斥着心怀不轨的人。这样,即使万一有人入侵了smtpd daemon,他顶多只能访问一小部分的文件系统,能够造成的损害非常有限,甚至无法从中获得任何好处。
不过,为postfix规划一个chroot环境是一件颇为复杂得工程,复杂到系统管理员通常不愿意面对。一般而言,chroot不是必要得,除非使用postfix得主机位于需要高度安全得环境中,或是位于必须暴露在外的服务器上,例如专用的防火墙与堡垒主机。
所有支持chroot的postfix进程,都可将它们的根目录改成queue_directory参数指定的子目录,这通常是/var/spool/postfix/pid目录,而且不能访问新根目录之外的文件系统。
除了pipe、virtual、local和proxymap之外的其他postfix服务器组件基本上都可以被chroot,只要将该组件在master.cf配置文件里的第五栏改成y即可。
既然chroot改变了服务器进程的文件系统的可视范围,我们就必须将进程所需的全部资源都放在新的根目录之下,这样被chroot的服务器进程才能顺利 运行。但是postfix daemons所需的资源因平台而异,这样很难逐一列出来说明。大体上,postfix需要能够访问账户信息(/etc/paswd)、DNS解析配置 (nsswitch.conf或resolv.conf)、时区信息或提供时间信息的函数库。某些平台还需要特定的设备文件。postfix包里随附了专 为不同平台而设计的脚步,在解压包的examples/chroot-setup/子目录下可以找到它们。
运行正确的脚步,应该足以为里的系统设置好chroot环境。如果没有适合里的平台的脚步,里可能要做一些小实验,才能备齐所有必要的资源。考虑先前提到 的那些资源,或是参考其他平台的脚步,应该对你有所帮助。实验时请留心观察日志文件,看看被你禁锢的进程发出了怎样的错误信息。比方说,如果你看到类似这 样的记录:
postfix/smtp(1575): fatal: unknown service: smtp/tcp
这个表示postfix无法判断smtp服务应该使用哪个通信端口,而问题可能是其无法在chroot环境下访问/etc/services文件所致,所 以,只要将该文件复制一份放在/var/spool/postfix/etc/services,问题或许就解决了。从错误尝试中学习看出症状背后所隐藏 的病因,也有助于累积实际管理经验。
如果平常的postfix日志提供了线索还不足以找出毛病,不妨提高服务器进程的“详细程度”(将-V加到服务器进程在master.cf里的命令行选 项),或者利用程序员常用的各种调试工具(例如truss、strace或tusc等)检查受测程序到底哪里停了下来。如果你发现失败原因是因为漏掉了某 个组件,那就将该组件复制到chroot环境下。关于如何利用调试工具来追踪postfix的运行情况,请参阅DEBUG_READMEW文件。
在chroot环境下运行的postfix系统,需要你多花一点心思维护,以保持平常环境的系统文件与chroot环境下的版本一致。举例来说,如果你的 chroot服务器进程需要/etc/passwd文件,那么,每当系统的/etc/passwd被改变,你就必须同步更新 /var/spool/posfix/etc/目录下的副本。创建文件链接的办法是行不通的,因为符号链接(symlink)无法进入chroot系统 (如果可以,那也不必chroot了),而硬链接无法进入文件系统。
在线说明书
原版postfix包随附了许多说明文件。如果你使用别人预先编译好的安装包(.rpm/.deb/.pkg等),这些文件不一定齐全,但是最基本的 manpage和配置文件样本应该都有。样本文件放在sample_directory参数指定的目录下(通常与main.cf位于同一个目录), postfix的所有参数都可以在这些样本文件里找到详细说明。
安装好postfix之后,在线说明书应该会安装在man能够自动找到的地方。要检查说明书的安装位置是否正确,只要直接下达man命令看看是否有效就可以了,例如
man postfix
如果你的系统没有显示说明书,而是出现类似这样的错误信息:
man postfix
no manual entry found for postfix
那表示你的说明书不是放错目录,就是当初根本没有安装它们。各个unix系统放置在线说明书的位置都不太一样,但是manpath环境变量应该可以给你一些线索。
postfix的各种命令行工具、查询表、daemon都有对应的在线说明,而且所有文件都有HTML版本。如果你的系统没有安装HTML文件,在 postfix的网站可以找到它们。在线说明文件永远能反映当前postfix版本的实况,如果你发现本书提供的信息不符合实际现况,记住,man就在你 身边。