sendmail大全
本章要点:
本章讨论电子邮件服务的基本概念及其配置、管理。
本章具体包括以下内容。
邮件传送的基本过程
sendmail的配置
邮件服务的一些特殊功能
qmail的简单介绍
7.1 sendmail 和SMTP
7.1.1 smtp和邮件传输代理
sendmail是最重要的邮件传输代理程序。理解电子邮件的工作模式是非常重要的。一 般情况下,我们把电子邮件程序分解成用户代理,传输代理和投递代理。
用户代理用来接受用户输入的指令,将用户给出的信件报文传送至信件传输代理。而 投递代理则从信件传输代理取得信件传送至最终用户的邮箱。显然,最终用户只能看到 用户投递代理。
当用户试图发送一封电子邮件的时候,他并不能直接将信件发送到对方的机器上,用 户代理必须试图去寻找一个信件传输代理,把邮件提交给它。
信件传输代理得到了邮件后,首先将它保存在自身的缓冲队列中,然后,根据邮件的 目标地址,信件传输代理程序将找到应该对这个目标地址负责的邮件传输代理服务器, 并且通过网络将邮件传送给它。对方的服务器接收到邮件之后,将其缓冲存储在本地, 直到电子邮件的接收者察看自己的电子信箱。
显然,邮件传输是从服务器到服务器的,而且每个用户必须拥有服务器上存储信息的 空间(称为信箱)才能接受邮件。(发送邮件不受这个限制)
可以看到,一个邮件传输代理的主要工作是监视用户代理的请求,根据电子邮件的目 标地址找出对应的邮件服务器,将信件在服务器之间传输并且将接收到的邮件缓冲或者 提交给最终投递程序。
有许多的程序可以作为信件传输代理,但是sendmail是其中最重要的一个,事实证明 它可以支持数千甚至更多的用户,而且占用的系统资源相当少。不过,sendmail的配置 十分复杂,因此,也有人使用另外的一些工具,如qmail。当然,基 于Windows NT的Exchange Server和NetScape Message Server也是这种产品的例子。
无论什么产品,它们必须支持同样的规范,如信件传输的报文格式,监听的端口等等 。一般来说,系统管理员并不需要了解信件传输的命令标准,用户代理会生成正确的命 令。但是,了解其他一些信息是重要的。
信件传输代理运行在25端口接受请求,当接受用户的请求时,它不需要了解用户的真 实身份,或者说不需要身份验证。因此用户不需要提交用户口令就可以发出电子邮件, 这意味着任何用户都可以冒充成另外一个用户发出假的电子邮件,这是电子邮件设计的 一个基础,无法消除。(关于这一点目前有一点说明。许多基于UNIX的系统运行indent d,可以记录客户机器上的用户的登录名字。不过,这个功能实际上用处不大,毕竟大部 分人不会用UNIX/Linux作为他的个人机器)。
当sendmail程序得到一封待发送的邮件的时候,它需要根据目标地址确定将信件投递 给那一个服务器,这是通过DNS服务实现的。例如,有一封邮件的目标地址是someone@y ahoo.com,那么,sendmail首先确定这个地址是用户名(someone)+机器名(yahoo.co m)的格式,然后,通过查询DNS来确定需要把信件投递给某个服务器。
DNS数据中,与电子邮件相关的是MX记录,这可以在查询DNS时设置查询类型为mx来得 到:
[wanghy@mail ~]$ nslookup
Default Server:
Address: 202.199.248.2
set q=mx
yahoo.com
Server:
Address: 202.199.248.2
Non-authoritative answer:
yahoo.com preference = 0, mail exchanger = mx1.mail.yahoo.com
yahoo.com preference = 1, mail exchanger = mx2.mail.yahoo.com
mx1.mail.yahoo.com internet address = 128.11.68.225
mx2.mail.yahoo.com internet address = 128.11.68.217
显然,在DNS中说明yahoo.com有两个信件交换(MX)服务器,于是,sendmail试图将 邮件发送给两者之一。一般来说,排在前面的的MX服务器的优先级别比较高,因此服务 器将试图连接mx1.mail.yahoo.com的25端口,试图将信件报文转发给它。如果成功,你 的smtp服务器的任务就完成了,在这以后的任务,将由mx1.mail.yahoo.com来完成。在 一般的情况下,mx交换器会自动把信件内容转交给目标主机,不过,也存在这样的情况 ,目标主机(比如yahoo.com)可能并不存在,或者不执行smtp服务,而是由其mx交换器 来执行信件的管理,这时候,最终的信件将保存在mx机器上,直到用户来察看它。
可以简单地在DNS记录中用MX关键字设置信件交换,例如,在我们的设置中:
@ IN SOA openlab.asnc.edu.cn. wanghy.openlab.asnc.edu.cn. (
1997022700 ; Serial
28800 ; Refresh
14400 ; Retry
3600000 ; Expire
86400 ) ; Minimum
IN NS openlab.asnc.edu.cn.
IN MX 10 mail.asnc.edu.cn.
IN MX 20 mail2.asnc.edu.cn.
openlab IN A 202.199.248.6
openlab IN MX 10 mail2.asnc.edu.cn.
mail IN A 202.199.248.11
www IN A 202.199.248.2
mail2 IN A 202.199.248.177
这里面定义了三个MX记录,MX记录的规则是[机器名/域名] IN MX [优先级] [服务 器]。优先级是一个整数,数值越小优先级越高。第一个IN MX 10 mail.asnc.edu.cn.因 为没有机器名,使用来自named.conf的缺省后缀,就是asnc.edu.cn,这个定义也就是让 所有some@asnc.edu.cn的信件传送到mail.asnc.edu.cn。IN MX 20 mail2.asnc.edu.cn .的概念差不多,只是其优先数为20,也就是说只有当mail.asnc.edu.cn拒绝接受(比如 ,服务器忙或者当机)的时候,信件才会投递到mail2.asnc.edu.cn。openlab IN MX 1 0 mail2.asnc.edu.cn.定义凡是someone@openlab.asnc.edu.cn的信件要发送到mail2.a snc.edu.cn,以此类推。
MX记录可以使得整个子域内的用户使用同样的邮件主机和传输代理,另外,如果你的 主机不 姨 痪了,那么信件可以暂时存储在你的信件 换主机上,直到你自己的机器恢 复为止。比如说,mail.yourdomain.com是一台smtp主机,而mx2.yourdomain.com是另外 一个smtp主机,你希望在mail.yourdomain.com正常的时候直接由其自身收发邮件,而万 一mail崩溃,mx2为它暂时存储一段时间的邮件直到mail恢复正常工作-这是常见的设置 ,那么,你需要把mail以比较高的优先数设置成自己的信件交换主机,而mx2作为一个优 先数较低的信件交换主机,也就是,在你的DNS配置文件中,应该这样配置:
mail IN MX 0 mail
IN MX 10 mx2
如果DNS查询无法找出对某个地址的MX记录(通常因为对方没有信件交换主机),那么 sendmail将是试图直接与对方的主机(来自邮件地址)对话并且发送邮件。例如,test@ openlab.asnc.edu.cn在DNS中没有对应的MX记录,因此sendmail在确定MX交换器失败后 ,将从DNS取得对方的IP地址并直接和对方对话试图发送邮件。
sendmail发送邮件时,如果经过设定的时间后仍然未能将信件投递到目的主机,它将 返回一个错误信息并且休息一段时间,然后重新试图投递,如果连续多次失败,sendma il最终将放弃投递并将错误信息投递给postmaster用户。在许多机器上,postmaster用 户是root用户的一个别名(参考下面关于别名的内容),你应该将它设置为邮件的实际 管理员的用户名。
上面说的基本就是sendmail的工作方式,然而仍然有一个很让人迷惑的东西,就是所 谓“信封地址”。简单地说,当sendmail向目标地址发信的时候,它并不是直接用你的 信件内容发送,相反,它依赖于你给它的命令。例如,你可能会用mail程序向某个地址 这样发信:
$mail someone@somedomain.com
Tother@otherdomain.com
Subject:test mail
test
.
那么,当sendmail发信的时候,它是向someone@somedomain.com发信而不是other@ot herdomain.com。相应地,如果你想向两个人发信,例如你在outlook里面写上:“投递 给user1@a.com,抄送user2@b.com”,那么sendmail应该怎么做?直接同时向两个地址 发信吗?否,它试图构造两个包装(称为信封),每个包装上只列出一个投递地址,各 投递一次。虽然邮件正文的头部仍然包含两个地址,但是sendmail不会看它。
7.1.2 sendmail的配置
sendmail是一个极为复杂的程序,其行为主要地依赖于在UNIX界“臭名昭著”的/etc /sendmail.cf配置文件。实际上,我怀疑会有谁真的从头去写一个sendmail.cf文件。一 般来说,我们总是用m4宏处理来书写sendmail.cf。实际上,m4程序几乎和sendmail.cf 一样复杂,不过,通常我们只需要关心一些比较重要的部分。
要使用宏处理程序,必须确定你已经安装了m4和sendmail-cf这样两个软件包,我们这 里讨论的是sendmail版本8.9.3,缺省下,sendmail-cf安装在/usr/lib/sendmail-cf目 录下。 录下。
我们首先从构造一个简单的可以使用的sendmail.cf文件开始,首先建立这样一个文件 ,称为sendmail.mc,并将其拷贝到/usr/lib/sendmail-cf/cf目录下:
include(`../m4/cf.m4)
define(`confDEF_USER_ID,``8:12)
OSTYPE(`linux)
FEATURE(redirect)
FEATURE(always_add_domain)
FEATURE(use_cw_file)
FEATURE(local_procmail)
MAILER(procmail)
MAILER(smtp)
注意里面的正反引号,而且不能随便加入空格。
然后,用m4程序可以生成一个sendmail.cf:
m4 sendmail.mc /etc/sendmail.cf
接下来,启动sendmail程序:
killall sendmail
sendmail –bd –q15m
你会发现现在你可以在这台主机上发送电子邮件了。
一般情况下,我们可以象这样用m4程序生成sendmail.cf,通过更改模板来改变sendm ail.cf的内容。一个mc模板文件通常可以包含几个段落:
divert
通常总是设置为divert(-1)让m4在输出中去掉一些垃圾。
OSTYPE OSTYPE
定义使用的操作系统类型,当然在我们的情况下就是linux,但是一定要注意m4程序中 引号的用法,一个反引号和一个正引号才代表把对应的东西括起来。
define
定义一些全局设置,对于Linux系统,设置了OSTYPE之后,可以定义下面的一些全局 参数,如果不定义,就使用缺省值。例如:
define(ALIAS_FILE,/etc/aliases)
变量名 说明(方括号中为缺省值)
ALIAS_FILE [/etc/aliases]
别名文件的位置。如果有多个别名文件,需要把它们用引号括起来(别忘了引号规则 !)。
confCR_FILE [/etc/mail/relay-domains]
缺省的域定义文件,在这个域中定义的域中机器可以通过你的服务器进行邮件发送。
HELP_FILE [/usr/lib/sendmail.hf]
此文件中含有对SMTP的HELP命令进行响应时要列出的信息。
QUEUE_DIR [/var/spool/mqueue]
邮件队列文件所在目录。
STATUS_FILE [/etc/sendmail.st]
sendmail的状态信息文件。
LOCAL_MAILER_PATH [/bin/mail]
用于投递本地邮件的程序。
LOCAL_MAILER_FLAGS [rmn9]
local mailer要用到的标志,永远包含标志lsDFM。
LOCAL_MAILER_ARGS [mail -d $u]
在投递本地邮件时所传送的参数。
LOCAL_MAILER_MAX [没有]
如定义了此参数,则为此邮件服务器所能接收最大单个邮件大小。
LOCAL_MAILER_CHARSET [没有]
如果定义了此参数,则被转化为MIME格式的从其他地址到local mailer的含有8位字符 的信息将被标为此字符集。
LOCAL_SHELl_PATH [/bin/sh]
用于投递利用管道功能处理的邮件的shell.
LOCAL_SHELL_FLAGS [eu9]
prog mailer用到的标志。在此标志中永远包含标志lsDFM.
LOCAL_SHELL_DIR [$z:/]
shell运行时所要查找的目录路径。
USENET_MAILER_PATH [/usr/lib/news/inews]
用于投递电子新闻组的程序名称。
USENET_MAILER_FLAGS [rlsDFMmn]
usenet mailer的投递标志。
USENET_MAILER_ARGS [-m -h -n]
usenet mailer的命令行参数。
USENET_MAILER_MAX [100000]
usenet mailer所能接收的最大信息大小。
SMTP_MAILER_FLAGS [没有]
SMTP mailer附加标志。对所有基于SMTPmailer其默认标志为mDFMUX;基于esmtp的邮差 (mailer)加上a标志;而基于"smtp8"的邮差则加上8。
SMTP_MAILER_MAX [没有]
使用smtp,smtp8或esmtp传输的单个邮件最大容量。
SMTP_MAILER_CHARSET [没有]
如果定义了此参数,则被转化为MIME格式的从其他地址到任一个smtp mailer的含有8 位字符的信息将被标为此字符集。
POP_MAILER_PATH [/usr/lib/mh/spop]
pop邮差的路径名。
POP_MAILER_FLAGS [Penu]
pop邮差附加标志。同时总是加上标志lsDFM。
POP_MAILER_ARGS [pop $u]
传给pop邮差的参数。
PROCMAIL_MAILER_PATH [/usr/local/bin/procmail]
procmail程序的路径名。此外FEATURE(local procmail)也用到此参数。
PROCMAIL_MAILER_FlAGS [SPhnu9]加给Procmail邮差的标志。同时总是加上"DFM"标志 。
PROCMAIL_MAILER_MAX [没有]
procmail所接收的最大单个邮件容量。如果你对某些人发送巨大的邮件感到困扰,启 用这个选项。
FEATURE
定义sednamil的一些运行参数,通常对我们来说最重要的一些选项是:
use_cw_file
读取文件/etc/sendmail.cw以确定这台机器应该替哪些机器接受邮件。此主机的别名 。当你使用 MX记录将此主机定义为其他主机的邮件交换机时需要使用这个特性。例如: FEATURE(use_cw_file)
relay_hosts_only
通常情况下,sendmail为sendmail.cf中明确列出的域(一般是localhost)和/etc/ mail/relay-domains中定义的域进行投递代理。缺省下这两处定义的都是域的名字。如 果你定义了这个参数,那么这两处的内容将被解释为主机名字。
use_ct_file
读取文件/etc/sendmail.ct以取得系统“信任”的用户名字,这些用户可以使用-f设 置其发信信封上的from地址而不产生警告信息。
redirect
使用REDIRECT特性,这个特性允许你对某些已经搬迁的用户发出重定向信息。(见下 一节)。例如:
FEATURE(redirect)
mailertable
包含一个用于覆盖到特定域路由(routing)的"mailer table".此特性参数定义可以是 一个关键词定义。如未指定任何参数, 其定义通常是:
FEATURE(mailertable,`hash -o /etc/mailertable)
domaintable
包含一个用于提供域名映象的"domain table",当改变你自已的域名时可能有用(如 你公司由oldname.com改为newname.com)。其定义通常是:
FEATURE(domiaintable,`hash -o /etc/domaintable)
always_add_domain
在本地发送邮件时也加上其主机域名。例如:
FEATURE(always_add_domain)
allmasquerade
如果使用了伪装(masquerading,使用MASQUERADE_AS),则此特性将使接收者的地址也伪 装为来自所伪装为主机。
limitd_masquerade
通常情况下$w所列出的所有主机将被伪装。如果使用了此特性,则只对那些$m所列出 的主机进行伪装。
masquerade_entire_domain
如使用了伪装且设置了MASQUERADE_DOMAIN,此特性将引起 地址重写,使所要伪装的网 域整个被隐藏。所有含有被伪装域名的主机用伪装域名(通常是MASQUERADE_AS)进行重写 。
masquerade_envelope
用此特性告知sendmail将信封和信件头中上的发送者和接收者进行伪装。
定义了有关masq的选项之后,就可以使用伪装了,可以直接将伪装命令写入mc模板, 示例如下:
MASQUERADE_AS(masq.com)
MASQUERADE_DOMAIN(foo.org)
这意味着我们的someone@foo.org发信的时候,sendmail将会把它的信封伪装为some one@masq.com。这对于统一整个域的电子邮件是非常重要的。
virtusertable
允许在同一个主机上使用多个虚拟域。参考下一节。例如:
FEATURE(`virtusertable,`hash –o /etc/mail/virtusertable)
nullclient
这是一个特殊情况--它生成一个除了支持将所有的邮件通过本地的基于SMTP的网络转 递到一个中心邮件HUB之外不含任何内容的配置文件。其参数是此邮件HUB的主机名。唯 一可与nullclient一起使用的其他特性是"nocanonify"(这样可以使非完全地址可通过S MTP连接进行发送;通常情况下地址将使用伪装名字转变为完全邮件名称,此伪装名字默 认值为邮件HUB主机的名字)。 在此特性使用是不应定义任何邮差。当然也不进行别名 处理或转寄。
local_procmail
使用procmail作为本地邮差。
smrsh
对到程序的邮件使用使用sendmail发行版所带的SendMail Restricted SHell (smrsh )而不是/bin/sh。由于sendmail是以root权限执行,某个发送到恶意程序的邮件可以破 坏系统,只要利用别名转向使得邮件被转发到对应的程序,因此缺省下sendmail用smrs h来处理邮件转发到程序的请求。这可以提高本地系统管理员控制对那些通过邮件运行程 序的行为,例如
FEATURE(`smrsh,`/usr/sbin/smrsh)
注意有些程序无法通过smrsh运行(例如majordomo的wrapper程序),这是出于安全 性的考虑,smrsh不准用户程序使用一些setuid功能。如果你一定要使用这些程序,清将 smrsh定义成其他shell程序,如sh。
access_db
本地存取控制文件的名字,缺省是/etc/mail/access.db,也可以用命令行指出,例 如:
FEATURE(`access_db)
或者 或者
FEATURE(`access_db,`hash –o /etc/mail/access)
mailertable
允许使用mailertable文件。这个文件定义对某确定的域使用什么样的邮差。例如:
FEATURE(`mailertable’,`hash –o /etc/mail/mailertable)。
blacklist_recipients
允许你用前面定义的access_db来禁止某个地方来的邮件,或是某个人的邮件,等等 。
relay_based_on_MX
是否允许别人用你的机器当成MX交换器。如果你设置了这个选项,那么任何人只要在 域名服务器中将你的机器设置成为他的MX交换就可以用你的机器转发电子邮件。这个功 能意味着:你的机器替它接受电子邮件,再提交给它;一般来说这个功能是不必要的; 如果你一定要使用这个选项,记住你可能被庞大的邮件流量吞没。但是在一种情况下这 个功能又是不可缺少的:假如你的系统有防火墙,只有邮件服务器能够对外连接,那么 这个功能是使网络内部其他主机能够接受自己电子邮件的唯一方法。
DOMAIN
这个关键字一般用来定义邮件中继,假如你的系统里面除了Internet互连之外还有类 似Decnet,UUCP之类的东西,那么你就需要设置DOMAIN来保证非internet的邮件被正确 中继。对于一般的系统,不需要定义这个属性。
MAILER
定义可以使用的投递程序(邮差)。
例如:
MAILER(smtp)
定义smtp投递。
MAILER(local)
定义局部投递。
如果你想做邮件服务,这样两个邮差是必须的。