BBS水木清华站∶精华区

发信人: ruster (尘埃*星辰*领悟), 信区: Linux        
标  题: 第七章 电子邮件(下) 
发信站: BBS 水木清华站 (Thu Dec 21 13:46:07 2000) 
 
 
7.4 qmail 
   
  sendmail的功能是足够强大的,然而它的配置和管理也是十分复杂的。有另一个也很 
常用的邮件服务程序称为qmail。 
   
  需要注意的是,许多人认为qmail要比sendmail简单一些。就笔者个人的感觉,不能同 
意这种说法。但是,qmail在配置一些稀奇古怪的功能方面确实比sendmail要稍微容易一 
些。另外qmail与sendmail不同之处在于,缺省的时候qmail将在用户的宿主目录中存储 
邮件,而不是像sendmail那样不分青红皂白地放在/var/spool/mail下面,并且qmail不 
需要使用文件锁定,所以可以把用户邮件放在NFS服务器上,这样,可以使用多台服务器 
来提供服务。对于大型邮件系统这是很重要的。(在sendmail也可以这样做,但必须非 
常小心以免造成邮件丢失)。但是这个功能虽然不错,却又产生了一些十分讨厌的后果 
。对于大型的ISP,qmail也很重要,它可以简化虚拟域的设置。我们将试图介绍如何用 
qmail构造一个邮件服务器。当然,这里的介绍不可能像介绍sendmail那样细致,如果要 
使用一些比较高级的功能,你也许必须研究qmail的文档。 
   
  7.4.1 下载和编译附加文件 
   
  通常我们很少会向读者提出“去某个地方下载xxx软件”,因为这些软件一般从某些大 
的ftp站台上要比从发布者那里下载容易的多。不过,qmail的安装需要一大堆稀奇古怪 
的东西,而且还都不大。因此,我们这里建议你下载全部的qmail附加工具。为了我们这 
里讲的内容,你需要下载下面这些软件: 
   
  ①qmail 
   
   这个是主程序,可以到http://koobera.math.uic.edu/www/qmail.html去下载,那里 
还有一个qmail分析程序,不过说实话从Linux发行光盘上或者专门的ftp站得到它会容易 
一些。 
   
  ②ucspi-tcp 
   
  可以到ftp://koobera.math.uic.edu/www/ucspi-tcp.html 去下载,对我们来说主要 
是利用它的TCP包装功能。 
   
  ③checkpassword 
   
  一个用来校验pop3用户口令的工具,可以到http://pobox.com/~djb/checkpwd.html去 
下载。 
   
  另外,如果要强化功能,在qmail的主页上还可以看到一些相关的工具,你可以自己去 
下载研究一下。 
   
  接下来,需要编译uscpi-tcp和chheckpassword,其中uscpi-tcp的编译需要用一个参 
数,例如,展开的uscpi-tcp源代码位于ucspi-tcp-0.84: 
   
  $cd ucspi-tcp-0.84 
   
  $make setup check 
   
  将生成tcpserver、tcprules程序和一个安装程序,执行安装程序 
   
  $./install 
   
  将会完成安装,缺省的安装目录是/usr/local/bin。 
   
  编译checkpassword程序则比较简单,只要进入源代码的目录,执行一下make程序,然 
后把文件拷贝到合适的地方就行了,我们假设tcpserver和tcprules安装在/usr/local/ 
bin下,checkpassword安装在/bin下。 
   
  7.4.2 安装qmail 
   
  安装qmail要比安装sendmail繁琐,我们把它分成几个段落来解释: 
   
  建立用户和编译 
   
  安装qmail本身不算复杂,但是需要建立多个用户,我们假设使用的是qmail 1.03,它 
