服务器 频道

用Linux作邮件服务器

  【IT168 服务器学院】在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<letter

        zhang@otherdonain.com...Connecting to otherdomain.com via top...

        Trying 123.45.67.1...connected

        220-otherdomain.com SMTP ready at Sun,14 Nov 1999 18:56:22-0500

        220 ESMTP spoken here

        >>>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的“黑洞”,因此这一别名的作用其实是把邮件清除掉。

0
相关文章