全部博文(1144)
分类: LINUX
2006-08-07 08:37:47
qmail与相关组件协同工作机制
一、qmail工作机制回顾
在qmail中邮件域分为本地(local)和虚拟(virtual)两种。本地域主要是同/etc/passwd文件相匹配,而虚拟域与qmail配置文件virtualdomains中所列的domains相匹配。
当接受到一个信件后,qmail会检查该邮件属于localdomain还是virtualdomains,如果是virtualdomains,会对邮件地址做相应的转换。然后交由qmail-lspawn控制邮件投递机制,它首先察看qmail-users机制(qmail-users是一个给用户指派-assign-地址的系统),若收信人地址没有定义在assign文件中则激活qmail-getpw程序,然后调用qmail-local来实现本地邮件投递。qmail-local首先试着投递邮件到的地址,其中localpart为本地用户名。若没有找到,则进一步察看/var/qmail/alias中定义的别名,若存在对应的别名则投递邮件到别名对应的用户目录下,否则退回邮件。
若按照qmail-users机制在assign中找到对应于邮件目的地址的规则,则从users/assign得到相关信息,然后进行标准的.qmail文件操作。一般来说,.qmail-
在对qmail邮件投递机制有的整体认识后,下面分节介绍虚拟域、qmail-users、扩展地址和.qmail处理过程。
1.1 虚拟域(virtualdomains)
使用 qmail, 虚拟域将在 virtualdomains 文件里面配置, 文件内由型如下面这行的条目构成:
qmail 转换 为 并且对待这个结果好像是本地域一样。 user@ 这个是可选的, 如果跳过它, 这个条目将匹配所有 @domain 域下面的地址。如果 example.net 邮件管理员希望创建 virtual.example.com 虚拟域, 并且将这个域置于用户 john 的管理之下, virtualdomains 文件下面的虚拟域条目应该这样写:
virtual.example.com:john
这样, 发往 的邮件,qmail识别出虚拟域之后,将会被修改为发往 , 然后进行本地传送。关于为什么受到用户john管理,将在qmail-users和扩展地址两节中介绍
使用多主机名的时候, 所有的虚拟域都必须在rcphosts列出, 这样 qmail-smtpd 才会知道那些地址应该被接受. 但是不像多主机名方式, 虚拟域不可以在locals里面设置相应条目。修改 virtualdomains文件之后, 发送给 qmail-send 一个 HUP (挂起) 信号, 通知它重新读取配置文件。 如果你使用本文的 qmailctl 脚本, 你可以运行如下命令:
qmailctl reload
同时, 不要忘了在 rcpthosts 里面增加虚拟域条目。
1.2 qmail-users
qmail-users 是一个分发地址给用户的系统. 由 /var/qmail/users 下的一系列文件构成. assign 文件是一个分配表. 有两种分配表的格式: 单体方式和通配符方式.
--------------------------------------------------------------------------------
注意: assign 文件包含了一系列分配表, 每行一个, 后面接一个包含了一个单独的小数点(.)的行. 如果你手动创建assign文件, 不要忘记小数点那一行.
--------------------------------------------------------------------------------
1.2.1. 单体分配表
一个单体分配表看起来是这个样子的:
=address:user:uid:gid:directory:dash:extension:
这个表的含义是: 作为 address 地址接收的邮件将会被使用用户 user 来传送, 使用指定的 uid 和 gid, 并且由 directory/.qmaildashextension 这个文件决定邮件如何被传送.
1.2.2. 通配符分配表
通配符分配表看起来是这个样子的:
+prefix:user:uid:gid:directory:dash:prepend:
这个表的含义是: 作为 prefixrest 地址里面匹配的邮件地址接收的邮件, 将会被使用用户 user 来传送, 使用指定的 uid 和 gid, 并且由 directory/.qmaildashextension 这个文件决定邮件如何被传送.
1.2.3. qmail-user 程序
qmail-user 有两个辅助程序: qmail-newu 和 qmail-pw2u.
qmail-newu 程序处理 assign 文件并且在 /var/qmail/users 下生成一个名为 cdb 的常量数据库(CDB)文件. CDB是二进制格式, 所以在内含数千条分配表的情况下, 仍然可以被 qmail-lspawn 快速访问.
qmail-pw2u 把系统用户数据库 /etc/passwd 转换为一系列适于 assign 的分配表. qmail-pw2u 使用一套文件集来修改翻译规则.
include: 要包括的用户
exclude: 不要包括的用户
mailnames: 用户的可替换的"邮件帐户名字"
subusers: 用户控制的额外的地址, 使用可选的 .qmail 扩展方式
append: 其他分配表
--------------------------------------------------------------------------------
注意: 如果你使用qmail-pw2u, 不要忘记在增加和删除用户, 或者改变UID和GID之后, 重新运行一下qmail-pw2u和qmail-newu. 标准的运行次序如下所示:
qmail-pw2u /var/qmail/users/assign
qmail-newu
1.3 扩展地址(extension addresses)
qmail 支持用户控制扩展地址. 在基本地址 上扩展的扩展地址为: ,用户同样可以接收发往扩展地址的邮件. 在本节其余部分, 我们讨论的范围都是在本地系统上, 所以我们将不再使用"@hostname.domain" 部分.
给用户 username 的邮件传送指令由 ~username/.qmail 文件指定. 对于型如username-extension 的扩展地址的传送指令由用户目录下的~username/.qmail-extension 文件指定.
举一个例子, 这个扩展地址的传送将由文件 ~dave/.qmail-lwq 来控制.
扩展地址可以拥有多个字段, 例如 dave-list-qmail 这个扩展地址, 由 ~dave/.qmail-list-qmail 来控制. 在这个例子里面, dave-list-qmai 这个地址被用来订阅 qmail 的邮件列表, ~dave/.qmail-list-qmail 则负责归档这个列表的邮件到单独的邮箱里面.
.qmail 文件可以用-default 后缀进行匹配。 所以 dave-list-qmail 可以由 ~dave/.qmail-list-default 操作. 这个文件可以一对多方式用一个.qmail文件控制所有型如 dave-list-加上任何后缀的地址. 注意 dave-list 不能由 ~dave/.qmail-list-default 控制, 因为在"list"后面没有"-".
qmail 会使用最接近的匹配方式. 例如, qmail在传送一个标志着送给dave-list-qmail这个地址的邮件时, 会按照下面顺序查找.qmail控制文件, 并按照最先匹配的.qmail文件传送这个邮件.
.qmail-list-qmail
.qmail-list-default
.qmail-default
如果没有找到相匹配的.qmail文件, 传送失败, 并且将邮件反弹给发送者.
1.4 .qmail处理过程(dot-qmail process)
一般来说,qmail-local程序投递每一封来信到系统信箱,homedir/Mailbox, 其中homedir为用户所在目录。同时,qmail-local也可以将邮件写入不同的文件或目录,转发到其它地址,投递给一个邮件列表,甚至执行一个程序,所有这些都在控制之下。
要改变qmail-local的行为,只需要再用户目录下设置.qmail文件。.qmail文件包含一行或者多行,每一行都是一条投递指令。qmail提供五种投递指令:注释、程序、转发、mbox和maildir:
l 注释指令行由 # 开头,qmail-local在处理时忽略这些行
l 程序指令行由 | 开头,后面接程序指令和参数,用空格分隔
l 转发指令行由 & 开头,后面直接跟要转发的邮件地址
l mbox行由 / 或者 . 开头,并且不以 / 结尾
l maildir行由 / 或者 . 开头,并且以 / 结尾
如果.qmail文件为空或者不存在,qmail-local将执行系统管理员设定的defaultdelivery指令,一般为./Mailbox,这时qmail会将邮件添加到Mailbox中。
二、其它相关组件介绍
2.1 vpopmail的协同工作机制
2.1.1 vpopmail简介
vpopmail是推出的qmail add-on,主要解决qmail、postfix系统中的虚拟域问题,qmail本身支持虚拟邮件域,但是使用不很方便,vpopmail使得虚拟域更易于使用和维护,而且,由于vpopmail支持Oracle、Sysbase、MySQL及LDAP方式的用户信息存储,使得建立和维护一个拥有几K、几M、几十M甚至更多用户的大型分布式系统成为可能。
vpopmail的主要优势体现在用户信息存于数据库或LDAP 目录,使得提取及共享用户信息变的简单,其缺点是用户信息过于简单,不如提供的LDAP patch。vpopmail 的LDAP支持不同于LDAP patch,vpopmail可存取的LDAP 目录中的条目远远少于 LDAP patch。
虽然vpopmail不支持丰富的用户信息,但若想整体的使用sqwebmail,vpopmail仍是最佳选择。同其相比,VMailMgr同样不支持丰富的用户信息,LDAP patch 虽提供了丰富的用户信息,但是缺乏成熟的 Web 客户端。
2.1.2 vpopmail的工作机制
简单的说,vpopmail的虚拟域管理和信件投递是建立在qmail自身虚拟域和扩展地址等机制上,通过自身的vdeliverymail程序,并提供数据库/目录接口来实现的。vpopmail安装后,需要建立用户vpopmail和组vchkpw,UID和GID均为89。vpopmail用户为该软件工作时所需要的,用来使邮件投递的控制权从qmail向vpopmail转移。
具体过程可以总结为以下几步(下面所提文件的默认均在/var/qmail目录下):
1. 修改control/virtualdomains文件,添加vpopmail所控制的虚拟域
2. 修改users/assign文件,明确虚拟域管理用户(vpopmail)和虚拟域所在用户目录(/usr/vpopmail/domains/yourdomain)
3. 在虚拟域所在的目录下创建.qmail-default文件,通过对此文件进行设置,将邮件的投递控制权转交给vdelivery
4. 最后,由vdelivery负责将邮件写入虚拟域下各个用户的Maildir中
下面给出提到的几个配置文件示例(每个文件的含义和功能参见本文第一部分):
/var/qmail/control/virtualdomains
--------------------------------------------------------------------------------
testdomain:testdomain
mail.appl.fsc:mail.appl.fsc
--------------------------------------------------------------------------------
/var/qmail/users/assign
--------------------------------------------------------------------------------
+testdomain-:testdomain:89:89:/home/vpopmail/domains/testdomain:-::
+mail.appl.fsc-:mail.appl.fsc:89:89:/home/vpopmail/domains/mail.appl.fsc:-::
.
--------------------------------------------------------------------------------
/home/vpopmail/domains/mail.appl.fsc/.qmail-default
--------------------------------------------------------------------------------
| /home/vpopmail/bin/vdelivermail '' /home/vpopmail/domains/mail.appl.fsc/postmaster
--------------------------------------------------------------------------------
假定现在qmail收到一封投递到的邮件,在qmail-send进程中,qmail会发现mail.appl.fsc并非为本地域,则它进一步检查control/virtualdomains文件,发现mail.appl.fsc为虚拟域,则qmail-send将在邮件前加前缀,使邮件地址变为,转交给qmail-lspawn。
qmail-lspawn在收到投递给的邮件时,发现该邮件前缀匹配users/assign文件中第二行的条目,故将邮件交给vpopmail(UID为89)处理,用户所在目录为/home/vpopmail/domains/mail.appl.fsc,再将邮件转交给qmail-local处理。
根据qmail-local中扩展地址的dot-qmail文件匹配规则,qmail-local没有找到.qmail-tester和文件,所以会匹配文件.qmail-default。
在.qmail-default文件中,vdelivermail接管了邮件的控制权,其第一个参数为了先下兼容没有使用。
vpopmail with ldap目前不提供smtp认证机制,对于vpopmail收信本文不作进一步介绍。
2.2 ezmlm/ezmlm-idx的协同工作机制
2.2.1 ezmlm/ezmlm-idx介绍
ezmlm是基于qmail的一个高效、易用的邮件列表管理器,用户可以使用它创建自己的邮件列表。ezmlm 非常可靠,即使面临系统突然断电的严重问题,它也不会丢失信件。ezmlm可以处理超大规模的邮件列表而不会受系统资源的限制。
ezmlm-idx是对ezmlm的扩展,它修订了ezmlm的部分功能并提供了扩展的其他丰富功能,使得管理和创建邮件列表更加简单、有效。特别是,它提供了MySQL和pgSQL的支持,使得更加容易同其他应用共享邮件列表的信息。
2.2.2 ezmlm的工作机制
ezmlm在qmail-local中介入qmail邮件处理,通过设置特定的dot-qmail文件,从而实现邮件列表的功能,下面通过实例介绍ezmlm创建的dot-qmail文件及其处理流程。
假定我们在虚拟域mail.appl.fsc上使用ezmlm新建了邮件列表,ezmlm会在~vpopmail/domains/mail.appl.fsc目录下创建dot-qmail符号链接文件:
ls –l /home/vpopmail/domains/mail.appl.fsc
--------------------------------------------------------------------------------
.qmail-list-all@ -> /home/vpopmail/domains/mail.appl.fsc/list-all/editor
.qmail-list-all-default@ -> /home/vpopmail/domains/mail.appl.fsc/list-all/manager
.qmail-list-all-owner@ -> /home/vpopmail/domains/mail.appl.fsc/list-all/owner
.qmail-list-all-return-default@ -> /home/vpopmail/domains/mail.appl.fsc/list-all/bouncer
--------------------------------------------------------------------------------
这四个dot-qmail文件分别负责邮件向邮件列表投递(list-all)、远程邮件管理(list-all-default)、向邮件管理者投递(list-all-owner)和邮件反弹处理(list-all-return-default)。
下面通过分析.qmail-list-all文件,来剖析ezmlm的工作机制:
cat .qmail-list-all
--------------------------------------------------------------------------------
|/usr/local/bin/ezmlm/ezmlm-reject '/home/vpopmail/domains/mail.appl.fsc/list-all'
|/usr/local/bin/ezmlm/ezmlm-issubn '/home/vpopmail/domains/mail.appl.fsc/list-all' '/home/vpopmail/domains/mail.appl.fsc/list-all/digest' '/home/vpopmail/domains/mail.appl.fsc/list-all/allow' '/home/vpopmail/domains/mail.appl.fsc/list-all/mod' || { echo "Sorry, only subscribers may post. If you are a subscriber, please forward this message to to get your new address included (#5.7.2)"; exit 100 ; }
|/usr/local/bin/ezmlm/ezmlm-send '/home/vpopmail/domains/mail.appl.fsc/list-all'
|/usr/local/bin/ezmlm/ezmlm-warn '/home/vpopmail/domains/mail.appl.fsc/list-all' || exit 0
--------------------------------------------------------------------------------
由本文第一部分对dot-qmail文件的介绍,可见.qmail-list-all文件中每行都以 | 符号开始,后面跟随的为投递程序。下面这个介绍这四个程序:
l ezmlm-reject dir
该程序用来拒绝垃圾邮件,具体办法是检查邮件头中是否包含Precedence:junk;后面所跟的参数dir用来读取dir/msgsize中的邮件体最大值/最小值;ezmlm-reject还可以拒绝邮件体中特定的mime parts,拒绝规则在dir/mimerejects文件中定义(注意,ezmlm-reject只对要拒绝的mimeparts做标记,具体的剥离过程在ezmlm-send中进行)。
l ezmlm-issubn
该程序用来检查邮件投递人是否属于该邮件列表,包括digest,allow,mod。如果ezmlm-issubn检查结果为失败,则返回错误提示消息给投递者,错误推出码为100。
l ezmlm-send dir
ezmlm-send的具体工作是将邮件投递到邮件列表,并对投递的邮件做其它相应处理。如果dir/archived文件存在,则ezmlm-send会为该投递邮件保留一个备份;如果dir/indexed文件存在,会为邮件建立索引;另外,dir/charset文件会定义邮件的字符编码处理;dir/maillinglist文件中定义了在邮件头处添加的Mailling-List字段;dir/listid文件将定义如何为邮件添加list-ID,这也是可选的。
在经过上面这些处理后,ezmlm-send在邮件中添加dir/headeradd中的新字段,并将标签<#h#>、<#l#>和<#n#>替换为list-host-name、list-local-name和message number,然后输出合适的Delivered-To行。接下来,ezmlm-send去除在dir/mimeremove中明确的MIME part;如果dir/prefix文件存在且不为空,则按该文件的内容为邮件主题加前缀。另外,如果前缀中包含#符号,最后一个#号将会被替换为邮件编号。
注意,前缀的添加是违反Internet Mail Standards的,ezmlm提供这一功能是因为用户的习惯和需求。
最后,ezmlm-send不投递反弹邮件至邮件列表。
l ezmlm-warn
ezmlm-warn检查该邮件列表是否有合适的反弹消息需要发送,如果有则发送反弹消息,没有则自动退出。
远程邮件管理(list-all-default)、向邮件管理者投递(list-all-owner)和邮件反弹处理(list-all-return-default)的工作机制同邮件列表投递类似,不再做进一步解释。
2.3 autorespond的系统工作机制
autorespond软件包基于qmail,提供简单的邮件自动回复功能。假如现有邮件地址,帐号所有者因为某种原因在一段时间内不能使用该帐号,则他可以通过autorespond为tester帐号创建自动回复,定制回复给向该帐号投递者的信件内容。
具体的实现过程为,autorespond在邮件虚拟域目录(假定虚拟域由vpopmail管理)/home/vpopmail/domains/mail.appl.fsc下,创建.qmail-tester文件,该文件缺省内容如下:
--------------------------------------------------------------------------------
|/bin//autorespond 10000 5 /home/vpopmail/domains/mail.appl.fsc/TESTER/message /home/vpopmail/domains/mail.appl.fsc/TESTER
--------------------------------------------------------------------------------
autorespond: usage: time num message dir [ flag arsender ]
time表示允许处理信件的总时间(以秒为单位),num为在这段时间内能够处理的最大信件数目,message为自动回复的信息内容,dir为记录日志文件的目录。
则上面.qmail文件中第一行解释为,在大约三分钟时间内,最多只接受5封邮件,日志目录为TESTER,自动回复的信息为TESTER/message;第二行为将邮件转发给available-addr,注意,转发地址应避免造成循环自动回复。
三、qmailadmin的集中管理
qmailadmin提供基于vpopmail的虚拟域和用户管理界面,使用qmailadmin可以方便地通过web方式管理虚拟域、用户及邮件列表。qmailadmin需要autorespond和ezmlm的支持,若想充分发挥它的功能,还需要ezmlm-idx。
qmailadmin通过cgi+htmlTemplate的方式提供web服务,由cgi对相应的template页面中##开通的关键字进行替换,使得用户可以方便的根据需要改变页面风格或者重新设计页面。