免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1032 | 回复: 0
打印 上一主题 下一主题

sendmail配置 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-03-01 17:18 |只看该作者 |倒序浏览
用Linux作邮件服务器
在Internet上,E-mail是用户之间交往沟通的最佳方式。通过电子邮件,可以为Linux系统开拓新的空间,增强与外界的联系。已经证明,电子邮件是Internet上使用最多的应用程序,甚至比WWW的使用还要多。本章介绍如何为Linux系统安装、配置E-mail软件。
8.1   Linux E-mail软件简介
    Linux中的E-mail软件系统分为两大类:MUA(邮件用户代理)和MTA(邮件传送代理)。MUA的功能是为用户提供读写邮件的界面,而MTA的作用则是处理邮件的收发工作。换言之,用户可以通过MUA写信、读信,利用MTA收信、发信。
    最常用的电子邮件MTA系统是sendmail,它由加州大学开发,其最新版本是8.9;另一个常见的MTA程序是smail,它由Curt Noll和Ronald Karr联合开发,也已经发布了几个版本。
    值得注意的是,与其他大型软件包一样,sendmail也有自己的一些缺陷。虽然引起sendmail失败或系统崩溃的错误已基本上被排除,但提供root访问权限的安全性漏洞仍然时有发现。如果配置不当,sendmail有可能为“黑客”提供可乘之机。为了安全起见,用户最好定期访问计算机紧急反应小组(CERT,www.cert.org)的网页,加入它的邮递列表,或者阅读由它主持的网络讨论组(conp.security.announce)来了解由它发出的安全性通知。
    电子邮件的MUA系统目前很多,大约有十几种,其中最常见是:mail和elm。
    8.2  sendmail及其配置
本节介绍如何安装和配置sendmail程序,不过在开始深入研究这些详细内容之前,先介绍SMTP协议以及域名系统(DNS)对E-mail在Internet上传输的影响。
8.2.1 SMTP
    SMTP是简单邮件传输协议的简称,是Internet上传输邮件的既定标准方式。sendmail的基础协议正是SMTP。sendmail程序提供为Linux支持SMTP连接所需的服务。
    要了解sendmail所做的各种不同工作,需要掌握有关互联网协议的一些知识。所谓协议就是硬件和软件进行通信所遵守的标准。协议通常分为不同的层次,高层的协议利用低层的协议作为基础。例如,互联网协议(IP)在网络之间发送和接受数据包,但不必创建诸如SMTP和其他高层协议所使用的端到端(PPP)的连接;建立在IP之上的传输控制协议(TCP)提供了被Telnet和SMTP程序所使用的面向连接的服务;总而言之,TCP/IP为互联网提供了基本的网络服务,例如文件传输协议(FTP)和SMTP的高层协议,都建立在TCP/IP之上。协议分层的优点在于,执行SMTP或FTP协议的程序不必知道与传送数据包和连接其他主机有关的任何内容,因为它们可以使用TCP/IP提供的服务来完成。即执行高层协议的程序不必关心低层协议的具体细节。
    SMTP定义了在互联网上交换E-mail的方式,因此软件版本和硬件环境对交换邮件的程序来说并不重要,只要这两个程序都正确地执行SMTP协议,它们就可以交换邮件。
    下面介绍一个使用的SMTP协议的例子:位于somedomain.gov的用户li正在向位于otherdomain.com的zhang发送邮件。
        $ sendmail-v zhang@otherdomain.com>>HELO somedomain.gov
        250 otherdomain.com Hello somedomain.gov [123.45.67.2],pleased to meet you
        >>>MAIL From:〈li@somedomain.gov〉
        250〈li@somedomain.gov...Sender ok
        >>>RCPT To:〈zhang@otherdomain.com〉
        250〈zhang@otherdomain.com)...Recipient ok
        >>>DATA
        354 Enter mail,end with"." on a line by itself
        >>>.
        250 SAA08680 Message accepted for delivery
        >>>QUIT
        221 otherdomain.com closing connection
        zhang@otherdomain.com...Sent
        S
    上面的第一行是直接调用Sendmail的一种命令格式,而不是利用用户所喜欢的邮件用户代理MUA(例如elm或mail)来执行这一任务。这里-v选项告诉sendmail使用冗余模式显示SMTP对话。其余行显示的是SMTP客户机和服务器进行的交谈。以>>>开始的行表示的是位于somedomain.gov处的客户机(寄件人),紧跟其后的行是位于otherdomain.com处的服务器(收件人)的答复。以220开始的第一行是最初连接之后SMTP服务器对自己进行的声明,它给出了自己的主机名以及日期和时间;第二行用来告诉客户机该服务器能够理解扩充的SMTP协议(ESMTP),以便客户能够使用它。像220这样的号码是SMTP客户机同SMTP服务器用来通信的回复代码,跟随回复代码后面的文本才是真正的内容。
    如果想对这一对话有更深刻的了解,可以阅读参考文献RFC821。以-v选项运行sendmail