要求建立6个用户和两个用户组,这可以使用下面的命令: 
   
  $ groupadd nofiles 
   
  $ useradd -g nofiles -d /var/qmail/alias -s /bin/false alias 
   
  $ useradd -g nofiles -d /var/qmail -s /bin/false qmaild 
   
  $ useradd -g nofiles -d /var/qmail -s /bin/false qmaill 
   
  $ useradd -g nofiles -d /var/qmail -s /bin/false qmailp 
   
  $ groupadd qmail 
   
  $ useradd -g qmail -d /var/qmail -s /bin/false qmailq 
   
  $ useradd -g qmail -d /var/qmail -s /bin/false qmailr 
   
  $ useradd -g qmail -d /var/qmail -s /bin/false qmails 
   
  然后可以编译安装qmail,假设qmail源代码在qmail-1.03下: 
   
  $cd qmail-1.03 
   
  $make setup check 
   
  这个动作将编译qmail源代码并且建立一个/avr/qmail目录,接下来,你需要建立qma 
il运行所需要的基本配置: 
   
  $./config 
   
  如果你的DNS查询已经正常了,本机器的域名也正确,这就是你需要的命令,否则,参 
考qmail的安装文档。 
   
  下一步你需要创建用户别名,要注意qmail的用法有些怪异,它会忽略任何发往root的 
邮件,因此除非你建立了一个root用户的邮件别名,否则你无法接受到那些发送给root 
的邮件。 
   
  邮件别名的用法是这样:对于任何一个用户,定义其别名的办法是在/var/qmail/ali 
as下面建立一个文件,文件名是".qmail-"加上用户名。例如,想建立root用户的别名, 
让发到root的邮件转移到supervisor用户,你需要建立的是/var/qmail/.qmail-root, 
属性设置为644,而内容就是简单地写上一行supervisor就可以了。一般你需要建立root, 
和postmaster,mailer-daemon的别名 
 
   
  替换sendmail 
   
  有些程序会直接在命令行上使用sendmail来发送电子邮件,最典型的是UNIX的mail程 
序。如果你使用的是qmail,显然你需要替换掉原来的sendmail。qmail提供了一个用来 
从命令行调用的程序,你可以用它替换掉原来的sendmail: 
   
  mv /usr/sbin/sendmail /usr/sbin/srndmail.backup 
   
  mv /usr/lib/sendmail /usr/lib/sendmail.backup 
   
  ln –s /var/qmail/bin/sendmail /usr/sbin/sendmail 
   
  ln –s /var/qmail/bin/sendmail /usr/lib/sendmail 
   
  使用/usr/lib是因为有些系统将sendmail放在/usr/lib目录下面。 
   
  启动本地投递 
   
  接下来的任务是启动局部递送,这个功能用来在本地用户之间转发邮件,以及接受由 
smtp服务器传送来的信息。它的工作其实就把信件存储到用户宿主目录下的Mailbox文件 
里面。通常这是通过一个名叫/var/qmail/boot/home的脚本来完成的,不过一般情况下 
我们把它拷贝出来: 
   
  $ cp /var/qmail/boot/home /var/qmail/rc 
   
  然后执行拷贝版本,这个脚本是csh的,可以直接在csh或者bash下执行: 
   
  $ rc & 
   
  然后你就可以实验一下在本机的用户之间发送邮件了,注意接受到的邮件都存放在用 
户目录下的Mailbox文件里面。 
   
  为了pop3服务的需要,qmail一般在用户的目录下面建立一个Maildir目录专门存放邮 
件,例如,要给用户wanghy建立邮件目录,首先以wanghy用户名登录系统,然后使用命 
令: 
   
  $ /var/qmail/bin/maildirmake $HOME/Maildir 
   
  $ echo ./Maildir/ > ~/.qmail 
   
  每个邮件用户都必须执行一次,这个过程很烦,而且实际操作也就是建立一个目录和 
它的子目录以及一个说明文件.qmail。所以更好的办法是把设置好的目录和.qmail都拷 
贝到/etc/skel下面,每当adduser的时候会自动将它们拷贝到新用户的目录下,就可以 
省去这样的操作了。 
   
  7.4.3 启动smtp投递代理 
   
  qmail的smtp投递代理是/var/qmail/bin/qmail-smtpd。这个程序通常是在inetd里面 
