第18章 电子邮件
18.1概要
电子邮件是现在使用最广泛的通信方式之一。这章将对在FreeBSD上运行一个邮件服务器做个基本的介绍。然而,它并不是一个完整的参考,事实上有许多重要的细节都被略过了。有关这个主题的更完整的介绍,你可以参考附录B中所列出的很多精彩的书籍。
读完这章,你会了解到:
什么软件组件是与发送和接收email有关的。
基本的sendmail配置文件在哪儿。
如何使用你的邮件服务器阻止一些非法信息。
如何处理一些基本的邮件服务器的问题。
在阅读这章之前,你必须了解:
正确地配置你的网络连接(第17章)。
正确地为你的邮件服务器配置DNS信息(第17章)。
知道如何安装第三方软件(第4章)。
18.2使用电子邮件
邮件交换共有5个部分。它们是:用户端程序,服务器端程序,DNS,pop或IMAP协议,邮件主机。
18.2.1用户端程序
用户端程序就是如elm,pine,mail这些的程序,或是更复杂一点的GUI程序如balsa,xfmail还有一些老的像WWW浏览器一样的程序。这些程序只是单纯地通过呼叫sendmail程序或是通过TCP来传送,把所有的邮件传输工作交给“邮件主机”来处理。
18.2.2邮件主机服务器守护程序
邮件主机服务器守护程序通常是指那些在后台执行的sendmail或是smail,还有像qmail,postfix或exim这些。还有其他一些,但这些用的不多。
服务器守护程序通常有两个功能——接收和发送邮件。
它不允许你通过POP或IMAP来连接读取邮件。你需要一个额外的守护程序。
需要记住,sendmail的一些比较老的版本有些安全问题,到现在这些问题都已经解决了。通常,将你的软件升级到最新版是个好主意。
18.2.3 Email和DNS
域名系统(DNS)以及它的守护程序named在邮件分发的过程中扮演了一个非常重要的角色。
为了从你的站点向另一个站点分发邮件,服务器守护程序将在DNS中寻找站点来决定将接收邮件的主机。
当你有邮件被发送给你的时候,它就用同样的方法工作。DNS包含了主机名到IP地址和主机名到邮件主机影射的数据库。IP地址用一个A记录来指定。MX记录指定为你接收邮件的邮件主机。如果你没有一个针对你主机名的一个MX记录,邮件将被直接分发到你的主机。
18.2.4接收邮件
为你的域接收邮件是通过邮件主机来完成的。它会把收集的邮件发送给你,然后存储起来以便阅读或挑选。为了获得保存的邮件,你需要连接到邮件主机。可以用POP或IMAP方式来做。如果你要直接从邮件主机阅读邮件,pop或IMAP服务器不是必需的。
如果你要运行一个POP或IMAP服务器,有两件事你必须做:
1, 从ports collection得到一个POP或IMAP守护程序,安装到你的系统。
2, 修改/etc/inetd.conf文件来加载POP或IMAP服务器。
18.2.5邮件主机
邮件主机是服务器给的一个名字,主要是从你的主机,也可能是你的网络发送和接收邮件。
18.3 sendmail配置
Sendmail是FreeBSD上默认的邮件传输代理(MTA)程序。Sendmail的工作是从邮件用户代理(MUA)那里接收邮件,然后根据配置文件的定义把它们分发给适当的邮箱。Sendmail也能够接受网络连接,把邮件分发给非本地邮箱或传给另一个程序。
sendmail使用下面的配置文件:
文件名 |
功能 |
/etc/mail/access |
sendmail访问数据库文件。 |
/etc/mail/aliases |
邮箱别名。 |
/etc/mail/local-host-names |
用来接收邮件的主机列表。 |
/etc/mail/mailer.conf |
邮件程序配置。 |
/etc/mail/mailertable |
邮件分发列表。 |
/etc/mail/sendmail.cf |
sendmail的主配置文件。 |
/etc/mail/virtusertable |
虚拟用户和域列表。 |
18.3.1
/etc/mail/access
访问数据库定义了什么主机或IP地址能访问本地邮件服务器和它们是哪种类型访问。主机可能会列出OK,REJECT,RELAY,或者简单地通过sendmail的错误检测程序来检测给定的邮件错误。主机默认是列为OK,只要邮件的最终目的地是本地机器,它允许发送邮件到这个主机。列出REJECT的主机将拒绝所有的邮件连接。它们的主机名上带有RELAY选项的主机被允许通过这个邮件服务器发送邮件到任何目的地。
例18-1.配置sendmail访问数据库
cyberspammer.com
550 We don't accept mail from spammers
FREE.STEALTH.MAILER@ 550 We don't
accept mail from spammers
another.source.of.spam
REJECT
okay.cyberspammer.com OK
128.32
RELAY
在这个例子中,我们有5个记录。与左边列表匹配的邮件发送者受到右边列表动作的影响。前两个例子给出了一个sendmail错误检测程序检测到的错误代码。当一个邮件与左边列表相匹配时,这个信息会被打印到远程主机上。下一个记录会拒绝来自internet上一个特定主机的邮件,another.source.of.spam。下一个记录会接受来自主机okay.cyberspammer.com的邮件连接,它要比上面的那行cyberspamer.com更加准确。更多特定的匹配会修改不准确的匹配。最后的记录会允许转播以128.32作为起始IP地址的主机的电子邮件。这些主机将能够通过这个前往其他邮件服务器的邮件服务器发送邮件。当这个文件被升级的时候,你必须在/etc/mail/中运行make来升级数据库。
18.3.2
/etc/mail/aliases
别名数据库包含了一个扩展为用户,文件,程序或其他别名的虚拟邮箱的列表。这儿是几个在/etc/mail/aliases中使用的例子:
例18-2. 邮件别名
root: localuser
ftp-bugs: joe,eric,paul
bit.bucket: /dev/null
procmail:
“|/usr/local/bin/procmail”
别名的升级是与冒号左边的邮箱名称相配的,将把它扩展为在右边的标记。第一个例子简单地把邮箱root扩展为一个localuser,它可以在别名数据库中找到。如果没有找到匹配的,那这个信息会被分发给本地用户localuser。下一个例子显示了一个邮件列表。发给ftp-bugs邮箱的邮件会被扩展为三个本地邮箱joe,eric和paul。注意一个远程邮箱可以用[email protected]的形式来指定。下一个例子将显示将邮件写到一个文件,在这个例子中是/dev/null。最后的例子显示了发送邮件给一个程序,在这个例子中,邮件信息通过一个UNIX管道被写到/usr/local/bin/procmail的标准输入中。
当这个文件被升级的时候,你必须在/etc/mail/中运行make来升级数据库。
18.3.3
/etc/mail/local-host-names
这是一个sendmail被接受作为本地主机名的主机名列表。可以放入任何Sendmail将从那儿接收邮件的域名或主机。例如,如果这个邮件服务器从域example.com和主机mail.example.com接收邮件,它的local-host-names可以是这样的:
example.com
mail.example.com
当这个文件被升级时,sendmail必须被重新启动以读取修正。
18.3.4
/etc/mail/mailer.conf
mailer.conf配置文件保存了一个包含习惯了使用给定动作的真正的邮寄者列表。很老的软件程序针对邮寄者的名称和路径是硬编码的,/usr/sbin/sendmail,这意味着它们可能与像postfix这样的其他邮件程序不兼容。今天,/usr/sbin/sendmail是一个可以在/etc/mail/mailer.conf中看到的和执行正确的二进制程序的软件包。当另一个邮件传输代理程序被安装在系统上时,mailer.conf将被升级以反映正确执行的程序。
18.3.5
/etc/mail/sendmail.cf
sendmail的主配置文件,sendmail.cf控制着sendmail的全部行为。从重写email地址到为远程邮件服务器打印遭抵制信息的每一样东西。自然地,作为这样一个不同的角色,这个配置文件是很复杂的,它的细节超出了这节的范围。幸运的是,这个文件在标准服务器上很少需要被修改。主sendmail配置文件可以用m4宏来定义sendmail的特性和行为。请参考/usr/src/contrib/sendmail/cf/README以了解更多细节。当这个文件被修改时,sendmail必须重新启动以使修改生效。
18.3.6
/etc/mail/virtusertable
Virtualusertable会为虚拟域和邮箱影射邮件给真实邮箱。这些邮箱可能是本地的,远程的,/etc/mail/aliases中定义的一个别名或一个文件。
例18-3.虚拟域邮件影射
[email protected]
root
[email protected]
[email protected]
@example.com
joe
在上面的例子中,我们影射了一个域example.com。这个文件用一个最初匹配的顺序处理。第一条项目,影射[email protected]到本地邮箱root。下一个记录影射[email protected]给主机noc.example.net上的邮箱postmaster。最后,如果来自example.com的没有什么被匹配,它将与匹配最后一个影射。这儿将被影射到本地邮箱joe。
18.4常见问题
1.为什么我必须在我的站点上为主机使用 FQDN?
你可能会发现主机实际上是在另外一个域里面。例如,如果你是在foo.bar.edu,而你要找一台在bar.edu域中的叫mumble的机器,你就必须用完整的域名mumble.bar.edu 而不是用mumble。
传统上,这在BSD BIND resolver中是可行的。然而目前随FreeBSD附带的BIND早已不再为同一域外的非FQDN 提供默认的缩写服务了。因此这个不完整的主机名称mumble必须以mumble.foo.bar.edu这种形式才能找到,或者它将在根域被找到。
这跟先前版本的处理是不一样的,前一版会继续找mumble.bar.edu 以及mumble.edu。如果你想知道为什么这种方式是不好的或甚至会造成安全方面的漏洞,请你参阅RFC 1535。
如果你想要求一个良好的工作环境,你可以使用
search foo.bar.edu bar.edu
以代替前一版所用的
domain foo.bar.edu
把这一行放在/etc/resolv.conf中。然而,请一定要确定这个搜寻的顺序不会造成 RFC 1535中所谓的“boundary between local and public
administration”问题。
2. Sendmail说“mail loops back to myself”
下面是sendmail FAQ中的回答:
* 我得到了一个如下的信息:“Local configuration error”
553
relay.domain.net config error: mail loops back to myself
554
<[email protected]>... Local configuration error
我要怎么解决这个问题?
你已经通过使用一个MX记录把邮件发送给了将被转寄给一个特定主机(relay.domain.net)的域(如:domain.net),而这个转寄的机器不认为它自己是domain.net。请把domain.net添加到/etc/sendmail.cw文件 (如果你用FEATURE(use_cw_file)
的话), 或是把“cw domain.net”添加到/etc/sendmail.cf文件。
sendmail
FAQ可以在/usr/src/usr.sbin/sendmail里找到,如果你想要对你的邮件设定动任何“手脚”,我建议你先把它看一看。
3. 我要怎么做才能通过一个拨号上网的PPP主机使用电子邮件?
你想要把局域网络上的FreeBSD主机连到因特网上,而这台 FreeBSD主机将会成为这个局域网络的邮件网关。这个PPP连接不必一直保持在联机状态。
至少有两个方法可以达到这个要求。另外的方法就是使用UUCP。
关键在于你要找到一个网络主机来为你的域提供副MX 主机服务。举例来说:
bigco.com. MX 10 bigco.com.
MX 20
smalliap.com.
只有一部主机被指定当作你的最终收信主机(在bigco.com主机的/etc/sendmail.cf文件中添加cw bigco.com)。
当寄信人的sendmail程序试图分发邮件的时候,它会试着通过modem连接到你的机器上。因为你并非处于在线状态,所以它老是得到一个超时的错误。此时sendmail 就会自动把信分发给副MX主机,如:你的ISP。这副MX 主机会每15
分钟(在/etc/rc.conf中的设置是sendmail_flags =-bd -q15m)连接到你主机,把信送给主MX站点。
你可能会想把下面这段设成一个登陆脚本:
#!/bin/sh
# Put me in
/usr/local/bin/pppbigco
( sleep 60 ;
/usr/sbin/sendmail -q ) &
/usr/sbin/ppp -direct
pppbigco
如果你想要为一般用户创建一个分开的登录脚本的话,你最好用sendmail -qRbigco.com代替上面那一段的脚本。这样做会迫使所有的邮件以你的顺序立即被处理。
更深入的方法可以参考下面这段。
这段资料是从freebsd-isp邮件列表中拿来的<[email protected]>。
> 我们为用户提供次要MX主机的服务。用户每天都会上线好几次并且自动把
> 信件取回主要MX主机(当有他们的邮件时我们并没有通知他们)。我们的
> mailqueue 程序每30 分钟清一次邮件队列。那段时间他们就必须上线
> 30 分钟以确保他们的信件有送达他们的主要MX 主机。
>
> 有任何指令可以启动sendmail并令它把所有邮件寄出吗?当然该用户在
> 我们的机器上没有 root 的权限。
在 sendmail.cf 的“privacy
flags”部分,有这么一个设定
Opgoaway,restrictqrun
为了要让非 root 用户也可以启动队列处理的程序,请把 restrictqrun 去
掉。你可能也要重新安排你的MX设定。我们是用户的主要MX主机,
而且我们还设定了这个:
# If we are the best MX for
a host, try directly instead of
generating
# local config error.
OwTrue
这样一来,别的机器就不会去试着连往你用户的机器而会直接把信送给你。然后你再把信送给你的用户就可以了。这个设定只对“主机”有效,所以你必须请你的用户在DNS中把他们的邮件主机取名为“customer.com”或是“hostname.customer.com”。只需要在DNS 中为“customer.com”多加一个A 记录就行了。
18.5 高级主题
下面这节将介绍邮件配置和为整个域安装邮件。
18.5.1基本配置
在邮箱外,在你设置/etc/resolv.conf或运行一个你自己的名称服务器时,你能够发送邮件给外部的域。如果你想把你的邮件发送给某个特定的主机,可以这样做:
运行你自己的域名服务器和你自己的域,例如FreeBSD.org。
获得直接分发给你主机的邮件。你可以直接使用你当前的DNS名称,例如example.FreeBSD.org。
不管你选择上面的哪一个,为了直接从你的主机上发送邮件,你必须有一个固定(静态)的IP地址(不是动态PPP拨号)。如果你处在一个防火墙后面,你必须通过SMTP传输。如果你要在自己的主机上接收邮件,你需要确定两件事:
确定在你DNS中的MX记录指向你主机的IP地址。
确定在你DNS中没有针对你主机的MX记录。
上面的每一个都允许你直接从你的主机上接收邮件。
试试这个:
# hostname
example.FreeBSD.org
# host example.FreeBSD.org
example.FreeBSD.org has
address 204.216.27.XX
如果你看到这些,直接使用<[email protected]>应该没有问题。
如果你看到这些:
# host example.FreeBSD.org
example.FreeBSD.org has
address 204.216.27.XX
example.FreeBSD.org mail is
handled (pri=10) by hub.FreeBSD.org
所有发送到主机(example.FreeBSD.org) 的邮件在同样的用户名下将在hub上被终止的收集,而不是直接被发送到你的主机。
上面的信息是通过你的DNS服务器来处理的。支持邮件路由信息的DNS记录是邮件交换记录。如果没有MX记录存在,邮件将通过它自己的IP地址被直接发送给主机。
freefall.FreeBSD.org的MX记录如下所示:
freefall MX
30 mail.crl.net
freefall
MX 40 agora.rdrop.com
freefall
MX 10 freefall.FreeBSD.org
freefall
MX 20 who.cdrom.com
正如你看到的,freefall有很多MX记录。最低的MX数字是最后终止接收邮件时的主机,而如果freefall很忙或当机的话,其他的将会临时地排列主机。
为了更高效地使用交换式MX站点,应当从你的机器上分离一些Internet连接。你的ISP或其他友好的站点可以毫无问题地为你提供这种服务。
18.5.2 Mail for Your
Domain
为了设置一个邮件主机,你需要把许多邮件发送到与它相连的几个工作站中。基本上,你要为你的域“hijack”很多邮件(在这个例子中是*.FreeBSD.org),然后把它转到你的邮件服务器上,所以你的用户能通过POP或直接在服务器上检查他们的邮件。
要使工作最简单,带有同样用户名的用户帐号应当同时存在于两台机器上。使用adduser来这样做:
你将使用的邮件主机必须为每个工作站指定一个邮件交换。这可以在你的DNS配置中这样来设置:
example.FreeBSD.org A 204.216.27.XX ; Workstation
MX 10 hub.FreeBSD.org
; Mailhost
无论A记录指向哪儿,这将为工作站重新定位邮件到邮件主机。邮件被发送到MX主机。你不能自己这样做,除非你正运行着一个DNS服务器。如果没有或不能,运行你自己的DNS服务器,可以询问你的ISP。
如果你正在使用虚拟email主机,下面的信息将派上用场。我们假设你有了一个带有他们自己域的客户,在这个例子中是customer1.org,你要把customer1.org的所有邮件发送到你的被命名成mail.myhost.com的邮件主机。你的DNS记录将是这样的:
customer1.org MX 10 mail.myhost.com
如果你只为域处理email,你不需要一个A记录。
注意:必须清楚,这意味着ping customer1.org将不能工作,除非一个A记录存在。
最后一件你必须要做的是在你的邮件主机上告诉sendmail接收邮件的是什么域和/或主机名。有好几种方法。下面方法中可以任选一种:
如果你使用FEATURE(use_cw_file),把主机添加到/etc/sendmail.cw文件中。如果你使用sendmail 8.10或更高版本,这个文件是/etc/mail/local-host-names。
如果你使用sendmail 8.10或更高版本,在/etc/sendmail.cf 或/etc/mail/sendmail.cf中添加一行cwyour.host.com。