上面在define和feature相关的子句中介绍了一些Sendmail的相关文件,现在来解释以下这些文件的用法。这些文件的名字通常都可以在对应的mc子句里面更改。
首先是/etc/Sendmail.cw。这个文件非常简单,它给出本地主机的别名。如果用户的主机有多个名字,或者主机是整个域的信件交换主机,这就需要这个文件了。例如,按照前面的那个配置,mail.cau.edu.cn是cau.edu.cn域的信件交换主机,所以需要在Sendmail.cw里面写上一行:
$ cat /etc/sendmail.cw
# sendmail.cw - include all aliases for your machine here.
asnc.edu.cn
如果有多个别名或者需要负责的交换域,则每个需要单独写上一行。
接下来的文件是/etc/mail/aliases,这个文件用来设置用户的别名。最简单的情况是需要作信件分发的情况。例如,一般情况下,电子邮件出现问题的时候,需要把出错的邮件头发送到本机的postmaster用户,但是也许系统上有多个系统管理员,因此每个人都需要得到一份这个邮件头的拷贝。这种情况下就需要使用用户别名文件了。
aliases文件的格式是邮件别名:实际用户名,如果一个别名有多个用户就用逗号分开,每个别名一行。例如,要把发给postmaster的信件发送给supervisor和manager,需要写上一行:
postmaster:supervisor,manager
别名还可以在定义自动的邮件转发的情况下使用。例如,某个用户以前在系统上接受电子邮件,现在他有了一个新的电子邮件,希望发到机器上的邮件自动被转发到他新的电子邮件地址上,那么,可以使用类似的别名方式(假设用户的机器是joe@yourdomain.com):
joe:joe@newaddr.com
以后发给joe@yourdomain.com的电子邮件就自动中转到joe@newaddr.com。注意左边自动加上用户的机器名字,所以左边只能是账号名字,不能是全限定邮件地址。
别名的右侧也可以是文件或程序。例如,上面的postmaster别名可以用下面的方法来设置:
postmaster::include:/etc/mail/myaliases
其中的include关键字表示让Sendmail去读取对应的包含文件。而/etc/mail/myaliases的内容需要设置成:
supervisor
manager
要把邮件重定向到程序,可以使用管道,例如:
test_param:"|/home/test/test"
那么,Sendmail将会把发给test_param的邮件的内容作为/home/test/test程序的输入,并且来执行这个程序。
在修改了别名文件之后,需要用-bi参数重新初始化别名数据库:
sendmail –bi
另一个常用的办法是重定向。如果用户在模板文件中定义了REDIRECT特性,那么可以使用这个功能。例如,某个人在机器上开了一个账户user1,后来迁移到user2@server2.com。那么,用户可以将其别名写成:
user1: user2@server2.com.REDIRECT
以后当有人向这个地址发信的时候,Sendmail会将其退回,并且返回一个551 User not local; please try user2@server2.com的信息。
在使用别名的时候,必须注意的是不要造成循环,例如user1转发给user2,user2又将其转发给user1……如此循环。在这种情况下,转发17次后,Sendmail将把它退还给发信人。最常见的错误发生在用户试图在转发邮件的同时在本地保留备份的情况下,例如:
user1: user1,user2
就构成了一个循环。
要在本地保留备份,使用转义符号,例如:
user1: user1,user2
建立了别名文件之后,需要将其初始化,这可以通过newaliases命令完成:
[root@localhost root]# newaliases
/etc/aliases: 17 aliases, longest 31 bytes, 241 bytes total
也可以使用Sendmail -bi命令:
[root@localhost root]# sendmail -bi
/etc/aliases: 17 aliases, longest 31 bytes, 241 bytes total
两种方式实际是完全一样的。
类似于通过aliases文件进行邮件转发,用户也可以使用自己的转发文件。例如,某个用户user1想让发送给自己的邮件全部转发到user2@domain.com,但是又不希望建立全局的用户别名,那么可以在自己的宿主目录下面建立一个.forward文件,内容只要一行:
user2@domain.com
这种技术可以让每个用户自己管理自己的邮件别名。
通常smtp协议是不需要身份认证的,也就是说任何人都能连接到服务器的25端口并且发送邮件。为了避免不必要的麻烦,比较高版本的Sendmail默认直接禁止其他不明身份的机器利用用户的系统投递邮件。这种情况下,一个非本地的机器使用服务器系统投递会产生一个550 relay denied错误。但是如果要作一个邮件服务器,则必须打开投递代理功能。
Sendmail的第一个投递代理设置文件是relay-domains。这个文件是一个简单的文本文件,文件的默认名字是/etc/mail/relay-domains,可以在confCR_FILE中定义。内容类似:
yourdomain.com
#所有*.yourdomain.com的机器可以使用用户的机器作为smtp服务。
192.168
#所有192.168.*.*的机器可以使用用户的机器作为服务。
/etc/mail/relay-domains文件是一个简单的文本文件,当需要投递的域很多的时候,其效率不是很高。因此,Sendmail还可以使用access.db来设定哪些地址的机器可以连接到25端口投递信件。这个文件的默认名字是/etc/mail/access.db,但是可以用FEATU RE(access_db)来修改,例如:
FEATURE(access_db,`hash –o /etc/access)。
一般/etc/mail/access.db是一个散列表数据库,它是用/etc/mail/access为模版产生出来的。/etc/mail/access文件的格式是:
[地址] [操作]
中间的分割符是空格键。
[地址]栏可以是主机地址或者名字,也可以是统配符,规则是:
yourdomain.com 代表所有*.yourdomain.com的名字。
192.168.12代表所有192.168.12.*的地址。
202.135代表所有202.135.*.*的地址。
someone@somedomain.com 代表一个特定的邮件发信人
而在每个地址后面可以跟上相应的操作,通常的操作有以下几点。
· OK:正常接受这封邮件。
· RELAY:允许SMTP代理投递,这封邮件就可以从用户的机器中转到别的机器上去。
· REJECT:拒绝接受。
· DISCARD:忽略这封邮件,这种情况下,邮件看上去是正常投递了,但是由于没有人接受,邮件会自动被删除。
错误代码+任何其他字符串:将向发信者返回这个字符串作为出错信息。错误代码是RFC 822定义的标准出错代码。例如:
550 We don like a spammer!
客户机器在投递邮件的时候,就会产生一个we don like a spammer投递失败信息。比如,用户认为someone@spammer是个专门投递垃圾邮件的家伙,那么可以写:
someone@spammer 550 we don like a spammer
修改了access文件之后,需要重新生成一下access.db,这可以用makemap命令完成。在命令行中输入下面命令:
makemap hash access.db < access
然后重新启动Sendmail就可以使用这些功能了。
如同Apache一样,Sendmail也允许使用虚拟主机功能,这是通过FEATURE(virtusertable)功能实现的,而虚拟主机的文件默认是/etc/mail/virtusertable.db,它用/etc/mail/virtusertable文件生成,这个文件的形式类似于aliases文件,即左地址右地址,中间用Tab键分开。例如:
someone@otherdomain.com localuser
系统就会将本来应该发送给someone@otherdomain.com的邮件,发送给本机的用户local user。
不过还需要具备两个条件:第一,用户的DNS记录中,本机应该是otherdomain.com的MX交换器;第二,本机Sendmail.cw文件应该包含otherdomain.com这个名字。
虽然纯粹的域意义不大,但是Sendmail还支持邮件虚拟域的参数翻译。例如:
@testdomain.com test@mydomain.com
意味着所有发往xxx@testdomain的邮件都会被发送到test@mydomain.com。而
@testdomain.com %1test@mydomain.com
则代表参数转义,例如user1@testdomain.com的邮件被发送到user1test@mydomain.c om,user2@testdomain.com被发送到user2test@mydomain.com。
建立virtusertable的方法与建立access的方法是一样的,用下面的方法建立:
makemap hash virtusertable.db < virtusertable
然后重新启动Sendmail。
/etc/mail/mailertable文件(在FEATURE mailertable里定义)用来定义对某个域名或者用户使用什么样的邮差,如local:user,smtp:mail.test1等等。一般情况下,并不需要定义这个功能。建立这个文件的方式与上面的几个hash数据库相同。
需要注意的是,当前版本的Sendmail对各种附加文件和配置文件的属性都有着严格的要求,特别是/etc/aliases文件,必须至少为0644以避免非授权的修改。
Fedora的Sendmail使用procmail作为信件的最终投递代理。这个程序有一些非常有用的功能,对于普通用户来说,最重要的功能是信件的自动过滤和分拣。
信件分拣对用户来说是最实用的功能,它按照邮件的文件头(发信地址、收信地址等等)甚至邮件的正文进行归类,并且可以自动存放在各个文件中或者转发给别的用户账号。而且相对于其他同类程序来说,用procmail配置自动分拣是一件非常容易的事情。
通常的Sendmail配置中已经使用了procmail作为邮件最终投递代理,如果Sendmail已经改动得非常多了,那么用户可以使用FEATURE(local_procmail)来设置这个功能。
procmail主要依靠用户宿主目录下面的procmailrc中的信息来处理邮件。如果这个配置文件不存在,则procmail只是简单地将邮件保存到用户的信箱中。
一般来说,procmailrc文件由配置行和行为规则组成。配置行是一些基本参数的设置,不过一般配置行可以不写;而行为规则通常由(查询)(行为)完成,下面是一个简单的例子:
0 H
* ^From:.*test@mydomain.com
{ {
0 c
! who@somewhere.edu
0
testsave
}
这个procmailrc文件将所有来自test的信件转发给who@somewhere.edu,同时在本地留一个保存一个备份在文件testsave中。
上面的形式是procmailrc行为规则的基本格式,规则的一般格式:
0 选项
[零个或多个条件,每个一行]
[动作命令] [动作命令]
当然配置命令中还有很多选项,它们的含义如表8-1所示。
表8-1 选项含义
选 项 |
含 义 |
0 |
表示开始一条规则,后面可以加上一些单字符的选项 |
H |
搜索匹配邮件头部 |
B |
搜索匹配整个邮件 |
D |
匹配时区分大小写 |
A |
如果前面最近的一个没有A或a选项的规则执行,则执行本规则 |
a |
如果上面一条规则执行,则本规则执行 |
E |
同A相反,前面最近的没有E或e选项的规则没有执行,则执行本规则 |
e |
同a相反 |
h |
通过管道传送邮件首部(默认) |
续上表
选 项 |
含 义 |
b |
通过管道传送邮件主体(默认) |
c |
复制一个邮件 |
I |
忽略所有写操作中的错误 |
r |
原始模式,即procmail不对mail进行任何模式的处理 |
配置命令中的条件是用一个*号开始,后面则跟上正则表达式。动作命令就是procmail在规则成功之后使用的命令,一般的命令如表8-2所示。
表8-2 命令含义
命 令 |
含 义 |
{} |
开始一个语句段,表示把一组命令集合成一个动作。如果用户要嵌套处理规则,(例如,对于来自test的邮件区分是含有computer字符串还是含有physics字符串)那么必须使用语句段把子规则括起来 |
! |
转发信件给某个用户 |
| |
启用管道将邮件传送给后面的程序,例如|auto-reply表示启动auto-reply程序并且将邮件内容作为标准输入传递给它 |
任意文件名 |
将邮件存入某个文件。如果文件已经存在,就添加在文件的末尾 |
所以前面例子中procmailrc的含义是:
· 0 H:开始了一个对邮件头部的搜索,^From.*test@mydomain.com表示邮件头部发现了From: test@mydomain.com之类的内容,行为规则启动。这里的行为规则是一个语句块,因此在语句段里面的子规则被执行。
· 0 c:开始的规则首先复制一份副本,然后将邮件转发给who@somewhere.edu,邮件本身消失了,但是副本仍然存在,接着副本继续执行下面的:0规则组。这个规则是存储邮件到文件testsave,邮件副本也被处理掉了,规则结束。
对于熟悉Perl或C语言的的用户,很容易用procmail的管道功能写出邮件的自动回复程序,这里不再介绍了,想进一步了解procmail的用户可以用
man procmail
man procmailrc
man procmailex
获得更加详细的信息。
配置完毕后就可以进行邮件服务测试了。可以直接连接到服务器的25端口测试投递代理:
[root@mail mail]# telnet 202.199.248.11 25
Trying 202.199.248.11...
Connected to 202.199.248.11.
Escape character is ^].
220 mail.pku.edu.cn ESMTP Sendmail 8.9.3/8.9.3; Fri, 3 Mar 2005 01:26:47 +0800
mail from:
250 ... Sender ok
rcpt to:
250 ... Recipient ok
data
354 Enter mail, end with "." on a line by itself
test
.
250 JAA08415 Message accepted for delivery
quit
221 mail.cau.edu.cn closing connection
Connection closed by foreign host.
上面的操作定义了一个邮件发送过程。现在的回应说明邮件投递代理是正常的。如果有任何的错误,就会在回应中出现。为了使用这种测试技术,用户需要了解SMTP协议的基本命令,如表8-3所示SMTP协议的部分基本命令。
表8-3 SMTP协议的部分基本命令
命 令 |
含 义 |
DATA |
开始写信,在MAIL和RCPT之后可以使用这个命令传输信件正文,传输完毕之后输入一个.退出 |
QUIT |
关闭smtp会话 |
RSET |
复位连接状态 |
HELO |
标志发起smtp请求的主机,例如,从client1发起smtp会话,可以使用HELO client1 |
MAIL FROM: MAIL FROM |
启动一个邮件会话,在这个行中需要标志发信人的信封地址,例如,要从user1@clie nt1发出邮件,使用MAIL FROM:,注意尖括号的用法 |
RCPT TO |
标志收信人的信封地址,例如,要发送给user2@mail2,使用RCPT TO: 。在一个MAIL FROM之后可以给出多个收信人地址,以便实现多副本的传送 |
VRFY |
验证某个地址,例如,要确定test@mail是一个可以投递的地址,使用VRFY test@mai l |
EXPN |
显示某个收件人地址或者用户名的实际名字。例如,要显示postmaster用户的实际投递地址,使用EXPN postmaster。如果在某个用户的目录下有.forward文件,这个文件的内容将会被自动使用 |
HELP |
显示这个命令表 |