有助于用户理解SMTP对话的工作方式。
    像otherdomain.com这样的名字对于用户理解和记忆是十分方便,而计算机采用的却是像123.45.67.1这样的数字化的IP地址。幸运的是,域名系统(DNS)提供了主机名到IP地址的转化以及其他的重要信息。用户没有必要记忆主机的IP地址。
    DNS把对主机进行命名和编号的权限分配给自治管理的域,例如,一个称为otherdomain. com的公司可以维护自己域中主机的所有信息。当主机a.otherdomain.com想发送邮件或远程登录(Telnet)到主机b.otherdomain.com时,它会通过网络向otherdomain.com的域名服务器发送一个请示,域名服务器不妨假设是主机ns.otherdomain.com。域名服务器ns.otherdomain.com将把b.otherdomain.com的IP地址(可能还有其他信息)返回给a.otherdomain.com,这样邮件将被发送,或者Telnet将被连接。由于us.otherdomain.com对otherdomian.com域具有管理权,因此它能够回答对otherdomain.com中的主机的任何查询,不管这些查询发自哪里;另外,它还有对域中的主机进行命名的权力。
    现在,如果a.otherdomain.com上的某人想给zhang@ somedomain.gov发送邮件会怎么样呢?虽然us.otherdomain.com没有位于somedomain.gov域中的主机的有关信息,但是它却知道如何找到这一信息。当城名服务器收到它不具有此域信息的某个城中的主机的查询请示时,它便向根域名服务器(root nameserver)询问那个域中(在本例中是somedomain.gov)具有管理权限的域名服务器的名字和IP地址。根域名服务器将把对somedomain.gov具有管理权限的域名服务器的名字和IP地址提供给us.otherdomain.com。us.otherdomain.com域名服务器将询问它们并把回复转发给a.otherdomain.com。
    从上可知,DNS是一个包含主机名到IP地址映射的大型分布式数据库。另外,它还包含其他信息。当利用像。sendmail这样的程序投递邮件时,它必须把收件人的主机名转化为一个IP地址。这部分DNS数据被称为A(地址)记录,它是关于主机的最基本的数据。主机数据的另一部分是邮件交换器(MX)记录,像a.otherdomain.com主机的MX记录列出的是能够为它接收邮件的一个或多个主机。
    也许读者会问:MX记录的作用是什么?为什么a.otherdomain.com不简单地接收它自己邮件并处理这一过程呢?
    MX记录的作用如下:
    (1)通过MX,不在Internet上的主机(例如,只利用UUCP的用户)能够指定一个Internet主机来接收它们的邮件,从而使它们看起来就像具有Internet地址一样。例如,假定a.
otherdomain.com只是偶尔通过UUCP连接到ns.otherdomain.com。如果us.otherdomain.com为它发布一个MX记录,其他Internet主机就能够向它发送邮件。当ns.otherdomain.com收到邮件时,它把邮件保存起来,直到a.otherdomain.com同它连接。MX记录能够使非Internet主机也可以接收来自Internet的E-mail。
    (2)通过MX,使用仅有发送功能MUA客户程序的用户也能接受电于邮件。假设有一台充当一群PC机的文件服务器的UNIX主机pcserv.otherdomain.com。这些PC机都具有可以发送邮件但不能接收邮件的带有内置SATP客户程序的MUA。如果发往外地的邮件具有类似someone@pcl.otherdomain.com的回复地址,那么接收方如何回复信件呢?通过MX记录,问题便迎刃而解:用pcserv.otherdomain.com做为所有PC机的MX主机,寄向它们的邮件都将正确到达。
    (3)通过MX可以把用户的电子邮件存储起来。由于一些难以预料的原因,主机可能会长时间地离开Internet。虽然用户的主机离开了Internet,但发往它的邮件可能在其他主机上排队,当经过一段时间后邮件便返回给寄件人。如果用户的主机具有在中断时间里为它保存邮件的MX主机,那么在用户的主机重新启用后邮件将被投递。这些MX主机可以是站点内的(即在用户的域中),也可以是站点外的,或者两者都有。有条件的情况下,最好选择站点外的MX主机。因为某些事故通常会使用户的整个站点与网络断开,在这种情况下,站点内的MX主机也就毫无用处。
    (4)MX记录能够隐藏信息并使用户更灵活地重新配置自己的局域网。
收邮件的主机被命名为wang.otherdomain.com还是liang.otherdomain.com并不重要,用户的通信者不会知道其中的差别。
    当某个SMTP客户程序向某个主机投递邮件时,它并不只是把主机名转化为IP地址。客户程序首先查找MX记录。如果MX记录存在,它便按照记录中所提供的优先级对这些记录进行排序。例如,otherdomain.com或许就具有MX记录,这些记录把主机mailerl.otherdomain.com、mailer2.otherdomain.com和mailer3.somedomain.gov列为愿意为它们收邮件的主机。注意,“主机”otherdomain.com除作为一个MX记录外可能并不存在,即它没有一个可用的IP地址。虽然这些主机中的任何一个都将为otherdomain.com接受邮件,但MX的优先级确定了SMTP客户程序应首先尝试投递的主机。在这里,系统管理员实际上已经设置了一个主邮件服务器mailer1.otherdomain.com和一个站点内的备用邮件服务器mailer2.otherdomain.com,并且还与mailer3.somedomain.gov的管理员协商,把它作为站点外的一个备用邮件服务器。管理员通过设置MX的优先级,从而使SMTP客户程序将首先试用主邮件代收器,其次是站点内的备用邮件服务器,最后是站点外的备用邮件服务器。
    当收集和排序MX记录之后,SMTP客户程序把这些主机的IP地址聚集起来并按照它们的MX优先级的顺序向它们投递。当邮件传送出现问题时,应该清楚这样一个事实:若一封信被投递的地址是zhang@otherdomain.com,这并不能说明主机。otherdomain.com一定存在;即使这一主机存在,或许它也不是直接接收邮件的主机。
    另外,很有必要了解邮件头和信封地址之间的差别,因为邮件路由器处理它们的方式是
