第十六章 邮件服务器

邮件服务器是因特网上常用的服务器,我们平常收发电子邮件都必须经过邮件服务器。通常一般人都是使用 ISP 或免费的电子邮件信箱,由于这种服务的使用者很多,您的电子邮件账号通常很长,而且不是您所喜欢的名称。例如 ,如果您的名字是 Alex,您大概很难申请到 alex@yahoo.com 这么好记的地址,只能申请到类似 alex0706_tw@yahoo.com 这种又臭又长的信箱。如果您想要有比较好的信箱地址,则必须自行架设一台邮件服务器。

本章将介绍如何使用 FreeBSD 架设邮件服务器,读完本章后,您将可以对邮件服务器的运作更加了解。本章将包含下列主题:

16.1 电子邮件概论

一个电子邮件地址可以分为二个部份,第一个部份是使用者名称,第二个部份是主机名称。以 john@yahoo.com 为例,yahoo.com 就是主机名称,而 john 为使用者名称。john@yahoo.com 可以念作「John at yahoo.com」,翻成中文就是在 yahoo.com 上的使用者 John。

假设 Alex 使用的信箱是 alex@gmail.com,则当 Alex 要寄信给 john@yahoo.com 时,会经过下列步骤:

  1. 首先 Alex 从个人计算机中写好一封信,送到他所属的 gmail.com 的主机中。
  2. gmail.com 会先将信件存在自己的机器上的暂存区。
  3. gmail.com 会检查信件目的地,并查找 yahoo.com 的 IP 地址。
  4. 接着经由因特网将信件送到 yahoo.com 的主机。
  5. yahoo.com 的主机收到信后,发现是给自己机器中的使用者,所以将信件存放到使用者的新件匣中。
  6. 当 John 有空时,从家里打开计算机,并主动去 yahoo.com 检查是否有新的信件,当发现有新的信,则下载到自己的计算机中。

图 16-1

如果 alex@gmail.com 要寄信给 john@gmail.com,因为寄信者和收信者使用同一个邮件服务器,所以在上述步骤二中,gmail.com 的主机发现收信者是自己机器的使用者,则会将该信件存放在使用者的新件匣中。

从寄信到收信的流程中,每一个网络上的组件都扮演着不同的角色,我们分别来谈一下每一个角色的功能:

图 16-2

当我们在寄信时,所使用的是 SMTP (Simple Mail Transfer Protocol) 通讯协议,在一台邮件服务器上,必须要先安装邮件服器软件,以接收 SMTP 协议所寄来的信件。MTA 和 MTA 之间传送信件时也是使用 SMTP 协定。而收信时,使用的是 POP3 (Post Office Protocol) 或是 IMAP (Internet Message Access Protocol) 协定。

一般常用的 SMTP 软件为 FreeBSD 内附的 Sendmail、Qmail、或 Postfix。而收信时所使用的 POP3 及 IMAP 软件 FreeBSD 并未内建 ,因此我们必须自行安装。然而做为一台 Mail Server,我们要设定的是最少要做到可以正常使用 POP3 及 SMTP 来让使用者收发信。另外,我们也将介绍使用 Web 接口的邮件收发软件,Web 接口的邮件收发软件可以让使用者不必使用 Outlook 等软件即可经由任何操作系统的浏览器轻松收发信件。

传统上,SMTP 在接受使用者寄信时,并不须经过身份认证,任何人都可以使用你的主机来制造垃圾信。因此 FreeBSD 内建的 Sendmail 是不接受 SMTP 寄信的。而一般的 ISP 业者大多是以控制联机来源的方式,禁止非允许网域的使用者 RELAY。但如果我们以控制联机来源的方式,便无法在其它非允许的IP地址使用SMTP,这对于想要任何地方都可以发信的人十分不分便。因此,本章里我们将介绍如何让使用者透过 FreeBSD 使用 SMTP 身份认证的功能来寄信,让要使用诸如 Outlook 以 SMTP 寄信的使用者必须先通过本机的身份认证。

在开始架设邮件服务器之前,您必须先设定好 DNS。由于传送信件时,必须查找目的地主机的 IP。如果您的主机没有合法的 DNS 设定,信件将无法正确送达。假设您要架设一台处理 twbsd.org 的邮件服务器,在 DNS 设定方面有二种方式。第一种是直接将您的主机名称设为 twbsd.org,并设定 DNS 将 twbsd.org 对映到您的主机 IP。第一种方法是使用 DNS 的 MX 设定,将 twbsd.org 的邮件交由另一台主机处理。如果您的 DNS 是交由申请单位代管,则只要到申请单位设定好名称对映即可。如果您要自行架设 DNS 服务器,请参考「DNS 服务器」一章的说明。

