在CentOS5中安裝Qmail商業郵件系統

Clam AntiVirus是專為UNIX而設的GPL防毒軟件,主要用於郵件伺服器(附件掃描)。整套
軟件包括多執行緒常駐程式、指令式掃描器和自動網上更新工具(作為優秀的防毒軟件,最
重要的當然是經常更新病毒資料庫)。透過這些由Clam AntiVirus套裝軟件所分發的共用檔
案庫程式,讓您自由結合軟件.

以下是其主要功能:
-------------------------------------------------------------------------------
指令式掃描器
快速及多執行緒的常駐程式
可結合sendmail使用的milter介面
支援數碼簽署的病毒資料庫更新功具
病毒掃描器C檔案庫
on-access掃描功能(Linux®及FreeBSD®)
每天多次更新病毒資料庫(病毒識別碼的總數可參閱網頁)
內置支援RAR (2.0)、Zip、Gzip、Bzip2、Tar、MS OLE2、MS Cabinet檔案、MS CHM (壓縮HTML)、MS SZDD
內置支援mbox、Maildir和原始郵件檔案
內置支援用UPX、FSG和Petite壓縮的Portable Executable檔案
-------------------------------------------------------------------------------

ClamAV的基本安装包含了三个二进制工具(在/usr/bin目录下):
-------------------------------------------------------------------------------
freshclam - As you know an anti-virus solution is only as good as the latest
virus updates it has. This tool is used to update the virus databases on your
system. It downloads the latest virus updates from the internet and keeps your
anti-virus solution upto date.

clamscan - This is the tool that actually checks your files to see if they are infected.

sigtool - When you download the latest virus updates from the net, there should
be a way of verifying the validity of the update. This is achieved by the sigtool.
It is used to verify the digital signatures of databases and list virus signature
names among other things.
-------------------------------------------------------------------------------
===============================================================================


===============================================================================
1) 检查系统所需相关套件和用户帐号(ClamAV需要zlib,bzip和gmp套件支持):
===============================================================================
-------------------------------------------------------------------------------
用RPM命令检查是否已经安装如下套件:
-------------------------------------------------------------------------------
rpm -qa | grep zlib;
rpm -qa | grep zlib-devel;
rpm -qa | grep bzip2;
rpm -qa | grep bzip2-devel;
rpm -qa | grep gmp;
rpm -qa | grep gmp-devel;
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
如果没有安装相关套件,可用如下命令安装:
-------------------------------------------------------------------------------
yum install zlib;
yum install zlib-devel;
yum install bzip2;
yum install bzip2-devel;
yum install gmp;
yum install gmp-devel;
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
检查openssl套件:
-------------------------------------------------------------------------------
rpm -qa | grep openssl;
yum list | grep openssl;        #检查是否需要安装或更新

yum install openssl;
yum update openssl;
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
建立用户帐户:
-------------------------------------------------------------------------------
如果是第一次安装,系统应该还没有相关帐号,就要新建立:

groupadd clamav;
useradd -g clamav -s /bin/false -c "Clam AntiVirus" clamav;

请注意: 后面将介绍的RPM和YUM安装方法会自动安装用户帐号,如果采用这两种方法安装,
可以忽略建立用户的步骤; 但为了提高安全性和统一性, 建议一并使用上述命令手工建立
用户帐户.

請注意: 因为本系统的clamav将要结合qmail-scanner来扫描电邮,即通过 qmail-scanner
腳本来调用ClamAV的掃描功能, 因此ClamAV的日志文件权限必须设置成qmail-scanner的
执行者具有读写權限,否則會導致無法接受電郵;
-------------------------------------------------------------------------------
===============================================================================


===============================================================================
2) 安装ClamAV防病毒系统(如下A,B和C三种方法可任选其一);
===============================================================================
-------------------------------------------------------------------------------
A) YUM在线安装方法(简单方便,推荐用此方法):
-------------------------------------------------------------------------------
yum list clamav;
yum install clamav;                (會連帶自動安裝clamav-db)
yum install clamav-devel;
yum install clamav-milter;        (僅sendmail需要,會連帶自動安裝clamd)
yum install clamd;                (若不安裝clamav-milter,就必須自行安裝clamd)

請注意: clamav-milter是專門為sendmail而設計的快速呼叫程序,如果您不使用sendmail,
或者想通過mail-scanner之類的腳本來呼叫ClamAV,則不必安裝和啟動clamav-milter.

vi /etc/passwd;                #为提高安全性,请将bash项目改为/bin/false,如下所示:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
clamav:x:104:104:Clam Anti Virus Checker:/var/clamav:/bin/false
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
請注意: /etc/shells 中必須有 /bin/false
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
B) RPM安装方法;
-------------------------------------------------------------------------------
参考网站:
http://www.clamav.net/
http://www.clamav.net/download/sources/
http://crash.fce.vutbr.cz/crash-hat/5/clamav/

下载RPM套件:
wget http://crash.fce.vutbr.cz/crash- ... v-0.90.1-0.i386.rpm;
wget http://crash.fce.vutbr.cz/crash- ... b-0.90.1-0.i386.rpm;
wget http://crash.fce.vutbr.cz/crash- ... l-0.90.1-0.i386.rpm;
wget http://crash.fce.vutbr.cz/crash- ... r-0.90.1-0.i386.rpm;
wget http://crash.fce.vutbr.cz/crash- ... r-0.90.1-0.i386.rpm;
wget http://crash.fce.vutbr.cz/crash-hat/5/clamav/clamav.spec;

下载RPM资源:        #如有需要,可用此src资源rebuild符合当前系统需要的rpm套件
wget http://crash.fce.vutbr.cz/crash- ... av-0.90.1-0.src.rpm;

rpm -ivh clamav-0.90.1-0.i386.rpm;
rpm -ivh clamav-db-0.90.1-0.i386.rpm;
rpm -ivh --nodeps clamav-milter-0.90.1-0.i386.rpm;
rpm -ivh clamav-server-0.90.1-0.i386.rpm;

請注意: 安裝clamav-milter時會尋找sendmail和sendmail-cf的依賴關系, 因此如果您的
系統不需要 sendmail, 就可用 --nodeps 參數忽略其依賴關系.
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
C) 二进制资源安装方法(本系统必须使用此安装方法);
-------------------------------------------------------------------------------
wget http://freshmeat.net/redir/clama ... lamav-0.90.1.tar.gz;
wget http://freshmeat.net/redir/clama ... lamav-0.90.3.tar.gz;
tar zxvf clamav-0.90.1.tar.gz;
cd clamav-0.90.1;

請注意: 此處編譯的關鍵地方是指定了 ClamAV 的運行者, 因此必須先建立相關用戶和組.
例如, 如果您打算采用(b)方式, 在下面的配置选项中指定用户 qscand 作为运行 ClamAV
的使用者身份,那么请先执行如下增加用户的Linux命令:

groupadd qscand;
useradd -g qscand -s /bin/false -c "Qmail-Scanner Account" qscand;