不同的。下面举例说明两者之间的差别。
    假定某个用户有一个便笺想寄给一些同事,他们分别是A公司的li和qiu以及B公司的zhang和wang吧。用户把便笺的一个副本交给了用户所信任的邮件收发员xie,他记录了所有的收件人。xie是个非常精明的人,他想为用户的公司节省邮费,因此把便笺复印了两份,然后把每份放进一个写有各自公司地址的信封里(而不是给每个收件人都发送一个副本)。在发往A公司的信封的封面上,他写有h和qiu的名字;在发往B公司的信封的封面上,写有zhang和wang。当xie在A公司和B公司的的同行收到这两个信封时,他们对便笺进行了复印并把它们分别送给了li、qiu和zhang、wang,而并不查看在便笺里面写的地址。对于A公司和B公司的邮件收发员来说,他们所关心的只是信封地址。
    上面的比喻说明了SMTP客户程序和服务程序的工作方式。假定zhang@somedomain.gov
向他的同事li@somedomain.gov和zeng@otherdomain.com发送邮件,信头部的收件人名单如下:
        To:li@somedomain.gov,zeng@otherdomain.com
    如果somedomain.gov的SMTP客户程序连接到。otherdomain.com邮件发送器来投递zeng的副本,当它准备列出收件人(信封地址)时,它该怎么处理呢?如果像上面To:行(邮件头地址)那样列出两个收件人,li将收到信件的两个副本,因为otherdomain.com的邮件发送器将向somedomain.gov转发一个副本。解决这一问题的方法是:somedomain.gov的SMTP客户程序把信件放在一个信封里,在此信封只包含一个主机上的收件人姓名,虽然所有收件人的名单仍然在信件的头部,但他们在信封之内,因此位于somedomain.gov和otherdomain.com处的SMTP服务程序也就看不到他们。在本例中,寄往otherdomain.com的信封将只列出zeng,寄往somedomain.gov的信封将只列出li。
    别名是说明邮件头和信封地址不同的另一个例子。假定要把邮件发送到别名为friends的人,friends包括的人名是Xie、zhang、li和qiu。在信中,用户写的是To:friends,然而。sendmail将扩展这一别名并构造一个包含所有收件人的信封。根据这些名字是否是别名,是否有可能在其他主机上,最初的消息将被装进四个不同的信封并投递到四个不同的主机。在每个信封上将只包含一个收件人的姓名,但在信头中包含的却是同一个别名friends。
    sendmail允许在命令行中指定收件人,假定有个名为letter的文件,其内容如下:
        To:null recipient〈 〉
        Subject:To show the differebce between in header and envelope addresses
        This is just a test for E-mail.
    利用下面的命令发送这一信件:
        $sendmail yourlogin〈letter
    即使用户的注册名没有在信件的头部,用户(yourlogin)也将会收到这一信件。因为用户的地址在信封上。除非以别的方式(例如利用-t标志)说明,否则sendmail将根据命令行上指定的收件人构造信封地址,而且邮件头地址和信封地址并不一定要相同。
    8.2.2  sendmail的安装与配置
    首先,必须获取sendmail源代码并进行编译。接着,必须选择同用户的站点需求相接近的sendmail.cf文件并对它进行必要的修改。然后,测试sendmail和它的配置文件。最后,必须安装sendmail、sendmail.cf以及其他辅助文件。
    上面所述的是基本步骤。但根据sendmail安装位置的不同,可能还需要修改系统登录脚本(/etc/init.d中的一个文件),从而使sendmail在系统引导下能够被正确地启动。此外,如果系统没有别名文件,还必须创建一个,别名文件通常被命名为/usr/lib/aliases或/etc/mail/aliases(别名文件的位置将在sendmail.cf中用到,因此可以把它放在用户想放的任何地方)。需要注意的是,可能还需要对系统的DNS数据库进行修改。
     1.获取源代码
    RedHat 6.1配备的是sendmail-8.9.3,从www.redhat.com站点上可以得到sendmail-8.9.3的RPM版本。sendmail的这一版本可以从http://www.sendmail.org站点得到,或者通过FTP从ftp://ftp.sendmail.org得到。
    注意:下载文件的确切名字依据V8 sendmail当前版本的不同而不同,当前的最新是版本8.9.3。另外,由于文件是被打包压缩的,因此在传输它们之前必须为FTP提供binary命令,即以二进制方式传输。还注意,应该使用自己完整的E-mail地址作为口令,例如username@somedomain.gov。
    2.解压源、解包并编译sendmail
    在获得了源代码后,必须把它打开。由于它是一个被压缩的tar映像文件,因此必须对它进行解压,然后从tar档案中抽取各个文件。假定文件存放在目录/usr/local/src下面。
        [root@lll src]# gzip -d sendmail-8.9.3.tar.gz
        [root@lll src]# tar -xvf sendmail-8.9.3.tar
    执行上述操作后,将产生子目录sendmail-8.9.3。接下来,运行cd和Is,查看这一源代码  目录中有哪些文件:
        [root@lll src]# cd sendmail-8.9.3/stc。
        [root@lll src]# ls
    Makefile     collect.c      macro.c      parseaddr.c     srvrsmtp.c
    Makefiles    conf.c         mailp.0      pathnames.h     stab.c
    READ_ME      conf.h         mailp.1      queue.c         stats.c
    TRACEFLAGS   convtime.c     mailstats.h  redcf.c         sysexits.c
    alias.c      daemon.c       main.c       recipient.c     sysexits.h
    aliases      deliver.c      makesendmail safefile.c      trace.c
    aliases.0    domain.c       map.c        savemail.c      udb.c
    aliases.5    envelope.c     mci.c        sendmail.0      useful.h
    arpadate.c   err.c          mime.c       sendmail.8      usersmtp.c
    cdefs.h      headers.c      newaliases.0 sendmail.h      util.c
    clock.c      ldap_map.h     newaliases.1 sendmail.hf     version.c
    现在可以准备编译sendmail了,但首先要阅读下面的文件,这些文件包含关于用户所下载的sendmail版本的最新消息。
        FAQ
        RELEASE-NOTES
        KNOWNBUGS
        READ_ME
    另外,还要注意doc/op子目录中的sendmail安装与操作指南(SIOG)。
    sendmail的安装过程非常简单。要编译新的sendmail版本,运行下面的命令即可。
        [root@lll src]# makesendmail
    在RedHat 6.x的2.2内核上,sendmail在编译时不会出现任何警告或错误。如果使用光盘上的RPM软件包文件,安装更简单。仅需执行下面的命令:
        [root@lll src]# rpm-ivh sendmail-8_9_3.rpm
    在安装新的sendmail时,一定要为被替换的所有文件创建一个备份,特别是原来的sendmail守护程序。如果新的sendmail不能正常工作,在排除新版本的故障时,将需要恢复原来的版本。
    要安装新版本的sendmail,首先利用下面的命令停止当前运行的守护进程:
        [root@lll src]#/etc/rc.d/init.d/sendmail.init stop
    然后把新的二进制文件拷贝到sendmail的正确位置:
        [root@lll src]# cp obj.Linux*/sendmail/usr/sbin/sendmail
    另外,还必须把新的手册页文件拷贝到正确位置:
        [root@lll src]# cp aliases.1/usr/man/man5/aliases.5
        [root@lll src]# cp mailq.0/usr/man/man1/mailq.1
        [root@lll src]# cp newaliases.0/usr/man/man1/newaliases.1
        [root@lll src]# cp sendmail.0/usr/man/man8/sendmail.8
    现在可以利用下面的命令重新启动新的sendmail守护进程:
        [root@lll src]# /etc/rc.d/init.d/sendmail/init start
    3.sendmail的别名文件
    sendmail依靠许多辅助文件来执行它的工作。最重要的文件是别名文件和配置文件Sendmail.cf。如果打算把sendmail作为SMTP服务程序运行(大多数站点都这么做),则应该安装SMTP的帮助文件sendmail.hf。这就是关于文件sendmail.st和sendmail.hf所需说明的内容。其他辅助文件包含在sendmail的安装和操作指南(Sendmail Internet and Operating Guide,简称SIOG)中。
    sendmail会检查收件人的地址是否为别名。例如,大部分Internet站点都设有一管理员地址Webmaster,遇到问题可以向他报告。然而大多数站点并没有这一名字的实际账号,而是把Webmaster的邮件转移到负责邮件管理的一个或几个人。例如,在假设的站点somedomain.gov上,用户zhang和li共同负责网站管理,因此别名文件会具有下面一项内容:
        Webmaster:zhang,li