另外,您的服务器 IP 也必须设好反解,IP 名称必须和您的主机名称对映,如果反解不正常,有的服务器可能会拒收您所送出的信件。

16.2 具身份认证的 sendmail

本文参考自中央研究院计算器中心张毓麟先生所发表的「具身分认证的邮件传送系统」,该文件的网址是 http://beta.wsl.sinica.edu.tw/~ylchang/Email/sendmail-auth。张先生对于在 FreeBSD 系统上建立安全的邮件服务器有多篇文章,您可以自 http://beta.wsl.sinica.edu.tw/~ylchang/Email/index.html 取得更多内容。

由于本章有许多指令,为了避免打字错误造成安装失败,笔者将这些安装过程写成一个快速安装的程序,您可以自本书光盘二中取出安装。安装方式如下:

# mount /cdrom
# cp -R /cdrom/mailserver /tmp/
# cd /tmp/mailserver
# sh mailserver.sh

接着依照画面指示即可快速安装本章具身份认证的 sendmail 了。安装完成之后,您可以使用下列指令以启动 sendmail:

# /usr/local/etc/rc.d/saslauthd.sh
# /usr/sbin/sendmail -bd -q30m

如果我们希望在一开机便启动 Sendmail,请在 /etc/rc.conf 中加入下面这一行:

sendmail_enable="YES"