打補丁新版本不用打)
wget http://www.fehcom.de/qmail/spamc ... .88.2_output.patch_;
請注意: 最新版補丁其實是包含在spamcontrol的資源中:
cp /usr/local/src/qmail/qmail-1.03/*_output.patch_ ./
tar zxvf clamav-0.90.3.tar.gz;
cd clamav-0.90.3;
patch ../*_output.patch_;

(a)指定用户clamav和组clamav来运行clamd:
./configure \
--sysconfdir=/etc \
--with-user=clamav \
--with-group=clamav \
--enable-milter;

(b)指定以root来运行clamd,以结合QHPSI的掃描方法(或預設安裝再修改成root的身份):
./configure \
--sysconfdir=/etc \
--with-user=root \
--with-group=root \
--disable-zlib-vcheck \
--enable-milter;

(c)指定用户qscand和组qscand来运行ClamAV,以结合后面qmail-qscand的安装:
./configure \
--sysconfdir=/etc \
--with-user=qscand \
--with-group=qscand \
--disable-zlib-vcheck \
--enable-milter;

注意: 因為本系统需要结合qmail-qscand来执行病毒扫描和用syslog来记录日志,所以若在
此編譯步驟中指定用户qscand来運行ClamAV, 就可以統一上述兩個系統的使用者,否则將要
在后面相關步驟中修改ClamAV的日志文档的属性,令qmail-qscand的脚本有权读写ClamAV的
日志文档.如果選擇使用QHPSI來調用ClamAV,則建議設置成用root的身份來掃描, 請參考后
續步驟(建立Qmail的運行腳本)中關于QHPSI的設置內容.

make;
make install;

請注意: 用tar資源安裝的預設路徑是/usr/local/bin/,若設置QHPSI請留意匹配相應設置.
-------------------------------------------------------------------------------
===============================================================================      
===============================================================================
3) 配置和调整ClamAV的设置;
===============================================================================
-------------------------------------------------------------------------------
(a) 设置系统自动啟動clamav-milter和clamd;
-------------------------------------------------------------------------------
chkconfig clamav-milter on
chkconfig clamd on
service clamav-milter start
service clamd start
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
(b) 修改設置文檔;
-------------------------------------------------------------------------------
vi /etc/sysconfig/clamav-milter;        #预设符合要求,一般不用修改

vi /etc/freshclam.conf;        #必须按说明注释掉freshclam.conf开头处一行如下:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Comment or remove the line below.
#Example                #注释此行,设置此行没有任何意义,只是确保执行修改动作
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

vi /etc/clamd.conf;        #必须按说明注释掉clamd.conf开头处一行如下:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Comment or remove the line below.
#Example                #注释此行,设置此行没有任何意义,只是确保执行修改动作

ScanMail yes                #必須打開ScanMail這個選項(其實默認已經開啟)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

请注意: 为保证安全,千万不要打开Clam AntiVirus的二进制执行文件的SGID和SUID;
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
(c) 調整sendmail的掃描參數(僅供參考,如果您需要sendmail的話);
-------------------------------------------------------------------------------
ClamAV-milter是專門給sendmail呼叫用的,因此必須修改sendmail設定.如果您不需要直接
由sendmail呼叫ClamAV-milter,例如是利用MailScanner來呼叫ClamAV的, 那么您就不需要
啟動ClamAV-milter(其實根本都不用安裝ClamAV-milter),但是可能要另外安裝 ClamAV 的
perl module.

如果安裝clamav-milter時未取消sm-client的支持,那么當clamav-milter啟動時候,它就會
自動檢查 /etc/mail/sendmail.cf 中是否已經配置了相應的掃描選項. 若檢查不到相應的
掃描設置, clamav-milter 就無法正常啟動, 而必須先在 /etc/mail/sendmail.mc 中設置
clmilter掃描選項, 然后再編譯成/etc/mail/sendmail.cf控制文檔.

當然如果您根本就不需要使用sendmail的話, 也可以干脆刪除sendmail,或者移除配置文檔
sendmail.cf,只要令clamav-milter無法尋找到 /etc/mail/sendmail.cf, 它就能正常啟動.

設置sendmail調用clamav-milter掃描功能的方法如下:

vi /etc/mail/sendmail.mc;        (必須在OSTYPE(`linux')dnl之後)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSTYPE(`linux')dnl
INPUT_MAIL_FILTER(`clmilter',`S=local:/var/clamav/clmilter.socket,T=S:4m;R:4m')dnl
define(`confINPUT_MAIL_FILTERS',`clmilter')
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

請注意:如果你也同時使用 milter-greylist,應該先放 milter-greylist 的設定,然後
才放 clamav-milter。這樣當一封電子郵件到達時,Sendmail 會先呼叫 milter-greylist
然後才呼叫 clamav-milter。整個設定如下:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSTYPE(`linux')dnl
INPUT_MAIL_FILTER(`greylist',`S=local:/var/milter-greylist/milter-greylist.sock')
define(`confMILTER_MACROS_CONNECT', `j, {if_addr}')
define(`confMILTER_MACROS_HELO', `{verify}, {cert_subject}')
define(`confMILTER_MACROS_ENVFROM', `i, {auth_authen}')
INPUT_MAIL_FILTER(`clamav-milter',`S=local:/var/run/clamav/clamav-milter.sock,F=, T=S:4m;R:4m')dnl
define(`ConfINPUT_MAIL_FILTERS', `clamav-milter')dnl
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

make -C /etc/mail;                (重新編譯sendmail.cf控制文檔)
service sendmail restart;

請注意: 因為本系統無需使用sendmail功能,上述設置只是因為clamav-milter安裝時需要
尋找sm-client的支持,因此順便介紹一下在sendmail系統中使用clamav的方法. 如果覺得
上述配置比較麻煩,那么建議您在安裝clamav-milter時候用--nodeps參數取消 sm-client
的支持,這樣就可以忽略本步驟.
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
(d) 啟動 clamav 相關服務:
-------------------------------------------------------------------------------
service clamd start;
service clamav-milter start;        (啟動clamav-milter可能需時較長)
-------------------------------------------------------------------------------
===============================================================================


===============================================================================
4) 测试并设置定时更新任务,并观察返回信息:
===============================================================================
-------------------------------------------------------------------------------
测试更新命令是否能顺利执行:
-------------------------------------------------------------------------------
/usr/bin/freshclam;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClamAV update process started at Fri Mar 30 10:00:53 2007
main.cvd is up to date (version: 42, sigs: 83951, f-level: 10, builder: tkojm)
daily.inc is up to date (version: 2965, sigs: 20319, f-level: 14, builder: ccordes)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ll /var/log/clamav/freshclam.log;        #检查一下更新记录档

如果返回错误信息,或者没有生成更新日志文档,请按如下步骤处理后在测试:
touch /var/log/clamav/freshclam.log;
chmod 600 /var/log/clamav/freshclam.log;

对应前面的安装所用的用户身份,请确保此目录的属性有相应权限:
chown -R clamav.clamav /var/log/clamav/;

注意: 此处测试用clamav来设置日志文档的权限, 如果您要在后面的安裝中使用clamav结合
qmail-scanner来扫描电邮(即通过qmail-scanner来调用ClamAV,而非使用QHPSI), 那么后面
的安装步骤全部完成后,ClamAV的日志文件权限必须设置成qmail-scanner的执行者有权读写;

说明: 可用如下参数,指定更新日志文档;
/usr/bin/freshclam --quiet -l /var/log/clam-update.log
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
设置定时更新病毒库的任务:
-------------------------------------------------------------------------------
vi /etc/crontab;        #如下定时任务中使用了--quiet参数,将不返回非错误信息
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
26 03 * * * root /usr/bin/freshclam --quiet
38 15 * * * root /usr/bin/freshclam --quiet
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

请注意: 按照官方网站的建议,因为大部分用户预设在每小时的开头0-3分钟更新,造成网络
非常拥塞,请尽量在别的分钟段内执行更新任务;
-------------------------------------------------------------------------------
===============================================================================

      
===============================================================================
1) 安装Mail-SpamAssassin(可按如下A和B方法任选其一);
===============================================================================
-------------------------------------------------------------------------------
A) YUM安装方法:
-------------------------------------------------------------------------------
rpm -qa | grep spamassassin;        #检查是否已经安装
yum list | grep spamassassin;        #检查可用资源
yum install spamassassin;        #新安装
或者:
yum update spamassassin;        #更新
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
B) TAR资源安装方法:
-------------------------------------------------------------------------------
参考网站: http://spamassassin.apache.org/
下载资源: http://spamassassin.apache.org/downloads.cgi?update=200702131100

mkdir /usr/local/src/qmail/spamassassin;
cd /usr/local/src/qmail/spamassassin/;
wget http://apache.hkmirror.org/spama ... sassin-3.1.8.tar.gz;
或者:
wget http://apache.hkmirror.org/spama ... sassin-3.2.1.tar.gz;
tar zxvf Mail-SpamAssassin-3.2.1.tar.gz;
cd Mail-SpamAssassin-3.2.1;

請注意,安裝TAR之前,應先檢查系統是否安裝了預設的RPM:
rpm -qa | grep spam;
如有安裝RPM,可以先刪除:
rpm -e spamassassin;

export LANG=en_US;
perl Makefile.PL;
make;
make install;

如有需要,可将tar资源编译成rpm资源:
rpmbuild -tb Mail-SpamAssassin-3.1.8.tar.gz;
ls /usr/src/redhat/BUILD/Mail-SpamAssassin-3.1.8;
-------------------------------------------------------------------------------
===============================================================================


===============================================================================
2) 调整配置Mail-SpamAssassin;
===============================================================================
增加一个用来运行Mail-SpamAssassin的用户:
groupadd spamd;
useradd -g spamd -s /bin/false spamd;

vi /etc/sysconfig/spamassassin;        #指定Mail-SpamAssassin以上述用户运行,改成如下:
-------------------------------------------------------------------------------
# Options to spamd
#SPAMDOPTIONS="-d -c -m5 -H"                        #这是原文
SPAMDOPTIONS="-x -u spamd -H /home/spamd -d"        #改成如此
-------------------------------------------------------------------------------
請注意: 如果用TAR安裝,可能不存在上述文件,那么則新建即可;

vi /etc/mail/spamassassin/local.cf;                #设置扫描参数
-------------------------------------------------------------------------------
# SpamAssassin config file for version 2.5x
# generated by http://www.yrex.com/spam/spamconfig.php (version 1.01)

# How many hits before a message is considered spam.
required_hits           5.0

# Whether to change the subject of suspected spam
rewrite_subject         1

# Text to prepend to subject if rewrite_subject is used
subject_tag             *****SPAM*****

# Encapsulate spam in an attachment
report_safe             1

# Use terse version of the spam report
use_terse_report        0

# Enable the Bayes system
use_bayes               1

# Enable Bayes auto-learning
auto_learn              1

# Enable or disable network checks
skip_rbl_checks         0
use_razor2              1
use_dcc                 1
use_pyzor               1

# Mail using languages used in these country codes will not be marked
# as being possibly spam in a foreign language.
# - chinese english
ok_languages            zh en

# Mail using locales used in these country codes will not be marked
# as being possibly spam in a foreign language.
ok_locales              en zh
-------------------------------------------------------------------------------

請注意: 上述設置在升級到3.2.1之后會報錯,是因為相關參數名稱已改,請用如下設置:
-------------------------------------------------------------------------------
# This is the right place to customize your installation of SpamAssassin.
#
# See 'perldoc Mail::SpamAssassin::Conf' for details of what can be
# tweaked.
#
# Only a small subset of options are listed below
#
###########################################################################

#   Add *****SPAM***** to the Subject header of spam e-mails
#
rewrite_header Subject *****SPAM*****


#   Save spam messages as a message/rfc822 MIME attachment instead of
#   modifying the original message (0: off, 2: use text/plain instead)
#
report_safe 1


#   Set which networks or hosts are considered 'trusted' by your mail
#   server (i.e. not spammers)
#
# trusted_networks 212.17.35.


#   Set file-locking method (flock is not safe over NFS, but is faster)
#
# lock_method flock


#   Set the threshold at which a message is considered spam (default: 5.0)
#
required_score 5.0


#   Use Bayesian classifier (default: 1)
#
use_bayes 1


#   Bayesian classifier auto-learning (default: 1)
#
bayes_auto_learn 1


#   Set headers which may provide inappropriate cues to the Bayesian
#   classifier
#
bayes_ignore_header X-Bogosity
bayes_ignore_header X-Spam-Flag
bayes_ignore_header X-Spam-Status

# Use terse version of the spam report
#use_terse_report        0

# Enable Bayes auto-learning
#auto_learn              1

# Enable or disable network checks
skip_rbl_checks         0
use_razor2              1
#use_dcc                 1
use_pyzor               1

# Mail using languages used in these country codes will not be marked
# as being possibly spam in a foreign language.
# - chinese english
#ok_languages            zh en

# Mail using locales used in these country codes will not be marked
# as being possibly spam in a foreign language.
ok_locales              en zh
-------------------------------------------------------------------------------

相关说明:
required_hits           5.0 (点数超过5就认为是垃圾邮件)
===============================================================================

===============================================================================
3) 设置开机自动运行:
===============================================================================
检查如下文件是否存在:
ll /etc/rc.d/init.d/spamassassin;

检查系统是否已经设置spamassassin服务:
setup->System Service
寻找是否有名为spamassassin的服务存在,如果有,则加上
  • 标记,设置为开机自动启动;

    一般情况下,用YUM方法安装,会自动设置spamassassin服务,如果用TAR资源安装,则必须手工
    设置(为了区别系统原先预设的spamassassin服务名称,可使用另一个名称,如spamd:

    cp spamd/redhat-rc-script.sh /etc/rc.d/init.d/spamd;
    chkconfig --add spamd;                #将init.d目录下名为spamd的程序设置为service服务
    chkconfig spamd on;                #将服务spamd设置为开机自动启动

    /etc/rc.d/init.d/spamd start;        #手工启动spamd
    或者:
    /etc/rc.d/init.d/spamassassin start;

    测试扫描功能:
    spamassassin -t < sample-spam.txt;
    spamassassin -t < sample-nonspam.txt;

    检查扫描结果:
    ll /root/.spamassassin/;
    (注: 以当前用户身份(root)扫描,会在家目录下产生.spamassassin目录和相关文件)
    ===============================================================================      
  • ===============================================================================
    1) 建立Qmail的service运行脚本(qmail-pop3d,qmail-smtpd和qmail-send)
    ===============================================================================
    如果下列相關目錄尚未建立,請先建立:

    mkdir /service;        (此目錄應該在安裝daemontools時自動產生)

    mkdir -p /var/qmail/supervise/qmail-pop3d/log;
    mkdir -p /var/qmail/supervise/qmail-smtpd/log;
    mkdir -p /var/qmail/supervise/qmail-send/log;

    vi /var/qmail/supervise/qmail-pop3d/run;
    -------------------------------------------------------------------------------
    #!/bin/sh
    PATH=/var/qmail/bin:/usr/local/bin:/usr/bin:/bin
    export PATH
    exec tcpserver -H -R -v -c 100 0 110 qmail-popup home.25u.com \
    /home/vpopmail/bin/vchkpw qmail-pop3d Maildir 2>&1
    -------------------------------------------------------------------------------

    vi /var/qmail/supervise/qmail-pop3d/log/run;
    -------------------------------------------------------------------------------
    #!/bin/sh
    PATH=/var/qmail/bin:/usr/local/bin:/usr/bin:/bin
    export PATH
    exec setuidgid qmaill multilog t s1000000 n20 /var/log/qmail/qmail-pop3d 2>&1
    -------------------------------------------------------------------------------

    vi /var/qmail/supervise/qmail-smtpd/run;
    -------------------------------------------------------------------------------
    #!/bin/sh
    export BASE64=""
    export QHPSI="clamdscan"
    export QHPSIARG1="--no-summary"
    export REPLY554="{virus found} [see: http://www.fehcom.de/emailolicy.html]"
    export BADMIMETYPE=""
    export BADLOADERTYPE="M"
    export SMTPAUTH=""
    export BOUNCEMAXBYTES=""
    QMAILDUID=`id -u vpopmail`
    NOFILESGID=`id -g vpopmail`
    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 softlimit -m 30000000 \
    tcpserver -v -R -l "$LOCAL" -x /etc/tcp.smtp.cdb -c "$MAXSMTPD" \
    -u "$QMAILDUID" -g "$NOFILESGID" 0 smtp rblsmtpd \
    /var/qmail/bin/qmail-smtpd \
    /home/vpopmail/bin/vchkpw /bin/true 2>&1
    -------------------------------------------------------------------------------

    vi /var/qmail/supervise/qmail-smtpd/log/run;
    -------------------------------------------------------------------------------
    #!/bin/sh
    PATH=/var/qmail/bin:/usr/local/bin:/usr/bin:/bin
    export PATH
    exec setuidgid qmaill multilog t s1000000 n20 /var/log/qmail/qmail-smtpd 2>&1
    -------------------------------------------------------------------------------

    vi /var/qmail/supervise/qmail-send/run;
    -------------------------------------------------------------------------------
    #!/bin/sh
    exec /var/qmail/rc
    -------------------------------------------------------------------------------

    vi /var/qmail/supervise/qmail-send/log/run;
    -------------------------------------------------------------------------------
    #!/bin/sh
    PATH=/var/qmail/bin:/usr/local/bin:/usr/bin:/bin
    export PATH
    exec setuidgid qmaill multilog t s1000000 n20 /var/log/qmail/qmail-send 2>&1
    -------------------------------------------------------------------------------

    設置上述腳本的執行權限:
    chmod 751 /var/qmail/supervise/qmail-pop3d/run;
    chmod 751 /var/qmail/supervise/qmail-pop3d/log/run;
    chmod 751 /var/qmail/supervise/qmail-smtpd/run;
    chmod 751 /var/qmail/supervise/qmail-smtpd/log/run;
    chmod 751 /var/qmail/supervise/qmail-send/run;
    chmod 751 /var/qmail/supervise/qmail-send/log/run;
    ===============================================================================


    ===============================================================================
    2) 建立Qmail的运行控制脚本rc和服務控制腳本qmailctl;
    ===============================================================================
    vi /var/qmail/rc;
    -------------------------------------------------------------------------------
    #!/bin/sh
    exec env - PATH="/var/qmail/binPATH" \
    qmail-start "`cat /var/qmail/control/defaultdelivery`"
    -------------------------------------------------------------------------------
    chmod 755 /var/qmail/rc;

    vi /var/qmail/bin/qmailctl;
    -------------------------------------------------------------------------------
    #!/bin/sh

    # For Red Hat chkconfig
    # chkconfig: - 80 30
    # 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..."
    echo ""
    if svok /service/qmail-send ; then
    svc -u /service/qmail-send /service/qmail-send/log
    echo "Starting qmail-send"
    else
    echo "qmail-send supervise not running"
    fi
    if svok /service/qmail-smtpd ; then
    svc -u /service/qmail-smtpd /service/qmail-smtpd/log
    echo "Starting qmail-smtpd"
    else
    echo "qmail-smtpd supervise not running"
    fi
    if svok /service/qmail-pop3d ; then
    svc -u /service/qmail-pop3d /service/qmail-pop3d/log
    echo "Starting qmail-pop3d"
    else
    echo "qmail-pop3d supervise not running"
    fi
    if [ -d /var/lock/subsys ]; then
    touch /var/lock/subsys/qmail
    fi
    ;;
    stop)
    echo "Stopping qmail..."
    echo ""
    echo " qmail-smtpd"
    svc -d /service/qmail-smtpd /service/qmail-smtpd/log
    echo " qmail-send"
    svc -d /service/qmail-send /service/qmail-send/log
    echo " qmail-pop3d"
    svc -d /service/qmail-pop3d /service/qmail-pop3d/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
    svstat /service/qmail-pop3d
    svstat /service/qmail-pop3d/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 "ausing qmail-send"
    svc -p /service/qmail-send
    echo "ausing qmail-smtpd"
    svc -p /service/qmail-smtpd
    echo "ausing qmail-pop3d"
    svc -p /service/qmail-pop3d
    ;;
    cont)
    echo "Continuing qmail-send"
    svc -c /service/qmail-send
    echo "Continuing qmail-smtpd"
    svc -c /service/qmail-smtpd
    echo "Continuing qmail-pop3d"
    svc -c /service/qmail-pop3d
    ;;
    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 "* Sending qmail-pop3d SIGTERM and restarting."
    svc -t /service/qmail-pop3d /service/qmail-pop3d/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
    -------------------------------------------------------------------------------

    chmod 755 /var/qmail/bin/qmailctl;
    ln -s /var/qmail/bin/qmailctl /usr/bin;
    ===============================================================================      
    3) 設置SMTP認證特性;
    ===============================================================================
    (a) 只允许本地(127.0.0.1)发送信件:
    -------------------------------------------------------------------------------
    echo '127.0.0.1:allow,RELAYCLIENT=""' > /etc/tcp.smtp;
    qmailctl cdb;        (需重新生成數據庫)

    请注意: 因为本安装只是要设置POP3服务器,所以不允许外部主机relay发信;如果需要配置
    通过SMTP发信的服务器,則需要具备SMTP认证功能.
    -------------------------------------------------------------------------------

    (b) 通過/etc/tcp.smtp啟用SMTP認證;
    -------------------------------------------------------------------------------
    在Qmail系統中啟動SMTP認證功能非常簡單,只需在/etc/tcp.smtp中設置變數SMTPAUTH=""
    即可.因此可將上述語句改為:

    echo '127.0.0.1:allow,SMTPAUTH="",RELAYCLIENT=""' >> /etc/tcp.smtp;
    qmailctl cdb;        (需重新生成數據庫)
    -------------------------------------------------------------------------------

    (c) 通過qmail-smtpd腳本啟用SMTP認證;
    -------------------------------------------------------------------------------
    也可以在supervise的qmail-smtpd服務的run腳本中加入SMTPAUTH=""變量,來啟動SMTP認證
    功能,例如:
    vi /var/qmail/supervise/qmail-smtpd/run;
    ----------------------------------------
    #!/bin/sh
    export BADMIMETYPE=""
    export BADLOADERTYPE="M"
    export SMTPAUTH=""
    QMAILDUID=`id -u vpopmail`
    NOFILESGID=`id -g vpopmail`
       ...
       ...
    ----------------------------------------
    -------------------------------------------------------------------------------

    請注意: 上述(a)與(b)中的變量SMTPAUTH=""指示qmail-smtpd采取plain認證方式,但這只
    是最新版本的spamcontrol(2.4.18)的要求,舊版本則不需要加入變量.
    ===============================================================================

    4) 建立Qmail的接收档生成脚本;
    ===============================================================================
    vi /var/qmail/users/vpopmail-users-alias2recipients;
    -------------------------------------------------------------------------------
    #!/bin/sh
    #LANG=C
    QMAIL=/var/qmail

    if [ -e $QMAIL/users/recipients ]; then
      if [ -e $QMAIL/users/recipients.bak ]; then
        rm -f $QMAIL/users/recipients.bak
      fi
      mv $QMAIL/users/recipients $QMAIL/users/recipients.bak
    fi

    for vdomainpath in `cat /var/qmail/users/assign | cut -d: -f 5 | grep -v -w -e '^\.$' | sort | uniq`; do
      if [ -d ${vdomainpath} ]; then
        cd ${vdomainpath}
        ls -l | grep ^d | awk '{print $9"@localhost"}' | sed -e 's/localhost/'${vdomainpath##*/}'/' | sort -u >> $QMAIL/users/recipients
        ls -l .qmail-*| grep -v .qmail-default  | tr -s " " | awk '{print $9}' | awk -F- '{print $2"@localhost"}' | sed -e 's/localhost/'${vdomainpath##*/}'/' | sed -e 's/:/./' | sed -e 's/:/./' | sort -u >> $QMAIL/users/recipients
      fi
    done

    if [ -s $QMAIL/users/recipients ]; then
      /var/qmail/bin/qmail-recipients
      qmailctl reload
    else
      rm -f $QMAIL/users/recipients
      mv $QMAIL/users/recipients.bak $QMAIL/users/recipients
    fi
    -------------------------------------------------------------------------------
    chmod 755 /var/qmail/users/vpopmail-users-alias2recipients;
    ===============================================================================

    5) 建立Qmail的非法格式地址档生成脚本;
    ===============================================================================
    vi /var/qmail/control/vpopmail-users-alias2badrcptto;
    -------------------------------------------------------------------------------
    #!/bin/sh
    LANG=C
    QMAIL=/var/qmail
    VPOPMAIL=/home/vpopmail/domains

    rm -rf $QMAIL/control/badrcptto
    echo "*" > $QMAIL/control/badrcptto

    for i in `ls -l $VPOPMAIL | grep ^d | awk '{print $9}'`
    do
      cd  $VPOPMAIL/$i
      ls -l | grep ^d | awk '{print "!"$9"@localhost"}' | sed -e 's/localhost/'$i'/' | sort -u >> $QMAIL/control/badrcptto
    done

    for i in `ls -l $VPOPMAIL | grep ^d | awk '{print $9}'`
    do
      cd  $VPOPMAIL/$i
      ls -l .qmail-*| grep -v .qmail-default  | tr -s " " | awk '{print $9}' | awk -F- '{print "!"$2"@localhost"}' | sed -e 's/localhost/'$i'/' | sort -u >> $QMAIL/control/badrcptto
    done
    -------------------------------------------------------------------------------
    chmod 755 /var/qmail/control/vpopmail-users-alias2badrcptto;
    ===============================================================================

    6) 建立Qmail的控制项脚本;
    ===============================================================================
    #本地郵件的投遞指令(若有.qmail文檔,則此參數會被.qmail內容覆蓋);
    echo "./Maildir" > /var/qmail/control/defaultdelivery;
    chmod 644 /var/qmail/control/defaultdelivery;

    #定義qmail可以同時處理的遠端郵件傳送數量;
    echo "100" > /var/qmail/control/concurrencyremote;
    chmod 644 /var/qmail/control/concurrencyremote;

    #
    echo "255" > /var/qmail/control/concurrencyincoming;
    chmod 644 /var/qmail/control/concurrencyincoming;

    #
    echo "users/recipients.cdb" > /var/qmail/control/recipients;
    chmod 644 /var/qmail/control/recipients;

    #指定qmail-smtpd能接收的最大位元組數(?**付?電郵不能大于1M);
    echo "1024000" > /var/qmail/control/databytes;
    chmod 644 /var/qmail/control/recipients;
    請注意: 若內容超過此限制,SMTP會立即返回一個552代碼(OUTLOOK錯誤碼為"0x800CCC6D"),
    返回信息包含: '552 sorry, that message size exceeds my databytes limit (#5.3.4)'

    #设置每个SMTP连线中的最大RCPT接收数量;
    echo "10" > /var/qmail/control/maxrecipients;
    chmod 644 /var/qmail/control/maxrecipients;
    (... ??? ...)

    #控制回彈電郵的大小不能超過2K(減輕垃圾郵件的反彈電郵的影響);
    echo "2048" > /var/qmail/control/bouncemaxbytes;
    chmod 644 /var/qmail/control/bouncemaxbytes;

    ll /var/qmail/control/rcpthosts;        #(檢查主機列表文件是否已經存在);
    echo "" > /var/qmail/control/rcpthosts;        #(若未有主機文件就必須手工建立);

    复制qmail安装资源目录下的四个控制文档:
    cp /usr/local/src/qmail/qmail-1.03/badmailfrom /var/qmail/control/;
    cp /usr/local/src/qmail/qmail-1.03/badrcptto /var/qmail/control/;
    cp /usr/local/src/qmail/qmail-1.03/badmimetypes /var/qmail/control/;
    cp /usr/local/src/qmail/qmail-1.03/badloadertypes /var/qmail/control/;

    上述四个控制文档必须从打过补丁(例如spamcontrol)的安装资源中复制,可用vi检查其内容:
    vi /var/qmail/control/badmailfrom;
    vi /var/qmail/control/badrcptto;
    vi /var/qmail/control/badmimetypes;
    vi /var/qmail/control/badloadertypes;
    ===============================================================================

    7) badmimetypes 和 badloadertypes 的使用
    ===============================================================================
    badmimetypes 和 badloadertypes 是一个在 smtp data 会话阶段的扫描功能, 由于不存在
    额外的进程调度, 并且 badmimetypes 及 badloadertypes 的数据均采用 cdb 结构,所以其
    扫描效率相当高.

    badmimetypes.cdb 是存放的需要过滤的MIME特征码,一般是取经过base64编码的MIME附件至
    少头9个字符, 例如下面的 badmimetypes 文檔內容:
    vi /var/qmail/control/badmimetypes;
    ------------------------------------------------------------------------------
    TVqQAAMAA
    TVpQAAIAA
    TVpAALQAc
    TVpyAXkAX
    TVrmAU4AA
    TVrhARwAk
    TVoFAQUAA
    TVoAAAQAA
    TVoIARMAA
    TVouARsAA
    TVrQAT8AA
    TVrvAEQAe
    # MyDoom (*.zip)
    UEsDBAoAA
    # *.zip 如果需要禁止所有 .zip 的附件, 可以取消下面一行的注释
    # UEsDBAkAA
    # *.z (gnu-zip)
    # H4sIADWWb
    # double Base 64 Windows Executable
    VFZxUUFBT
    # triple Base 64 Windows Executable
    VkZaeFVVR
    # Pif File
    TVoAAAEAA
    # Bagle
    ZGltIGZpb
    ------------------------------------------------------------------------------

    可以通过任何文本编辑器, 建立或者编辑 /var/qmail/control/badmimetypes 文件,然后
    使用 /var/qmail/bin/qmail-badmimetypes 生成 badmimetypes.cdb 供qmail-smtpd调用.

    在Qmail系統中激活 badmimetypes 功能的方法是,在qmail-smtpd环境中增加BADMIMETYPE
    变量, 例如要通过tcp.smtp.cdb來調用badmimetypes,參考如下設置:

    vi /etc/tcp.smtp;
    ------------------------------------------------------------------------------
    :allow,BADMIMETYPE=""
    ------------------------------------------------------------------------------

    通過在/var/qmail/supervise/qmail-smtpd/run中設置相同的變數,也可以達到目的:

    vi /var/qmail/supervise/qmail-smtpd/run;
    ------------------------------------------------------------------------------
    export BADMIMETYPE=""
    ------------------------------------------------------------------------------

    badloadertypes 的原理与 badmimetypes 类似, 不同之处是 badmimetypes 仅仅对 MIME
    编码的开始至少9个字符进行匹配比较, 而 badloadertypes 匹配的是整行,也可以说是整
    个附件内容. badloadertypes 是存放的敏感的 windows 调用特征码, 例如Kernel32.dll,
    截取了其中的32.dll, 其相应的base64编码为MzIuZ,下面是一些基本的badloadertypes的
    特征码:

    vi /var/qmail/control/badloadtypes;
    ------------------------------------------------------------------------------
    # Kernel32.dll; BADLOADERTYPE='M'
    Mi5kb
    MzIuZ
    MyLmR
    MyLkR
    Mi5ET
    My5le
    #LoadLibraryA; BADLOADERTYPE='A'
    #AExvYWRMaWJyYXJ5QQAA
    #GetProcAddress; BADLOADERTYPE='A' (false positive risk)
    #AABHZXRQcm9jQWRkcmVzcwAA
    ------------------------------------------------------------------------------

    通过使用 /var/qmail/bin/qmail-badloadertypes ,可以从 badloadertypes 生成數據庫
    badloadertypes.cdb, 以供 qmail-smtpd 使用.

    在Qmail中激活badloadertypes功能的方法跟上述調用badmimetypes的方法一樣,也是必須
    在qmail-smtpd环境中增加變數 BADLOADERTYPE="M" 或者 BADLOADERTYPE="A".例如要通过
    tcp.smtp.cdb來調用badloadertypes,參考如下設置:

    vi /etc/tcp.smtp;
    ------------------------------------------------------------------------------
    :allow,BADLOADERTYPE="M"
    ------------------------------------------------------------------------------

    通過在/var/qmail/supervise/qmail-smtpd/run中設置相同的變數,也可以達到目的:

    vi /var/qmail/supervise/qmail-smtpd/run;
    ------------------------------------------------------------------------------
    export BADLOADERTYPE="M"
    ------------------------------------------------------------------------------      
    ===============================================================================
    8) 使用QHPSI(Qmail High Performance Scanner Interface - Qmail高性能掃描接口);
    ===============================================================================
    QHPSI 是一个调用外部病毒扫描程序的接口, 邮件在进入 qmail-queue 程序中 fork 外部
    程序执行扫描, 不像qmail-scanner 一类的软件, 需要额外的程序和进程开销, 因此QHPSI
    效率很高.

    QHPSI 可以和现在流行的开源软件 clamav 完美结合. 配置的方法是在qmail-smtpd的环境
    中设置如下相關變數:

    QHPSI                设置病毒扫描程序(AV),例如 clamdscan ;
    QHPSIARG1        设置調用病毒扫描程序的相应参数;
    QHAPSIARG2        设置調用病毒扫描程序的相应参数;
    QHPSIARG3        设置調用病毒扫描程序的相应参数;
    QHPSIRC         设置扫描程序的返回码,若AV扫描到病毒时返回码不是1,則用此指定;
    QHPSIMINSIZE        设置扫描邮件的最小长度,單位為字節,避免掃描小郵件,節省系統開銷;
    QHPSIMAXSIZE        设置扫描邮件的最大长度,單位為字節,避免掃描大郵件,防止系統延迟;

    請注意: 利用QHPSI調用Clam AV來掃描病毒, 會遇到同利用Qmail-Scnnner來調用 Clam AV
    一樣的權限問題.請參考安裝Qmail-Scnnner中關于設置Clam AV權限的章節,將Clam AV設置
    成以root的身份來運行(因為SMTP的執行身份是qmailq).

    vi /etc/clamd.conf;        #找到User设置项目,请按如下修改:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #User clamav
    User root
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    請注意: 使用root身份來執行掃描,則無需再調整Clam AV的日志文件和病毒庫文件的屬性,
    因為root本身已經具備讀寫相關文件的權限.

    參考網址: [url]http://www.fehcom.de/qmail/qmail.html[/url]

    cd /usr/local/src/qmail/spamcontrol/;
    wget [url]http://www.fehcom.de/qmail/qhpsi/qhpsi-020_tgz.bin[/url];


    使用方法:

    請參考在/etc/tcp.smtp中的設置調用Clam AV的范例:
    -------------------------------------------------------------------------------
    :allow,BASE64='',QHPSI='clamdscan',QHPSIARG1='--no-summary',REPLY554="{virus found}
    -------------------------------------------------------------------------------

    在qmail-smtpd中设置QHPSI来调用Clamv AV的范例:
    -------------------------------------------------------------------------------
    export BASE64=""
    export QHPSI="clamdscan"
    export QHPSIARG1="--no-summary"
    export REPLY554="{virus found [see: [url]http://www.fehcom.de/emailolicy.html[/url]]}"
    -------------------------------------------------------------------------------

    說明: 在上述設置中, BASE64='' 變數用于設置 QHPSI 僅僅對 base64 編碼的 MIME 附件
    才有效,其他類型的附件以及郵件正文內容則忽略掃描. 這樣設置可以節省系統開銷和提高
    掃描性能, 因為目前大部分病毒均使用 base64 編碼,并且通常只是存在于郵件的附件當中.
    但當然也不排除一部分 script 類型的病毒存在于 HTML 郵件的正文部分中,因此,您也可以
    根据實際情况來決定是否取消 BASE64 选项.

    - The path of 'clamdscan' can be omitted, because it is in
      the standard path (/usr/local/bin).
    - In the configuration file clamav.conf, the option
      'ScanMail' has to be enabled; clamd has to run as 'root'.
    - The argument QHPSIARG1='--disable-summary' tells Clam AV
      to provide a single line output of the scan results.
    - The argument QHPSIRC is not necessary, because
      'clanmdscan' return with 'RC=1' (the default) in
      case a virus infection is recognized.

    注意: 如果clamdscan是用TAR资源安装的,那么默认路径应该是/usr/local/bin/clamdscan
    和/usr/local/bin/clamscan,其配置文件则可能是/usr/local/etc/clamd.conf,相应的启动
    服务则是/usr/local/sbin/clamd.

    用TAR资源安装的clamav所有的运行权限应该是root,如有需要,可运行如下命令:

    chmod +s /usr/local/bin/clamdscan;
    chmod +s /usr/local/bin/clamscan;

    如欲在/etc/tcp.smtp中來設置,那么的相应設置是:
    -------------------------------------------------------------------------------
    :allow,BASE64='',QHPSI='/usr/local/bin/clamdscan',QHPSIARG1='--no-summary'
    -------------------------------------------------------------------------------

    在qmail-smtpd中设置QHPSI来调用Clamv AV的范例:
    -------------------------------------------------------------------------------
    export BASE64=""
    export QHPSI="/usr/local/bin/clamdscan"
    export QHPSIARG1="--no-summary"
    export REPLY554="{virus found [see: [url]http://www.fehcom.de/emailolicy.html[/url]]}"
    -------------------------------------------------------------------------------

    另外: 在QHPSI中调用clamdscan需要先在**启动clamd服务,否则clamdscan无法调用扫描
    程序则会令 SMTP 连线失败.若在QHPSI中调用clamscan则不需要预先启动clamd服务, 因为
    clamscan 会在每次调用的时候自己启动一个独立的clamd服务,无需一个常驻内存的 clamd
    进程,但扫描性能则相对较弱.通常情况下,用clamdscan来调用常驻内存的clamd服务来执行
    扫描任务,速度比调用clamscan快上好几倍.

    請注意: 本安裝手冊最後部分還另外介紹了一個名為qmail-scanner的掃描腳本,如果您想
    使用qmail-scanner來執行病毒掃描功能,那么可以忽略此處的設置.當然,若在此選擇設置
    QHPSI來設置掃描功能,則后面的qmail-scanner安裝部分也可以忽略病毒掃描部分(但仍然
    需要qmail-scanner來呼叫垃圾掃描部分). 必須注意的是,若是從速度和效率角度來評價,
    無疑QHPSI的掃描性能是要比qmail-scanner更為優越的,因此建議您盡可能選擇使用QHPSI
    來調用病毒掃描任務.
    ===============================================================================


    ===============================================================================
    9) 运行相关脚本,进行qmail系统的初始化工作;
    ===============================================================================
    生成recipients系統帳號:
    /var/qmail/users/vpopmail-users-alias2recipients;
    ll /var/qmail/users/;

    生成recipients数据库:
    /var/qmail/bin/qmail-recipients;

    检查一下是否正确生成或者更新了相关文档:
    ll /var/qmail/users/recipients.cdb;

    /var/qmail/bin/qmail-badmimetypes;
    /var/qmail/bin/qmail-badloadertypes;

    请注意: 因为vpopmail-users-alias2recipients程序调用到/var/qmail/users/assign,和
    /var/qmail/users/recipients,然而此时两个文件并不存在(要等后面安装好 vpopmail,并
    执行./home/vpopmail/bin/vadddomain test.com password后才会产生), 所以会显示错误
    信息.


    建立啟動service的鏈接:
    ln -s /var/qmail/supervise/qmail-send /service;
    ln -s /var/qmail/supervise/qmail-smtpd /service;
    ln -s /var/qmail/supervise/qmail-pop3d /service;

    設置定時執行任務:        (每30分鐘執行一次更新用戶列表)
    -------------------------------------------------------------------------------
    0-59/30 * * * * root /var/qmail/users/vpopmail-users-alias2recipients
    -------------------------------------------------------------------------------

    請注意: 因為svscan會自動掃描service目錄,一旦上述鏈接建立,Qmail系統就會自動啟動,
    可用 ps aux | grep qmail 命令查看啟動結果.
    ===============================================================================

    请注意: 为了方便安装,可以将上述(1-9)步骤中的命令整理一下,将需要生成和复制的控制
    文件集合成一个安装资源(放在scripts目录下),写成一个脚本程序(名为qmail-scripts.sh)
    来执行安装任务.      
    1) 安装autorespond套件;
    ===============================================================================
    http://www.inter7.com/index.php?page=development

    mkdir /usr/local/src/qmail/qmailadmin;
    cd /usr/local/src/qmail/qmailadmin/;

    wget http://www.inter7.com/devel/autorespond-2.0.5.tar.gz;
    tar zxvf autorespond-2.0.5.tar.gz;
    cd autorespond-2.0.5;
    make;
    make install;

    請注意: 本安裝會將autorespond安裝到/usr/bin/目錄下,后面安裝qmailadmin時必須要用
    這個路徑來指定其中的選項.
    ===============================================================================

    2) 安装ezmlm - easy mail listing manager
    ===============================================================================
    參考網站: http://www.ezmlm.org/archive/

    功能簡介:
    -------------------------------------------------------------------------------
    ezmlm-0.53 is a qmail-based mailing list manager written by Dan J. Bernstein.
    It has all the basic functionality of a mailing list manager, such as subscriber
    address management including automated bounce handling as well as message
    distribution and archiving.
    ---
    ezmlm-0.53 是一個基于Qmail系統的郵件列表管理系統,由Dan J.Bernstein所開發.它具備
    郵件列表管理系統的所有基本功能,例如訂閱,地址管理,包括自動反彈處理, 還有消息發布
    和歸檔.
    ---
    ezmlm-idx is an add-on to ezmlm. It adds multi-message threaded message retrieval
    from the archive, digests, message and subscription moderation, and a number of
    remote administration function. It modifies the configuration program ezmlm-make(1)
    so that it uses a text file template rather than compiled-in texts in list creation.
    In this manner, ezmlm-idx allows easy setup of lists in different languages and
    customization of default list setup. ezmlm-idx also adds MIME handling, and other
    support to streamline use with languages other than English. As an ezmlm add-on,
    ezmlm-idx does not work without ezmlm and tries to be compatible with ezmlm as
    much as possible. ezmlm-idx also modifies the ezmlm subscriber database to be case
    insensitive to avoid many unsubscribe problems.
    ---
    ezmlm-idx 是ezmlm的一個附件.
    ---
    說明: 上述文字摘錄自官方網站的FAQ,為方便理解,我翻譯了部分中文.
    -------------------------------------------------------------------------------


    首先安裝ezmlm:
    -------------------------------------------------------------------------------
    參考網站: http://pobox.com/~djb/ezmlm.html

    cd /usr/local/src/qmail/qmailadmin/;
    wget http://cr.yp.to/software/ezmlm-0.53.tar.gz;
    wget http://www.ezmlm.org/archive/ezmlm-0.53.tar.gz;
    tar zxvf ezmlm-0.53.tar.gz;

    請注意: 如果在下一步驟(安裝ezmlm-idx)中采用(a)方式安裝TAR資源,那么可以暫時先忽略
    如下安裝步驟(因為安裝ezmlm-idx的TAR資源需要先打idx.patch補丁):

    cd ezmlm-0.53/;
    make;
    make man;
    make setup;
    -------------------------------------------------------------------------------

    再安裝ezmlm-idx附件(可選擇a或b方式):
    -------------------------------------------------------------------------------
    (a) 安裝TAR資源;

    官方网站最新版本: http://www.ezmlm.org/archive/6.0.0/
    wget http://www.ezmlm.org/archive/5.1.1/ezmlm-idx-5.1.1.tar.gz;
    wget http://www.ezmlm.org/archive/6.0.0/ezmlm-idx-6.0.0.tar.gz;
    tar zxvf ezmlm-idx-0.xx.tar.gz;

    mv ezmlm-idx-0.xx/* ezmlm-0.53/;
    上述命令需對應相應的版本,例如:
    mv -f ezmlm-idx-5.1.1/* ezmlm-0.53/;
    mv -f ezmlm-idx-6.0.0/* ezmlm-0.53/;

    cd ezmlm-0.53;
    patch < idx.patch;

    make;
    make man;
    make setup;

    如果make setup時出現如下編譯錯誤:
    -------------------------------------------------------------
    fatal: unable to read ezmlm-mktab-mysql: file does not exist
    -------------------------------------------------------------

    vi BIN;        (請先刪除如下兩行,然后再make setup一次)
    -------------------------------------------------------------
    c:::755:/:ezmlm-mktab-mysql:
    c:::755:/:ezmlm-mktab-pgsql:
    -------------------------------------------------------------

    (b) 安裝RPM套件;
    官方网站最新版本: http://www.ezmlm.org/archive/6.0.0/
    wget http://www.ezmlm.org/archive/6.0.0/ezmlm-idx-6.0.0-1.i386.rpm;
    rpm -ivh ezmlm-idx-6.0.0-1.i386.rpm;

    Qmail官方网站所提供的ezmlm的最新版本:
    http://www.qmail.org/rpms/ezmlm-idx.html
    wget http://www.qmail.org/rpms/RPMS/e ... 112memphis.i386.rpm;
    rpm -ivh ezmlm-idx-std-0.53.442-5.i386.rpm;

    一个较新的RPM版本(ezmlm-idx-std-5.1.1-7.i386.rpm):
    http://distro.ibiblio.org/pub/li ... s.System.group.html
    wget http://distro.ibiblio.org/pub/li ... td-5.1.1-7.i386.rpm
    rpm -ivh ezmlm-idx-std-5.1.1-7.i386.rpm;
    -------------------------------------------------------------------------------

    請注意: ezmlm的安裝至此即可,下列步驟若無興趣可忽略;

    自動測試:
    -------------------------------------------------------------------------------
    ./ezmlm-test;        (這是ezmlm-idx的測試程序,若成功則返回如下信息)
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ezmlm-make (1/2):     OK
    Using subdb plugin:   std
    ezmlm-reject:         OK
    ezmlm-[un|is]sub[n]:  OK
    ezmlm-send:           OK
    ezmlm-tstdig:         OK
    ezmlm-weed:           OK
    ezmlm-make (2/2):     OK
    ezmlm-clean:          OK
    ezmlm-store:          OK
    ezmlm-return:         OK
    ezmlm-warn (1/2):     OK
    ezmlm-manage (1/2):   delivered manget1 to wrong address
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -------------------------------------------------------------------------------

    手工測試:        (下列步驟參考自ezmlm-0.53安裝文檔的范例)
    -------------------------------------------------------------------------------
    1. 確認資源目錄下有ezmlm-make執行檔. Create a mailing list:
    ./ezmlm-make ~/testlist ~/.qmail-testlist me-testlist host
    用您自己的電郵地址替換"me"和"host",例如:
    ./ezmlm-make ~/testlist ~/.qmail-testlist user1-testlist test.com;

    2. Subscribe yourself to the list manually:
    ./ezmlm-sub ~/testlist user1@test.com;

    3. Send a message to the list:
    echo subject:testing | /var/qmail/bin/qmail-inject testlist@test.com[/email];
    (您將會在user1@test.com郵箱中收到一條標題為:testing的消息)

    4. View the list membership:
    ./ezmlm-list ~/testlist
    (您將會看到的是只有一行,包含您的郵箱地址)

    5. Unsubscribe yourself through e-mail:
    /var/qmail/bin/qmail-inject testlist-unsubscribe@test.com[/email] < /dev/null;

        When you receive the confirmation number, reply to complete your
        unsubscription. Use ezmlm-list to check that the list is empty.

    6. Retrieve the first message from the archive:
    /var/qmail/bin/qmail-inject testlist-get.1@test.com[/email] < /dev/null;
    (您將會收到一個標題為:testing的消息備份)

    7. 報告成功消息:
    echo 'First M. Last'; cat `cat SYSDEPS` | mail qst@koobera.math.uic.edu[/email]
    請用您自己的名稱替代上面的'First M. Last',例如:
    echo 'Jason Cheng'; cat `cat SYSDEPS` | mail qst@koobera.math.uic.edu[/email];
    -------------------------------------------------------------------------------

    配置CGI的網頁瀏覽界面:
    -------------------------------------------------------------------------------
    cp -p ezmlm-cgi /var/www/cgi-bin/;
    chown root.root /var/www/cgi-bin/ezmlm-cgi;
    chmod 4755 /var/www/cgi-bin/ezmlm-cgi;

    vi /etc/ezmlm/ezcgirc;        (如果目錄/etc/ezmlm/不存在,請先建立)
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    # Format for ezcgirc file
    #listno;uid;listdir;listaddr;buttonbar;charset;style;bannerprog
    0;0;/root/testlist;postmaster@test.com;[Home]=http://192.168.0.9/cgi-bin/ezmlm-cgi
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -------------------------------------------------------------------------------
    ===============================================================================


    3) 下载qmailadmin最新版本
    ===============================================================================
    参考网站: http://sourceforge.net/project/showfiles.php?group_id=6691

    cd /usr/local/src/qmail/qmailadmin/;
    wget http://jaist.dl.sourceforge.net/ ... admin-1.2.11.tar.gz;
    tar -zxvf qmailadmin-1.2.11.tar.gz;
    cd qmailadmin-1.2.11;

    请注意: qmailadmin-1.2.11依然还不支持Domain Quota的动态分配和域名用户的自行調整,
    因此我们必须在configure之前手工修改原程序才能支持.关于修改的方法,请参考下一步骤
    所介绍的方法.為了簡化qmailadmin的安裝過程, 我將已經成功安裝的資源打包成一個名為
    qmailadmin-1.2.11.fixquota.tar.gz的壓縮檔案,可以直接使用.(若不想自己動手修改,就
    可以忽略下述第4步驟,直接跳到第5步驟開始安裝).
    ===============================================================================

          
    ===============================================================================
    4) 修改Domain Quota限制;
    ===============================================================================
    qmailadmin源程序无法控制Domain Quota,邮件帐户可以设置任意大小的限制值而不受总
    Quota的控制.如要限制邮件帐户的Quota数值不能大于总的Domain Quota值,就必须在编译
    之前先修改qmailadmin的源程序.

    -------------------------------------------------------------------------------
    (a)如下是所需要修改的档案清单:
    -------------------------------------------------------------------------------
    所需修改的使用界面为:
    html/add_user.html
    html/mod_user.html
    html/show_users.html

    所需修改的各种语言的信息定义变量:
    lang/en                                #英文语言的信息变量定义
    lang/zh-cn                        #简体中文(gb2312)的信息变量定义

    所需修改的原程序文件为:
    limits.c
    qmailadmin.c
    qmailadminx.h
    template.c
    user.c                                #请注意新版中部分函数改名和参数调动问题
    -------------------------------------------------------------------------------

    -------------------------------------------------------------------------------
    (b)修改使用界面;
    -------------------------------------------------------------------------------
    vi html/add_user.html;                #第44行需添加支持Quota的标记:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    <td align="left"><input type="text" size="16" name="quota" maxlength="128"> ##X901##+ ##X902##-</td>
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    vi html/mod_user.html;                #第98行(旧版为118行)改为如下:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
               ##X901##+  ##X902##-
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    vi html/show_users.html;        #第42行改为如下:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
               ##X901##+ ##X902##-[
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    请注意: 上述修改使用了+和-做Quota的标记,是因为新版(qmailadmin-1.2.11)在其源程序
    (template.c)中已经使用了所有英语符号来做标记,所以必须使用别的符号来做配额的标记.
    我们这里选择用+(Domain Quota)和-(Used Quota)来做标记,也就是在template.c中CASE中
    选择了+和-来标记相关限额,上述修改中的所有涉及这个标记的修改,均是为了配合template.c
    中的修改.
    -------------------------------------------------------------------------------

    -------------------------------------------------------------------------------
    (c) 修改各种语言的信息定义变量:
    -------------------------------------------------------------------------------
    vi lang/en;        #最后面添加五行如下:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    901 Whole storage:
    902 Applied storage:
    903 Over storage quota
    904 Whole storage was totally used
    905 setted storage must larger than the used storage
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    vi lang/zh-cn;        #参照说明补充两行,在最后面添加5行如下(注意用简体中文字):
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    316 修改密码
    317 你不能删除管理者帐户
    #上述两个定义参照lang/en中的定义(可能原程序遗漏了):

    901 整个域总容量:
    902 已分配容量:
    903 设置的容量超过可用容量
    904 已分配的容量已达到整个域总容量
    905 设置的容量一定要大于已使用容量
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    如果要修改其他所有语言信息定义文件,可以先建立一个lang_fixquota.patch文件:
    vi lang_fixquota.patch;
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    901 Whole storage:
    902 Applied storage:
    903 Over storage quota
    904 Whole storage was totally used
    905 setted storage must larger than the used storage
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    然后用 cat 命令将lang_fixquota.patch文件的内容添加到相关文件中:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    cat fixquota.patch >> bg;
    cat fixquota.patch >> cs;
    cat fixquota.patch >> da;
    cat fixquota.patch >> de;
    cat fixquota.patch >> es;
    cat fixquota.patch >> fi;
    cat fixquota.patch >> fr;
    cat fixquota.patch >> hu;
    cat fixquota.patch >> it;
    cat fixquota.patch >> ja;
    cat fixquota.patch >> lt;
    cat fixquota.patch >> nl;
    cat fixquota.patch >> no;
    cat fixquota.patch >> pl;
    cat fixquota.patch >> pt-br;
    cat fixquota.patch >> ru;
    cat fixquota.patch >> sk;
    cat fixquota.patch >> sv;
    cat fixquota.patch >> tr;
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    请注意: 上述语言信息定义格式采用阵列形式,左边数字是索引,右边文字为解释;在源程序
    中,语言信息定义是用阵列html_text[]来储存,因为新版qmailadmin改用数字来做索引,而且
    源程序中所定义的阵列长度是350。如果新添加的信息定义的索引数字大于350(例如我们上
    述所添加的索引数字为901,902,903,904 和 905,均大于350), 在某些系统下可能无法
    正确储存阵列(取决于C语言的编译特性),由此而导致调用到此语言定义信息的相关页面无法
    正常显示,因此需要修正(增大)阵列长度.

    vi qmailadmin.h;        #此头文件定义系统环境变数
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #define MAX_LANG_STR 350        // 找到定义MAX_LANG_STR的此行;
    #define MAX_LANG_STR 950        // 将350修改为950;
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -------------------------------------------------------------------------------


    -------------------------------------------------------------------------------
    (d) 在limits.c, qmailadmin.c和qmailadminx.h中增加变量定义;
    -------------------------------------------------------------------------------
    vi limits.c;                (旧程序46行附近插入如下行
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    DefaultDomainQuota = Limits.diskquota;
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    vi qmailadmin.c;        (旧程序82行附近插入如下行
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    int DefaultDomainQuota;
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    vi qmailadminx.h;        (旧程序61行附近插入如下行
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    extern int DefaultDomainQuota;
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -------------------------------------------------------------------------------

    -------------------------------------------------------------------------------
    (e) 修改template.c源程序;
    -------------------------------------------------------------------------------
    vi template.c;               

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (e.1) 第41行处增加一行如下:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #include "qmailadmin.h"
    #include "qmailadminx.h"

    #define NOLIMIT_STR get_html_text("229")        #这是插入的新行

    static char dchar[4];
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (e.2) 第53行处增加一行如下:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    static char NTmpBuf[500];

    float count_users_quota();        #这是插入的新行

    /*
    * send an html template to the browser
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (e.3) 第79行处增加一行如下(send_template_now子函数):
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    struct vqpasswd *vpw;
    char value[MAX_BUFF];
    float UsedQuota = (count_users_quota())/1048576.0;        #这是插入的新行

      if (strstr(filename, "/")!= NULL||strstr(filename,"..")!=NULL) {
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (e.4) 第578行处增加两个case(+和-)共16行,因为新版(qmailadmin-1.2.11)其源程序中已
    经使用了所有文字符号来做标记,所以必须使用别的符号来做配额的标记.例如用+(Domain
    Quota)和-(Used Quota)来做标记:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
              case '+':                #这是新增加的case
                   {
                     if (DefaultDomainQuota > 0) {
                        fprintf(actout, "%dM", DefaultDomainQuota);
                     } else {
                            fprintf(actout, "%s", NOLIMIT_STR);
                     }
                   }
                 break;

              case '-':                #这是新增加的case
                   {
                     if (UsedQuota > 0.0) fprintf(actout, "%-2.2lfM", UsedQuota);
                     else fprintf(actout, "%s", NOLIMIT_STR);
                   }
                 break;
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    提示: 可用如下的grep命令可查看当前版本中使用了那些符号作标记: grep 'case' template.c;
    -------------------------------------------------------------------------------

    -------------------------------------------------------------------------------
    (f) 修改user.c源程序;
    -------------------------------------------------------------------------------
    (f.1) 第56行处增加一行如下:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #endif

    float count_users_quota();        #这是插入的新行

    int show_users(char *Username, char *Domain, time_t Mytime)
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -      
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (f.2) 第333行处(adduser()子函数)需增加一个变量和IF条件语句如下:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      if ( MaxPopAccounts != -1 && CurPopAccounts >= MaxPopAccounts ) {
        sprintf(StatusMessage, sizeof(StatusMessage), "%s %d\n", html_text[199],
          MaxPopAccounts);
        show_menu(Username, Domain, Mytime);
        vclose();
        exit(0);
      }

    #这是插入的变量和IF条件语句开始处
      float UsedQuota = count_users_quota();
      if ((DefaultDomainQuota > 0 && UsedQuota) >= (DefaultDomainQuota*1048576.0)) {
        snprintf (StatusMessage, sizeof(StatusMessage), "%s %dM\n", html_text[904],
          DefaultDomainQuota);
        show_menu(Username, Domain, Mytime);
        vclose();
        exit(0);
      }
    #这是新插入的IF条件的结束处

      send_template( "add_user.html" );
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    说明: 在旧版本中用get_html_text("###")函数来调用语言定义信息,show_menu()也无须
    参数;但在新版本中,则用html_text[###]数组来储存语言定义信息,而且show_menu()函数
    也带有三个参数,变为show_menu(Username, Domain, Mytime).
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (f.3) 第391行处(addusernow()子函数)需增加一个变量和IF条件语句如下:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      if ( MaxPopAccounts != -1 && CurPopAccounts >= MaxPopAccounts ) {
        sprintf(StatusMessage, sizeof(StatusMessage), "%s %d\n", html_text[199],
          MaxPopAccounts);
        show_menu(Username, Domain, Mytime);
        vclose();
        exit(0);
      }

    #这是插入的变量和IF条件语句如下
      float UsedQuota = count_users_quota();
      if ((DefaultDomainQuota > 0) && (UsedQuota >= (DefaultDomainQuota*1048576.0))) {
        sprintf(StatusMessage, sizeof(StatusMessage), "%s %dM\n", html_text[904],
          DefaultDomainQuota);
        show_menu(Username, Domain, Mytime);
        vclose();
        exit(0);
      }
    #这是新插入的IF条件的结束处

      GetValue(TmpCGI,Newu, "newu=", sizeof(Newu));
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (f.4) 第409行(addusernow()子函数)需增加一个IF条件语句如下
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      // Coded added by jhopper
    #ifdef MODIFY_QUOTA
      GetValue(TmpCGI, Quota, "quota=", sizeof(Quota));
    #如下是新插入的行开始处,这是一个IF条件语句:
      if ((atof(Quota) > 0.0) && (atof(Quota) <= 500.0)) {
        if (quota_to_bytes(qconvert, Quota)) {
          sprintf(StatusMessage, html_text[314"));
          adduser();
          vclose();
          exit(0);
        } else if ((UsedQuota + (atof(Quota)*1048576.0)) > (DefaultDomainQuota*1048576.0)) {
          sprintf(StatusMessage, html_text[903"));
          adduser();
          vclose();
          exit(0);
        }
      } else {
        sprintf(StatusMessage, html_text[307"));
        adduser();
        vclose();
        exit(0);
      }
    #这是新插入的IF条件语句的结束处:
    #endif
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (f.5) 第503行需注释掉一个sprintf函数
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        /* report success */
    /*    snprinth (StatusMessage, sizeof(StatusMessage), "%s %H@%H (%H) %s",
          html_text[2], Newu, Domain, Gecos,
          html_text[119]);
    */
      } else {
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (f.6) 第785行处需修改多行程序,修改后如下可将整个#ifdef - #endif 替换掉)
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #ifdef MODIFY_QUOTA
      /* strings used: 307 = "Invalid Quota", 308 = "Quota set to unlimited",
       * 309 = "Quota set to %s bytes"
       */
      if (AdminType == DOMAIN_ADMIN) {
        GetValue(TmpCGI, Quota, "quota=", sizeof(Quota));
        vpw = vauth_getpw(ActionUser, Domain);
        if ((strlen(Quota) == 0) || (strcmp (vpw->pw_shell, Quota) == 0)) {
          /* Blank or no change, do nothing */
        } else if ((atof(Quota) > 0.0) && (atof(Quota) <= 500.0)) {
          quotaptr = Quota;
          if (quota_to_bytes(qconvert, quotaptr)) {
            sprintf(StatusMessage, html_text[307"));
          } else if(strcmp(qconvert, vpw->pw_shell)==0) {
            /* unchanged, do nothing */
          } else {
            float UsedQuota = count_users_quota();
            vpw = vauth_getpw(ActionUser, Domain);
            float OldQuota = (atof(vpw->pw_shell));
            char path[256];
            long diskquota = 0, maxmsg = 0;
            snprintf(path, sizeof(path), "%s/Maildir", vpw->pw_dir);
            readuserquota(path, &diskquota, &maxmsg);
            if ((float)diskquota >= (atof(Quota)*1048576.0)) {
              sprintf(StatusMessage, html_text[905"));
            } else {
              if ((UsedQuota - OldQuota + (atof(Quota)*1048576.0)) > DefaultDomainQuota*1048576.0) {
                sprintf(StatusMessage, html_text[903"));
              } else if(vsetuserquota( ActionUser, Domain, qconvert )) {
                sprintf(StatusMessage, html_text[307"));
              } else {
                sprintf(StatusMessage, html_text[309], qconvert);
              }
            }
          }
        } else {
          sprintf(StatusMessage, html_text[307"));
        }
      }
    #endif
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (f.7) 第1013行(最后面)增加一个函数
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    float count_users_quota()
    {
      struct vqpasswd *pw;
      float ret = 0.0;

      pw = vauth_getall(Domain,1,0);
      while(pw!=NULL){
        if (strcmp(pw->pw_shell, "NOQUOTA") == 0) return -1.0;
        ret += atof(pw->pw_shell);
        pw = vauth_getall(Domain,0,0);
      }
      return ret;
    }
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -------------------------------------------------------------------------------

    请注意: 对于上述修改,我用diff命令(带 -ruN参数)做了一个patch档案,(请参考附录资源
    中的qmailadmin-1.2.11.fixquota.patch文档), 若有朋友嫌自己动手修改源程序麻烦, 也
    可以直接用下载此patch来使用.

    另外:Qmailadmin有关Quota限额的C源程序存在一个小小的BUG,它无法正确显示限额数值
    大于2048的数字(所有大于2048的数值都显示为2048),虽然真正有效的限额数值可以大于
    2048,但這個错误的显示却会使人相当困扰。
    ===============================================================================


    5) 安装qmailadmin
    ===============================================================================
    建立網頁主目錄:
    mkdir /var/www/qmailadmin;

    #一个标准(比较精简)的安装选项:
    ./configure \
    --disable-ipauth \
    --enable-modify-quota \
    --enable-cgibindir=/var/www/cgi-bin \
    --enable-htmllibdir=/var/www/qmailadmin \
    --enable-htmldir=/var/www/html

    #一个增强(比较丰富)的安装选项:
    ./configure \
    --disable-ipauth \
    --disable-user-index \
    --enable-modify-quota \
    --enable-vpopuser=vpopmail \
    --enable-vpopgroup=vchkpw \
    --enable-htmldir=/var/www/html \
    --enable-cgibindir=/var/www/cgi-bin \
    --enable-cgipath=/cgi-bin/qmailadmin \
    --enable-imageurl=/images/qmailadmin \
    --enable-imagedir=/var/www/html/images/qmailadmin \
    --enable-htmllibdir=/var/www/qmailadmin \
    --enable-qmaildir=/var/qmail \
    --enable-ezmlmdir=/usr/local/bin/ezmlm \
    --disable-ezmlm-mysql \
    --enable-autoresponder-path=/usr/bin \
    --enable-maxusersperpage=30 \
    --enable-maxaliasesperpage=30 \
    --enable-no-cache \
    --enable-help

    #相关选项的说明:
    --enable-domain-autofill                #登錄ID自動補充主機名
      With autofill enabled, qmailadmin will search the file
      /var/qmail/control/virtualdomains for an entry that matches the
      hostname of the HTTP request.  So, if test.com appears in your
      virtualdomains file, <http://www.test.com/cgi-bin/qmailadmin>
      will pre-fill the domain field with "test.com".

      Note that with or without autofill enabled, you can pass parameters
      to qmailadmin to pre-fill the "User Account" and "Domain" fields.
      <http://www.test.com/cgi-bin/qmailadmin?dom=xyz.net&user=john> will
      prefill "Domain" with xyz.net and "User Account" with john.

    --enable-spamcmd-needs-email        #
    --enable-modify-spam
    --enable-spam-command=CMD
    --enable-modify-spam                #在管理頁面顯示垃圾掃描選項
    --enable-vpopuser=vpopmail        #指定執行CGI程序的USER名稱
    --enable-vpopgroup=vchkpw        #指定執行CGI程序的GROUP名稱
    --enable-help                        #在登錄界面中顯示HELP鏈接

    请注意: 关于垃圾扫描的选项,必须配合目前系统所安装的扫描功能特性.

    因為qmailadmin的CGI執行程序必須啟用suid功能,請確認您的cgi-bin目錄并不是在設置
    了'nosuid'選項的分區上(可在/etc/fstab上檢查到此選項).

    make;
    make install-strip;
    ===============================================================================


    6) 测试安装结果:
    ===============================================================================
    http://xxx.xxx.xxx.xxx/cgi-bin/qmailadmin

    注意: 请在[User Account]中输入邮箱的用户帐号,例如postmaster, 在[Domain Name]中
    输入域名,例如test.com, 在[Password]中输入此邮件用户帐号的密码.
    ===============================================================================      
    ===============================================================================
    1) 安装 Courier authentication library
    ===============================================================================
    参考网站: http://www.courier-mta.org/
    下载资源: http://www.courier-mta.org/download.php#authlib

    mkdir /usr/local/src/qmail/courier/;
    cd /usr/local/src/qmail/courier/;

    wget http://prdownloads.sourceforge.n ... hlib-0.59.1.tar.bz2;
    wget http://prdownloads.sourceforge.n ... hlib-0.59.1.tar.bz2;
    wget http://prdownloads.sourceforge.n ... hlib-0.59.3.tar.bz2;
    tar jxvf courier-authlib-0.59.3.tar.bz2;
    cd courier-authlib-0.59.3;

    請注意: courier-authlib-0.59.3 無法安裝成功,需按如下方法修正authvchkpw.c程序檔:
    vi authvchkpw.c; (源程序缺少函數定義,請在第25行處插入如下補丁-請自行移除加號)
    -------------------------------------------------------------------------------
    static const char rcsid[]="$Id: authvchkpw.c,v 1.26 2007/04/22 18:53:30 mrsam Exp $";
    +
    +static int auth_vchkpw_login(const char *service, char *authdata,
    +        int (*callback_func)(struct authinfo *, void *), void *callback_arg);
    +
    extern int auth_vchkpw_pre(const char *userid, const char *service,
            int (*callback)(struct authinfo *, void *),
    -------------------------------------------------------------------------------

    ll /usr/local/libexec/authlib;                #检查是否已有库目录
    mkdir /usr/local/libexec/authlib;        #如果没有就要先建立

    先設定環境參數:
    -------------------------------------------------------------------------------
    CPPFLAGS="-I/home/vpopmail/include"; export CPPFLAGS;
    LDFLAGS="-L/home/vpopmail/lib"; export LDFLAGS;
    -------------------------------------------------------------------------------

    ./configure \
    --prefix=/usr/local \
    --exec-prefix=/usr/local \
    --without-authdaemon \
    --without-stdheaderdir \
    --without-authuserdb \
    --without-authpam \
    --without-authpwd \
    --without-authshadow \
    --without-authpgsql \
    --without-authcustom \
    --without-authldap \
    --without-authmysql \
    --disable-root-check \
    --with-authvchkpw \
    --with-ssl \
    --with-authchangepwdir=/usr/local/libexec/authlib \
    --with-redhat

    make;
    make check;
    make install-strip;
    make install-configure;
    cd ..

    vi /etc/rc.local;        #(設置開機自動啟動,请加入下面一行);
    -------------------------------------------------------------------------------
    /usr/local/sbin/authdaemond start;
    -------------------------------------------------------------------------------
    ===============================================================================

    ===============================================================================
    2) 安装 Courier-IMAP
    ===============================================================================
    参考网站: http://www.courier-mta.org/
    下载资源: http://www.courier-mta.org/download.php#imap

    cd /usr/local/src/qmail/courier/;
    wget http://prdownloads.sourceforge.n ... -imap-4.1.2.tar.bz2;
    或者下載當前最新版:
    wget http://prdownloads.sourceforge.n ... -imap-4.1.3.tar.bz2;

    cp -p courier-imap-4.1.3.tar.bz2 /home/vpopmail/;
    chown vpopmail.vchkpw /home/vpopmail/courier-imap-4.1.3.tar.bz2;

    su - vpopmail;                #注意:按開發者指示,一定要转换成vpopmail用户来编译;
    cd /home/vpopmail/;
    tar jxvf courier-imap-4.1.3.tar.bz2;
    cd courier-imap-4.1.3;

    ./configure \
    --prefix=/usr/local \
    --exec-prefix=/usr/local \
    --without-ipv6 \
    --with-authvchkpw \
    --without-authldap \
    --without-authmysql \
    --disable-root-check \
    --with-ssl \
    --with-authchangepwdir=/usr/local/libexec/authlib \
    --with-redhat

    make;
    make check;
    exit;                                        #退出普通用户的身份,回到root的身份
    cd /home/vpopmail/courier-imap-4.1.3/;        #回到刚才的安装目录
    umask;                                        #检查root的umask是否022,如果不是,要先设置成022
    make install-strip;                        #如果make install-strip失败,可试试make install;
    make install-configure;

    生成SSL证书:
    ll /usr/local/share/imapd.pem;                #先检查一下是否已经有SSL证书
    /usr/local/sbin/mkimapdcert;                #替IMAP-SSL产生一个SSL证书
    ll /usr/local/share/imapd.pem;                #再检查一下是否已经产生SSL证书

    注意事项:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    This will start and automated process that creates a self-signed imap-ssl X.509
    certificate called imapd.pem. It should create this new certificate at
    /usr/local/share/imapd.pem. If the certificate already exists, the "mkimapdcert"
    tool will not let you overwrite it.

    意思是说mkimapdcert工具会产生一个"self-signed"的认证文档 /usr/local/share/imapd.pem,
    而如果此文档已存在, mkimapdcert工具不会覆盖它.

    A Note on IMAP-SSL certificates: Keep in mind that since this SSL certificate is
    self-signed and is not from a "trusted" authority such as Verisign or Thawte,
    mail clients such as Outlook will give a warning when they attempt to connect to
    your IMAP-SSL server on port 995. The warning will state that the certificate is
    not from a "trusted" authority. While the warning is a bit ugly, it does NOT mean
    your IMAP-SSL connection is any less secure than it would be with a real certificate
    from Verisign or Thawte. All it means is that the SSL certificate was not generated
    by a company which Microsoft recognizes as a "trusted" authority. From a security
    standpoint, however, your IMAP-SSL server is every bit as secure as it would be
    if you bought the certificate from Verisign or Thawte. If the warning is too
    inconvenient for your purposes, you will need to purchase a "real" certificate
    from a "trusted" authority such as Verisign or Thawte. Be prepared to shell out
    a good chunk of change if you do so.

    大意是说"self-signed"证书会引起如Outlook之类的客户端邮件系统产生一个"not from a
    trusted authority"警告.也就是说Outlook通过995端口进行SSL连线时会弹出一个"安全凭
    证无法验证"的警告.
    -------------------------------------------------------------------------------

    注意: 必需在安裝 vpopmail 之後才可以安裝 courier-imap 套件。這樣 authvchkpw 模組
    才會被建立.
    ===============================================================================

    ===============================================================================
    3) 检查并修改安装程序产生的相关文件,配置SSL支持:
    ===============================================================================
    ll /etc/pam.d/imap;                        #检查是否生成imap文件
    ll /etc/pam.d/pop3;                        #检查是否生成pop3文件
    ll /usr/local/etc/;                        #检查相关配置文档是否符合要求

    -------------------------------------------------------------------------------
    vi /usr/local/etc/imapd.cnf;                #修改管理者的电邮地址
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    emailAddress=postmaster@example.com
    #请将电邮地址改成您的管理者电邮地址,例如:
    emailAddress=postmaser@2068.net
    -------------------------------------------------------------------------------

    -------------------------------------------------------------------------------
    vi /usr/local/etc/imapd;                #设置IMAPD的启动状态
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    请将 IMAPDSTART=NO 改为 IMAPDSTART=YES
    如需要可将 MAXPERIP=4 改成 MAXPERIP=10         (同一IP最大連線數目,其實默认值4已足够)
    -------------------------------------------------------------------------------

    -------------------------------------------------------------------------------
    vi /usr/local/etc/imapd-ssl;                #配置SSL支持参数
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    请将 IMAPDSSLSTART=NO 改为 IMAPDSSLSTART=YES

    保证设置中如下行(如果没有此行,则手工添加一行即可):
    TLS_CERTFILE=/usr/local/share/imapd.pem

    如需要可添加一行 MAXPERIP=4                 (默认未设限制)
    -------------------------------------------------------------------------------

    -------------------------------------------------------------------------------
    vi /usr/local/etc/authlib/authdaemonrc;        #设置认证模式
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    authmodulelist="authvchkpw authpipe"
    找到上面那行(在第27行),请改为如下(保证只有authvchkpw):
    authmodulelist="authvchkpw"

    注意: 请不要修改 authmodulelistorig="authvchkpw authpipe" 此行设置;
    -------------------------------------------------------------------------------
    ===============================================================================