这行代码告诉sendmail,寄向Webmaster的邮件将被改寄到用户名为zhang和li处。事实上,这些名字还可以是别名,例如:
        Webmaster:firstgroup,secondgroup,thirdgroup
        firstgroup:zhang,li
        secondgroup:liu,deng
        thirdgroup:qiu,wang
    在所有这些例子中,别名的名字在冒号的左边,这些名字所代替的真实名字在冒号的右边。sendmail将反复地分析别名直到他们被解析为一个真正的用户或一个远程地址为止。在前面的例子中,要解析别名Webrmaster,sendmail首先把它扩展为收件人名单firstgroup、secondgroup和thirdgroup。然后进一步扩展这些别名中的每一个,从而得到最终的名单——zhang、li、liu、deng、qiu和wang。
    需要指出的是,别名的右边可以指定为一个远程主机,但左边却不能。别名zhang:zhang@otherdomain.com是合法的,而zhang@otherdomain.gov@otherdomain.com是不合法的。
    别名可用于创建邮递列表(mailing list)。在上面的例子中,别名Webmaster实际上就是一个本地邮件管理员的邮递列表。对于大型的或是经常改动的名单,可以利用:include的别名形式指示sendmail从文件中来读取名单的成员。如果别名文件包含行
        friends::include:/home/zhang/friends.aliases
并且文件/home/zhang/friends.aliases包含
        zhang
        li
        liu
        deng
    其效果与下面的别名相同:
        friends:zhang,li,liu,deng
    这一指令对于经常变动的邮递列表或哪些由用户而非邮件管理员管理的邮递列表非常方便。如果经常要求改变邮件别名,用户一般希望把它置于自己的控制之下。
    别名文件也可被用于向某个程序发送邮件的内容。例如,许多邮递列表的设立使用户可以获取所列的信息或通过向某一特定地址list-request发送信件来订阅信息。这种信件的主体通常只包含一个单词,比如help或subscribe等。假设zhang的邮递列表具有名为zhang-request的一个地址:
        zhang-request:|/usr/local/lib/auto-zhang-reply
    上面表达式的管道号(|)通知sendmail使用程序的邮件发送器,它通常被定义为/bin/sh。sendmail将把信息提供给/usr/local/lib/auto-zhag-reply的标准输入,如果它存在,sendmail便考虑投递信件。
    用户还可以创建一个使sendmail向文件发送邮件的别名。下面是别名nobody的一个例子,它在运行NFS的系统上是经常用到:
          nobody:/dev/null
