【实验名称】

Qmail 邮件服务器的搭建
【实验环境】
REAL-HAT-5.4 虚拟机一台
【实验目标】
掌握Qmail邮件服务器的基本配置,实现基本的邮件收发。
【实验步骤】
第一步:实验环境的搭建。
(1)修改系统信息。
System-config-network
Vi /etc/sysconfig/network
Vi /etc/hosts
Vi /etc/sysconfig/selinux
清楚默认防火墙策略,并保存设置。
(1)     安装DNS相关软件包,并作相关配置。配置完成之后重启。
挂载光盘,并且安装DNS服务相关软件包。
编辑主配置文件添加区域记录,vi /etc/named.rfc1929.zone
编辑正向区域数据文件,并且添加相应的MX记录。
编辑反向区域数据文件。
更改区域数据文件的属组为named
启动服务,并且进行解析测试。
(2)     挂载Qmail光盘,将服务软件包释放的相应的目录。
netqmail-1.03 qmail 基本系统 包含补丁集和一些脚本
ucspi-tcp-0.88 tcpsever
等服务程序,一个 inetd 超级服务器的替换程序,由一组工具组成。它们用来简单的建立客户机-服务器 tcp 后台程序  
daemontools-0.76
监视工具,是 inetd winetd 的代替品 , 用它来监听 qmail-send,qmail-smtpd,qmail-pop3d
checkpassword-0.90 pop3
验证用户的程序, POP3 服务模块化的密码检查
(4)开始正式配置Qmail服务器。
创建一个package目录将daemontools-0.76.tar.gz释放到这个目录下。
为创建的目录赋予相应的权限, 非常重要,如果没有赋予相应的权限smtp服务是不能启动的。
进入netqmail-1.05这个目录,然后运行此脚本。出现一下7行信息表示运行成功。
注意qmail安装程序会自行创建需要的子目录, 只需要创建qmail的"home"目录:
创建Qmail所需要的相应用户和组。
注意:在创建相应组和用户时,Qmail自带一个脚本,只需要在一下目录中将原脚本文件拷贝然后做相应的修改,其次加上可知行权限,最后执行就OK了
以下是经过修改的脚本文件。
赋予可执行权限,然后执行。
注意:这里的提示是说此用户已经存在,当要创建此用户时,系统会将原来这个用户的目录文件拷贝过来,不用理会就可以了。
(5)进行软件的编译以及安装。
注意:以上步骤中创建用户与组没有创建完整,那么此步的编译安装会出现错误。
出现以下信息表明编译安装成功完成。
编译完成之后,执行当前目录下的./config脚本文件,此脚本是为了将您系统的主机全名写入Qmai的相关配置文件中。
但是为了避免后面的配置中出现错误,可以使用./config-fast zlb.xapc.com 进行再次指定。
(6)编译安装 ucspi-tcp-0.88 tcpsever 等服务程序,在安装之前必须先打上相关补丁。
然后执行 make && make setup check 出现以下信息表明编译安装成功。
7 )编译安装 daemontools-0.76 监视工具,在安装之前先打补丁。
回到上一级目录进行安装。
安装完成之后查看 svscan 服务是否正常运行。
8 )创建 Qmai 启动脚本。
Vi /var/qmai/rc
为创建的脚本添加可执行权限,然后创建 qmail 日志文件目录。
如果选择标准的 qmail /Mailbox 传送格式
如果你手动执行 /varqmail/rc 脚本 , qmail 只会部分被运行起来 . 可是我们希望希望每次系统启动后 , qmail 都能自动被启动 ; 每次系统停止时候 qmail 自动被关闭。创建一个如下的 /var/qmail/bin/qmailctl 文件可以完成实现
Vi /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
将上面这个 qmailctl 脚本设置为可执行脚本 , 然后链接到你的用户执行程序目录 :
9 )建立 supervise 脚本,为 qmail 的服务创建 supervise 目录:
vi /var/qmail/supervise/qmail-send/run 脚本内容如下:
#!/bin/sh
exec /var/qmail/rc
vi /var/qmail/supervise/qmail-send/log/run 脚本内容如下:
#!/bin/sh
exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/qmail
vi /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 控制文件 .
vi /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 文件设置为可执行文件 :
然后建立 log 文件目录并且设置目录属组为 qmaill
建立 supervise 目录到 /service 目录的链接,其中这个 service 目录是 daemontools 安装时建立的目录。
建立这个链接之后, qmail 系统会自动启动。这时可以使用命令将其停止。
设置 SMTP 访问控制。以下命令是设置只允许 Qmail 服务器为 127 网段以及 192.168.3 网段的主机提供服务。
启动 Qmai 服务,并且创建邮件用户。
依次为用户建立自己的 Maildir 格式信箱:在切换其他用户时,先使用 exit 命令退出当前 shell
测试安装,查看 Qmail 启动状态。
10. 安装 qmail-pop3d
为验证用户的程序包打补丁。
然后进行编译安装。
Make setup check 出现以下信息表示安装成功完成。
创建运行 pop3d 服务的相应目录已经运行脚本。
脚本内容如下:
创建 pop3d 日志监视脚本。
脚本内容如下:
建立 log 日志文件夹并且设置相应的 run 脚本 , 将脚本链接到 /service 目录 :
修改 qmailctl 脚本:
将下面内容加入 qmailctl 脚本的 "start" 部分
 
    if svok /service/qmail-pop3d ; then
      svc -u /service/qmail-pop3d /service/qmail-pop3d/log
    else
      echo qmail-pop3d supervise not running
    fi
 
将下面内容加入 qmailctl 脚本的 "stop" 部分
 
    echo " qmail-pop3d"
    svc -d /service/qmail-pop3d /service/qmail-pop3d/log
 
将下面内容加入 qmailctl 脚本的 "stat" 部分
 
    svstat /service/qmail-pop3d
    svstat /service/qmail-pop3d/log
 
将下面内容加入 qmailctl 脚本的 "pause" 部分
 
    echo "Pausing qmail-pop3d"
    svc -p /service/qmail-pop3d
 
将下面内容加入 qmailctl 脚本的 "cont" 部分
 
    echo "Continuing qmail-pop3d"
    svc -c /service/qmail-pop3d
 
将下面内容加入 qmailctl 脚本的 "restart" 部分
 
    echo "* Restarting qmail-pop3d."
    svc -t /service/qmail-pop3d /service/qmail-pop3d/log
添加完成之后,重启 qmail 服务,然后进行测试。
测试成功。
实验总结:
问题原因
这个问题是 Qmail 的经典问题,因为 life with qmail 中的 pop3 启动脚本中 softlimit 限制了默认的内存使用上限为 2000000 ,而实际这是不够的
所以使用默认的脚本就会出现各种各样的连接 110 端口错误,常见的还有
 /usr/local/bin/tcpserver: error while loading shared libraries: 
   libc.so.6: failed to map segment from shared object: Cannot allocate memory
解决方案
修改 pop3 启动脚本
vi /var/qmail/supervise/qmail-pop3d/run
# 2000000 改为 3000000 或者 5000000 保存退出
重启 qmail 服务,其实只要重启 pop3 就可以了,因为传统的 qmail 是用 qmailctrl 控制的,所以重启 qmail 比较方便一点
/path/to/qmailctl restart 这样问题就已经解决了。