如果您希望自行一步步操作,请依下列各小节的说明来安装,但请特别注意一些标点符号的差异,例如 ` (位于键盘左上角) 及 ' (位于键盘右边) 等符号。 笔者建议您如果要自行安装,在输入设定档内容时请使用本书光盘片中的范例,以免打字错误。

16.2.1 安装 Cyrus SASL

SASL (Simple Authentication and Security Layer) 可以让一些通讯协议 (例如 SMTP、IMAP 等) 具有身份认证的功能。Sendmail 自从 8.10 就支持 SASL 的功能。目前 cyrus-sasl 版本是 cyrus-sasl-2.1.21.tar.gz,我们可以 ftp 到各大 FTP 站台的 distfiles 目录下去取得最新版的 cyrus-sasl 或从本书光盘中 的 mailserver 目录中取得。取回后以下列指令安装。

# tar zxf cyrus-sasl-2.1.21.tar.gz
# cd cyrus-sasl-2.1.21
# ./configure --enable-login --enable-plain
# make
# make install
# cd /usr/lib
# ln -s /usr/local/lib/sasl2 .
# ln -s /usr/local/lib/sasl2 sasl
# ln -s /usr/local/lib/libsasl* .
# echo "pwcheck_method: saslauthd " > /usr/lib/sasl2/Sendmail.conf

接着我们要在一开机时就执行 saslauthd 这支认证用的程序,请新增文件名为 /usr/local/etc/rc.d/saslauthd.sh 的执行档,内容如下:

#!/bin/sh

case $1 in
"start")
	echo "Starting saslauthd"
	/usr/local/sbin/saslauthd -a pam
	;;
"stop")
	echo "Stoping saslauthd"
	killall saslauthd
	;;
*)
	echo "Usage $0 start|stop"
	;;
esac

然后将该档案属性变为可执行,并建立一个 saslauthd 所需使用的工作目录:

# chmod 755 /usr/local/etc/rc.d/saslauthd.sh
# mkdir -p /var/state/saslauthd

16.2.2 安装 Sendmail

在安装 Sendmail 之前,如果系统中正在执行旧版的 Sendmail,请先使用以下指令将它停掉:

# kill -9 `cat /var/run/sendmail.pid|head -1`

接着请到 www.sendmail.org 去下载最新版的 sendmail,您也可以在光盘二的 /ports/mailserver 目录中找到 Sendmail 8.13.5。Sendmail 自 8.12.0 版起,需要先建立一个使用者smmsp及所属群组供 Sendmail 使用。而 FreeBSD 自从 4.5-RELEASE 起己经内建了该使用者,如果你使用的是 4.5-RELEASE 以前的版本,请先编辑 /etc/group 加入下面一行:

smmsp:*:25:

再来增加使用者,执行 vipw 并增加下面一行:

smmsp:*:25:25::0:0:Sendmail user:/var/spool/clientmqueue:/sbin/nologin

将抓回来的 sendmail.8.13.5.tar.gz 放到 /tmp 底下,并以下列指令解压缩:

# tar zxvf sendmail.8.13.5.tar.gz

接着 ee /tmp/sendmail-8.13.5/devtools/Site/site.config.m4 建立档案并加入下列内容:

PREPENDDEF(`confENVDEF', `-DMAP_REGEX')
PREPENDDEF(`confOPTIMIZE', `-O2')
APPENDDEF(`confENVDEF', `-DTCPWRAPPERS -DSASL=2')
APPENDDEF(`conf_sendmail_LIBS', `-lwrap -lsasl2')
APPENDDEF(`confLIBDIRS', `-L/usr/local/lib')
APPENDDEF(`confINCDIRS', `-I/usr/local/include')
APPENDDEF(`confENVDEF', `-DMILTER')

由于上述档案内容中,有很多特殊的符号,为了避免打错字,建议您直接使用本书所附第二片光盘中的 /examples/site.config.m4 。完成后就可以开始安装 Sendmail 了:

# cd /tmp/sendmail-8.13.5
# sh Build
# sh Build install

为了要让本地的使用者不必经由身份认证使用 SMTP,还须再做下列设定:

# cd /tmp/sendmail-8.13.5/obj*
# cd mail.local
# make force-install
# chown root /usr/libexec/mail.local
# chmod u+s /usr/libexec/mail.local

接下来编辑 sendmail 设定模板档案以便产生出具有身分认证功能的 sendmail.cf 设定文件,请以下列指令执行:

# cd /tmp/sendmail-8.13.5/cf/cf
# cp generic-bsd4.4.mc MYCF.mc
# cd ../feature
# cat access_db.m4 >> ../cf/MYCF.mc
# cat delay_checks.m4 >> ../cf/MYCF.mc
# cat virtusertable.m4 >> ../cf/MYCF.mc
# cd ../cf
# cat >> MYCF.mc
TRUST_AUTH_MECH(`LOGIN PLAIN')dnl
define(`confAUTH_MECHANISMS', `LOGIN PLAIN')dnl
^D(同时按Ctrl+D)

上述要增加到 MYCF.mc 的二行字符串,您一样可以在本书所附第二片光盘中的 /examples/ 目录中找到 MYCF.mc.append 。为了避免打字错误,您可以使用下列指令来将上述二行附加在 MYCF.mc 中:

# mount /cdrom
# cat /cdrom/example/MYCF.mc.append >> MYCF.mc

接着我们要建立 sendmail.cf

# sh Build MYCF.cf
# cp MYCF.mc /etc/mail/sendmail.mc
# cp MYCF.cf /etc/mail/sendmail.cf

接下来请编辑 /etc/mail/access 这个档案,我们可以在 access 指定哪些 IP 或 domain 来源的机器是否可以经由我们的服务器寄信。如果您希望自己内部网域的机器可以不必使用身份认证,你可以在这个档案中加入内部网域的 IP。

127.0.0.1	     RELAY
192.168.0.1	RELAY
# 内部网络不需要认证
192.168.0	    RELAY

接着请产生二个 sendmail 所需要的档案:

# touch /etc/mail/virtusertable
# touch /etc/mail/aliases

然后请新增 /etc/mail/local-host-names 的档案, 里面填入 localhost 以及机器的完整名字 (如 mail.abc.com),当收到信的收件者不是给 mail.abc.com 时便会拒绝。接着,再新增一个档名为 /etc/mail/relay-domains 的档案填入本地的 domainname,例如 mydomain.com,这样一来由本地的 domain 发信时便不需再一次做使用者认证。然后将这些档案做成 sendmail 能接受的 DB 格式:

# cd /etc/mail
# makemap hash access.db < access
# makemap hash virtusertable.db < virtusertable
# newaliases

这样就完成了。您可以执行 sendmail -d0.1 -bv root | grep SASL 应该会出现 SASL 的字样,表示己可认证。

最后,我们可以使用下列指令来启动认证所需的程序及 Sendmail:

# /usr/local/etc/rc.d/saslauthd.sh start
# /usr/sbin/sendmail -bd -q30m

在启动 Sendmail 之后,如果执行 telnet localhost 25 ,再打ehlo localhost,我们应该看到一堆 250- 开头的讯息,其中有一行 250-AUTH LOGIN PLAIN 就代表 Sendmail 己经具有身份认证的功能,此时请输入 quit 结束。万一没有出现,请阅读 /var/log/maillog 里面的讯息可以知道错在哪里。

# telnet localhost 25
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 vmware.alexwang.com ESMTP Sendmail 8.13.5/8.13.5; Sat, 24 Sep 2005 19:16:09 +0800 (CST)
ehlo localhost  <--输入 ehlo localhost
250-vmware.alexwang.com Hello localhost [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-EXPN
250-VERB
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH LOGIN PLAIN  <-- 有这一行表示安装成功了!!
250-DELIVERBY
250 HELP
quit  <-- 输入 quit 以离开
221 2.0.0 vmware.alexwang.com closing connection
Connection closed by foreign host.

如果我们希望在一开机便启动 Sendmail,请在 /etc/rc.conf 中加入下面这一行:

sendmail_enable="YES"

16.2.3 Client 端的设定

微软的 outlook 由 4.0 版开始支持发信时身分认证功能,只要在 outlook 的设定里面将『外寄邮件服务器需要查验身分』的选项打勾就可以了。

第一步骤,选取『工具』菜单的『账号』选项:

图 16-3

第二步骤,选取账号选单中的『内容』按钮:

图 16-4

步骤三,将『外寄邮件服务器需要查验身分』功能项打勾:

图 16-5

按确定钮回到 outlook 中,即可使用身分认证功能发信。

16.3 POP3 及 IMAP 设定

传统上使用 Outlook 等收信软件时,我们会使用 POP3 来下载服务器上的信件。使用者有新的信件时,该信件会存放于 /var/mail/username 中,这个档案我们称之为 inbox。当我们使用 POP3 收信软件下载信件时,在下载完毕后,除非我们有设定在服务器上保留原本的信件,否则预设会在下载后自动将该信件自服务器中移除,以节省空间。

然而,如果您平常使用多台计算机,或是想在不同的地方依然可以看到之前的信件,则 POP3 就不太符合需求。除了 POP3 外,还有一个邮件通讯协议名为 IMAP。IMAP 和 POP3 最主要的差异在于 IMAP 一开始只下载信件标题,直到点选该信件后,它才会将信件下载至您所使用的计算机中。而在下载之后,IMAP 并不会将服务器上的邮件删除,所有浏览过的信件依然保存于 /var/mail/username 中。随着信件越来越多,inbox 的资料也会越来越大。此时我们可以使用 IMAP 建立新信夹的功能,在使用者家目录中建立许多新的数据夹,并将 inbox 的信件移至新建立的数据夹中,以减少 inbox 的大小,并加快收信的速度。而且,当我们寄出新信件时,若使用 POP3 协定,则寄件备份只会存放于您寄信时所使用的计算机中,但 IMAP 则会将寄件备份存于于服务器中。因此,如果您常使用多台不同的计算机收信,使用 IMAP 会蛮方便的,但 IMAP 在使用上速度会比 POP3 慢。

本章中,我们将介绍二种不同的 POP3 及 IMAP 收信软件,您可以依自己的需求安装合适的软件。

16.3.1 简单的 POP3 服务器

POP3 的设定很简单,我们只要选一个喜欢的 pop3 软件,以 ports 安装完后再做一些设定就好了。在这里我选用 popa3d:

# cd /usr/ports/mail/popa3d
# make install clean

接着编辑 /etc/inetd.conf,找到 pop3 的部份,将开头的 # 拿掉后,并加以修改如下:

#
# example entry for the optional pop3 server
#
pop3    stream  tcp     nowait  root    /usr/local/libexec/popa3d       popa3d

接着重新跑 inetd 即可:

# kill -HUP `cat /var/run/inetd.pid`

16.3.2 加密的 POP3 及 IMAP

在 FreeBSD ports 中,收录了许多 IMAP 及 POP3 的软件,我们选择了 IMAP-UW 这套软件来安装。IMAP-UW 不仅支持 IMAP 及 POP3,我们也可以设定要求使用加密过的 POP3 及 IMAP-UW 以加强密码及信件传送的安全性。首先,请使用下列指令安装 IMAP-UW:

# cd /usr/ports/mail/imap-uw
# make WITH_SSL_AND_PLAINTEXT=yes install

接下来,我们要产生 IMAP 及 POP3 所需使用的 SSL 凭证:

# cd /usr/ports/mail/imap-uw
# make cert

接着屏幕会出现一些问题,请依序回答:

输入国家代码,例如 TW。
Country Name (2 letter code) [NO]:TW
输入所在省份,例如 Taiwan。
State or Province Name (full name) [Some-State]:Taiwan
输入所在城市,例如 Taipei。
Locality Name (eg, city) []:Taipei
输入您的组织名称,你可以输入公司或学校名称,或直接按 Enter 即可。
Organization Name (eg, company) [FooBar Inc.]:My Company
输入单位名称,可以直接按 Enter 跳过。
Organizational Unit Name (eg, section) []:
输入您的机器完整名称,也就是您在 Outlook 等收信软件中所设定的服务器名称。
Common Name (FQDN of your server) []:mydomain.com

接下来我们必须设定一下 /etc/inetd.conf,并加入 POP3 及 IMAP 的相关设定:

pop3	stream	tcp	nowait	root	/usr/local/libexec/ipop3d	ipop3d
imap4	stream	tcp	nowait	root	/usr/local/libexec/imapd	imapd
pop3s	stream	tcp	nowait	root	/usr/local/libexec/ipop3d	ipop3d
imaps	stream	tcp	nowait	root	/usr/local/libexec/imapd	imapd

若您在开机时并未执行 inetd,请在 /etc/rc.conf 中加入下列设定:

inetd_enable="YES"

若您已启动 inetd,则设定完 inetd.conf 之后,我们必须重新启动 inetd:

# kill -HUP `cat /var/run/inetd.pid`

现在我们就可以设定使用 Outlook 来收发。如果您想使用加密的 IMAP 或 POP3 联机,您可以在设定完新的邮件账号后,点选内容,并选取 [进阶] 的部份,将 [这个服务器需要安全联机] 打勾,即可设 IMAP 或 POP3 收信时使用加密的联机。

图 16-6

16.4 进阶邮件服务器设定

架设邮件服务器只是服务器管理的第一步,后续的维护更是重要。好的系统管理者不仅仅是把机器架好,而是要管理好系统安全、解决使用者问题、并尽可能满足使用者需求。因此,我们接下来必须说明服务器的进阶管理议题,在使用者有问题时,我们才知道要如何处理。

16.4.1 设定邮件别名及自动转寄

当有同事离职时,我们常会被要求将该同事的信件转给某人。这种自动转寄的功能在 Sendmail 中很容易就可以做到,我们只要设定 /etc/aliases 即可。

/etc/aliases 是用以告知 sendmail 要将信转给哪个使用者或是交由哪个程序处理。aliases 这个档案是用来设定邮件的别名,也就是可以设定要将某人的信件转给其它地方(人员或程序),你也可以同时将某人的信转给很多人。这个档案的位置是由 sendmail.cf 档案中的 AliasFile 这个选项所决定的。当 sendmail 收到信时,会一行一行比对,当第一行符合后,就不会再继续下去,所以应注意优先级。

我们来看下列几个设定的范例:

#本档案的语法开头的 "#" 代表该行是批注,大小写都视为一样。
# 范例一
root: alex

# 范例二
john: alex,john

# 范例三
webmanager: alex,jack,jim@other.hostname.com

# 范例四
nobody: /dev/null

# 范例五
homework: |/usr/local/bin/homework.sh

# 范例六
olduser: :include: /usr/local/olduser_list

当设定了一堆复杂的别名之后,我们要看最后信会寄到哪里时,可以使用下面指令来看寄给 username 的信最后寄给谁:

# sendmail -bv username

aliases 档中将很多东西都转向 root,因此你可以去读 root 的信箱或是将 root 的信转给别的地方,下面这一行是将 root 的信都转给 my@my.domain:

root:	me@my.domain

当邮件无法送出被退回时给使用者时,都是以 MAILER-DEAMON 为账号寄出。因为使用者可能会回复那封被退回的信,所以这个别名是必备的。而 postmaster 则负责处理所有关于邮件问题的信件,因此也是必备的,一定要保留下面二行,这是必要的系统基本设定:

MAILER-DAEMON: postmaster
postmaster: root

请注意,修改完 /etc/aliases 后,我们必须使用下列指令来让所做的修改在 Sendmail 中发生作用:

# newaliases

16.4.2 一舨使用者设定自动转寄及自动回信

除了管理者可以经由设定 /etc/aliases 来转信使用者的信件外,一般使用者也可以设定将寄给自己的信转寄一份给其它人。

一般使用者只要在自己的家目录中新增一个档名为 .forward 的档案,并设定要转寄的对象即可。以下为 .forward 的设定范例:

\alex
alexwang@yahoo.com

如果我们在使用者 john 的家目录中新的上述的 .forward 档,则所有寄给 john 的信都会转寄给本机的 alex 及 alexwang@yahoo.com。我们必须要注意的是在上述的设定中,使用者 john 并不会收到寄给自己的信。如果自己也要收到信的设,必须在 .forward 檔中加入自己的名字。

另外,如果您要出国旅游,可能有很长的一段时间无法收信,并希望当有人寄信给您时,系统能自动回信告诉寄件者,则可以使用 .forward 的功能加上 vacation 这个指令来达成。

假设您的使用者名称是 alex,首先,我们先在 alex 的家目录下新增档案 .forward,其内容如下:

\alex
"|/usr/bin/vacation alex"

接着,我们要在家目录下新增档案 .vacation.msg 并加入下列内容:

From: "Alex Wang" <alex@alexwang.com>
Subject: I am on vacation now

Hello,

I will not be reading my mail for a while.
Your mail will be read when I return.

Thanks,
Alex

如果有人寄信给 alex 的话,除了 alex 会收到信外,寄件者也会收到一封标题为「I am on vacation now」的信,内容就是 .vacation.msg 中的内容。

vacation 这个指令名字取的很有趣,作者大概认为无法收信就是渡假去了。我们在 .forward 档中设定了当有信件进来时,就交由 vacation 去处理,而 vacation 会自动将 .vacation.msg 的内容回复给寄件者,这样就达到了自动回信的功能了。

小提示

一般使用者可以经由设定 .forward 及 .vacation.msg 来自动回信,但是这种设定方式对于一般使用者而言可能不太方便。我们可以使用下一章要介绍的 Openwebmail 来提供从网页中设定自动回复的功能。

16.4.3 限制每封邮件大小上限

不论您的系统硬盘多大、网络多快,在复杂的网络世界中,难保没有人会恶意寄送大型邮件来灌瀑您的信箱。不论如何,我们还是应该要做好基本的防护。在 Sendmail 的设定档中,可以让我们限制接收的邮件大小。

如果您要限制接收信件的大小,可以修改 /etc/mail/sendmail.cf,将下列项目开头的批注移除:

# maximum message size
O MaxMessageSize=5000000

我们限制最大的信件大小为 5000000 bytes (即 5MB)。修改完后,您必须重新启动 sendmail 设定才会生效。

# killall sendmail
# /usr/sbin/sendmail -bd -q30m

16.5 邮件问题处理

在管理邮件服务器时,我们常会遇到使用者报怨信件无法送出、信件收不到、寄信出现错误等等。在遇到这类问题时,我们必须具备问题追踪的能力,以协助使用者解决寄信的问题。

在处理收发信件问题时,您可能必须查询 DNS 的设定、了解邮件结构。在说明如何处理收发信件问题前,我们先来了解一些基本的邮件管理知识。

16.5.1 邮件结构

Sendmail 会将所有的使用者新收到的信件放在 /var/mail 中,并将使用者刚寄出的信放在 /var/spool/mqueue 中。在 /var/mail 目录中,每个使用者的新件匣都是一个和使用者名称一样的档案。例如,使用者 alex 的新件匣是 /var/mail/alex、使用者 john 的新件匣是 /var/mail/john。当我们使用 Outlook 或 webmail 收信时,随然我们看到的是一封封的邮件,但在系统中,这些邮件是以纯文字模式全部存放在同一个档案中。所以,当使用者的信件很多时,该档案会越来越大,在使用 IMAP 或 webmail 收信时,速度也会变得比较慢。

由于 /var/mail/var/spool/mqueue 中的信件都是以纯文字格式存放信件,管理者可以直接使用任何文书编辑软件打开使用者的信箱。因此,管理者本身的操守很重要,否则所有人的机密都会被看见。

为了了解一封信的结构,我们还是要看一下信件的内容。您可以打开 /var/mail 目录中自己的信件,或是在 Outlook Express 中对着信按右键 -> [内容],再选 [详细资料] -> [邮件原始文件],即下图示:

图 16-7

接下来,我们可以看到一个邮件原始数据如下:

# Return-Path 表示要回信则会回给 edm@ebp.eracom.com.tw
Return-Path: <edm@ebp.eracom.com.tw>

# 这是由 alexwang.com 的 Sendmail 所产生的标头。表示信件是由 ebp135.eranet.net
# 所寄出,并由 alexwang.com 处理此信件。
Received: from eracom.com.tw (ebp135.eranet.net [203.95.231.171])
	by alexwang.com (8.13.5/8.13.5) with ESMTP id j8QE1IpL059750
	for <alex@alexwang.com>; Mon, 26 Sep 2005 22:01:24 +0800 (CST)

# 这是由 eracom 的邮件软件所产生的标头。
Received: from mail pickup service by eracom with Microsoft SMTPSVC;
	 Mon, 26 Sep 2005 22:01:25 +0800

# Thread-index 及 Thread-Topic 是用来在回信时让客户端的软件判断信件是和哪几封信
# 同一个主题用的。
thread-index: AcXCg/dY0ifrCKOiTJO8PTlqFlJD/A==
Thread-Topic: =?big5?B?pn6lTrDiVkqvqVPVIp9yp2qq6xV2kT6FJsXqkU6vnr+A=?=
	=?big5?B?v/m5TA==?=

# From 是寄件者的名称及 Email。
From: =?big5?B?pn6lTrDisrw=?= <edm@ebp.eracom.com.tw>

# 这是收件者的信箱。
To: <alex@alexwang.com>

# CC 是复本收件者。
Cc:

# Subject 是本封信件的主题。
Subject: =?big5?B?pn6lTrDisrwgLqvmhqVPVIp9yp2qq6xV2kT6FJsXqkU6vnr+A=?=
	=?big5?B?v/m5TA==?=

# Date 是收信的时间。
Date: Mon, 26 Sep 2005 18:20:49 +0800

# Message-ID 是由发信软件所产的邮件编号。
Message-ID: <9a3d401c5c283$f7587140$abe75fcb@louis1712gid2f>

# 此封邮件所使用的 MIME 版本。
MIME-Version: 1.0

# 邮件内容格式。
Content-Type: multipart/alternative;
	boundary="----=_NextPart_000_9A3D5_01C5C2C7.057BB140"

# 邮件的优先级。
Priority: normal

# 表示这是 multi-part MIME 格式的邮件。
This is a multi-part message in MIME format.

# 以下为邮件本文
... 略 ...

我们可以从邮件的标头中看到信件真正的来源。有的邮件来源可能会假造,我们也可以从邮件的标头中看出来。

16.5.2 限制寄件者来源

邮件信箱用久了,难免会收到垃圾信。如果您常收到垃圾信,或是想要阻挡某一个网域寄来的信件,最简单的做法是使用 Sendmail 内建的阻挡功能。

我们可以经由设定 /etc/mail/access 来阻挡某个网域的信件。以下是几个设定的范例:

192.168                RELAY
free.spammail.com      REJECT
cyperspammer.com       550 We don't accept from spammers
somespammer.com        DISCARD
sendmail.org           OK

/etc/mail/access 的格式是先列出网域、网址、或 Email,再加上 DISCARD、REJECT、RELAY、OK、或是一串有错误代码的讯息。如果是 OK,表示可以寄信到这一台机器中,这是默认值,所以我们很少用到 OK 这个关键词。而 RELAY 表示可以使用这台机器送信到其它的机器。REJECT 表示不可以使用这台机器的邮件服器。DISCARD 表示将信收下,并直接删除,寄件者会以为信件正常被送出。550 加上一个字符串表示响应此字符串给寄件者。

在设定完 /etc/mail/access 后,我们必须执行下列指令,以将该档案做成 Sendmail 所使用的数据文件:

# makemap hash /etc/mail/access < /etc/mail/access

我们当我们收到垃圾信时,寄件者往往是假造的,但我们还是可以从邮件标头中看出该信件的真正来源。以下列标头为例:

Received: from hoho88_nserver.cx (10p2.ppp.odn.ad.jp [219.66.191.46])
by alexwang.com (8.13.1/8.13.1) with SMTP id j8P6ke57004728
for <alex@alexwang.com>; Sun, 25 Sep 2005 14:46:40 +0800 (CST)
Date: Sun, 25 Sep 2005 14:46:40 +0800 (CST)
Delivered-To: <alex@alexwang.com>

Message-ID: 20030120467mail@mail.hi9658754215_starweb88_mainserver.cx
From: mikas_mail_0911@yahoo.co.jp
To: alex@alexwang.com
Subject: =?iso-2022-jp?B?gXWCqJCimGKCyYLIgsGCxIKoguiC3IK3gUk=?=
MIME-Version: 1.0
Content-Type: text/plain;
charset="iso-2022-jp"

我们可以看到虽然寄件者是 mikas_0911@yahoo.co.jp、发信的主机是 hoho88_nserver.cx,但实际上是的来源 IP 是 219.66.191.46,这个 IP 就是我们要阻挡的地址。或者,您可以阻挡整个 ppp.odn.ad.jp 的信件。

16.5.3 处理未寄出之信件

系统中所有未寄出的信件都会放在 /var/spool/mqueue 中,在该目录中,一封未寄出的信会有二个档案,这二个档案包含了原始信件及寄件失败的原因。我们可以使用下列指令列出所有未寄出的信件。

# mailq
               /var/spool/mqueue (1 request)
-----Q-ID----- --Size-- -----Q-Time----- ------------Sender/Recipient-----------
j8NFunJe071657    15472 Fri Sep 23 23:56 <>
                (Deferred: Connection refused by mail.somewhere.com.)
                                        <www@some.your.com>
               Total requests: 1

我们可以看到有一封信未送出,原因是被 mail.somewhere.com 拒绝了。

一般而言,Sendmail 每隔一段时间 (依启动 Sendmail 所加的 -q 参数而决定) 会自动重新送出队列中的信件,最后都无法送出则会通知寄件者。如果您要立即重新送出队列中的信件,可以使用下列指令:

# sendmail -qf

如果您要删除某一封在队列中的信件,请先使用 mailq 查看 Q-ID,再到 /var/spool/mqueue 中删除 qfXXXX 及 dfXXXX 的档案,其中 XXXX 是您要删除的 Q-ID。

16.5.4 收发信件问题处理

电子邮件在现在的企业中使用非常频繁,很多公司几乎所有事务都经由电子邮件处理,收发信不正常往往是 MIS 人员的恶梦。很多时候问题可能不是出现在邮件服务器本身,而是网络设定、DNS 问题、或是对方服务器的问题。当您遇到收发信件问题时,就必须要从系统记录、发信软件中查出蛛丝马迹。在检查问题之前,请先确认您的邮件服务器的 DNS 设定没问题,而且邮件服务器 IP 和主机名称正反解都正确。DNS 设定不正常的服务器往往是不能收发信件的主因。

发信问题处理

在发信问题方面,如果您使用发信软件寄不出信件,请先检查发信软件所秀出的讯息,再找解决之道。通常发信问题可以分为二类,一种是在使用 Outlook Express 送信时就已经送不出去,另一种是信送出了,但对方没收到。第一种问题比较好解决,我们只要看 Outlook Express 的错误讯息即可看出端倪。以下列讯息为例:

图 16-8

我们可以看到错误讯息中有「Relaying denied. Proper authentication required.」,很明显的是因为这一台服务器必须经过身份认证后才可以使用,我们只要在送信设定中使用身份认证即可。在 Outlook Express 的讯息中,也有可能出现类似 DNS 找不到、主机找不到、使用者不存在等问题。我们只要依这些讯息来查看设定、Email 地址,即可找到原因。

第二种问题是信件寄出了,但是对方没收到。这种情形,我们就必须要多花点心力了。首先,我们先到服务器上 /var/spool/mqueue 查看信件是否在队列中。如果在,则查看一下送出去出的原因,并依错误讯息解决问题。如果从错误讯息中看不出问题,则可以查阅 /var/log/maillog,并找出该信件的寄送讯息:

Sep 23 00:22:42 mail sendmail[22426]: j8MGMKkE022408:
to=john@myfriend.com, ctladdr=john@myfriend.com (1029/501),
delay=00:00:22, xdelay=00:00:05, mailer=esmtp, mailer=esmtp,
relay=alexwang.com, dsn=5.1.2, stat=Host unknown (Name server:
myfriend.com: host not found)

以上述范例为例,就是因为找不到 myfriend.com 这台主机。这时候,我们可以手动使用 nslookup 查找该主机,并检查 DNS 的设定是否有问题。如果是 DNS 主机的问题,则可以更换 DNS 服务器设定。

如果收件者的服务器有安装防垃圾信软件,有的时候我们的服务器所使用的 IP 可能会因为某些列为垃圾信。在发信后,您可能会收到下列退信:

 ----- The following addresses had permanent fatal errors -----
<jousset@sultant.com>
(reason: 554 EMail from mailserver at 10.22.102.129 is refused.

See
http://spamblock.outblaze.com/10.22.102.129)

----- Transcript of session follows -----
... while talking to sultant-com.outblaze.com.:
>>> DATA
<<< 554 EMail from mailserver at 10.22.102.129 is refused. See
http://spamblock.outblaze.com/10.22.102.129
554 5.0.0 Service unavailable
<<< 554 Error: no valid recipients

这时候我们就必须依该信件指示,到该黑名单网站中要求对方将我们的 IP 从黑名单中移除。

如果从 /var/log/maillog 中确认信已经从本机寄出而对方还是没收到,则接下来就要请对方 MIS 人员查看对方服务器是否有问题了。

总结关于发信问题处理步骤如下:

收信问题处理

在收信问题方面,和发信问题一样,最关键的还是 DNS 设定。我们必须先检查客户端所使用的计算机是不是可以正常的找到邮件服务器。如果找不到,则必须修改 DNS 设定。

接下来,必须确认客户端的发信软件有连到服务器,并可以正常使用 POP3 或 IMAP。如果在联机时出现错误,您一样可以从 /var/log/maillog 中看出问题。以下列联机记录为例:

Sep 23 02:16:12 mail sm-mta-in[24776]: j8MV5024776: ruleset=check_rcpt,
arg1=<peter.fr@mail1.stofan.dk>, relay=[219.93.1.218], reject=550 5.7.1
<peter.fr@mail1.stofane.dk>... Relaying denied. IP name lookup failed

从记录中,我们可以看出来是因为反查 mail1.stofane.dk 失败,所以我们的服务器拒收此封信件。这就是为什么邮件服务器最好还是要设定好 IP 反查的原因。

如果有人抱怨一直没有收到客户寄来的信,我们可以从 /var/log/maillog 中找出该寄件者到底有没有将信件寄到我们的服务器。如果没有,则可以请对方检查邮件信箱是否正确、对方服务器中是否有其它讯息。