指定文件的别名让sendmail把它的消息追加到被指定的文件中。由于这一特殊的文件/dev/null是Linux/UNIX的“黑洞”,因此这一别名的作用其实是把邮件清除掉。
4.配置sendmail
    sendmail是通过sendmail.cf文件来配置的。这个文件通常在目录/etc下面(有些系统是在/etc/lib目录下)。sendmail.cf文件使用的语法与其他配置文件不同,而且比较复杂。    配置文件的每一行都以一个单一的命令字符开头,这一字符用来说明这一行的功能和语法。以#开始的行是注释行;空行被忽略;以空格或制表符开始的行是上一行的续行,不过通常应该尽量避免续行。
    下面介绍命令字符及它们的功能。
    (1)#  注释符,以#开始的行是注释行。例如:
          # This file is a sample for sendmail.cf
    (2)D  使用格式为:DX string。其功能是把宏X定义为字符串string,例如:
            DM mail.somedomain.gov
    (3)C  使用格式为:CX word1、word2。其功能是把类X定义为wor1、word2。例如:
          Cw localhost my_host
    (4)F  使用格式为:FX/file。其功能是把类X定义为从文件中读取的值。例如:
          Fw/etc/hosts
    (5)H  使用格式为:H?mailerflag?name:template。其功能是定义邮件头。例如:
          H?F?From:\ $ q   
    (6)O  使用格式为:OX option arguments。其功能是设置选X,例如:
          OL8# sets the log level to 8
    (7)P  使用格式为:Pclass=n。其功能是根据邮件的类来设置邮件投递的优先级。例如:
          Pjunk=100
    (8)V  使用格式为:Vn。其功能是把配置文件的版本级别通知给V8 sendmail。例如:
          V3
    (9)K  使用格式为:Kname class arguments。其功能是定义一个关键字文件(数据库映像)。例如:
          Kuucphosts dbm/etc/uuphosts
    (10)M  使用格式为:Mname,f1=v1,...。其功能是定义一个邮件发送器。例如:
          Mpop,P=/bin/sh,F=lsD,A=sh-c $ u
    (11)S  使用格式为:Sun。其功能是开始一个新的规则集。例如:
            S22
    (12)R  使用格式为:Rlhs rhs comment。其功能是定义一个匹配/改写规则。例如:
        R $ + $>jg call ruleset jg
    上面简要地列出操作符的类型,现在对它们进行详细介绍。
    · D操作符
    宏类似于shell变量,当为一个宏定义了值后,可以在配置文件的后面对它进行引用,宏将会被它的值所取代。例如,一个配置文件可能有多个行包含假设的邮件中心mailer.somedomain.gov,为了避免一次次地输入这一名字,可以像下面这样为它定义一个宏R(代表中继邮件发送器):
        DRmailer.somedomain.gov
    当sendmail在sendmail.cf中遇到$ R时,sendmail将把它替换为字符串mailer.somedomain.gov。
    宏的名字通常是一个单字符。sendmail定义有许多宏,这些宏不应该被再次定义,否则将会出现一些问题。sendmail使用小写字母来定义自己的宏;大写字母可以被自由地使用。
    · C和F操作符
    类与宏类似,但是在改写规则中用于不同目的。与宏一样,类的名字也是一个单字符,小写字母由sendmail使用,大写字母用于由用户定义的类。一个类包含有一个或多个单词。例如,可以像下面这样定义一个包含本地域中所有主机的类H:
        CH host1 host2 host3
    为了方便起见,大型的类可以续行定义。下面对类H的定义与前面定义的结果相同:
        CH host1
        CH host2
        CH host3
    另外,还可以通过从某个文件中读取它的单词来定义一个类:
        CF/usr/usr/localhosts
    如果/usr/localhosts文件包含host1、host2和host3,并且是每行包含一个,那么这一定义与前面的两个定义等价。
    使用宏和类最主要的优点是它们可以集中配置文件中信息。在上面的例子中,如果决定把邮件中心由mailer.somedomain.gov改变为mail1.somedomain.gov,只需要改变宏$ R的定义就可以了,配置文件仅需作很少的改动。否则名字mailer.somedomain.gov散布在文件的各处,那么可能会在某些位置忘记对它们进行修改。另外,集中的重要信息,可以在单独的一个位置详细地对它进行注释。由于配置文件一般比较难于理解,因此如果很长一段时间之后对自己所做的某种修改感到迷惑时,在配置文件中添加详细的注释是很有帮助的。
    · H操作符
    一般情况下,不需要对V8 sendmail的配置文件所提供的邮件头进行修改,因为它们已经遵从了公认的标准。下面是一些邮件头的示例:
        H? D? Date:$ a
        H? F? Resent-From:$ q
        H? F? From:$ q
        H? x? Full-Nnme:$ x
    可以看出,在邮件头的定义中可以使用宏。当插入到某封信中时,这些宏将被扩充,由它相应的值取代。例如,在上面的例子中,用于邮件头定义Full-Name:中的宏$ x将被取代为寄件人的全名。在邮件头的定义中,可选的?mailerflag?结构用来通知sendmail只有在被选择的邮件发送器具有这一邮件发送器标志时才插入邮件头。
    假如在用户的本地邮件发送器的定义中具有一个标志Q,并且sendmail选择了这一邮件发送器来投递某一信件,如果配置文件包含一个像下面这样的邮件头定义,那么sendmail将把这一邮件头插入到通过本地邮件发送器被传递的信件中,并利用相应的值来取代宏$ F:
        H? Q? It-is-a-wonderful-day:$ F
    为什么要使用?mailerflag这一特性呢?这是因为不同的协议可能会需要不同的邮件头。另外,由于它们也需要不同的邮件发送器,因此可以通过在邮件发送器定义中定义相应的邮件发送器标志并使用邮件头定义中的?mailerflag?结构,来通知sendmail是否要插入相应的邮件头。
    ·0操作符
    sendmail具有许多选项,这些选项用来改变sendmail的操作或者用来通知所使用的文件的位置。大部分选项既可以通过命令行提供,也可以在配置文件中给出。例如,用户既可以在命令行也可以在配置文件中指定别名文件的位置;要是在命令行上指定别名文件,可以使用-o选项:
        $ sendmail-oA/etc/aliases[other arguments...]
