m4 命令根据其自身的语法规则处理宏定义文件,而无需理解任何关于正确 sendmail 语法的内容;因此,如果您在宏定义文件中出现任何错误,都不会有任何错误消息。因此,彻底测试您的配置非常重要。幸运的是,sendmail 提供了一种相对简单的方法来执行此操作。
sendmail 支持“地址测试”模式,允许我们测试我们的配置并识别任何错误。在这种操作模式下,我们从命令行调用 sendmail,它会提示我们输入规则集规范和目标邮件地址。sendmail 然后使用指定的规则处理该目标地址,并在进行过程中显示每个重写规则的输出。要将 sendmail 置于此模式,我们使用以下命令调用它–bt参数
# /usr/sbin/sendmail -bt ADDRESS TEST MODE (ruleset 3 NOT automatically invoked) Enter <ruleset> <address> > |
使用的默认配置文件是/etc/mail/sendmail.cf文件;您可以使用–C参数指定备用配置文件。为了测试我们的配置,我们需要选择多个要处理的地址,这些地址将告诉我们是否满足了每个邮件处理要求。为了说明这一点,我们将完成对 示例 18-2 中所示的更复杂的 UUCP 配置的测试。
首先,我们将测试 sendmail 是否能够将邮件传递到系统上的本地用户。在这些测试中,我们期望所有地址都被重写为这台机器上的 local 邮件程序
# /usr/sbin/sendmail -bt ADDRESS TEST MODE (ruleset 3 NOT automatically invoked) Enter <ruleset> <address> > 3,0 isaac rewrite: ruleset 3 input: isaac rewrite: ruleset 96 input: isaac rewrite: ruleset 96 returns: isaac rewrite: ruleset 3 returns: isaac rewrite: ruleset 0 input: isaac rewrite: ruleset 199 input: isaac rewrite: ruleset 199 returns: isaac rewrite: ruleset 98 input: isaac rewrite: ruleset 98 returns: isaac rewrite: ruleset 198 input: isaac rewrite: ruleset 198 returns: $# local $: isaac rewrite: ruleset 0 returns: $# local $: isaac |
此输出向我们展示了 sendmail 如何处理寻址到此系统上 isaac 的邮件。每一行都向我们展示了已提供给规则集的信息或从规则集处理获得的结果。我们告诉 sendmail 我们希望使用规则集 3 和 0 来处理地址。规则集 0 是通常调用的规则集,我们强制使用规则集 3 是因为它默认情况下未经过测试。最后一行显示规则集 0 的结果确实将发送给 isaac 的邮件定向到 local 邮件程序。
接下来,我们将测试发送到我们的 SMTP 地址的邮件:isaac@vstout.vbrew.com。我们应该能够产生与上一个示例相同的最终结果
# /usr/sbin/sendmail -bt ADDRESS TEST MODE (ruleset 3 NOT automatically invoked) Enter <ruleset> <address> > 3,0 isaac@vstout.vbrew.com rewrite: ruleset 3 input: isaac @ vstout . vbrew . com rewrite: ruleset 96 input: isaac < @ vstout . vbrew . com > rewrite: ruleset 96 returns: isaac < @ vstout . vbrew . com . > rewrite: ruleset 3 returns: isaac < @ vstout . vbrew . com . > rewrite: ruleset 0 input: isaac < @ vstout . vbrew . com . > rewrite: ruleset 199 input: isaac < @ vstout . vbrew . com . > rewrite: ruleset 199 returns: isaac < @ vstout . vbrew . com . > rewrite: ruleset 98 input: isaac < @ vstout . vbrew . com . > rewrite: ruleset 98 returns: isaac < @ vstout . vbrew . com . > rewrite: ruleset 198 input: isaac < @ vstout . vbrew . com . > rewrite: ruleset 198 returns: $# local $: isaac rewrite: ruleset 0 returns: $# local $: isaac |
同样,此测试通过。接下来,我们将测试发送到我们的 UUCP 风格地址的邮件:vstout!isaac。
# /usr/sbin/sendmail -bt ADDRESS TEST MODE (ruleset 3 NOT automatically invoked) Enter <ruleset> <address> > 3,0 vstout!isaac rewrite: ruleset 3 input: vstout ! isaac rewrite: ruleset 96 input: isaac < @ vstout . UUCP > rewrite: ruleset 96 returns: isaac < @ vstout . vbrew . com . > rewrite: ruleset 3 returns: isaac < @ vstout . vbrew . com . > rewrite: ruleset 0 input: isaac < @ vstout . vbrew . com . > rewrite: ruleset 199 input: isaac < @ vstout . vbrew . com . > rewrite: ruleset 199 returns: isaac < @ vstout . vbrew . com . > rewrite: ruleset 98 input: isaac < @ vstout . vbrew . com . > rewrite: ruleset 98 returns: isaac < @ vstout . vbrew . com . > rewrite: ruleset 198 input: isaac < @ vstout . vbrew . com . > rewrite: ruleset 198 returns: $# local $: isaac rewrite: ruleset 0 returns: $# local $: isaac |
此测试也已通过。这些测试证实,无论地址的格式如何,为此机器上的本地用户接收的任何邮件都将被正确传递。如果您为您的机器定义了任何别名,例如虚拟主机,您应该为该主机已知的每个备用名称重复这些测试,以确保它们也能正常工作。
接下来,我们将测试发送到 vbrew.com 域中其他主机的邮件是否使用 SMTP 邮件程序直接传递到该主机
# /usr/sbin/sendmail -bt ADDRESS TEST MODE (ruleset 3 NOT automatically invoked) Enter <ruleset> <address> > 3,0 isaac@vale.vbrew.com rewrite: ruleset 3 input: isaac @ vale . vbrew . com rewrite: ruleset 96 input: isaac < @ vale . vbrew . com > rewrite: ruleset 96 returns: isaac < @ vale . vbrew . com . > rewrite: ruleset 3 returns: isaac < @ vale . vbrew . com . > rewrite: ruleset 0 input: isaac < @ vale . vbrew . com . > rewrite: ruleset 199 input: isaac < @ vale . vbrew . com . > rewrite: ruleset 199 returns: isaac < @ vale . vbrew . com . > rewrite: ruleset 98 input: isaac < @ vale . vbrew . com . > rewrite: ruleset 98 returns: isaac < @ vale . vbrew . com . > rewrite: ruleset 198 input: isaac < @ vale . vbrew . com . > rewrite: ruleset 198 returns: $# smtp $@ vale . vbrew . com . / $: isaac < @ vale . vbrew . com . > rewrite: ruleset 0 returns: $# smtp $@ vale . vbrew . com . / $: isaac < @ vale . vbrew . com . > |
我们可以看到此测试已将消息定向到 SMTP 邮件程序,以便直接转发到 vale.vbrew.com 主机,并指定用户 isaac。此测试证实我们的LOCAL_NET_CONFIG定义工作正常。为了使此测试成功,目标主机名必须能够被正确解析,因此它必须在我们的/etc/hosts文件或我们的本地 DNS 中有条目。我们可以看到如果目标主机名无法解析会发生什么,方法是故意指定一个未知主机
# /usr/sbin/sendmail -bt ADDRESS TEST MODE (ruleset 3 NOT automatically invoked) Enter <ruleset> <address> > 3,0 isaac@vXXXX.vbrew.com rewrite: ruleset 3 input: isaac @ vXXXX . vbrew . com rewrite: ruleset 96 input: isaac < @ vXXXX . vbrew . com > vXXXX.vbrew.com: Name server timeout rewrite: ruleset 96 returns: isaac < @ vXXXX . vbrew . com > rewrite: ruleset 3 returns: isaac < @ vXXXX . vbrew . com > == Ruleset 3,0 (3) status 75 rewrite: ruleset 0 input: isaac < @ vXXXX . vbrew . com > rewrite: ruleset 199 input: isaac < @ vXXXX . vbrew . com > rewrite: ruleset 199 returns: isaac < @ vXXXX . vbrew . com > rewrite: ruleset 98 input: isaac < @ vXXXX . vbrew . com > rewrite: ruleset 98 returns: isaac < @ vXXXX . vbrew . com > rewrite: ruleset 198 input: isaac < @ vXXXX . vbrew . com > rewrite: ruleset 95 input: < uucp-new : moria > isaac </ @ vXXXX . vbrew . com > rewrite: ruleset 95 returns: $# uucp-new $@ moria $: isaac </ @ vXXXX . vbrew . com > rewrite: ruleset 198 returns: $# uucp-new $@ moria $: isaac </ @ vXXXX . vbrew . com > rewrite: ruleset 0 returns: $# uucp-new $@ moria $: isaac </ @ vXXXX . vbrew . com > |
此结果非常不同。首先,规则集 3 返回一条错误消息,指示主机名无法解析。其次,我们通过依赖我们配置的另一个关键特性,即智能主机来处理这种情况。智能主机将处理任何其他无法投递的邮件。我们在本次测试中指定的主机名无法解析,规则集确定邮件应使用 uucp-new 邮件程序转发到我们的智能主机 moria。我们的智能主机可能连接更好,并且知道如何处理该地址。
我们的最终测试确保发送到我们域之外的任何主机的邮件都将传递到我们的智能主机。这应该产生与我们之前的示例类似的结果
# /usr/sbin/sendmail -bt ADDRESS TEST MODE (ruleset 3 NOT automatically invoked) Enter <ruleset> <address> > 3,0 isaac@linux.org.au rewrite: ruleset 3 input: isaac @ linux . org . au rewrite: ruleset 96 input: isaac < @ linux . org . au > rewrite: ruleset 96 returns: isaac < @ linux . org . au . > rewrite: ruleset 3 returns: isaac < @ linux . org . au . > rewrite: ruleset 0 input: isaac < @ linux . org . au . > rewrite: ruleset 199 input: isaac < @ linux . org . au . > rewrite: ruleset 199 returns: isaac < @ linux . org . au . > rewrite: ruleset 98 input: isaac < @ linux . org . au . > rewrite: ruleset 98 returns: isaac < @ linux . org . au . > rewrite: ruleset 198 input: isaac < @ linux . org . au . > rewrite: ruleset 95 input: < uucp-new : moria > isaac </ @ linux . org . au . > rewrite: ruleset 95 returns: $# uucp-new $@ moria $: isaac </ @ linux . org . au . > rewrite: ruleset 198 returns: $# uucp-new $@ moria $: isaac </ @ linux . org . au . > rewrite: ruleset 0 returns: $# uucp-new $@ moria $: isaac </ @ linux . org . au . > |
此测试的结果表明主机名已解析,并且消息仍将被路由到我们的智能主机。这证明我们的LOCAL_NET_CONFIG定义工作正常,并且它正确处理了这两种情况。此测试也已成功,因此我们可以欣然假设我们的配置是正确的并使用它。