启动的,问题在于出于某种原因,qmail缺省的情况下不使用投递代理功能,而且它的投 
递代理是基于用户名字的。简单地说,如果一封信的回信地址不是本机器,或者邮件来 
自客户机器,那么它将直接拒绝投递并产生一个错误。解决的办法是在启动qmail-smtp 
d的时候提供一个环境变量RELAYCLIENT,这样它将不再作邮件地址检查。问题是从inet 
d启动这个功能是困难的,我们一般使用前面提到的tcpserver程序。 
   
  tcpserver是一个类似inetd的服务程序,但是它可以对连接地址进行检查,并且设定 
服务器进程启动时的参数。详细的介绍我们不作了,在这里,如果要启动投递代理,需 
要首先生成TCP规则,首先要建立一个/etc/tcp.smtp文件。例如你想对192.168.12.*的 
用户启动投递代理的话,这个文件要包括这样的行: 
   
  192.168.12.:allow,RELAYCLIENT="" 
   
  注意后面的点号,例如127.代表127.*.*.*,192.168.代表192.168.*.*。 
   
  然后执行: 
   
  tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp 
   
  tcprules程序将把tcp.smtp转换成tcpserver使用的数据库形式。 
   
  最后就可以启动smtp投递代理了,可以用类似这样的命令来完成: 
   
  tcpserver -x /etc/tcp.smtp.cdb -u 81 -g 60000 0 smtp /var/qmail/bin/qmail- 
smtpd & 
   
  不要忘记了最后的&符号,这里的81是qmaild用户的uid,而60000是nofiles用户组的 
gid,你需要把它们换成自己的值。tcpserver程序通常允许最多40个smtp同时连接,如 
果你的负担太重的话,用-c [数字]可以将它加大到200以上的值。 
   
  接下来,你就可以连接到服务器的25端口来实验smtp服务器是否正确工作了。 
   
  7.4.4 启动pop3服务 
   
  qmail的pop3服务程序是qmail-popup和qmail-pop3d。我们可以就在inetd.conf里面设 
置pop3服务,例如,首先设置/etc/services文件加入 
   
  pop3 110/tcp 
   
  然后将inetd.conf有关pop3的行改成: 
   
  pop3 stream tcp nowait root  /var/qmail/bin/qmail-popup qmail-popup  
   
     mail.yourdomain.com /bin/checkpassword /var/qmail/bin/qmail-pop3d Maild 
ir 
   
  注意mail.yourdomain.com应该改成你的这台服务器的名字,而Maildir则是前面设置 
的存放邮件的目录。 
   
  也可以使用tcpserver程序来启动pop3服务: 
   
  tcpserver 0 pop-3 /var/qmail/bin/qmail-popup YOURHOST \ 
   
     /bin/checkpassword /var/qmail/bin/qmail-pop3d Maildir & 
   
  无论哪一种,你都可以试着发送和接受邮件了。一般来说,接受的邮件会暂时存储在 
用户宿主目录的Maildir下,里面有三个目录: 
   
  bash-2.03# ls /home/wanghy/Maildir 
   
  cur     new     tmp 
   
  new目录下存放还没有读过的邮件,每封邮件一个文件: 
   
  bash-2.03# ls /home/wanghy/Maildir/new 
   
  951853189.5966.openlab.asnc.edu.cn      951853197.5971.openlab.asnc.edu.cn 
   
  在测试正常之后,将前面需要执行的几个命令加入到启动脚本中。 
   
  7.5 讨论组 
   
  除了一般的电子邮件服务之外,邮件的另外一个常用的功能是电子新闻(讨论组)和 
邮件列表。 
   
  7.5.1 NewsGroup 
   
  新闻组服务是Internet上大量消息的源泉。如果你在维护一个比较大或者学术性质比 
较浓的网络系统,那么,开设一个新闻组让用户之间可以相互讨论是非常有好处的。 
   
  在使用新闻组之前,首先需要理解几件事情。新闻组是依赖于电子邮件在用户之间交 
换信息,用户可以连接到新闻组服务器来获取别人发表的消息,并且用电子邮件发送自 
己的消息或者回应。两台新闻组服务器之间可以相互传递消息,或者说,把主体相同的 
新闻在服务器之间复制。 
   
  建立本地服务 
   
  在Linux下可以使用的新闻组服务程序有好几种,不过我们最常用的是innd,它的配置 