要是在配置文件指定别名文件,可在配置文件中添加如下一行代码:
        OA/etc/aliases
    这两种方法是等价的。但由于像别名文件的位置这种选项很少改变,因此人们通常在配置文件sendmail.cf中设置它们。V8 sendmail的所有选项在SIOG中有详细的说明。
    ·P操作符
    用户可以在邮件中包含用来指示邮件的相对重要性的标题,sendmail可以根据这些标题来确定信件的优先级。假设为V8 sendmail提供的优先级如下:
        Pemergent=100
        Pimportant=0
        Pnormal=-30
    如果用户在他们的信息中含有标题Drecedence:normal,那么sendmail为这些邮件提供的优先级要低于利用标题Precedence:importangt的邮件。
    ·V操作符
    随着V8 sendmail的发展,许多Linux爱好者不断地为它添加新的特性。 V操作符能够使V8 sendmail知道在配置文件中它可以找到哪些特性。老版本的sendmail不能够识别这一命令。在SIOG中,对配置文件的版本级别有详细的说明。
    注意:配置文件的版本级别与sendmail的版本级别并不是一回事。V8 sendmail能够理解从版本1到5的配置文件,而版本8的配置文件并不存在。
    ·K操作符
    sendmail使用了一些关键字数据库,例如别名数据库。假如给定了关键词Webmaster,sendmail将查找与这一关键词相关的数据,V8 sendmail把这一概念扩充为任意的数据库,包括NIS mps(Sun的网络信息服务,以前称为Yellow Pages或YP)。K操作符可用来向sendmail通知数据库的位置、类别以及访问方法。V8 sendmail支持的数据库类别有:dbm、btree、hash和NIS。当在Linux下编译时,使用的缺省类别是dbm格式。
    · M操作符
    前面已经介绍,邮件发送器或者是MTA或者是最终投递代理。针对每种目标,可以定义一个专门的邮件发送器。即使SMTP,MTA被内置,它也必须有一个邮件发送器定义来定制sendmail的SMTP操作。邮件发送器的定义是很重要的,因为所有收件人的地址必须在0号规则集中解析到一个邮件发送器。解析到本地邮件发送器将通过定义在其中的最终投递代理(例如/bin/mail)把信件发送给某个本地用户,解析到SMTP邮件发送器将通过定义在其中的sendmail固有的SMTP传输器把信件发送给另一个主机。下面将介绍一个定义邮件发送器的具体例子,由于sendmail需要一个本地邮件发送器,因此给出下面的例子:
        Mlocal,P=/bin/mail,F=lsDFMfSn,S=10,R=20, A=mail-d$u
    所有邮件发送器的定义都以M操作符和邮件发送器的名字开头(在本例中是local),其他字段在后面并且分别由逗号隔开。每个字段由字段名和它的值组成,字段名和它的值之间由等号(=)隔开,允许使用的字段在SIOG中有详细的说明。在上面本地邮件发送器的定义中,P=用来提供投递邮件的程序所处位置的路径名/bin/mail,字段F=用来为本地邮件发送器提供sendmail标志。这些标志并不是要传递给字段P=中所指定的命令,而是由sendmail用来根据它所选择的邮件发送器来修改自己的操作。例如,sendmail通常在调用邮件发送器之前放弃它的超级用户身份,但可以利用S邮件发送器标志通知sendmail为某些邮件发送器保持这一身份。
    字段S=和R=用来为sendmail指定在改写寄件人和收件人地址时用到的规则集。由于可以为所定义的每个邮件发送器提供不同的R=和S=标志,因此可以针对每个邮件发送器的不同特点来改写地址。例如,如果用户的UUCP邻居运行的是一个不理解域寻址的陈旧软件,就需要专门为他的站点说明一个特殊的邮件发送器,并编写针对特殊邮件发送器的规则集,从而把地址转化为它的邮件发送器能够理解的形式。S=和R=字段还可以指定用来改写信封和邮件头地址的各种规则集,像S=21/31这种表达式将通知sendmail利用21号规则集改写寄件人的信封地址,利用31号规则集改写寄件人的邮件头地址。这一功能对于要求不同地显示信封地址和邮件头地址的邮件发送器是很有用的。
    A=字段用来为被运行的程序(在本例中是/bin/mail)提供变量向量(命令行)。在这一例子中,sendmail将运行命令mail-d $ u,其中的宏$ u将被替换为被投递的用户名:
        /bin/mail-d zhang
    用户可以在命令提示符下把与此完全相同的命令输人到shell中。
    另外,还可以使用其他邮件发送器标志来调节邮件发送器。例如,可以根据不同的邮件发送器限制信息的最大尺寸。
    · S和R操作符
    配置文件sendlnail.cf由一系列规则集组成。规则集用来探测错误的地址,把地址改写为远程邮件发送器能够理解的形式,以及把邮件路由到sendmail内部的某个邮件发送器。sendmail按照固有的顺序向规则集传送地址,而规则集可以不按固有顺序调用其他规则集。固有顺序与处理的邮件地址以及选择用来投递信件的邮件发送器有关。
    规则集由S命令宣布,跟在它后面的是用来标识规则集的编号。sendmail将收集下面的R(规则)行,直到它发现另一个S操作符或配置文件的结尾为止。下面的例子定义了编号为11的规则集:
        #  Ruleset 11
        S11
        R $+$:$>22$ I call ruleset 22
    sendmail分三种途径来处理地址:一种用来选择投递代理,一种用来处理寄件人地址,一种用于处理收件人地址。
    所有邮件地址首先被传送到3号规则集进行预处理从而变为规范的形式,以便其他规则集能够容易地处理它们。不论地址多么复杂,3号规则集的任务是确定某个邮件应该被发送到的下一个主机,3号规则集将尽力在地址中查找那一主机并利用尖括号来标记它。例如,在一种最简单的情况下,一个像zhang@somedomain.gov这样的地址将变为znahg。接下来,0号规则集将确定用于每个收件人的正确的投递代理(邮件发送器)。例如,一封由li@othedomain.com发给zhang@somedomain.gov(一个Internet站点)和posthost!zhao(一个老式的UUCP站点)的信件需要两个不同的邮件发送器:一个用于somedomain.gov的SMTP邮件发送器,一个用于posthost的老式UUCP邮件发送器。邮件发送器的选择决定以后对寄件和收件人的地址进行处理的方式。因为提供在“S=”和“R=”邮件发送器标志中的规则集根据邮件发送器的不同而不同。
    经过0号规则集的地址必须解析到一个邮件发送器。因此,当某个地址匹配lhs时,rhs将提供一个由邮件发送器、用户和主机组成的三元组。下面这行代码表示的是解析到某个邮件发送器的规则的语法:
        Rlhs $ # mailer $ @host $:user some comment here...
    上面的mailer是利用M命令定义的一个邮件发送器的名字,例如SMTP。host和user通常是来自lhs的位置宏。
    当sendmail在0号规则集中选择了一个邮件发送器后,它将通过1号规则集(通常是空的)来处理寄件人的地址,然后把它们发送到由这个邮件发送器中的S=标志所提供的规则集。
    类似地,sendmail将把收件人的地址发送到2号规则集(通常也是空的)中进行处理,然后再把它们发送到邮件发送器的标志R=所提供的规则集。
    最后,sendmail将在4号规则集中对所有地址进行后处理。4号规则集将把在3号规则集中插入的尖括号删除。
    为什么不同的邮件发送器具有不同的S=和R=标志呢?考虑前面向zhang@somedomain.gov和posthost!zhao发送信件的例子。如果li@othedomain.com发送邮件,它必须针对每个收件人以不同的形式出现。对于zhang,它应该是一个域地址li@otherdomain.com;对于zhao,由于otherdomain.com希望老式的UUCP地址(假设它具有一个连向posthost的UUCP链接并且otherdomain.com的UUCP主机名是posthost),因此返回地址应该是otherdomain!li。zhang的地址也必须为posthost的UUCP邮件发送器进行改写,并且zhang的副本必须包括他的邮件发送器可以处理的posthost的地址。
    当sendmail把一个地址传递给某个规则集后,规则集中的每一个规则行将逐行地对它进行处理。如果某个规则行的lhs与地址相匹配,地址将被Ihs改写;如果它不匹配,sendmail将继续到下一个规则,直到达到规则集的末尾为止。在规则集的最后,sendmail将把被改写的地址返回给调用规则集的规则集或是固有执行顺序的下一个规则集。
