Life with qmail — 中文版(英文版本2 Jan 2006)
Life with qmail — 中文版(英文版本2 Jan 2006)
原(英)文作者: Dave Sill 本中文版发布时间:14 Apr, 2006原文web地址: http://www.lifewithqmail.org/
翻译:Jerry Zhou (Jerry underline ZhiJun(@)21cn.com)
原始版权由作者Dave Sill拥有
中文翻译版使用权由原作者和翻译者共同所有, 请不要用于商业用途.
转载, 刊登, 摘录请首先取得原作者和译者的同意
中文版上一版为2003年8月16日, 这个旧版本的讨论和取得请访问这里:lwq2003.justso.cn,
这个版本的讨论主页设在linuxforum 的邮件和DNS服务器版面,可以访问这里到达 lwq2006.justso.cn.
本文为完整的中文版本. 这个版本由Dave Sill收藏于http://www.lifewithqmail.org/.
谨以此翻译的劳动致谢我的父母, 姐姐一家以及很多朋友和同事.
也可以通过我的blog地址找到我: www.justso.cn
紫色小字号为译者注, 包括英文原文考量和一些基础知识.
文中将统一应用英文逗号(,) 和句号(.) 以及引号(”)等英文标点符号.
如果哪位港台同胞乐意制作Big5码的版本, 请和我联系.Jerry underline ZhiJun(@)21cn.com. 如果你对里面翻译的文字有任何意见和商榷, 请e-mail译者, 我们一起来把LWQ翻译的更好! 给译者信箱发送邮件, 请指定标题为”For Translations of LWQ“. 否则将被作为垃圾邮件处理, 不情之请, 希望见谅.
中文翻译 版本: 2006-4-14
下面是这个版本和2003-8-16版本相比的更新修正:
目录
-
- 1.1. 适合阅读本文的读者
1.2. 什么是qmail?
1.3. 为什么用qmail?
1.4. 发展历史
1.5. 特点
1.6. 相关的软件包
1.7. 体系结构
1.8. 版权许可信息
1.9. 和其他MTA相比较
1.10. 文档
1.11. 技术支持- 2.1. 不同的安装形式以及相互的比较
2.2. 准备工作
2.3. 系统要求
2.4. 下载源代码
2.5. 编译源代码
2.6. 安装 ucspi-tcp
2.7. 安装daemontools
2.8. 运行 qmail
2.9. 测试- 5.1. 关于 procmail
5.2. POP 和 IMAP 服务器
5.3. POP 和 IMAP 客户端
5.4. Multi-RCPT 与 Single RCPT 传送方式的比较
5.5. 关于 VERP
5.6. 故障处理
5.7. 大型服务器
5.8. 从 Sendmail 转移到 qmail
5.9. 邮件列表管理器
5.10. 补丁
5.11. QMTP
5.12. 在SMTP对话过程中拒绝非法接收者
5.13. TLS 和 STARTTLS- B.1. dot-forward
B.2. fastforward
B.3. ucspi-tcp
B.4. daemontools
B.5. qmailanalog
B.6. rblsmtpd
B.7. serialmail
B.8. mess822
B.9. ezmlm
B.10. safecat
B.11. djbdns
B.12. maildrop
B.13. syncdir- G.1. qmail 不能给超级用户发邮件
G.2. qmail 不能给没有主目录的用户发邮件
G.3. qmail 不能给名字含有大写字符的用户发邮件
G.4. qmail 处理扩展地址的时候用冒号(:)替换掉了点(.)
G.5. qmail 处理扩展地址的时候把大写字符转换成了小写字符
G.6. qmail 不使用/etc/hosts 文件.
G.7. qmail 不在日志记录 SMTP 的活动
G.8. qmail 不生成邮件延迟通知
G.9. qmail 由于/var/qmail/queue/lock/trigger 文件丢失、权限设置错误或者错误的文件属性设置等原因变的很慢
G.10. DNS 或者 IDENT 查询使 SMTP变慢
G.11. 回车(Return)和换行(CRLF) 不同
G.12. 日志回滚造成qmail-send 和 tcpserver 停止
G.13. qmail-smtpd 不能使地址的本地部分生效
G.14. 设置防火墙导致远程无法连接 SMTP/POP3/IMAP 服务器
G.15. 如果USER 和 LOGNAME 没有设置的话, qmail-inject 将设置邮件发送方字段(From)为匿名(anonymous)
G.16. 停止qmail-send进程的时候, 它不总是立即退出.
G.17. 不能通过把邮件传送到/dev/null 将邮件丢弃.
G.18. qmail-send 正在运行过程中修改邮件队列是危险的.- H.1. 这个Life with qmail 的版本是多少?
H.2. 谁拥有Life with qmail?
H.3. Life with qmail 的版权信息?
H.4. 我怎么取得新版 LWQ 的发布通知?
H.5. 在哪里可以为 LWQ 投稿, 捐助以及讨论它?
H.6. Life with qmail 被翻译成其他语言了吗?
H.7. Life with qmail 有没有 PostScript, PDF, plain text, 或者其他任何除了HTML的格式?
H.8. 我按照 Life with qmail 说的作了, 可是我的系统崩溃了, 或者弄坏了我的硬盘, 或者毁了我的爱情, 或者弄死了我的狗, 等等问题, 我该怎么办? (这属于老外的幽默啦. ^_^, 译者注)
H.9. 我怎么为 LWQ捐赠和投稿?
H.10. 这个版本的LWQ有那些变化呢?
1. 介绍
2. 安装
3. 配置
4. 使用方法
5. 高级话题
附录 A. 致谢
附录 B. 相关软件包介绍
附录 C. 因特网邮件工作原理
附录 D. 体系结构
附录 E. 一些不常见的问题
附录 F. 错误讯息
附录 G. 新手常见问题
附录 H. 关于本文Life with qmail 的常见话题
1. 介绍
1.1. 适合阅读本文的读者
Life with qmail 的目标读者是那些对qmail有兴趣, 却被归类于业余爱好者, 新手的人, 那些在一台空闲(原文为: a spare PC 译者注)PC机上操作Linux, 希望日后成为经验丰富的系统管理员或邮件系统管理员的人写作的. 如果你发现文章中有缺陷或者不清楚的地方, 请用电子邮件告诉我. (英文) lwq at sill dot org. (译者的电子邮件: Jerry underline ZhiJun(@)21cn.com 译者注).
各种不同的来源存在着丰富的 qmail相关信息. 其中一些是以新手为目标, 另外一些假定读者具有比较多的经验, Life with qmail 就是一篇试图成为”胶水”性质的文章, 集合这些信息为一体, 不过读者必须首先掌握下面这些基础知识:
- 在UNIX环境下熟练的操作文件和目录的能力
- 会使用web浏览器和FTP客户端软件
- 能够读懂下面的使用方法
1.2. 什么是 qmail?
qmail是一个因特网邮件传送代理, (英文: Mail Transfer Agent, 简写为MTA, 译者注) 它运行在UNIX兼容系统下, 是一个直接代替UNIX下 Sendmail软件的邮件传送程序. qmail 使用简单报文传送代理协议 SMTP 传输邮件(Simple Mail Transfer Protocol).
注意: 它的名字是 “qmail” , 而不是 “Qmail”.
1.3. 为什么用 qmail?
你的操作系统如果包含一个MTA, 那很有可能是Sendmail, 而你阅读了下面的文档之后, 你可能想(抛弃Sendmail, 另外)找一个更好的MTA了.
1.3.1. 安全
qmail 是面向安全而设计的. Sendmail 的历史上出现过很多严重的安全问题. 在编写Sendmail的时代, 网络是非常友好的地方, 每个在网上交流的人都能够很容易的了解对方, 几乎没有必要为了安全而设计软件, 编写代码. 而现在的因特网对于网络服务器却是险象丛生. Eric Allman, Sendmail的作者, 和目前的维护者Claus Assman 为了加强Sendmail的安全做了很多工作, 但是无论如何, 除了重新设计, 怎样的修正也不能让Sendmail达到真正的安全.
1.3.2. 性能
qmail 并行处理邮件传送, 缺省配置情况下, 能够达到20个并行邮件同时传送.
1.3.3. 可靠性
qmail保证已经接收的新邮件不被丢失, qmail使用一种新的邮箱格式, 其可靠性超过了没有文件锁的NFS存储系统.
1.3.4. 简单Simplicity
qmail 比其他实现同样功能的MTA都要小.
注意: qmail 的正式主页, http://cr.yp.to/qmail.html 有更多的 qmail 特色介绍.
1.4. 发展历史
qmail由 Dan Bernstein (DJB)编写, 关于他可以参考这里http://en.wikipedia.org/wiki/Daniel_J._Bernstein. 他现在任职于 Illinois 大学 Chicago 分校数学教授. 它在密码术研究方面的工作, 以及他关于密码术源代码的出版问题对美国政府的诉讼也是很有名的, 关于这次诉讼的情况详见 http://en.wikipedia.org/wiki/Bernstein_v._United_States 或 http://cr.yp.to/export.html 查看关于诉讼的信息. (可能wikipedia在中国大陆无法访问, 请参考使用代理或其他方式. 译者注)
第一个公开发行的 qmail 版本是1996年1月24日发表的 0.70 beta 版. 第一个 gamma 发行版是在1996年8月1日的0.90版.
第一个常规发行版本是1.0, 时间是1997年2月20日. 现在使用的1.03版本, 发行于1998年6月15日.
预期下一个版本将是2.0评估版, 即将在2.0版里面出现的一些新功能可以在http://cr.yp.to/qmail/future.html 找到.
1.5. 特点
qmail 的web页 http://cr.yp.to/qmail.html 列出了非常全面的qmail的特点. 本节即针对这个页面列出的特点予以着重介绍.
1.5.1. 安装
- 自动适应于UNIX的各种版本
- 自动适应于单主机配置
- 快速安装–不必作大量的配置工作
1.5.2. 安全
- 地址, 文件以及程序之间分隔清晰
- 最少限度的应用setuid编码
- 最少限度的应用root编码
- 五个不同权限信任级别区隔运行(指利用五个分隔的uid运行qmail的不同功能模块. 译者注) –深入的安全保障
- 可选的邮件单向散列计算功能, 包括整个邮件内容的hash计算等功能. (参考 附录 E 的什么是 QUEUE EXTRA?)
1.5.3. 邮件结构
- 符合RFC 822 和RFC 1123 标准.
- 邮件地址组的完整支持.
- 自动转换旧格式地址为RFC 822 格式.
- 支持sendmail命令, 与目前的邮件用户代理兼容.
- 仅受限于内存大小的长邮件头支持.
- 主机伪装(参见 defaulthost)
- 用户伪装(参见 MAILUSER和 MAILHOST)
- 自动生成邮件跟踪列表(参见 QMAILMFTFILE )
1.5.4. SMTP 服务
- 兼容 RFC 821, RFC 1123, RFC 1651, RFC 1652, 和 RFC 1854 标准
- 全 8-bit 操作(qmail直接对邮件进行8bit操作. 译者注)
- 支持 RFC 931/1413/ident/TAP 回查–用来跟踪垃圾邮件和伪造邮件
- 转信控制–阻止未授权的外来转信请求.
- 自动识别本地IP地址.
- 每缓冲超时
- 跃点计算
- 并行访问限制(通过 ucspi-tcp)
- 对已知的垃圾邮件发送者, 拒绝连接(通过 ucspi-tcp)
- 支持授权用户转信和消息重写
- 可选的黑洞名单(Realtime Blackhole List, RBL)和开放转信系统修正(Open Relay Behavior-modification System, ORBS) 支持(通过 rblsmtpd)
1.5.5. 队列管理
- 对加入队列的邮件即时处理
- 并行处理限定
- 分割队列目录–队列很大时不降低处理速度
- 二次幂重试时间表排定算法–队列内越陈旧的消息得到的发送机会相对新消息越小 (参考 附录 E)
- 每个邮件独立的重试时间表
- 自动安全队列–系统崩溃情况下不丢失邮件.
- 自动每邮件接收者检查
- 自动队列清除
- 队列观察(参看 qmail-qread)
- 详细的传送过程分析 (通过 qmailanalog)
1.5.6. 邮件反弹
- QSBMF反弹邮件–包括机器易读和人类易读两种格式
- HCMSSC 支持–不受语言约束的 RFC 1893 错误代码
- 发送两次反弹邮件给系统管理员(postmaster)
1.5.7. 基于域名的邮件路由
- 支持任意数量的本地主机名(参看 locals)
- 支持任意数量的虚拟域 (参看 virtualdomains)
- 支持域名通配符 (参看 virtualdomains)
- 可配置的”percent hack”支持 (参看 percenthack)
- UUCP 钩 (UUCP hook)
1.5.8. SMTP 传输
- 兼容 RFC 821, RFC 974, 和 RFC 1123 协议
- 全8-bit字符支持
- 对关闭的主机自动延迟处理
- 人工路由–smarthost, localnet, mailertable (参考 smtproutes)
- 每缓冲超时设定
- 被动SMTP队列–对(低速)SLIP/PPP线路的完美支持 (通过 serialmail)
- Auto TURN支持 (通过 serialmail)
1.5.9. 转发和邮件列表
- 兼容Sendmail的 .forward控制文件(通过 dot-forward).
- 散列的转发数据库(通过 fastforward)
- 兼容Sendmail的 /etc/aliases 控制文件(通过 fastforward)
- 地址通配符 (参见 .qmail-default)
- 邮件列表所有者–自动转移反弹邮件和假期邮件
- VERPs–自动邮件列表反弹邮件接收者识别
- 自动防止循环成环邮件传送, 甚至可以避免对于交叉串联主机的配置方式成环邮件传送
1.5.10. 本地(邮件)传送
- 支持用户控制的地址分级–任意FRED(Fast Random Enquiry Display 快速随 机询问显示, 译者注) mbox传送
- 可靠的NFS传输(参见 maildir)
- 支持用户可控的邮件程序传送, 比如procmail等, (参见 qmail-command)
- 可选的新邮件通知(参见 qbiff)
- 可选的NRUDT返回收条(参见 qreceipt)
- 条件过滤(参见 condredirect 和 bouncesaying)
1.5.11. POP3 服务
- 兼容 RFC 1939
- 支持UIDL
- 支持TOP
- APOP钩
- 模块化的密码检查(通过 checkpassword)
1.6. 相关的软件包
qmail遵循经典UNIX哲学: 每个软件工具都要有专一的, 规范良好的功能; 而复杂的功能应该由一系列多个独立的简单工具联合完成, 形成一个”流水线”模式. 另外一种方式是在更为简单的工具上不断的建立和丰富越来越复杂的的功能来完成大量的复杂的功能.
qmail并没有拥有所有人要求的任意功能, 这点并不令人惊讶惊讶. 相反的, qmail拥有的是一些实现那些功能的流行的插件(add-ons). 当然了, 许多标准UNIX实用工具也都可以作为插件和qmail协同工作. 下面介绍一些插件:
- dot-forward –一个兼容Sendmail的.forward控制文件的插件
- fastforward — 一个兼容Sendmail别名数据库的插件
- ucspi-tcp — 一个inetd超级服务器的替换程序
- daemontools — 一个管理后台服务程序以及日志的工具套件
- qmailanalog — 一个qmail日志文件分析工具套件
- serialmail — 用于低速网络邮件传送的工具
- mess822 — 一个对因特网邮件的进行分析的工具
- ezmlm — 一个基于qmail的管理邮件列表的工具
1.7. 体系结构
附录 D 介绍了qmail的功能和结构. 简单的说, qmail包含了一系列的程序(模块)来完成不同的任务.
1.8. 版权许可信息
qmail的版权由作者Dan Bernstein所有, qmail没有和用户权利声明一同发布. 在web页面 http://cr.yp.to/softwarelaw.html 上, 作者Dan Bernstein概要陈述了他认为用户在美国版权法下拥有的权利和义务. 在web页 http://cr.yp.to/qmail/dist.html 上描述了作者授权给qmail的源代码分发用户的权利和义务. 二进制发行遵循条款在下面这个web页面上可以找到 http://cr.yp.to/qmail/var-qmail.html, 也可以参考这里: http://en.wikipedia.org/wiki/License-free_software.
发行权限的最底线: 你可以将qmail用于任何用途, 你可以再次分发未修改的qmail源代码和有资格的var-qmail二进制发行包, 你也可以发行qmail补丁程序. 但是你不能发行修改过的qmail源代码和non-var-qmail二进制发行包.
1.9. 和其他MTA相比较
这个题目完全可以写一本书啦. 不过可能是很单调乏味的一本. 这里给出一个qmail和其他最常见的UNIX MTA的快速比较表格(中: medium, 高: high, 低: low, 是: yes, 否: no, 插件: addons, 可选的: optional. 译者注)
| MTA | 成熟度 | 安全性 | 特色 | 性能 | 是否兼容Sendmail | 模块化 |
| qmail | 中 | 高 | 高 | 高 | 插件 | 是 |
| Sendmail | 高 | 低 | 高 | 低 | - | 否 |
| Postfix | 中 | 高 | 高 | 高 | 是 | 是 |
| exim | 中 | 低 | 高 | 中 | 是 | 否 |
| Courier | 低 | 中 | 高 | 中 | 可选的 | 是 |
兼容Sendmail意思是MTA运转是否类似于Sendmail, 从而可以在某种用户透明度上从此MTA和Sendmail之间过渡和切换, 比如.forward控制文件, /etc/aliases文件以及是否传送邮件到目录 /var/spool/mail等等行为.
Jonathan de Boyne Pollard 曾经回顾了很多UNIX下的MTA, web页面在http://homepages.tesco.net/~J.deBoynePollard/Reviews/UnixMTSes/ . 另外一个很详细的的比较文章请参考http://www.geocities.com/mailsoftware42/. (geocities可能在国内无法直接访问. 译者注)
1.10. 文档
1.10.1. man 帮助手册
qmail发行包包含了完整的man手册. 安装qmail之后, 他们通常位于 /var/qmail/man. 你可能需要自己手动增加这个手册目录路径到你的环境变量MANPATH里面.
| Shell 解释器 | 命令行 |
| Bourne (/bin/sh) | MANPATH=$MANPATH:/var/qmail/man; export MANPATH |
| bash, Korn | export MANPATH=$MANPATH:/var/qmail/man |
| C Shell | setenv MANPATH $MANPATH:/var/qmail/man |
(上面表格为各个不同shell下运行的增加环境变量的命令行格式, 故不予翻译, 用户也可以参考man man来查阅直接指定man的指定目录开关的设定, 在Bourne下, 这个开关一般是 -M.译者注) (修改环境变量之后) 用型如”man name-of-qmail-man-page”的命令格式即可调出相关的手册页面.
也可以访问man手册页面的在线web页面形式, 地址是:
注意: qmail的man手册页面承载了大量的信息, 它的写作语言偏重技术术语, 可能相当晦涩难懂, 必须仔细加以研读. 你可能需要通读一遍来熟悉它. 因为很少有重复性的内容, 你必须首先知道里面都写了哪些内容,以及你感兴趣的那些内容在哪里, 否则你可能根本找不到你要的东西.
1.10.2. 文档
qmail发行版包含了一系列文档, 通常安装在/var/qmail/doc目录下. 它们包括以下内容: (本文中默认的两个位置,一个就是文档的根位置/var/qmail/doc, 这个位置的文档也通常被作者描述为qmail源代码文件目录下的doc文档, 内容是一致的. 还有一个就是qmail 的安装后的主目录下的控制文档, 通常为/var/qmail/control下面, 在很多情况下, 作者并不明确指出这两个具体位置. 译者注)
- FAQ: 常见问题以及回答.
- INSTALL.* 文件集: 安装文档.
- PIC.*文件集: 描述了qmail如何完成核心任务的文档. 查找更多相关信息, 请参看附录体系结构.
- 其他几个安装相关文档.
这些文档也可以在线查看, 请到web页面:
1.10.3. 常见问题 FAQs
有两个正式的常见问题(Frequently Asked Questions, FAQ. 附相关回答)文档:
- /var/qmail/doc/FAQ 目录下, 纯文本版本, 以及
- web页面FAQ, 地址: http://cr.yp.to/qmail/faq.html.
web页面的FAQ更完整一些.
1.10.4. 书籍
1.10.4.1. qmail 手册 (英文书名: The qmail Handbook)
作者Dave Sill, 也是本文Life with qmail的作者, 曾经为Apress(http://www.apress.com/)出版社撰写了一本qmail书籍. 这本qmail 手册 (英文书名: The qmail Handbook), 包括了本文所有内容, 某些方面更为详细, 同时也介绍了大量的新领域.
更多信息, 请参看 http://www.apress.com/catalog/book/1893115402/. 需要在我的书店定购本书, 请到我和Amazon.com合作书店 http://www.amazon.com/exec/obidos/ASIN/1893115402/davesill.
1.10.4.2. qmail (英文书名: qmail)
据报道, John Levine为O’Reilly & Associates (http://www.oreilly.com/)出版社写作的一本qmail书籍.
1.10.4.3. Running qmail (英文书名: Running qmail)
作者Richard Blum, Sams出版. 这本书被认为接受了qmail邮件列表里面的各种观点.
定购本书, 请参看 http://www.amazon.com/exec/obidos/ASIN/0672319454/davesill.
1.10.4.4. qmail: Yuksek Performansli E-Posta Sunucu
Ismail Yenigul, 以及其他人著作的qmail 书籍. 参见 http://www.acikakademi.com/catalog/qmail/.
1.10.5. 邮件列表文档
qmail的邮件列表, 由Dan Bernstein 维护, 极为有价值的信息来源. web文档保存在以下位置:
这个文档的一个搜索引擎位置在:
其他web文档可以在以下地址访问到:
大多数关于qmail的问题的答案都可以首先在这个邮件列表的文档里面搜索到.
1.10.6. 其他Web站点
- http://cr.yp.to/qmail.html : qmail的正式主页.
- http://www.qmail.org/. qmail的非正式主页. 包含了大量关于功能插件和补丁的信息, 以及很多很棒的关于qmail的web页面的链接.
- http://www.flounder.net/qmail/qmail-howto.html: Adam McKenna 制作的HOWTO.
1.11. 技术支持
1.11.1. 邮件列表
下面的这些列表位于主机 list.cr.yp.to. 为了防止被发送垃圾邮件者获取地址, 我没有使用完整有效的邮件地址, 以及”mailto”格式的URL.(这里隐去了真实的listname, 具体请参看qmail的正式主页介绍或者查看1.11.1.节, 也就是本节的几个小节的带有下划线的英文标题名字, 译者注)
这些邮件列表由ezmlm管理, 使用不同的地址实现不同的功能.
- listname@list.cr.yp.to: 订阅地址. 发送到这个地址的邮件将会被发送给列表的所有用户. 请不要发送订阅和退订要求到这个地址, 这样作是无效的, 而且还会打扰其他订阅者.
- listname-help@list.cr.yp.to: 这是”帮助”地址. 发送邮件到这个地址将会返回使用信息.
- listname-subscribe: 发送空消息到这个地址订阅列表.
- listname-unsubscribe: 发送空消息到这个地址退订列表.
举例, 一个订阅或者退订地址, 比如 joe@example.com, 发送邮件到这个地址订阅列表:
- listname-subscribe-joe=example.com@list.cr.yp.to.
1.11.1.1. qmail
这是一个主要的qmail邮件列表.讨论和提问/回答很多有关于qmail的问题. 不过不包括有关于他们自己的列表的问题. 在这个列表提问之前请阅读Charles Cazabon的”12 Steps to qmail List Bliss” web页面位置http://pyropus.ca/personal/writings/12-steps-to-qmail-list-bliss.html .同时请首先阅读FAQ或者在这里搜索列表的过去的文章. 提问的时候, 请尽量包含充分详尽的细节, 便于其他人回答. 请注意以下这些提问要点:
- 你做了什么? 你的配置? 如果你不清楚哪些比较重要, 那就把qmail-showctl 的输出算上. 你都做了那些举动? 如果是新安装的qmail, 讲述一下你如何安装的.
- 你期待发生什么? 你想达到一个什么目的? 不要假设读者会猜到你的想法.
- 曾经发生了什么? 描述一下实际的结果. 包括log文件的部分剪辑, 消息的副本, 包括头部分.
注意: qmail的邮件列表使用了一个叫做qsecretary的工具来校验投递到列表的邮件是否是垃圾邮件. 每封到达列表的邮件都会首先由qsecretary返回一个确认邮件. 用户阅读确认邮件并且按照返回邮件上的指令确认你的邮件–通常就是回复qsecretary的确认信息就可以了. 经常在列表投递的订户一般使用类似Charles Cazabon编写的pymsgauth (在这里http://pyropus.ca/software/pymsgauth/.) 的自动回复程序来自动完成邮件确认. pymsgauth 校验发往列表的邮件的确是你发出的, 所以它不会确认那些冒充你的名字发送到列表的邮件.
1.11.1.2. qmailannounce
qmail的公告邮件列表. 没有投稿地址, 这是个只读的列表.
1.11.1.3. serialmail
讨论serialmail 软件的列表.
1.11.1.4. ezmlm
ezmlm 邮件列表管理器的的讨论列表.
1.11.2. 咨询者
参看 http://www.qmail.org/top.html#paidsup 的商业支持提供者名单.
1.11.3. FAQTS 知识库
http://qmail.faqts.com/ 一个qmail相关问题的数据库, 包括问题解答.如果你在FAQ里面找不到回答, 试试搜索这个知识库. 它的专长在于回答”如何去作”的问题.
2. 安装
这一节介绍qmail的安装. 如果你是个经验丰富的系统管理员, 你完全可以按照qmail的发布源文件里面的INSTALL文件的指导完成安装. INSTALL文件是正式的安装指导. 这个指导比 Life with qmail, 也就是本文的指导复杂很多. INSTALL文件假定读者是一个经验丰富的系统管理员或者邮件管理员. 而且INSTALL这个文件也比较陈旧, 反映不了Bernstein(qmail作者)最近的操作规程建议.
注意: 如果你选择使用下面的安装指导, 请你一定要通读下面整个小节以熟悉全部安装过程.
2.1. 不同的安装发布形式以及相互的比较
2.1.1. 二进制安装对比源代码安装
由于qmail对于预先编译的二进制代码包的发行有限制性的许可, 通常qmail都是由源代码安装的.
如果你不是很熟悉源代码和二进制的区别, 想像一下你订了一个pizza饼. “二进制”形式的pizza饼送来了立刻就能吃, 而”源代码”pizza饼就像全部制作pizza的材料, 面粉, 发酵粉, 干酪, 沙司还有浇头调料, 以及烹饪pizza的指导, 你必须自己作pizza. 虽然有点费劲, 不过如果你仔细的按照指导来作, 结果是一样的, 甚至更好. 自己作的pizza更新鲜, 你也可以按照自己的配置调整浇头调料, 并且你更多的了解了你的pizza以及它是如何”工作”的.
安全的运行一个因特网服务并不容易. 一个不适当配置的服务可能给你的主机系统带来被攻击以及被用来攻击其他站点的风险–有可能让管理员承担法律责任的安全风险. 更多的知道你的网络服务如何运行的, 就更有可能让他们正确和安全的工作.
2.1.2. Tarball 对比 特定操作系统安装包 (Tarball vs. OS-specific package)
一些操作系统提供一种自动源代码安装机制. 回到上文我们的pizza制作分析里面. 这就好像把所有的pizza的成分和制作指导都打包到一起, 这样你简单的按一下按钮pizza就能把自己烤好啦.
觉得这样作很不错, 是吧?
实际上, 那可不是一个想当然的好主意. 组装这些包是个相当困难的工作, 它们有时并不是按照假定的方式工作的. 这是软件, 而且和其他软件一样, 他们会有bugs. 即使不提那些bugs, 那些安装的方便也是用牺牲你自己烤的pizza饼的很多优点来达到的. 比如你自己调整浇头调料的的能力, 还有知道怎么作pizza饼, 以及pizza如何工作等等.
如果qmail仅仅是一个pizza, 哪自安装方式还是可以接受的. 不过qmail可是个相当复杂的系统. 安装和维护qmail的人都需要对它相当的了解才能平稳的运行它. 自安装方式的qmail更容易安装, 不过用户手动安装方式更容易调整配置和查找故障. 你可能就安装一次qmail, 但是你可能要几次才能调整好它, 或者当邮件并不是按照你想要的方式运行的时候, 设法找出并解决问题.
由于这些原因, 我建议使用源代码的tarball方式安装, 而不是Red Hat RPM或者其他自安装包方式.
2.2. 准备工作
安装qmail之前, 尤其如果是你第一次安装qmail, 有几个需要注意的地方.
- 如果可能, 尽量在一个”试验”系统上安装qmail. 这样的话可以有机会犯错, 不至于在正在工作的服务器上安装时丢失重要的邮件或者中断mail服务.
- 如果你没有空闲的计算机系统, 而你要安装的系统上面已经运行sendamil, smail或者其他的MTA, 这些MTA还在进行邮件投递, 你可以在这种系统上完成大部分的qmail 安装而不中断现有的邮件服务.
- 如果从其他MTA移植到qmail–即使你在qmail上已经很有经验–首先制订一个安装计划, 也是非常必要的.
2.3. 系统要求
qmail 必须安装在UNIX或者类UNIX系统上, 一些系统要求:
- 安装需要大约10兆空间. 安装之后可以删除目标文件释放出大约4兆空间.
- 一个完整的C开发环境, 包括编译器, 系统头文件, 以及函数库. 构建指导将告诉你如何显示你是否拥有这些必要的部分.
- 二进制代码, 文档, 和配置文件需要几兆空间.
- 邮件队列需要一个安全的文件系统. qmail 的可靠性要求文件系统兼容传统的BSD FFS语义. 大多数现代的本地文件系统都符合这个要求除了一个很重要的例外: link()系统调用常常是异步的–这意味着link()操作返回时不会将数据写入磁盘. Bruce Guenter 的syncdir 库可以用来解决这个问题. 更多信息请参见附录里面相关软件包 syncdir.
- 邮件队列需要的足够的磁盘空间. 小型单用户系统仅仅需要2兆. 大型系统可能需要2吉(2G).
- 兼容的操作系统. 多数变种UNIX都可以. 参考qmail源代码里面的README文件, 里面有已知的兼容系统版本列表.
- 最好有权使用域名服务器. 没有这个条件, qmail就只能按照smtproutes配置文件里面配置的远程主机发送邮件.
- 足够的网络带宽. qmail是为良好接入网络的系统设计的, 所以你不可能在一个28.8k的拨号线路上运行一个邮件列表. serialmail软件包是为在低速连接上的系统运行qmail而设计的. 更多信息请参见附录内serialmail相关的节.
注意: 邮件队列所在的文件系统必须允许使用可执行文件和设置setuid()文件. 一些操作系统自动挂载(mount) /var 目录选项为非suid 和非可执行.这种情况下, 必须在 /var/qmail/bin 内禁止这些选项, 或者, 将这个文件夹放置在其他没有这两项限制的文件系统上. 稍后我将在建立目录小节提到如何使用符号链接来解决这个问题. 如果/var 挂载为非suid, 你可能在qmail-send 日志内看到如下的错误消息:delivery : deferral: Sorry,_message_has_wrong_owner._(#4.3.5)
注意: 本文或者INSTALL 文件的说明, 是不能作为qmail 在苹果X 操作系统上的安装指导的, Eben Pratt 存档了如何在苹果X 系统上安装qmail 的文档, 参考这里 http://netdevice.com/qmail/#osx.
2.4. 下载源代码
好了, 你已经准备好安装qmail的系统了. 第一步就是下载qmail和插件的源代码. 当然了, 你需要qmail, 还有ucspi-tcp和daemontools.
- qmail, http://www.qmail.org/netqmail-1.05.tar.gz
- ucspi-tcp, http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz
- daemontools, http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
用你的web浏览器, 或者web客户端(比如wget), FTP客户端下载这些源代码.
注意: 如果这些链接的其中任何一个失效, 都有可能由于他们已经升级了, 如果是这种情况, 你需要到http://cr.yp.to/software.html 查找相应软件包的链接下载最新版本. 有可能升级版本不兼容下面的指导内容, 所以请一定阅读这些发行版本的”Upgrading from previous version…”小节中的注意事项.
注意: 本文安装指导使用netqmail 发行版, netqmail 包含了qmail 1.03 tarball版和一个补丁, 这个补丁修正了一些漏洞, 不足和兼容性问题. 在这里访问netqmail http://www.qmail.org/netqmail/ netqmail 的CHANGES 文件内有更多的相关信息.
2.5. 编译源代码
2.5.1. 检验编译(源代码)环境
首先你要确定的是你有编译程序的必要的工具. 如何确定取决于你使用的UNIX变种. 虽然不能保证可靠, 但最简单的断定方式就是去试.
注意: 下面任何一个测试通过了, 你都可以停下来直接跳到下一节.
- 在计算机的命令提示行下, 敲入 cc 然后回车.
$ cc cc: No input files specified $
- 如果你得到类似上面的反应, 表明你的缺省搜索访问路径上有一个可用的C编译器. 如果没有类似反应, 也不意味着你必然没安装任何C编译器. 也有可能那个编译器不在你的缺省搜索访问路径上, 当然, 也有可能你根本没有编译器. 接着来试这几个命令:
- /usr/bin/cc
- /usr/bin/gcc
- /usr/local/bin/cc
- /usr/local/bin/gcc
- /usr/ccs/bin/cc
- 如果他们中间没有一个命令起作用, 你可能要多试点和平台有关的命令啦. 在命令提示符下, 区别于你使用的平台不同, 分别敲入以下命令:
- 对于 Red Hat Linux, 使用: rpm -qa | grep gcc 或者 rpm -qa | grep egcs
- 对于 FreeBSD: 默认安装已经包括了GCC编译器.
- 如果你找不到编译器, 你必须确定它的位置或者安装一个. 请联络你的操作系统销售商或者操作系统技术支持.
这节我们将要实现编译qmail的步骤. 剪切/粘贴(意思是复制或者粘贴脚本和命令行. 译者注) 会很方便, 不过也不是必须的.
2.5.2. 解压发行包
如果你一直按照这个指导来作, 那么现在你已经有了一个C编译器, 以及源代码的tarball副本. 下一步, 拷贝或者移动tarball包到工作目录. 目录/usr/local/src 对于qmail 和ucspi-tcp安装是个不错的位置. 而daemontools 应该建立在/package下.
现在你需要成为root用户, 如果你还没有, 那就成为root吧.
su
umask 022
mkdir -p /usr/local/src
mv netqmail-1.05.tar.gz ucspi-tcp-0.88.tar.gz /usr/local/src
mkdir -p /package
mv daemontools-0.76.tar.gz /package
chmod 1755 /package
现在你可以解开软件包了.
cd /usr/local/src
gunzip netqmail-1.05.tar.gz
tar xpf netqmail-1.05.tar
cd netqmail-1.05
./collate.sh # 在这儿要注意错误信息
cd ..
gunzip ucspi-tcp-0.88.tar.gz
tar xpf ucspi-tcp-0.88.tar
rm *.tar # 此步骤可选, 除非硬盘空间很紧张
cd /package
gunzip daemontools-0.76.tar.gz
tar xpf daemontools-0.76.tar
rm *.tar # 此步骤可选, 除非硬盘空间很紧张
那么, 现在应该有下面几个目录 /usr/local/src/netqmail-1.05, /usr/local/src/ucspi-tcp-0.88, and /package/admin/daemontools-0.76.
2.5.3. 建立目录
qmail安装程序会自行创建需要的子目录, 你只需要创建qmail的”home”目录.
mkdir /var/qmail
然后直达下一节.
注意: 如果你想把qmail的全部或者部分文件安装到除了/var的其他地方, 可以在/var/qmail下建立软链接到其他位置. 举个例子, qmail配置文件可以存放在/etc/qmail下面, 如下操作:
mkdir /etc/qmail ln -s /etc/qmail /var/qmail/control
2.5.4. 创建用户和组
最容易的创建用户和组的方式是创建一个小脚本文件然后执行它. 在源代码目录下你可以找到一个名字是INSTALL.ids的文件, 它包括了在你的系统平台下创建用户和组的命令行. 复制这个文件并命名另外一个名字, 编辑它来运行命令既快捷又简单.
cd /usr/local/src/netqmail-1.05/netqmail-1.05
cp INSTALL.ids IDS
接下来, 用你最顺手的编辑器, 删除文件其余部分, 除了保留你的平台需要的命令部分. 举个例子, 下面是为FreeBSD平台编辑之后留下的部分:
pw groupadd nofiles
pw useradd qmaild -g nofiles -d /var/qmail -s /nonexistent
pw useradd alias -g nofiles -d /var/qmail/alias -s /nonexistent
pw useradd qmaill -g nofiles -d /var/qmail -s /nonexistent
pw useradd qmailp -g nofiles -d /var/qmail -s /nonexistent
pw groupadd qmail
pw useradd qmailq -g qmail -d /var/qmail -s /nonexistent
pw useradd qmailr -g qmail -d /var/qmail -s /nonexistent
pw useradd qmails -g qmail -d /var/qmail -s /nonexistent
然后运行这个脚本, 用chmod将脚本设置为可执行或者用sh来运行它.
第一种方法:
chmod 700 IDS ./IDS
第二种方法:
/bin/sh IDS
这个脚本运行完毕, 你的所有的用户和组就已经添加完毕, 你可以继续下一节的安装了.
可是如果你的系统在INSTALL.ids 上没有提到怎么办? 那你就必须手动创建用户和组了. 使用你比较顺手的编辑器编辑这个文件/etc/group, 增加下面两行:
qmail:*:2107: nofiles:*:2108:
注意: 首先确定2107和2108没有被使用, 如果已经被占用, 选择2个文件中未用的数字.
下一步, 使用vipw(大多数系统都有这个命令, 如果没有你就必须用编辑器手动编辑, 不过这次可是/etc/passwd文件)在文件尾部增加下面这些行:
alias:*:7790:2108::/var/qmail/alias:/bin/true qmaild:*:7791:2108::/var/qmail:/bin/true qmaill:*:7792:2108::/var/qmail:/bin/true qmailp:*:7793:2108::/var/qmail:/bin/true qmailq:*:7794:2107::/var/qmail:/bin/true qmailr:*:7795:2107::/var/qmail:/bin/true qmails:*:7796:2107::/var/qmail:/bin/true
注意: 首先确定7790-7796这些未被占用以及和刚才上面编辑的2107, 2108是同一个组id. 如果任意一个用户ID(UID)被占用, 必须选用其他未被占用的用户id.
你不必一定把这些行加到文件尾部, 这样作只是最容易说明问题的方式.你现在已经可以进入下一节了.
2.5.5. 编译
现在你可以开始编译qmail了. 进入/usr/local/src/netqmail-1.05/netqmail-1.05 目录, 我们开始吧!
cd /usr/local/src/netqmail-1.05/netqmail-1.05
在检验编译环境小节, 你定位了你的C编译器. 如果它的名字不是cc或者不在你访问的环境变量PATH定义的任何目录下, 你必须修改conf-cc和conf-ld. 假设你的编译器名字是gcc, 并且gcc在你的环境变量PATH内可见, 那么简单来说, 编辑conf-cc和conf-ld然后置换所有”cc”为”gcc”就可以了.
现在敲入下面的命令:
make setup check
这个编译完成之后, 你需要作一些安装后配置工作. 运用下面两个脚本用来让工作更简单.
如果你的DNS配置恰当, 运行这个脚本:
./config
如果由于某些原因config 脚本不能在DNS找到你的主机名, 你就必须运行config-fast脚本: (这个原因一般来说是由于config在dns反查主机IP对应的规范的主机名时候没有记录或者出错造成的. 现代商业dns一般都不提供IP反查. 所以安装过程可能更多机会是直接使用config-fast 脚本, 而不是config 脚本. 译者注)
./config-fast the.full.hostname
举个例子, 如果你的域名是example.com, 你的计算机的主机名是dlphin, 你的config-fast 命令行应该这样写:
./config-fast dolphin.example.com
注意: 你可能计划在小型本地局域网使用伪域名比如”.local”, 举例来说, 如果你的主机名是”mash”, 你可能要用 ./config-fast mash.local , 如果你这样作了, 要确定配置qmail在返回地址上使用了合乎逻辑的因特网域名. (参见第3节, 配置.)
qmail现在已经安装到你的系统内, 并且准备运行了! 下一节将要介绍运行和测试qmail.
2.6. 安装 ucspi-tcp
刚才你解压了qmail, ucspi-tcp, 和daemontools 的tarball包, 现在进入ucspi-tcp目录.
cd /usr/local/src/ucspi-tcp-0.88
刚才在编译一节, 如果你修改了conf-cc和conf-ld文件, 你必须在这个目录作同样的修改.
然后, 运行:
patch < /usr/local/src/netqmail-1.05/other-patches/ucspi-tcp-0.88.errno.patch
make
make setup check
ucspi-tcp安装完毕.
2.7. 安装 daemontools
进入daemontools安装目录
cd /package/admin/daemontools-0.76
再说一次, 如果你在编译qmail和ucspi-tcp的时候修改了conf-cc和conf-ld文件, 你必须在在src目录作同样的修改.
然后, 运行:
cd src
patch < /usr/local/src/netqmail-1.05/other-patches/daemontools-0.76.errno.patch
cd ..
package/install
在BSD系统上(没有 /etc/inittab), 你必须重新启动计算机再运行svscan, 这是后台服务器的管理服务程序.
使用 “ps -ef | grep svscan” 或者”ps waux | grep svscan” 检查svscan是否在运行.
注意: 在Solaris下, 你必须修改/etc/inittab中关于svscan的启动条目, 将
SV:123456:respawn:/command/svscanboot
改为:
SV:123456:respawn:/command/svscanboot </dev/null >/var/log/svscan 2>&1
或者改为:
SV:123456:respawn:/command/svscanboot </dev/null >/dev/msglog 2>&1
选择那种方式, 这取决于你是想把启动svscan的出错消息记录到log文件里面还是显示到控制台上. 这样作的必要性请参考下面的文章:
http://marc.theaimsgroup.com/?l=log&m=100327801309834&w=2
注意: 一个Slackware的用户报告x1之前的SV /etc/inittab条目必须被移动, 否则启动后无法运行svscan.
2.8. 运行 qmail
2.8.1. /var/qmail/rc
/var/qmail/boot 目录包含了不同配置的qmail启动脚本示例: /var/spool/mail 方式和$HOME/Mailbox 方式, 使用procmail或者.forward 控制文件, 以及这些方式的不同组合配置. 你可以随意考查这些方式, 不过这里我们选用下面的脚本:
#!/bin/sh # Using stdout for logging # Using control/defaultdelivery from qmail-local to deliver messages by default exec env - PATH="/var/qmail/bin:$PATH" \ qmail-start "`cat /var/qmail/control/defaultdelivery`"
注意: 这个脚本使用了反引号(`), 而不是单引号(’). 最好拷贝和粘贴上文的脚本而不是自己键盘输入, 后者容易出错. (反引号非常小,请仔细看. 译者注)
用你的编辑器将上面的脚本保存为 /var/qmail/rc, 然后执行下面这些命令:
chmod 755 /var/qmail/rc mkdir /var/log/qmail
现在你需要决定一下, 除了由.qmail 文件指示传送的邮件外, 其他邮件将采用何种默认传输方式, (.qmail 文件是指示文件传送路径的重要文件, 后面还会讨论. 译者注)下面的列表大致阐述了几种一般性的选择:
| 邮箱格式 | 名称 | 保存位置 | 缺省的传输方式 | 注释 |
| mbox | Mailbox | $HOME | ./Mailbox | 最常见的格式, 大多数MUA都可以正确识别 |
| maildir | Maildir | $HOME | ./Maildir/ | 更可靠, 少数MUA支持的格式 |
| mbox | username | /var/spool/mail | 参见 INSTALL.vsm文件 | 传统的UNIX邮箱 |
更多信息请参考 INSTALL.mbox, INSTALL.maildir 和 INSTALL.vsm 文件.
选择缺省的邮箱格式, 只要选择上表里面的”缺省传输方式”的值, 填写到/var/qmail/control/defaultdelivery里面就可以了. 例如, 如果选择标准的qmail /Mailbox 传送格式, 这样作就行了:
echo ./Mailbox >/var/qmail/control/defaultdelivery
注意: defaultdelivery并不是标准的qmail控制文件. 而是上文/var/qmail/rc 文件的要素. 对于qmail-start来说, defaultdelivery 变量只是在没有实际的 .qmail 文件指定传送指令的情况下作为 .qmail 文件的内容出现的. 把这个指令加入到单独的控制文件内, 就不必再在指令内重复引用shell元字符, 避免了出现多行杂乱的命令参数.
2.8.2. 系统启动文件
2.8.2.1. qmailctl 脚本
如果你手动执行/varqmail/rc 脚本, qmail只会部分被运行起来. 可是我们希望希望每次系统启动后, qmail都能自动被启动; 每次系统停止时候qmail自动被关闭.
创建一个如下的 /var/qmail/bin/qmailctl 文件可以完成这个愿望:
#!/bin/sh # description: the qmail MTA PATH=/var/qmail/bin:/bin:/usr/bin:/usr/local/bin:/usr/local/sbin export PATH QMAILDUID=`id -u qmaild` NOFILESGID=`id -g qmaild` case "$1" in start) echo "Starting qmail" if svok /service/qmail-send ; then svc -u /service/qmail-send /service/qmail-send/log else echo "qmail-send supervise not running" fi if svok /service/qmail-smtpd ; then svc -u /service/qmail-smtpd /service/qmail-smtpd/log else echo "qmail-smtpd supervise not running" fi if [ -d /var/lock/subsys ]; then touch /var/lock/subsys/qmail fi ;; stop) echo "Stopping qmail..." echo " qmail-smtpd" svc -d /service/qmail-smtpd /service/qmail-smtpd/log echo " qmail-send" svc -d /service/qmail-send /service/qmail-send/log if [ -f /var/lock/subsys/qmail ]; then rm /var/lock/subsys/qmail fi ;; stat) svstat /service/qmail-send svstat /service/qmail-send/log svstat /service/qmail-smtpd svstat /service/qmail-smtpd/log qmail-qstat ;; doqueue|alrm|flush) echo "Flushing timeout table and sending ALRM signal to qmail-send." /var/qmail/bin/qmail-tcpok svc -a /service/qmail-send ;; queue) qmail-qstat qmail-qread ;; reload|hup) echo "Sending HUP signal to qmail-send." svc -h /service/qmail-send ;; pause) echo "Pausing qmail-send" svc -p /service/qmail-send echo "Pausing qmail-smtpd" svc -p /service/qmail-smtpd ;; cont) echo "Continuing qmail-send" svc -c /service/qmail-send echo "Continuing qmail-smtpd" svc -c /service/qmail-smtpd ;; restart) echo "Restarting qmail:" echo "* Stopping qmail-smtpd." svc -d /service/qmail-smtpd /service/qmail-smtpd/log echo "* Sending qmail-send SIGTERM and restarting." svc -t /service/qmail-send /service/qmail-send/log echo "* Restarting qmail-smtpd." svc -u /service/qmail-smtpd /service/qmail-smtpd/log ;; cdb) tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp chmod 644 /etc/tcp.smtp.cdb echo "Reloaded /etc/tcp.smtp." ;; help) cat <<HELP stop -- stops mail service (smtp connections refused, nothing goes out) start -- starts mail service (smtp connection accepted, mail can go out) pause -- temporarily stops mail service (connections accepted, nothing leaves) cont -- continues paused mail service stat -- displays status of mail service cdb -- rebuild the tcpserver cdb file for smtp restart -- stops and restarts smtp, sends qmail-send a TERM & restarts it doqueue -- schedules queued messages for immediate delivery reload -- sends qmail-send HUP, rereading locals and virtualdomains queue -- shows status of queue alrm -- same as doqueue flush -- same as doqueue hup -- same as reload HELP ;; *) echo "Usage: $0 {start|stop|restart|doqueue|flush|reload|stat|pause|cont|cdb|queue|help}" exit 1 ;; esac exit 0
这个脚本可以在线下载, 地址是http://www.lifewithqmail.org/qmailctl-script-dt70.
(建议所有直接使用, 或者拷贝-粘贴web页面指令和文件格式脚本指令的读者, 都要注意脚本编码转换的问题. 本文讲到的qmail 是在Unix/Linux 类型服务器上运行的, 而UNIX 的回行和DOS/Windows的回车在脚本内表示的ACSII码是完全不同的, 如果遇到这个问题, 在之后的脚本执行中, 可能出现非常奇怪的错误信息. 有兴趣的读者可以在搜索引擎上查找深入介绍内容. 细心的读者还会注意到, 英文原文和翻译版本, 在代码前后都加上了<PRE></PRE>格式符, 其目的就是为了保证指令代码不会被web页面的格式代码”污染”. 译者注)你可以自己输入这个脚本, 不过我推荐你用浏览器下载上面链接的文件.
将上面这个qmailctl 脚本设置为可执行脚本, 然后链接到你的用户执行程序目录:
chmod 755 /var/qmail/bin/qmailctl ln -s /var/qmail/bin/qmailctl /usr/bin
2.8.2.2. supervise 脚本
为 qmail 的服务创建 supervise 目录
mkdir -p /var/qmail/supervise/qmail-send/log mkdir -p /var/qmail/supervise/qmail-smtpd/log
建立 /var/qmail/supervise/qmail-send/run 文件
#!/bin/sh exec /var/qmail/rc
建立 /var/qmail/supervise/qmail-send/log/run 文件:
#!/bin/sh exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/qmail
建立 /var/qmail/supervise/qmail-smtpd/run 文件:
#!/bin/sh QMAILDUID=`id -u qmaild` NOFILESGID=`id -g qmaild` MAXSMTPD=`cat /var/qmail/control/concurrencyincoming` LOCAL=`head -1 /var/qmail/control/me` if [ -z "$QMAILDUID" -o -z "$NOFILESGID" -o -z "$MAXSMTPD" -o -z "$LOCAL" ]; then echo QMAILDUID, NOFILESGID, MAXSMTPD, or LOCAL is unset in echo /var/qmail/supervise/qmail-smtpd/run exit 1 fi if [ ! -f /var/qmail/control/rcpthosts ]; then echo "No /var/qmail/control/rcpthosts!" echo "Refusing to start SMTP listener because it'll create an open relay" exit 1 fi exec /usr/local/bin/softlimit -m 2000000 \ /usr/local/bin/tcpserver -v -R -l "$LOCAL" -x /etc/tcp.smtp.cdb -c "$MAXSMTPD" \ -u "$QMAILDUID" -g "$NOFILESGID" 0 smtp /var/qmail/bin/qmail-smtpd 2>&1
注意: concurrencyincoming并不是标准的qmail控制文件. 它是上面脚本的一个要素. 并且, 第一个LOCAL 行上面的是”破折号 + 数字1″, 下面的tcpserver行上的参数是”破折号 + 小写字母l” . (由于英文小写字母l和数字1容易混淆, 原作者特意补充的注意事项. 由译者将被提到两行修改成为红色. 这也是为什么作者希望读者直接拷贝脚本而不是自行输入避免脚本出错的主要原因之一. 另外注意这个脚本中很多字体很小的引号和反引号. 译者注)
注意: Solaris系统下一般位置的id程序不能正常工作, 请使用这个位置的 /usr/xpg4/bin/id:
QMAILDUID=`/usr/xpg4/bin/id -u qmaild` NOFILESGID=`/usr/xpg4/bin/id -g qmaild`
注意: 根据你的操作系统和硬件平台的不同, 可能需要调整softlimit命令的的内存限制参数. 如果你的系统出现连接25端口失败和无法接收远程系统发送的邮件, 或者看到了类似下面这样的错误消息:
/usr/local/bin/tcpserver: error while loading shared libraries: libc.so.6: failed to map segment from shared object: Cannot allocate memory
试一下把这个参数调整到3000000到4000000.
建立concurrencyincoming 控制文件.
echo 20 > /var/qmail/control/concurrencyincoming chmod 644 /var/qmail/control/concurrencyincoming
建立 /var/qmail/supervise/qmail-smtpd/log/run 文件
#!/bin/sh exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/qmail/smtpd
将各个run文件设置为可执行文件:
chmod 755 /var/qmail/supervise/qmail-send/run chmod 755 /var/qmail/supervise/qmail-send/log/run chmod 755 /var/qmail/supervise/qmail-smtpd/run chmod 755 /var/qmail/supervise/qmail-smtpd/log/run
然后建立log文件目录:
mkdir -p /var/log/qmail/smtpd chown qmaill /var/log/qmail /var/log/qmail/smtpd
最后, 建立 supervise 目录到 /service 目录的链接:
ln -s /var/qmail/supervise/qmail-send /var/qmail/supervise/qmail-smtpd /service
/service 目录是 daemontools 安装时建立的目录.
注意: 建立这个链接之后 qmail 系统会很快自动被启动起来, 如果你还不想立刻运行qmail, 运行下面这个,命令来停止qmail:
qmailctl stop
2.8.2.3. SMTP 访问控制
允许本地主机通过SMTP方式发送邮件:
echo '127.:allow,RELAYCLIENT=""' >>/etc/tcp.smtp qmailctl cdb
2.8.3. 停止并且禁用(其他)已经安装的MTA
虽然有可能同时运行qmail 和现存的MTA, 比如Sendmail, 不过我建议你除非你知道自己到底在干什么, 否则可不要这么干. 说实话, 如果你正在读我这段话, 你可能也不知道自己在干嘛. :-)
如果现存的MTA是Sendmail, 你应该能利用运行Sendmail的init.d脚本的”stop”参数来停止它的运行. 例如下面命令中的一个可能是有效的:
/etc/init.d/sendmail stop /sbin/init.d/sendmail stop /etc/rc.d/init.d/sendmail stop
如果你找不到任何一个init.d/sendmail 下的脚本, 你可以用 “ps -ef|grep sendmail” 或者 “ps waux|grep sendmail” 命令找出 sendmail 的PID, 然后用下面的命令来停止Sendmail: (kill 命令加上Sendmail的PID作参数, 译者注)
kill PID-of-sendmail
如果你的MTA不是Sendmail, 检查相关文档找出正确的停止MTA的方法.
你应该考虑一下把旧的MTA彻底的从你的系统里面删除. 至少禁用它的 init.d 脚本, 防止下一次系统重启动的时候旧的MTA也被试图重启.
对于使用rpm方式安装Sendmail的 Red Hat Linux, 执行下面的命令来删除Sendmail:
rpm -e --nodeps sendmail
注意: 如果你使用基于RPM方式的Linux, 比如 Red Hat, 删除MTA可能带来进一步的问题. 系统的某些应用程序将会试图重新安装Sendmail, 一些MUA程序将无法安装, 因为他们找不到安装好的MTA. Mate Wierdl 提供了一个占位程序, 称作 “fake_mta”, 安装这个程序之后可以防止出现以上的问题. 简单的RPM安装包可以在下面的地址取得 http://www.csi.hu/mw/fake_mta-1-1memphis.noarch.rpm.
检查一下没有其他程序在监听SMTP服务端口(25). 旧的MTA, inetd, 或者 xinetd 等程序都有可能造成问题. (按照以上步骤执行后, 再) 运行下面的命令应该是没有输出结果的(除非这个时候 qmail-smtpd 服务也在运行).
netstat -a | grep smtp
如果有什么程序在运行, 首先确定不是qmail, 那么先运行下面的命令:
qmailctl stop
然后重复 netstat 检查:
netstat -a | grep smtp
如果你还是能看到这个命令有一些输出, 你就必须在qmail 的SMTP服务运行起来之前把肇事程序找出来.
最后, 将现存的 /usr/lib/sendmail 替代为 qmail 版本.
mv /usr/lib/sendmail /usr/lib/sendmail.old # 忽略错误提示 ignore errors mv /usr/sbin/sendmail /usr/sbin/sendmail.old # 忽略错误提示 ignore errors chmod 0 /usr/lib/sendmail.old /usr/sbin/sendmail.old # 忽略错误提示 ignore errors ln -s /var/qmail/bin/sendmail /usr/lib ln -s /var/qmail/bin/sendmail /usr/sbin
注意: 创建 sendmail 的链接是很重要的, 即使不管以前的MTA, sendmail 命令也是一个会被很多程序调用来发送邮件的重要命令.
最后步骤是建立两个系统别名.
2.8.4. 建立系统别名
在所有 qmail 安装上面都要建立四个系统别名:
| 别名 | 目的 |
| postmaster | RFC 2821 标准要求, 指向邮件系统管理员(也就是你) |
| mailer-daemon | 反弹邮件事实上的标准接收者 |
| root | 转发特权用户, 根(root)用户的邮件给系统管理者 |
| abuse | 事实上的邮件滥用(垃圾邮件)举报地址 |
建立这些系统别名, 取决于你想让这些邮件发送到哪里(一个本地用户或者一个远程地址)并且适当的创建一个.qmail 文件集合. 举个例子, 加入你想让本地用户 dave 接收发给系统管理员和邮件管理员的邮件, 就这么作:
echo dave > /var/qmail/alias/.qmail-root echo dave > /var/qmail/alias/.qmail-postmaster ln -s .qmail-postmaster /var/qmail/alias/.qmail-mailer-daemon ln -s .qmail-postmaster /var/qmail/alias/.qmail-abuse chmod 644 /var/qmail/alias/.qmail-root /var/qmail/alias/.qmail-postmaster
在 INSTALL.alias 文件里面有更详细的细节.
2.8.5. 运行 qmail
如果依照上文, 你创建 /service 之后就停止了qmail, 你现在应该重新启动 qmail:
qmailctl start
2.9. 测试安装
qmail 现在应该是正在运行的状态. 首先运行 qmailctl stat 来检验那些服务启动并运行中:(下面命令后部分为演示结果, 并不是必然如此的系统输出. 译者注)
# qmailctl stat /service/qmail-send: up (pid 30303) 187 seconds /service/qmail-send/log: up (pid 30304) 187 seconds /service/qmail-smtpd: up (pid 30305) 187 seconds /service/qmail-smtpd/log: up (pid 30308) 187 seconds messages in queue: 0 messages in queue but not yet preprocessed: 0
所有的四个服务都应该是”up”(启动了)1秒钟以上. 如果不是这样, 你可能就是在写脚本的时候写错了一些东西或者你漏过了创建一个甚至多个必要的文件, 目录或者链接. 返回上面的安装指导, 一步一步的再检查一下你的工作. 你也可以下载并运行 inst_check 脚本, 在这里下载 http://lifewithqmail.org/inst_check. 举个例子:
# sh inst_check ! /var/log/qmail has wrong owner, should be qmaill ...try: chown qmaill /var/log/qmail #
如果 inst_check 发现了问题, 解决问题后重新运行这个检查脚本. 当所有情况被判断为正确的时候, inst_check 将会报告:
Congratulations, your LWQ installation looks good!
readproctitle 程序维持着由svscan 管理的各个服务的错误消息的日志. 使用 ps 或者其他进程列表命令. 举个例子, 你可以看到类似下面这样的输出:
# ps -efl | grep "service errors" | grep -v grep 000 S root 1006 1001 0 76 0 - 334 pipe_w Mar31 ? 00:00:00 readproctitle service errors: ...unable to start qmail-smtpd/run: exec format error #
这个例子里面, 问题出在 /service/qmail-smtpd/run 这个脚本的第一行–很有可能由于脚本文件是 DOS 格式 (DOS使用回车符-换行符结束一行的方式和Unix的仅仅用换行符方式不同).
有时候为了检验配置错误, 手动运行一下服务也会很有帮助的. 举个例子, 如果你的 qmail-smtpd/log 服务没有运行, 那么执行下面的命令:
cd /service/qmail-smtpd/log svc -d . ./run 如果没有错误, 输入一行字符然后按回车键 如果还是没有错误, 输入CTRL-D (文件结束符)
这个时候, 你应该能够识别问题所在并且解决它了. 这个做完之后, 返回服务目录, 如果有必要, 运行命令:
svc -u .
一旦那些服务的启动时间都大于1秒钟后, 依照 TEST.deliver 和 TEST.receive 文件里面的指令去校验服务是否正确的工作. 注意, 应用这些指令, 日志将由multilog 程序记录到 /var/log/qmail 下, 而不是 splogger 记录到类似 /var/log/maillog 的文件里面.
注意: 如果你选择了 maildir 邮箱格式作为默认的传送方式, 在运行这些指令之前, 你必须在你的主目录和别名的主目录创建 Maildir 目录. 参见 maildir 小节查找如何恰当的创建这个目录.
3. 配置
你已经从源代码tarball方式, 或者自编译包方式, 或者var-qmail包方式安装了 qmail. 这一节的内容就是按照你的需要配置qmail.
3.1. 配置文件
所有的qmail系统配置文件, 除了在~alias下的 .qmail 文件, 都位于 /var/qmail/control 目录下. qmail-control 的man手册页包括了一个像下面这样的表:
查找这些特殊控制文件的更多信息, 请参考上面表格 “被用于” 列下的各个模块的 man 手册页.
3.2. 中继转信
3.2.1. 介绍
什么是转信? 转信是 MTA 通过SMTP接收到一封既不是发给本地地址也不是从本地发送者发来的邮件之后, MTA转发这个邮件的动作就是转信.
在垃圾邮件时代之前, MTA被配置为开放转信是很常见的: 各种各样的服务器接受来自任何人的邮件, 转发给任何人.
现代的绝大多数 MTA 都被配置为或者完全禁止转信, 或者只允许某些被信任的用户或者系统使用中继转信功能.
Chris Johnson 为qmail 的用户写了一个非常好的文档. 我鼓励你去看一看: http://www.palomine.net/qmail/relaying.html.
3.2.2. 禁止转信
如果你是按照 qmail 的正式安装指导安装的话, 那么转信在默认情况下已经被关闭了. 这个功能是通过把local和virtualdomains(指本地主机)文件里面列出的有充分资格的域名写入 /var/qmail/control/rcpthosts 文件来完成的. rcpthosts 这个文件名是来源于SMTP对话中的的RCPT(接收者)命令. 在SMTP对话里面, RCPT是用来确认邮件接收者地址的, 然后, rcpthosts 列出可以出现在RCPT地址里面的有效的主机名.
3.2.3. 允许有选择的转信
大多数单用户和小型工作组服务器可以完全禁止转信, 可是如果你维护的是一个分布式的用户社区, 你就必须有一个方式能够允许你的用户, 而且只能是你的用户通过的你的系统转信. 本文是通过使用 tcpserver 来设置RELAYCLIENT 环境变量, 使 qmail-smtpd 重载 rcpthosts 文件完成这个功能的.
如果你是按照这个文档的指导安装的话, 有选择的转信已经在默认情况下安装好了. 如果需要给客户端转信权利, 首先在 /etc/tcp.smtp 文件里面增加类似下面的行:
IP address of client:allow,RELAYCLIENT=""
(斜体IP address of client代表客户端的IP地址. 译者注) 然后重建SMTP的访问许可数据库:
qmailctl cdb
或者运行下面的命令(重建数据库):
tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp chmod 644 /etc/tcp.smtp*
如果你是按照正式安装指导安装的, Chris Johnson写了另外一个非常好的如何配置qmail允许选择主机转发邮件的文档, 参见: http://www.palomine.net/qmail/selectiverelay.html.
3.2.4. 使用smart host中继转信
如果在一个典型的家庭宽带上网条件下建立邮件服务器, 那么将有非常大的可能, 这个服务器的IP地址会被列入黑名单, 比如SORBS(http://www.dnsbl.sorbs.net/lookup.shtml)的黑名单, 这样作是为了防止垃圾邮件. 绝大多数ISP都给他们的用户提供SMTP服务器用来转信, 这些服务器通常不在黑名单内. 举个例子, Road Runner(美国某ISP. 译者注)在辛辛那提(美国地名. 译者注)使用smtp-server.cinci.rr.com 这个服务器来为她的用户提供SMTP转信服务. 你可以让qmail 将所有向外传送的SMTP 访问都通过这个服务器, 你可以这样作:
echo ":smtp-server.cinci.rr.com" > /var/qmail/control/smtproutes
smtproutes 文件可以提供更多的路径选择功能, 请参考qmail-remote 的man 帮助文档.
3.3. 多主机名
如果你的主机名已知配置了多个名字, 例如, 所有的来自user@host1.example.com 的地址也可以被写成 user@example.com 或者 user@mail.example.com, 那么你就必须告诉 qmail 哪一个地址是它应该本地传送的地址, 哪一个地址是它应该接受的远程主机发送的地址.
如果要这样作, 只要把所有的名字加入下面两个控制文件就行了:
- rcpthosts, 这个文件通知 qmail-smtpd 接收这个主机可以接受的地址. 还有
- locals, 这个文件通知 qmail-send 哪些地址是本地传送地址.
给 qmail-send 发送一个HUP(挂起)信号来通知它重新读取 locals文件. 如果你使用的是本文的 qmailctl 脚本, 那么运行下面的命令就可以了:
qmailctl reload
3.4. 虚拟域
虚拟域和上节提到的多主机名类似, 不过这里面有一些很重要的不同之处. 首先如果 example.net 是 virtual.example.net 虚拟域的宿主主机, 那么一个发送给 joe@virtual.example.net 的邮件将不会被发送给即使是同一个邮箱的 joe@example.net, 这里虚拟域的名字空间是冲突的.
使用 qmail, 虚拟域将在 virtualdomains 文件里面配置, 文件内由型如下面这行的条目构成:
user@domain:prepend
qmail 转换 user@domain 为 prepend-user@domain 并且将这个转换后的名字作为本地域一样对待. user@ 这个部分是可选的, 如果缺少这个部分, 这个名字将匹配所有 @domain 域下面的地址.
回到上文的 example 剧情里面, 如果 example.net 邮件管理员希望创建 virtual.example.com 虚拟域, 并且将这个域置于用户 john 的管理之下, virtualdomains 文件下面的虚拟域条目应该这样写:
virtual.example.com:john
这样, 发往 joe@virtual.example.com 的邮件将会被修改为发往 john-joe@virtual.example.com , 然后进行本地传送. 更多信息, 请参见 .qmail 小节, 以及 扩展地址 细目. 那里将介绍 john 如何管理他的虚拟域.
使用多主机名的时候, 所有的虚拟域都必须在rcphosts列出, 这样 qmail-smtpd 才会知道那些地址的邮件才应该被接受. 但是不像多主机名方式, 虚拟域不可以在locals里面设置相应条目.
修改 virtualdomains文件之后, 发送给 qmail-send 一个 HUP (挂起) 信号, 通知它重新读取配置文件. 如果你使用本文的 qmailctl 脚本, 你可以运行如下命令:
qmailctl reload
同时, 不要忘了在 rcpthosts 里面增加虚拟域条目.
注意: 必须设置域名服务器(DNS)的邮件交换器(MX)记录, 以使虚拟域指向正确的邮件服务器. 这是名字服务器管理员的工作, 超出了本文讨论的范围.
3.5. 别名
qmail的标准别名机制是由qmail的本地传送机制自然派生出来的.qmail-local 试图传送地址为 localpart@host 的邮件给本地叫做 localpart 名字的用户. 如果没有匹配这个名字的用户存在, 邮件将会被发送给别名 alias 用户, 别名用户是qmail系统里面通常主目录位于 /var/qmail/alias 的伪用户.
举例, 如果你想要创建一个叫做 info@example.com 的别名, 这个别名用户将把上文收到的所有无主邮件转发给用户 tom, 在我们举例的 example.com 上, 这样作的方式是: 作为 root 用户, 运行下面的命令:
echo \&tom > /var/qmail/alias/.qmail-info
.qmail 小节, 以及 扩展地址 细目介绍了如何创建 .qmail文件, 这些文件确定了那些别名存在, 以及如何处理哪些发给他们的邮件的.
附录 新手常见问题 介绍了两个关于别名应用的复杂案例. 那些别名使用了大写字母和小数点(”.”), 以及 .qmail 文件的 man 手册页面, 其中包含了完整的关于 .qmail 文件用法的文档.
注意由于别名在 qmail 里面的实现方式, 别名是不能够优先与一个已知用户的传送的. 例如, 如果 rachel 是一个普通用户, 那么~alias/.qmail-rachel 别名是无效的.
fastforward 软件包另外提供了一个可行的别名机制, 它将多个别名放入单独一个和Sendmail别名数据库兼容的文件里面.
下一节, qmail-users, 描述了其他实现别名的机制.
3.6. 关于 qmail-users
qmail-users 是一个分发地址给用户的系统. 由 /var/qmail/users 下的一系列文件构成. assign 文件是一个分配表. 有两种分配表的格式: 单体方式和通配符方式.
注意: assign 文件包含了一系列分配表, 每行一个, 后面接一个包含了一个单独的小数点(.)的行. 如果你手动创建assign文件, 不要忘记小数点那一行.
3.6.1. 单体分配表
一个单体分配表看起来是这个样子的:
=address:user:uid:gid:directory:dash:extension:
这个表的含义是: 作为 address 地址接收的邮件将会被使用用户 user 来传送, 使用指定的 uid 和 gid, 并且由 directory/.qmaildashextension 这个文件决定邮件如何被传送.
3.6.2. 通配符分配表
通配符分配表看起来是这个样子的:
+prefix:user:uid:gid:directory:dash:prepend:
这个表的含义是: 作为 prefixrest 地址里面匹配的邮件地址接收的邮件, 将会被使用用户 user 来传送, 使用指定的 uid 和 gid, 并且由 directory/.qmaildashextension 这个文件决定邮件如何被传送.
3.6.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 </etc/passwd >/var/qmail/users/assign qmail-newu
3.7. 反垃圾邮件
Chris Hardie 写了一个极好的的qmail反垃圾邮件 HOWTO. 可以在这个地址访问到它: http://www.summersault.com/chris/techno/qmail/qmail-antispam.html.
3.8. 病毒扫描
Jason Haar编写了 Qmail-Scanner, 一个为qmail设计的内容扫描装置. 更多信息请参见 http://qmail-scanner.sourceforge.net/.
Qmail-Scanner 包括了一个简单策略阻止组件(例如, 阻止*.scr文件, 或阻止”Yellow!”这样的标题), 同时也直接支持许多不同的防病毒”插件”, 包括ClamAV Antivirus扫描器 http://www.clamav.net/.
4. 使用方法
这一节介绍了qmail 针对普通用户的使用方法. 如果你在 qmail 系统上读信和发信, 那么你阅读本节就可以找到如何用qmail 达成你的目的了.
4.1. .qmail 文件
传送用户邮件通常是由一个或者几个 “.qmail”(发音 dot kyoo mail) 文件控制的. 这些文件位于用户的主目录, 文件名由 .qmail 开头. .qmail 的man 手册页面描述了 .qmail 文件使用方法.
.qmail 文件包括了一个传送指令清单, 每行一个指令. 每行的第一个字符决定了选择那种传送方式.
| 字符 | 传送类型 | 值 |
| # | 无 (注释) | 忽略 |
| | | 程序 | 由shell 执行的命令 |
| / 或者 . | mbox邮箱格式 (如果路径最后一个字符不是一个斜杠) | mbox 的路径名 (包括斜杠”/”或者 点”.”) |
| / 或者 . | maildir邮箱格式 (如果路径最后一个字符是一个反斜杠) | maildir 的路径名 (包括斜杠”/”或者 点”.”) |
| & | 转发 | 转发邮件的地址 |
| 字母或者数字 | 转发 | 转发邮件的地址 (包括第一个字符) |
4.1.1. 程序传送
如果.qmail 文件内指令由程序传送, qmail 将启动一个 shell (/bin/sh) 来执行这个命令, 然后使用标准把邮件的一个副本传送给这个命令. qmail-command 的man 帮助文档对这个过程有详细描述.
程序传送是非常强大的, 被用来实现的功能范围非常广阔, 例如邮件过滤, 自动回复, 以及通过第三方传送代理比如procmail来传送邮件.
例如:
|preline /usr/ucb/vacation djb
这个指令操作qmail 启动preline, 将 /usr/ucb/vacation 和 djb 作为参数传送给 preline, 并且使用标准输入将邮件的副本传送给这个命令.
4.1.2. mbox 格式邮箱的邮件投递
mbox 是标准的UNIX邮箱格式, 在一个独立文件内存放多个邮件, 每个邮件由一个”From” 的开头的行开始. 这一行看起来像一个邮件头字段, 不过那不是邮件头, 那仅仅是传送代理添加的, 作为一个标记,便于找到每个邮件的开始部分.
例如:
./Mailbox
这个设置表示邮件将被追加到 $HOME/Mailbox 文件上, 每个邮件由”From”开头的行引领. 一个只存放了一个邮件的, 简单的mbox 的邮箱看起来是下面这个样子的:
From user1@example.net Thu May 13 18:34:50 1999 Received: (qmail 1287205 invoked from network); 13 May 1999 18:34:49 -0000 From: user1@example.net To: user2@example.com Subject: hey What's up?
第一行是 qmail 传送邮件时添加的.
4.1.3. maildir 格式邮箱的邮件投递
maildir 是 Dan Bernstein 为了表明 mbox 邮箱格式的缺陷而创造的格式. 一个 maildir 邮箱包含三个子目录, new, cur, 和 tmp. 在各个子目录下的每个邮件根据状态的不同分别存储在各个子目录下独立的文件中. 未读邮件存储在new中, cur存储已读邮件, tmp 是为那些正在传送过程中的邮件使用的. maildir 的man手册页详细描述了maildir格式的细节.
maildir 格式的优点之一就是保证邮件传输的安全, 即使在不锁定情况下, 不同邮件代理同时更新邮件, 也能保证传输的可靠. 这意味着maildir 邮箱可以安全的建立在以NFS性质挂接的文件系统上.
例如:
./Maildir/
这个设置表示将把邮件存储在 $HOME/Maildir 下面的 maildir 格式的邮箱.
注意: qmail-local 可以将邮件传送到 maildir 格式邮箱, 但是不能创建这种邮箱. 你需要使用qmail 附带的maildirmake 程序来创建 maildir 格式邮箱. 例如: “maildirmake ~/Maildir”. 不过要确定你使用maildir的拥有者运行maildirmake, 而不是 root 用户. 另外的方式, 你的 useradd 和 adduser 命令可能支持”skeleton”骨架目录, 例如: /etc/skel, 然后可以直接复制这个目录给所有新用户.
4.1.4. 转发邮件
转发邮件就是将邮件重发到指定地址. 这些写入.qmail文件内的地址不能包含注释部分和多余的空格.
下面的写法是错的:
&<user@example.com> & user@example.com &Joe User <user@example.com>
下面的是正确的写法:
&user@example.com user@example.com &user
前两个将邮件副本转发给 user@example.com, 最后一个将邮件副本转发给本地用户 user.
4.1.5. 扩展地址
qmail 支持用户控制扩展地址. 在基本地址 username@hostname.domain 上扩展的扩展地址为: username-extension@hostname.domain ,用户同样可以接收发往扩展地址的邮件. 在本节其余部分, 我们讨论的范围都是在本地系统上, 所以我们将不再使用”@hostname.domain” 部分.
给用户 username 的邮件传送指令由 ~username/.qmail 文件指定. 对于型如username-extension 的扩展地址的传送指令由用户目录下的~username/.qmail-extension 文件指定.
举一个例子, dave-lwq@sparge.example.com 这个扩展地址的传送将由文件 ~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文件, 传送失败, 并且将邮件反弹给发送者.
4.2. 发送邮件
邮件用户通常并不直接发送邮件. 典型的方式是利用邮件用户代理(Mail User Agent, MUA)程序, 例如 pine 或者 mutt 编写并发送邮件. MUA程序调用MTA传送邮件. 这个处理邮件到MTA的调用过程称为注入(injection).
有两种方式完成注入, 一种利用SMTP协议(Simple Mail Transfer Protocol, SMTP), 或者利用MTA提供的的特定程序.
4.2.1. SMTP 方式
MUA程序可以使用TCP协议连接到标准的SMTP协议端口25, 可以是本地主机或者指定的邮件服务器. MUA和MTA后续进行的回话导致两个结果:
- 邮件被传送给MTA, 或者
- 返回一份错误报告给MUA
SMTP没有身份认证的机制, 所以发送邮件的过程是不要求用户名和密码的. 但是, 大多数MTA拒绝接收既不是来自本地用户也不是发送给本地用户的邮件的. 如果一个恰当的格式的邮件被MTA拒绝, 最大的可能就是转信限制造成. 参见转信小节查看更多的如何配置转信的信息.
4.2.2. /var/qmail/bin/sendmail 文件
很多年以来, UNIX MTA一直都是Sendmail. 由于Sendmail的应用十分普遍, 许多程序员假定它是默认的MTA. 结果, Sendmail的本地注入机制成为标准的本地邮件注入的应用编程接口(Application Programmer’s Interface, API). qmail 以及其他非Sendmail的MTA因此也提供一个sendmail程序应用于本地注入方式上, 它的工作方式和真正的Sendmail 的 sendmail程序一样.
qmail 的用于替换Sendmail相应部分的 sendmail 程序, 通常位于 /var/qmail/bin/sendmail, 典型的Sendmail的程序位于下面这些位置:
- /usr/lib/sendmail
- /usr/sbin/sendmail
在qmail系统里面, 使用命令”ls -l path-to-sendmail“将会显示出, sendmail实际上是一个指向/var/qmail/bin/sendmail 的符号连接.
$ ls -l /usr/lib/sendmail lrwxrwxrwx 1 root root 29 Feb 19 11:04 /usr/lib/sendmail -> /var/qmail/bin/sendmail
4.2.3. qmail-inject
除了模仿 sendmail 的 API之外, qmail 也拥有自己的注入程序: qmail-inject. 实际上, qmail提供的sendmail 程序只是一个qmail-inject的外壳程序.
作为一个API标准, sendmail可能更好用, 因为它使用广泛. qmail的API由qmail-inject提供, 只能在qmail系统下运行, 而sendmail接口几乎是全球通用的.
举一个例子, 可以这样发送一个空白邮件给 joe@example.com:
echo To: joe@example.com | /var/qmail/bin/qmail-inject
4.3. 环境变量
一些qmail程序设定和使用环境变量, 下面的表格列出了这些变量并且描述了他们的用法.
| 字母 | 使用目的 |
| c | 为From部分使用地址注释风格 |
| s | 不考虑任何传入邮件的返回路径部分 |
| f | 删除所有传入邮件的From部分 |
| i | 删除所有传入邮件的Message-ID部分 |
| r | 使用每接收者VERP |
| m | 使用每邮件VERP |
5. 高级话题
5.1. 关于 procmail
procmail 是一个流行的邮件传送代理( Message Delivery Agent , MDA). MDA的功能是从MTA为特定用户或者邮箱接收邮件, 然后按照用户的要求传送邮件的程序. procmail 可以用来针对邮件主体或者不同的邮件头内容过滤邮件. 举一个例子, 从某个特定的人发来的邮件可以被定向传送到某个专门为这个人准备的邮箱.
在qmail上应用procmail有两个技巧. 第一个, procmail 通常被配置成传送邮件到/var/spool/mail 下的mbox 格式的邮箱. 你可以重新设置安装procmail到缺省的$HOME 路径下, 或者指导用户不要依赖procmail 将邮件投递到默认的mbox位置. 除非你为$HOME 邮件投递方式打补丁, 否则, procmail依然会使用/var/spool/mail 作为临时文件.
另外一个问题是qmail-command和procmail使用的退出码是不同的. procmail使用的是标准UNIX退出码: 零代表成功, 非零代表失败, 失败的原因由/usr/include/sys/errno.h 定义. qmail-command 使用某个非零码指示永久错误, 其余作为临时码. 解决方式可以应用一个小的shell脚本为 qmail-command 翻译退出码. 这样的一个shell脚本曾经在qmail 邮件列表刊登, 现在被存档在这个位置http://www.ornl.gov/lists/mailing-lists/qmail/1998/04/msg00487.html.
同样的情况, 旧版本的procmail(3.14之前)不能直接传送邮件给maildir格式的邮箱. 最好的办法是升级你的procmail到最新版本. 另外一个解决办法是使用safecat, 这个程序将标准输入的邮件写入指定的maildir格式的邮箱. 用户可以使用 procmail 处方(传送指令)来使用safecat 保存邮件. 也可以完全跳过procmail, 使用maildrop.
最后, procmail 认为邮件将被接收到mbox格式的邮箱, 常规的qmail传送程序仅仅包括实际的邮件, 而不包括”From”起始行. 这里可以使用preline 命令来格式化邮件, 以保证procmail的要求. 上面链接提到的脚本就包括了 preline.
举一个例子, 假设用户”dave”希望用procmail来处理他的邮件. 他的系统管理员设置procmail来传送邮件到默认的$HOME, 并且已经配置好了上面的退出码翻译脚本程序, 假设名字是 /usr/local/bin/qmail-procmail, 那么他的.qmail文件应该是这个样子的:
|/usr/local/bin/qmail-procmail
5.2. POP 和 IMAP 服务器
qmail包括一个POP服务器, qmail-pop3d, 不过并没有作为qmail 安装过程的一部分. 你可以选用其他POP或者IMAP服务器, 尽管他们大多数都是为Sendmail编写的, 在qmail下运行这些服务器时, 需要作一些额外的修改工作.
5.2.1. qmail-pop3d
qmail-pop3d 是qmail自带的很不错的POP服务器. 很多qmail站点都使用它作为POP服务器. 它是模块化的, 可以通过不同的认证模块支持多种认证方案.
注意: qmail-pop3d只支持maildir格式的邮箱, 所以如果你的用户登录到POP服务器并且在本地运行MUA程序, 这些程序必须支持maildir格式的邮箱. 如果所有用户都是通过POP来读取邮件, 那么服务器端的邮箱格式就不是什么问题了.
5.2.1.1. qmail-pop3d的结构
qmail-pop3d服务器包括三个模块:
- qmail-popup: 取得用户名/密码
- checkpassword: 鉴别用户名/密码
- qmail-pop3d: POP后台服务程序
典型的, qmail-popup由inetd 或者 tcpserver运行, 在110端口监听, 一旦有连接, 它将提示输入用户名和密码, 然后它调用checkpassword来校验用户名/密码, 通过校验后调用qmail-pop3d.
5.2.1.2. 安装 qmail-pop3d
1. 完整安装并测试qmail. 如果你希望所有用户都可以用 POP 方式访问邮箱, 那么首先确定 defaultdelivery 文件内容已经设置为 ./Maildir/. 如果你是按照本文的安装小节安装的qmail, /var/qmail/rc脚本已经被安装到恰当位置, 那么在文件 control/defaultdelivery 中已经配置了这个参数. 如果不是这样安装的, 则这个参数可能是在/var/qmail/rc 的 qmail-start 命令行上实现的.
2. 从http://www.qmail.org/top.html#checkpassword下载checkpassword 程序. 如果你不需要其他特别的东西, 也可以在http://cr.yp.to/checkpwd.html 下载标准的checkpassword程序.
3. 按照安装指导编译并安装checkpassword程序. 确定你安装程序到 /bin/checkpassword 下.
注意: 如果你安装的是标准checkpassword, 解开源代码之后别忘记打修补错误返回码的补丁:
patch < /usr/local/src/netqmail-1.05/other-patches/checkpassword-0.90.errno.patch
4. mkdir /var/qmail/supervise/qmail-pop3d5. 创建一个/var/qmail/supervise/qmail-pop3d/run 脚本, 包括如下内容:
#!/bin/sh exec /usr/local/bin/softlimit -m 2000000 \ /usr/local/bin/tcpserver -v -R -H -l 0 0 110 /var/qmail/bin/qmail-popup \ FQDN /bin/checkpassword /var/qmail/bin/qmail-pop3d Maildir 2>&1
这里 FQDN 是你建立的POP服务器的完整的有资格的正式域名, 例如, pop.example.net.
注意: 由softlimit命令 指定的内存使用限度是可以依赖于你是用的的硬件平台和操作系统作适当提高的. 当连接到110端口失败或者POP3连接以难以理解的方式失败情况下, 或者你查看到如下错误信息:
/usr/local/bin/tcpserver: error while loading shared libraries: libc.so.6: failed to map segment from shared object: Cannot allocate memory
试着将这个参数提高到3000000或者5000000.
6. mkdir /var/qmail/supervise/qmail-pop3d/log7. 创建包括以下内容的/var/qmail/supervise/qmail-pop3d/log/run 文件.
#!/bin/sh exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t \ /var/log/qmail/pop3d
8. 建立log日志文件夹并且设置相应的run脚本, 将脚本链接到 /service 目录:
chmod +t /var/qmail/supervise/qmail-pop3d # if daemontools < 0.75 mkdir /var/log/qmail/pop3d chown qmaill /var/log/qmail/pop3d chmod 755 /var/qmail/supervise/qmail-pop3d/run chmod 755 /var/qmail/supervise/qmail-pop3d/log/run ln -s /var/qmail/supervise/qmail-pop3d /service
9. 将下面内容加入qmailctl脚本的”start”部分
if svok /service/qmail-pop3d ; then svc -u /service/qmail-pop3d /service/qmail-pop3d/log else echo qmail-pop3d supervise not running