也比较简单,我们将介绍如何在Linux下安装innd服务程序。 
   
  要使用innd服务器程序,首先必须安装inn软件包: 
   
  rpm –i inn-2.2-1.rpm 
   
  以前的版本与这个版本有一定区别,使用时要注意。 
   
  现在我们首先要建立一个内部的新闻服务器,为此,首先必须配置/etc/news/inn.co 
nf。要注意,和Apache以及sendmail一样,这个目录是在编译时确定的,如果你不愿意 
编译源代码,也可以用rpm程序察看一下它的配置文件: 
   
  [root@mail cf]# rpm -qlc inn |grep inn.conf 
   
  /etc/news/inn.conf 
   
  现在我们看一下inn.conf的内容,这是一个相当大的文件,按照我们的一贯方式,我 
们要在缺省的inn.conf上作修改以便得到一个可以使用的innd服务器。这个文件里面也 
有一些我不能解释的东西,你可以自己看有关的手册页面或者自己实验。首先备份原来 
的innd.conf程序,然后修改这个文件中下面几行: 
   
  organization:           Your Company Name 
   
  #这个选项会显示在新闻组消息的“单位”一栏。你可以随便设置 
   
  server:                 news.yourdomain.com 
   
  #新闻组服务器的名字 
   
  pathhost:               news.yourdomain.com 
   
  #innd会为每一封新闻消息构造一个邮件头,这个选项会定义在邮件头里面如何命名本 
地服务器。 
   
  pathalias:    newssender 
   
  #这个选项会紧跟着pathhost出现在邮件头上,例如你会在邮件的源文件中看到Path: 
 news.yourdomain.com!newssender!not-for-mail 
   
  domain:                 yourdomain.com 
   
  #新闻组服务器的所在域的名字 
   
  fromhost:               news.yourdomain.com 
   
  #建立邮件头的时候,在From栏里添上这个内容 
   
  mta:                    /usr/sbin/sendmail -oi %s 
   
  #使用的信件传输代理程序 
   
  mailcmd:                /usr/bin/innmail 
   
  #发送信件的程序 
   
  checkincludedtext:      false 
   
  #这个选项可以是true或者false。是true的时候,邮件服务器会要求回应信件时的引 
文长度不能超过50%。 
   
  localmaxartsize:   1000000 
   
  #一封信件的最大长度,单位是字节。 
   
  spoolfirst:    false 
   
  #如果这个选项被设置成true,那么新闻将首先被缓冲而不是立刻交给innd服务程序。 
通常你应该设置它为false,如果你按照某个原因将它设置成true(例如,系统负担太大 
),那么你需要用rnews –U命令定期执行新闻的传送。 
   
  maxforks:    10 
   
  #最大允许forks多少个新闻组服务进程,缺省值是10,这已经基本够用,如果你的新 
闻组太忙,可以设的大一些。 
   
  nicekids:               0 
   
  nicenewnews:            0 
   
  #这两个值用来设置新闻服务程序的优先数(nice值)。 
   
  peertimeout:            3600 
   
  clienttimeout:          1800 
   
  #设置客户的超时时间 
   
  maxconnections:         50 
   
  #最大多少个NNTP连接 
   
  pathnews:               /usr 
   
  pathbin:                /usr/bin 
   
  pathfilter:             /usr/bin/filter 
   
  pathcontrol:            /usr/bin/control 
   
  pathdb:                 /var/lib/news 
   
  pathetc:                /etc/news 
   
  pathrun:                /var/run/news 
   
  pathlog:                /var/log/news 
   
  pathhttp:               /var/log/news 
   
  pathtmp:                /usr/tmp 
   
  pathspool:              /var/spool/news 
   
  patharticles:           /var/spool/news/articles 
   
  pathoverview:           /var/spool/news/overview 
   
  pathoutgoing:           /var/spool/news/outgoing 
   
  pathincoming:           /var/spool/news/incoming 
   
  patharchive:            /var/spool/news/archive 
   
  pathuniover:            /var/spool/news/uniover 
   
  overviewname:           .overview 
   
  #这一组信息用来设置与inn相关的各种数据文件的位置。我们不鼓励你修改它们。 
   
  我们不想解释更多的东西了,一般修改了上面那些必要的内容就足够了。但是一定要 
注意,任何一个未定义的选项,其结束字符都不能是空格,这是很容易出现问题的地方 
。如果你想精细地调整系统,自己man inn.conf。 
   
  下一个文件是/etc/news/nnrp.access,它确定那些用户可以访问你的新闻组服务器, 
缺省的内容是: 
   
  # Default to no access  
   
  *:: -no- : -no- :!*  
   
  #allow access from localhost  
   
  localhost:Read Post:::*  
   
  这个设置是禁止除了本地以外的任何客户使用inn服务。为了打开服务,需要增加必要 
的行,格式是[地址表]:[权限]:[用户名]:[口令]:[可用新闻组]。例如,你想要让 
yourdomain.com域的所有成员可以读取和发送新闻,那么可以写成 
   
  *.yourdomain.com:Read Post:::* 
   
  用户名和口令这样两个域是可选的。如果你希望你的服务器需要身份认证就添上,否 
则将它设置为空。最后一个域是可用新闻组的列表,可以用统配符,例如*代表所有新闻 
组,comp.*代表所有comp.打头的新闻组。!表示排除某个新闻组。如果有多个新闻组说 
明,用逗号分开。例如,想让用户访问除了control之外的所有新闻组,使用 
   
  *.yourdomain.com:Read Post:::,!control 
   
  权限可以有三种,一般可以使用缩写R、P和N。R代表Read,P代表Post,而N代表New( 
创建新的新闻组)。一般我们只应该开放RP权限。 
   
  下一步的任务是建立新闻组。这个任务是通过编辑/var/news/active文件来完成的, 
当然你的实际路径可能和我们所使用的有所不同,这决定于inn.conf的设置。一个acti 
ve文件的基本格式是: 
   
  新闻组 旧文章编号 新文章编号 模式 
   
  例如,一个典型的新闻组说明可以是这样: 
   
  comp.os.linux 0000010201 0000010490 y 
   
  第一栏是新闻组的名字,第二栏是当前系统中存储的最旧一篇文章的编号,第三栏是 
当前系统中最新一篇的文章的编号,(因此下一篇文章的编号就是0000010491)。最后一 
个字符是模式,模式的基本取值是这样: 
   
  y 本组存在,可以张贴,可以从上游服务器取得新内容 
   
  n 本组存在但是本站点没有 
   
  m 限制 
   
  x 可以从上游下载,但是不能张贴 
   
  j 本组文章仅仅是通过本服务器转发 
   
  另一个非常重要的文件是/etc/news/expire.ctl。它决定旧的文章可以在系统上保留 
多少天。这个文件中有两种行:第一种是remember行,它的格式是 
   
  /remeber/:[时间] 
   
  例如 
   
  /remeber/:21 
   
  这表示旧文章的标题将被保存三周的时间; 
   
  第二种行是新闻组的有效期,例如: 
   
  comp.os.linux:A:7:14:21 
   
  第一栏是新闻组的名字,可以使用统配符,第二栏是类型,通常设置为A,表示受限制 
和不受限制的所有类型,剩下的三栏依次是保留文章的最少天数,缺省天数,最大天数 
。 
   
  设置了上面的文件之后,用/usr/bin/inncheck命令检查文件是否有错误,注意inn对 
文件的属性要求很严格,inncheck命令会检查出所有错误的属性并且提示。另外,上面 
说的所有文件的属主都应该是news用户。 
   
  设置无误之后,启动inn: 
   
  /usr/sbin/innd 
   
  然后就可以访问邮件服务器了。 
   
  管理邮件的流动 
   
  电子新闻是一个活动的体系,可以在各个不同的新闻组服务器之间传送。这一点是它 
吸引人的地方,也是许多问题的来源。 
   
  要使用邮件的传送功能,需要使用hosts.nntp和newsfeeds文件。hosts.nntp解释那些 