如果某个地址与lhs相匹配并且被rhs改写,这一规则将再次被调用——一个隐式循环。
    如前面介绍,每一个改写规则都由R命令引人并且具有三个字段——左端(lhs或匹配端)、右端(rhs或改写端)以及可选的注释,各个字段之间必须由制表符隔开:
        Rlhs rhs coment
    sendmail将把地址和规则的lhs解析成标记,然后再逐个标记地把地址和lhs进行比较。宏$o包含sendmail用来把地址分隔成标记的字符,它通常具有如下的定义:
        #address delimiter characters
        Do.:%@!^/[]
    $o中的所有字符,既是标记分隔符,又是标记。sendmail获取像xie@rainbow.org这样的地址,然后根据宏o中的字符把它分解成多个标记,就像下面这样:
       “xie”“@”“rainbow”“.”“org”
    sendmail也把改写规则lhs分解为标记,从而使它们可以同输人的地址一个个地相比较,以确定是否匹配。例如,lhs $ -@rainbow.org分解后的内容如下:
        $-”“@”“rainbow”“.”“org”
    其中“$-”是一个模式匹配操作符,类似于shell通配符,它用来匹配任何单一的标记符。现在可以把两组标记放在一起来揭示sendmail如何确定一个地址是否与规则的lhs相匹配。
        “xie”“@”“rainbow”“.”“org”
        “$”“@”“rainbow”“.”“org”
    在此例中,由于来自地址的每个标记都匹配一个常量字符串(例如rainbow)或一个模式匹配操作符($-),因此地址和lhs相匹配并且sendmail将使用rhs来改写这一地址。接下来,考查一个改变$o值的效果。sendmail把地址xie@rainbow.org分解为五个标记;然而,如果@字符不在$o中,这一地址将完全不同地被分解为三个标记:
        “xie@rainbow”“.”“org”
    由此看来,改变$o将对sendmail的地址解析产生极大的影响。因此除非用户对自己所做的事情非常有把握,否则应该保持它的原状。
    · 规则的左端(lhs)
    lhs是sendmail用来与输入地址进行对比的模式,lhs既可以包含普通的文本,又可以包含任何模式匹配操作符。
    lhs的模式匹配操作符主要包括:$-(匹配一个标记)、$+(匹配一个或多个标记)、$ *(匹配零个或多个标记)、$@(匹配空的输入,用来调用错误邮件发送器)。
    在lhs中,还可以利用下列宏和类的匹配操作符:$ X(匹配宏X的值)、$=C(匹配类C中的任何一个词)、$~C(匹配不属于类C的任何一个标记)。
    模式匹配操作符以及宏和类的匹配操作符是十分必要的,因为大多数规则必须匹配许多不同的输入地址。例如,某个规则可能需要匹配所有以somedomain.gov结尾、以一个或多个其他任何内容开头的地址。
    · 规则的右端(rhs)
    rhs是改写规则,其作用是通知sendmail如何来改写一个与lhs相匹配的地址。lhs可以包含文本、宏及对匹配内容在lhs中的位置把它匹配的内容赋值给一个数字宏$ n。例如,假设地址zhang@hostl.somedomain.gov被传递给下面的规则:
        R $+@$+$:$1<@ $ 2>foucus on domain
    在此例中,由于zhang与$+(一个或多个任何内容的标记)相匹配,因此sendmail将字符串zhang赋值给$ l;地址中的@与lhs中的@相匹配,但常量字符串不被赋值给位置宏;字符串hostl.somedomain.gov中的标记与第二个$十相匹配,因此它被赋值给了$ 2。这样被改写后的地址是$ l<@$ 2>,也就是zhang。
    现在考查下面的这条规则:
        R $ * $:$ 1add local domain
    当在rhs改写一个地址后,sendmail将把改写过的地址再与当前规则的lhs相对比。在本例中,由于$*可以与0个或多个任何内容的标记相匹配,因此无论rhs如何改写地址,它将始终与$ *相匹配,因此这一匹配规则将无限制地循环下去。为了避免sendmail在这条规则上进人死循环,引用了$:,它用来通知sendmail只对这一规则使用一次。
    当希望一个规则集立即终止并把地址返回给调用这一规则集的规则集或sendmail固有顺序中的下一个规则集时,可以在规则的rhs之前添加$@,它将使sendmail在rhs改写地址之后立即退出这一规则集。
    一个规则集可以通过在rhs前面添加$>向另一个规则集传递地址,考查下面这一条规则:
        R $ * $:$>22 $ 1 call ruleset 22