主机可以传送文章到你的服务器,格式非常简单,例如: 
   
  news.otherdomain.com: 
   
  news.edu.cn: 
   
  每一行定义一个服务器主机。 
   
  如果你只是想下载某个站点的文章,那么你剩下的唯一事情就是取得对应站点的服务 
,跟对方的管理者联系一下,让它把文章传送给你就行了。为了同步新闻组的名字,你 
需要下载对方的active文件,这可以用直接telnet到对方的News服务来完成: 
   
  [root@mail /etc]# telnet 202.199.248.11 119 
   
  Trying 202.199.248.11... 
   
  Connected to 202.199.248.11. 
   
  Escape character is '^]'. 
   
  list active 
   
  200 path.asnc.edu.cn InterNetNews NNRP server INN 2.2.1 25-Aug-1999 ready  
(post. 
   
  215 Newsgroups in form "group high low flags". 
   
  control.cancel 0000000000 0000000001 y 
   
  comp 0000000001 0000000001 y 
   
  asnc 0000000004 0000000001 y 
   

   
  然后把中间两栏清空就成了。 
   
  newsfeeds文件定义如何为别人提供文章来源,配置这个文件我认为是世界上最恶心的 
几件事情之一(其他几个是修改sendmail.cf,安装oracle 和修改Windows NT注册表) 
。这个文件分成四栏,第一栏是准备从你这里接受文章的站点的名字,第二栏是传送的 
新闻组类型,第三栏是如何传送文件,第四栏是传送用的中转机器,一般我们不使用中 
转,因此第四栏应该和第一栏相同。举例来说,要让你的服务器提交信件到news2.your 
domain.com,那么可以使用 
   
  news2.yourdomain.com:comp.*:Tf,Wnm:news2.youdomain.com 
   
  中间的Tf,Wnm是使用nntpsend的参数,如果要详细了解传送方式,参考相应的手册页 
面。 
   
  nntpsend是最常见的在新闻组服务器之间传送文章的办法,它需要用/etc/news/nntp 
send.ctl文件进行控制。这个文件的格式基本上是这样: 
   
  news2.youdomain.com:news2.yourdomain.com::-S -t300  
   
  头两栏就是newsfeeds文件的第一栏和第四栏。 
   
  最后可以使用nntpsend命令传送了: 
   
  /usr/bin/nntpsend news2.yourdomain.com news2.youdomain.com 
   
  如果一切正常的话,把这个命令放到cron程序的设置里,让它自动定期执行。 
   
           
   
  7.5.2 邮件列表 
 
   
  另一个经常通过电子邮件实现的功能是邮件列表,这是一种快速向所有用户发送电子 
邮件的服务器程序,国内大部分较大的网站都支持这种服务,许多人把它当成电子刊物 
来使用。 
   
  可以用最简单的办法创建邮件列表,就是利用sendmail的别名功能。如同我们在前面 
指出的,sendmail支持从文件提取别名,所以你可以建立一个简单的别名文本,然后定 
义一个别名用户,使得向这个用户投递的邮件自动转发给文件内列出的所有用户。通常 
对于几百人的邮件列表可以这样作,并且在加入一个用户时调用一下newaliases命令。 
但是这种方法在用户很多的时候并不方便。一般如果你的用户量很大,就需要使用专业 
的邮件列表工具了,例如majordomo。 
   
  本书不涉及majordomo程序的配置,如果你决定作一个比较大的邮件列表,请自己参考 
相应的手册。 
   
   
 
-- 
当我越过无尽虚空的时候,我看见星辰的欲望,光荣和毁灭,这是光辉世界的宿命, 
一切的一切,最终必将落入黑暗和虚无。 
所以,我随着星光飞翔,去逃脱必然的终结,也许有一天,我将回到世界的原初, 
等待新的星辰的诞生。 
尘埃是星的起源,星的终结。 
 
 
※ 修改:·ruster 於 Dec 21 14:06:01 修改本文·[FROM:   202.112.90.20] 
※ 来源:·BBS 水木清华站 smth.org·[FROM: 202.112.90.20] 

BBS水木清华站∶精华区