rhs的$ *匹配零个或多个标记,因此sendmail将不断地执行rhs,但由于在rhs前具有$:,所以这一规则只被使用一次。在这一规则中,$>22 $ 1 将以 $ 1 为输入地址调用22号规则集。由于$ 1匹配的内容正是lhs中的内容,因此这一条规则只是把当前的输入地址原封不动地传递给22号规则集。22号规则集返回的任何内容都将传递给这一规则集中的下一条规则。
8.2.3  测试sendmail
    在安装一个新的或经过修改的sendmail.cf之前,必须对它进行彻底的测试,因为即使是很小的、看起来不会造成危害的修改也可能会导致严重的后果。
    测试的第一步是创建一些地址,这些地址应该是用户的站点需要用到的有效地址。例如,在没有UUCP连接Internet站点somedomain.gov处,下面的地址有效。
        zhang
        zhang@host1.somedomain.gov
        znang@somedomain.gov
    即使somdomain.gov具有一个UUCP连接,也应该测试这些地址。其他一些需要考虑的地址包括各种别名(例如,Webmaster,include:列表,用来向文件邮寄的别名,用来向程序邮寄的别名)、非本地地址、源路由地址等等。
    当创建好测试地址的列表后,可以使用-C和-bt选项来查看将要发生的情况。这些地址至少应该被传递3号规则集和0号规则集,从而确定它们是否能够被路由到正确的邮件发送器。完成这一任务的比较简单的方法是,创建一个包含被调用的规则集以及测试地址的文件,然后对它执行sendmail。例如,如果文件sdml.test包含下面的行:
        3,0 zhang
        3,0 zhang@hostl.somedomain.gov
        3,0 zhang@somedomain.gov
那么,可以通过输入下面的命令来测试配置文件test.cf:
        $ sendmail-Ctest.cf-bt

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/6816/showart_79872.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP