Sendmail配置全解析:从基础到规则集的深度探索
1. 冻结配置文件
在Sendmail的配置中,冻结配置文件是一个重要的概念。只有冻结之前修改过的ASCII格式的
sendmail.cf
文件,才能改变冻结配置文件。冻结配置的优点是Sendmail启动速度会更快,但缺点是更改Sendmail配置时需要额外的步骤。很容易忘记这一步,不过在执行
sendmail -bz
命令之前,
/etc/sendmail.cf
文件的任何更改都不会影响冻结配置。
冻结的Sendmail配置虽然常用,但并非必需。Sendmail只是检查文件是否存在,如果
/etc/sendmail.fc
冻结配置文件存在,就对其进行解析;否则,读取
/etc/sendmail.fc
配置文件。
2. Sendmail配置文件概述
许多Sendmail配置文件具有相同或相似的结构,它们大多源自一些原始模板文件,不会从头编写。在任何UNIX实现中,通常都会包含多个版本的模板,如有需要还可以下载新版本。一般来说,应选择最接近所需实现的
sendmail.cf
模板,然后进行定制。大多数模板配置文件只需进行少量修改即可实际应用。
2.1 sendmail.cf文件结构
sendmail.cf
文件结构包含多个部分,每个部分指定特定的Sendmail配置实体,并包含功能相似的条目。这里以一个子机(subsidiary machine)的配置文件为例,子机是指完全支持电子邮件,但不属于主邮件服务器组的主机。选择子机配置文件的原因很合理:一是复杂度较低,便于理解配置条目;二是大多数系统都属于这一类别。
以下是配置文件的开头部分:
$cat /etc/sendmail.cf
#############################################################################
# SENDMAIL CONFIGURATION FILE FOR SUBSIDIARY MACHINES
#
# You should install this file as /etc/sendmail.cf
# if your machine is a subsidiary machine (that is, some
# other machine in your domain is the main mail−relaying
# machine). Then edit the file to customize it for your
# network configuration.
#
# See the manual "System Administration for the Sun Workstation."
# Look at "Setting Up The Mail Routing System" in the chapter on
# Communications. The Sendmail references in the back of the
# manual are also very useful.
#
# @(#)subsidiary.mc 1.11 SMI; from UCB arpa.mc 3.25
#
这些自解释的介绍性注释描述了文件的用途。每个注释行以
#
字符开头,Sendmail程序会忽略这些注释。在继续之前,有几点关于语法的说明:
- 配置文件中除注释外的每一行都是一个配置条目。
- 每行的第一个字符(单个大写字母)定义了条目的类型。
- 配置条目的格式取决于类型,但大多数条目是一个连续的字符串,其中字符的位置具有特定含义。
- Sendmail按顺序从文件开头到结尾读取条目,这在处理相互关联的条目(如重写规则条目)时很重要。
- 一般来说,所有配置条目都可以修改(前提是有足够的知识和技能),但只有少数必须定制。
2.2 配置文件具体内容
2.2.1 本地信息和通用配置
# local UUCP connections −− not forwarded to mailhost
CV
# my official hostname
Dj$w.$m
# major relay mailer
DMether
# major relay host
DRapollo.ph.myschool.scps.edu
# CRmailhost
本地信息通常依赖于站点,需要根据具体实现进行修改。有些本地数据可以由系统自动生成,如主机名和域名,但其他数据必须在配置文件中明确指定,然后使用相应的宏和类定义。
通用配置信息部分涉及本地域名:
# local domain names
#
# These can now be determined from the domainname system call.
# The first component of the NIS domain name is stripped off unless
# it begins with a dot or a plus sign.
# If your NIS domain is not inside the domain name you would like to have
# appear in your mail headers, add a "Dm" line to define your domain name.
# The Dm value is what is used in outgoing mail. The Cm values are
# accepted in incoming mail. By default Cm is set from Dm, but you might
# want to have more than one Cm line to recognize more than one domain
# name on incoming mail during a transition.
# Example:
# DmCS.Podunk.EDU
# Cm cs cs.Podunk.EDU
#
# known hosts in this domain are obtained from gethostbyname() call
Dmph.myschool.scps.edu
本地域名现在可以通过
domainname
系统调用确定。如果NIS域名的第一部分不以点或加号开头,则会被去掉。如果NIS域名不在希望出现在邮件头中的域名内,可以添加
Dm
行来定义域名。
Dm
值用于外发邮件,
Cm
值用于接收邮件。默认情况下,
Cm
从
Dm
设置,但在过渡期间,可能需要多个
Cm
行来识别多个域名。
2.2.2 宏和类定义
2.2.2.1 定义宏命令
定义宏命令
D
用于定义宏并存储值。定义后的宏可以为其他
sendmail.cf
命令或Sendmail本身提供存储的值(定义的宏通过名称和前面的
$
字符指定)。这使得多个系统可以共享Sendmail配置,只需修改一些特定于系统的宏。
宏名可以是任何单个ASCII字符,小写字母保留给Sendmail的内部宏,用户创建的宏使用大写字母作为名称。以下是Sendmail的一些内部宏及其功能:
| 名称 | 功能 |
| ---- | ---- |
| a | RFC 822格式的发件日期 |
| b | RFC 822格式的当前日期 |
| c | 跳数 |
| d | UNIX(ctime)格式的日期 |
| e | SMTP入口消息 |
| f | 发件人“from”地址 |
| g | 相对于收件人的发件人地址 |
| h | 收件人主机 |
| i | 队列ID |
| j | 此站点的“官方”域名 |
| l | UNIX from行的格式 |
| n | 守护进程的名称(用于错误消息) |
| o | 地址中的“运算符”集合 |
| p | Sendmail的PID |
| q | 发件人地址的默认格式 |
| r | 使用的协议 |
| s | 发件人的主机名 |
| t | 当前时间的数字表示 |
| u | 收件人用户 |
| v | Sendmail的版本号 |
| w | 此站点的主机名 |
| x | 发件人的全名 |
| z | 收件人的主目录 |
有些内部宏必须在
sendmail.cf
文件中定义,例如:
| 名称 | 分配值的宏 | 示例 |
| ---- | ---- | ---- |
| e | SMTP入口消息 | De$j Sendmail $v ready at $b |
| j | 站点的官方域名 | Dj$w.$D |
| l | UNIX from行的格式 | DlFrom $g $d |
| n | 错误消息中使用的名称 | DnMAILER−DAEMON |
| o | 地址中的运算符集合 | Do.:%\@! ^ =/ |
| q | 默认发件人地址格式 | Dq$g$?x ($x)$. |
需要注意的是,所有列出的宏都必须在配置文件中指定,但通常只有宏
j
的值需要修改,宏
$D
是用户定义的。
macro q
的定义包含一个条件:
$?x ($x)$..
,它测试
macro x
是否有值设置,如果设置了,则解释条件后面的文本。
$?
和
$.
分别指定条件的开始和结束。这意味着如果
macro x
被设置,
q
将被分配
macro g
的值和括号内
macro x
的值。条件还可以与
else
结构
$|
一起使用,例如:
$?x text1 $| text2 $.
解释为:
if
x is set
(construct $?)
use text1
else
(construct $|)
use text2
fi
(construct $.
除了内部宏,用户还可以使用大写字母定义特定的宏,常见的宏及其描述如下:
| 宏 | 描述 |
| ---- | ---- |
| B | Bitnet中继 |
| C | DECnet中继 |
| D | 本地域名 — 通常不需要 |
| E | 保留用于X.400中继 |
| F | 传真中继 |
| H | 邮件中心(用于邮件集群) |
| L | Luser中继 |
| M | 伪装(声称自己是谁) |
| R | 中继(用于不合格的名称) |
| S | 智能主机 |
| U | 我的UUCP名称(如果有UUCP连接) |
| V | UUCP中继(V类主机) |
| W | UUCP中继(W类主机) |
| X | UUCP中继(X类主机) |
| Y | UUCP中继(所有其他主机) |
| Z | 版本号 |
2.2.2.2 定义类命令
C
和
F
两个命令用于定义Sendmail类。类是一个值数组,用于处理多个值以相同方式处理的情况,例如本地主机的多个名称或UUCP名称列表。类允许Sendmail与值列表进行比较,而不是对单个值进行多次比较。为此引入了特殊的模式匹配符号:
$=
符号匹配类中的任何值,
$~
符号匹配类中不存在的任何值。
类具有单字符名称,用户创建的类使用大写字母作为名称。类值可以在一行、多行上定义,也可以从文件中加载。
C
命令用于从单行或多行分配类,例如:
CV host1 host2 host3
或
CV host1 host2
CV host3
类定义中的每个新行值都会追加到先前定义的类值中。
F
命令用于从文件加载类值,例如:
Fw /etc/sendmail.cw
将定义类
w
为文件
/etc/sendmail.cw
的内容。
一些类定义可能需要在Sendmail配置文件中修改,这些类与别名主机名、邮件路由的特殊域名或其他特定于站点的数据相关。常见的类及其描述如下:
| 类 | 描述 |
| ---- | ---- |
| B | 最佳MX查找的候选域名 |
| E | 不应看起来来自宏
$M
的地址 |
| F | 要转发的主机 |
| G | 应在通用表中查找的域名 |
| L | 不应转发到宏
$R
的地址 |
| M | 应映射到宏
$M
的域名 |
| O | 表示网络操作的运算符(不能在本地名称中) |
| P | 顶级伪域名:BITNET、DECNET、FAX、UUCP等 |
| R | 我们愿意中继的域名(通过反垃圾邮件过滤器) |
| U | 我的UUCP名称(如果有UUCP连接) |
| V | 连接到中继宏
$V
的UUCP主机 |
| W | 连接到中继宏
$W
的UUCP主机 |
| X | 连接到中继宏
$X
的UUCP主机 |
| Y | 本地连接的智能UUCP主机 |
| Z | 本地连接的域名化UUCP主机 |
|. | 仅包含点的类 |
| [ | 仅包含左括号的类 |
2.2.3 版本号和标准宏
配置文件继续定义版本号:
# Version number of configuration file
DVSMI−4.1
版本号是宏
V
,与其他宏的定义方式相同。通常不需要修改,但记录Sendmail配置的更改是个好主意,每次配置更改时都可以修改版本号。
接下来是标准宏(有时也称为特殊宏):
### Standard macros
# name used for error messages
DnMailer−Daemon
# UNIX header format
DlFrom $g $d
# delimiter (operator) characters
Do.:%@! ^ =/ []
# format of a total name
Dq$g$?x ($x)$.
# SMTP login message
De$j Sendmail $v/$V ready at $b
标准宏部分包含Sendmail使用的一些特殊宏,例如Sendmail返回错误消息时用于标识自身的名称,或SMTP登录期间显示的消息。所有宏都以通常的方式定义,这部分通常不需要修改。
2.2.4 选项部分
### Options
# Remote mode − send through server if mailbox directory is mounted
OR
# location of alias file
OA/etc/aliases
# default delivery mode (deliver in background)
Odbackground
# rebuild the alias file automagically
OD
# temporary file mode −− 0600 for secure mail, 0644 for permissive
OF0600
# default GID
Og1
# location of help file
OH/usr/lib/sendmail.hf
# log level
OL9
# default messages to old style
Oo
# Cc my postmaster on error replies I generate
OPPostmaster
# queue directory
OQ/usr/spool/mqueue
# read timeout for SMTP protocols
Or15m
# status file −− none
OS/etc/sendmail.s
# queue up everything before starting transmission, for safety
Os
# return queued mail after this long
OT3d
# default UID
Ou1
选项部分指定了所有实现的Sendmail选项,每个选项条目以大写字母
O
开头,第二个字母是选项名称。偶尔,如果已定义的(或默认)选项与实际情况不符,可以修改一些选项。当选项定义所需文件和目录的路径名时,强烈建议保留其标准位置。
除了此特定配置中定义的选项,还有其他可用选项:
| 选项 | 含义 |
| ---- | ---- |
| aN | 等待N分钟以处理
@:@
,然后重建别名文件 |
| Bc | 定义空白替换字符 |
| c | 为昂贵的邮件程序排队邮件 |
| di | 交互式投递 |
| dq | 在下一次队列运行时投递 |
| ee | 发送错误消息并返回状态0 |
| em | 发回错误消息 |
| ep | 打印错误消息 |
| eq | 返回退出状态;无错误消息 |
| ew | 写回错误消息 |
| f | 保留UNIX风格的“From”行 |
| I | 使用BIND(DNS)解析主机名 |
| i | 忽略传入消息中的点 |
| Mxval | 将宏
x
设置为
val
|
| m | 也发送给我 |
| Nnet | 将家庭网络的名称定义为“net” |
| qn | 定义用于决定何时排队作业的因子
n
|
| v | 以详细模式运行 |
| Wpass | 定义用于远程调试的密码“pass” |
| Xl | 如果平均负载超过“l”,拒绝SMTP连接 |
| xl | 如果平均负载超过“l”,排队消息 |
| Y | 为每个排队的作业单独投递 |
| yn | 为每个收件人将作业的优先级降低“n” |
| Zn | 每次运行作业时将作业的优先级降低“n” |
| zn | 用于与优先级一起确定消息优先级的因子 |
选项可以是字符串、整数、布尔值或时间间隔,没有用户创建的选项,每个选项的含义在Sendmail程序中是硬编码的。对于配置文件中缺失的选项,采用默认值。
2.2.5 消息优先级和受信任用户
### Message precedences
Pfirst−class=0
Pspecial−delivery=100
Pjunk=–100
### Trusted users
T root daemon uucp
消息优先级部分为进入队列的消息分配优先级(称为“消息优先级”),优先级数字越高,消息的优先级越高(默认值为0),这部分通常不需要修改。
受信任用户部分定义了允许使用邮件程序标志
-f
覆盖发件人地址的用户列表,这可能存在安全问题,因此最好不要修改。
2.2.6 邮件头部分
### Format of headers
H?P?Return−Path: <$g>
HReceived: $?sfrom $s $.by $j ($v/$V) id $i; $b
H?D?Resent−Date: $a
H?D?Date: $a
H?F?Resent−From: $q
H?F?From: $q
H?x?Full−Name: $x
HSubject:
H?M?Resent−Message−Id: <$t.$i@$j>
H?M?Message−Id: <$t.$i@$j>
HErrors−To:
邮件头部分定义了Sendmail插入到电子邮件中的邮件头格式。邮件头中定义的宏在插入邮件头之前会被展开,通常不需要更改邮件头。为了更好地理解邮件头条目,可以重新阅读宏的定义部分。
2.2.7 邮件程序部分
# Local and Program Mailer specification (mandatory)
Mlocal, P=/bin/mail, F=rlsDFMmnP, S=10, R=20, A=mail −d $u
Mprog, P=/bin/sh, F=lsDFMeuP, S=10, R=20, A=sh −c $u
############################################################
#####
##### Ethernet Mailer specification
#####
##### Messages processed by this configuration are assumed to remain
##### in the same domain. This really has nothing particular to do
##### with Ethernet − the name is historical.
Mether, P=[TCP], F=msDFMuCX, S=11, R=21, A=TCP $h
# UUCP Mailer specification
Muucp, P=/usr/bin/uux, F=msDFMhuU, S=13, R=23, A=uux − −r −a$f $h!rmail ($u)
邮件程序部分是插入在规则集之间的独立部分,邮件程序由
M
命令定义。每个Sendmail配置文件都必须有两个邮件程序:
local
和
prog
,在本例中分别是
/bin/mail
程序和Bourne shell
/bin/sh
。另外还定义了两个邮件程序:
ether
用于通过网络(由
[TCP]
指定)进行Sendmail通信,
uucp
(程序
/usr/bin/uux
)用于通过电话线进行UUCP投递。
2.3 规则集和重写规则
规则集定义了将电子邮件地址转换为适合电子邮件投递格式的规则,由大写字母
S
和规则集编号标识。较新的Sendmail版本还允许使用文本标识规则集,这有助于确定规则集的用途(名称通常描述规则集的基本功能)。
规则集包含一个或多个重写规则,每个重写规则是定义特定地址转换的单独行(条目),也允许有空规则集。重写规则条目以大写字母
R
开头,规则集的结束由下一个规则集的开始或任何其他配置条目(除重写规则条目)定义。规则集的输入是要解析的地址,输出是解析后的输入地址。规则集可以由Sendmail直接调用,也可以由另一个规则集调用,规则集内的重写规则条目按顺序处理。当规则集为空(没有任何重写规则条目)时,地址保持不变(输入和输出地址相等)。
以下是一些规则集的示例:
###########################
### Rewriting rules ###
###########################
# Sender Field Pre−rewriting
S1 # an empty ruleset
# None needed.
# Recipient Field Pre−rewriting
S2 # an empty ruleset
# None needed.
# Name Canonicalization
# Internal format of names within the rewriting rules is:
# anything<@host.domain.domain…> anything
# We try to get every kind of name into this format, except for local
# names, which have no host part. The reason for the "<>" stuff is
# that the relevant host name could be on the front of the name (for
# source routing), or on the back (normal form). We enclose the one that
# we want to route on in the <>'s to make it easy to find.
#
### = = = = = = = = = = # here is the beginning of Ruleset #3
S3
# handle "from:<>" special case
R$*<>$* $@@ turn into magic token
# basic textual canonicalization
R$*<$+> $* $2 basic RFC822 parsing
# make sure <@a,@b,@c:user@d> syntax is easy to parse −− undone later
R@$+,$+:$+ @$1:$2:$3 change all "," to ":"
R@$+:$+ $@$>6<@$1>:$2 src route canonical
R$+:$*;@$+ $@$1:$2;@$3 list syntax
R$+@$+ $:$1<@$2> focus on domain
R$+<$+@$+> $1$2<@$3> move gaze right
R$+<@$+> $@$>6$1<@$2> already canonical
# convert old−style names to domain−based names
# All old−style names parse from left to right, without precedence.
R$−!$+ $@$>6$2<@$1.uucp> uucphost!user
R$−.$+!$+ $@$>6$3<@$1.$2> host.domain!user
R$+%$+ $@$>3$1@$2 user%host
### = = = = = = = = = = # here is the end of Ruleset #3
# Final Output Post−rewriting
S4
R$+<@$+.uucp> $2!$1 u@h.uucp => h!u
R$+ $: $>9 $1 Clean up addr
R$*<$+> $* $1$2$3 defocus
指定的规则集和重写规则是Sendmail唯一知道并遵循的规则,它们必须足以进行完整和正确的电子邮件处理。虽然不太常见修改这部分,但更深入的Sendmail定制通常与此部分相关。如果在电子邮件投递中遇到问题,这也是最可能需要检查的地方。如果必须修改此部分,必须极其小心。
2.4 规则集序列
规则集可以从另一个规则集或由Sendmail直接调用。直接调用规则集是Sendmail程序中编码的规则集序列的结果。默认情况下,所有电子邮件地址在解析过程中遵循相同的规则集路径。起初,这个路径对所有电子邮件地址都是统一的,但基于Sendmail的长期使用经验和不断增加的安全需求,默认规则集序列最近得到了修改和改进。自Sendmail 8版本以来,在解析信封和邮件头电子邮件地址时引入了单独的默认规则集路径。简单来说,信封和邮件头地址可以根据实现的投递过程(即处理电子邮件的邮件程序)以不同的方式处理。
以下是规则集序列的相关说明:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始]):::startend --> B(解析地址):::process
B --> C{地址类型}:::decision
C -->|信封地址| D(信封规则集路径):::process
C -->|邮件头地址| E(邮件头规则集路径):::process
D --> F(规则集处理):::process
E --> F
F --> G(邮件程序选择):::process
G --> H(邮件投递):::process
H --> I([结束]):::startend
每个标有数字的框定义了相应规则集的数字名称:
-
S
框表示规则集,其数字名称由邮件程序定义中的
S
字段定义。每个邮件程序可以指定自己的规则集,用于在邮件投递前对发件人地址进行特定于邮件程序的清理。
-
R
框表示规则集,其数字名称由邮件程序定义中的
R
字段定义。每个邮件程序可以指定自己的规则集,用于在邮件投递前对收件人地址进行特定于邮件程序的清理。
小写字母
e
和
h
分别对应信封和邮件头地址。
Sendmail中有五个内置规则集具有特殊功能:
1.
规则集3
:是应用于地址的第一个规则集,将地址转换为规范形式:
local-part@host.domain
。在互联网电子邮件寻址概念尚未完全普及的时期,找到一种通用的地址格式非常重要。
2.
规则集0
:应用于用于投递电子邮件的地址,在规则集3之后应用,仅应用于实际用于电子邮件投递的收件人地址,将收件人地址解析为三元组
mailer-host-user
。
3.
规则集1
:应用于邮件中的所有发件人地址,现在通常是空规则集。
4.
规则集2
:应用于邮件中的所有收件人地址,现在通常是空规则集。
5.
规则集4
:应用于所有地址,用于将内部地址格式转换回初始的外部地址格式。
除了这些硬编码在Sendmail程序中的规则集,其他规则集的标识似乎是任意的。规则集可以任意命名(使用数字、字母或组合),并修改相应的重写规则以调用新标识的规则集。然而,规则集命名有一些约定,强烈建议遵循这些约定。以下是一些常见规则集命名及其用途:
| 规则集编号 | 用途 |
| ---- | ---- |
| 1x | 邮件程序规则(发件人限定) |
| 2x | 邮件程序规则(收件人限定) |
| 3x | 邮件程序规则(发件人邮件头限定) |
| 4x | 邮件程序规则(收件人邮件头限定) |
| 5x, 6x, 7x | 邮件程序子例程(通用) |
| 8x | 保留 |
| 90 | 邮件表主机剥离 |
| 96 | 规则集3的下半部分(旧Sendmail中的规则集6) |
| 97 | 递归调用规则集0的钩子(旧Sendmail中的规则集7) |
| 98 | 规则集0的本地部分(旧Sendmail中的规则集8) |
| 99 | 保证为空(用于调试) |
2.5 规则集0
规则集0是Sendmail配置文件中的一个特殊部分,是电子邮件投递的核心规则集。它解析电子邮件地址并做出“在哪里以及如何投递电子邮件”的关键决策。为了做出这样的决策,Sendmail总是对收件人的电子邮件地址应用规则集0,输出必须是关于目的地和相应邮件程序的决策,或者是一个错误。
规则集0有特殊的重写规则语法,它定义了指定邮件投递程序、收件人主机和收件人用户的三元组
(mailer, host, user)
。特殊转换语法如下:
$#mailer$@host$:user
其中:
-
mailer
:由
sendmail.cf
文件中的
M
命令定义的邮件程序名称。
-
host
:用于投递电子邮件的主机名(可能与收件人主机不同)。
-
user
:收件人主机上的收件人用户名。
-
$#
、
$@
和
$:
:分别是这三个部分的前导构造。
还有一种特殊变体,仅在规则集0中使用,用于向用户传递错误消息:
$#error$: message
其中
message
是返回给用户的任意错误消息文本。
规则集0通常位于
sendmail.cf
文件的末尾(尽管规则集的顺序是任意的)。以下是规则集0的部分内容:
##### RULESET ZERO PREAMBLE
# Ruleset 30 just calls rulesets 3 then 0.
S30
R$* $: $>3 $1 First canonicalize
R$* $@ $>0 $1 Then rerun ruleset 0
S0
# On entry, the address has been canonicalized and focused by ruleset 3.
# Handle special cases…..
R@ $#local $:$n handle <> form
# Earlier releases special−cased the [x.y.z.a] format, but SunOS 4.1 or later
# should handle these properly on input.
# now delete redundant local info
R$*<$*$=w.LOCAL>$* $1<$2>$4 thishost.LOCAL
R$*<@LOCAL>$* $1<@$m>$2 host == domain gateway
R$*<$*$=w.uucp>$* $1<$2>$4 thishost.uucp
R$*<$*$=w>$* $1<$2>$4 thishost
# arrange for local names to be fully qualified
R$*<@$%y>$* $1<@$2.LOCAL>$3 user@etherhost
# For numeric spec, you can't pass spec on to receiver, since old rcvr's
# were not smart enough to know that [x.y.z.a] is their own name.
R<@[$+]>:$* $:$>9 <@[$1]>:$2 Clean it up, then...
R<@[$+]>:$* $#ether $@[$1] $:$2 numeric internet spec
R<@[$+]>,$* $#ether $@[$1] $:$2 numeric internet spec
R$*<@[$+]> $#ether $@[$2] $:$1 numeric internet spec
R$*<$*.> $* $1<$2>$3 drop trailing dot
R<@>:$* $@$>30$1 retry after route strip
R$*<@> $@$>30$1 strip null trash & retry
################################################
### Machine dependent part of ruleset zero ###
################################################
# resolve names we can handle locally
R<@$=V.uucp>:$+ $:$>9 $1 First clean up, then...
R<@$=V.uucp>:$+ $#uucp $@$1 $:$2 @host.uucp:…
R$+<@$=V.uucp> $#uucp $@$2 $:$1 user@host.uucp
# optimize names of known ethernet hosts
R$*<@$%y.LOCAL>$* $#ether $@$2 $:$1<@$2>$3 user@host.here
# other non−local names will be kicked upstairs
R$+ $:$>9 $1 Clean u
R$*<@$+> $* $#$M $@$R $:$1<@$2>$3 user@some.where
R$*@$* $#$M $@$R $:$1<@$2> strangeness with @
# Local names with % are really not local!
R$+%$+ $@$>30$1@$2 turn % => @, retry
# everything else is a local name
R$+ $#local $:$1 local names
规则集0首先对地址进行规范化和聚焦处理,然后处理各种特殊情况,如处理
<>
形式、删除冗余的本地信息、处理本地名称的完全限定等。对于不同格式的地址,规则集0会进行相应的转换和处理,最终确定邮件的投递方式和目的地。
通过对Sendmail配置文件的详细解析,我们了解了从冻结配置文件到规则集和重写规则的各个方面。掌握这些知识可以帮助我们更好地配置和管理Sendmail,确保电子邮件的正常投递和系统的稳定运行。在实际操作中,需要根据具体的需求和环境对配置文件进行适当的调整和优化。
3. 规则集0详细解析及应用示例
3.1 规则集0特殊情况处理
规则集0的主要任务是解析邮件地址并决定邮件的投递方式和目的地。在处理地址时,它会先处理一些特殊情况。
3.1.1 处理
<>
形式
R@ $#local $:$n handle <> form
这条规则用于处理
<>
形式的地址,将其转换为本地投递,
$n
代表守护进程的名称,通常用于错误消息。
3.1.2 删除冗余本地信息
R$*<$*$=w.LOCAL>$* $1<$2>$4 thishost.LOCAL
R$*<@LOCAL>$* $1<@$m>$2 host == domain gateway
R$*<$*$=w.uucp>$* $1<$2>$4 thishost.uucp
R$*<$*$=w>$* $1<$2>$4 thishost
这些规则用于删除地址中冗余的本地信息,比如当地址中包含本地主机名的特定后缀(如
.LOCAL
、
.uucp
)时,会将其简化,以避免信息的重复和混淆。
3.1.3 本地名称完全限定
R$*<@$%y>$* $1<@$2.LOCAL>$3 user@etherhost
这条规则用于确保本地名称是完全限定的。如果地址中的主机部分是一个以太网主机名,会在其后面添加
.LOCAL
后缀,以便更准确地进行路由。
3.1.4 处理数字规格地址
R<@[$+]>:$* $:$>9 <@[$1]>:$2 Clean it up, then...
R<@[$+]>:$* $#ether $@[$1] $:$2 numeric internet spec
R<@[$+]>,$* $#ether $@[$1] $:$2 numeric internet spec
R$*<@[$+]> $#ether $@[$2] $:$1 numeric internet spec
对于数字规格的地址(如
[x.y.z.a]
形式),由于旧的接收方可能无法识别这种格式,规则集0会先进行清理,然后将其转换为以太网投递方式。
3.1.5 处理空垃圾信息
R<@>:$* $@$>30$1 retry after route strip
R$*<@> $@$>30$1 strip null trash & retry
当地址中包含空垃圾信息(如
<@>
)时,规则集0会先去除这些信息,然后重新运行规则集30,以确保地址的准确性。
3.2 规则集0的机器相关部分
3.2.1 本地可处理名称的解析
R<@$=V.uucp>:$+ $:$>9 $1 First clean up, then...
R<@$=V.uucp>:$+ $#uucp $@$1 $:$2 @host.uucp:…
R$+<@$=V.uucp> $#uucp $@$2 $:$1 user@host.uucp
如果地址是
@host.uucp
或
user@host.uucp
形式,并且
host
属于类
$=V.uucp
,规则集0会先进行清理,然后将其转换为UUCP投递方式。
3.2.2 已知以太网主机名的优化
R$*<@$%y.LOCAL>$* $#ether $@$2 $:$1<@$2>$3 user@host.here
对于已知的以太网主机名,规则集0会将其优化为以太网投递方式,确保邮件能够高效地通过网络传输。
3.2.3 非本地名称的处理
R$+ $:$>9 $1 Clean u
R$*<@$+> $* $#$M $@$R $:$1<@$2>$3 user@some.where
R$*@$* $#$M $@$R $:$1<@$2> strangeness with @
对于非本地名称,规则集0会先进行清理,然后根据宏
$M
和
$R
的值,将其转发到相应的中继主机进行处理。
3.2.4 处理包含
%
的本地名称
R$+%$+ $@$>30$1@$2 turn % => @, retry
如果本地名称中包含
%
符号,规则集0会将其转换为
@
符号,然后重新运行规则集30,以确保地址符合规范。
3.2.5 其他名称视为本地名称
R$+ $#local $:$1 local names
如果地址无法匹配上述任何规则,规则集0会将其视为本地名称,采用本地投递方式。
3.3 规则集0应用示例
假设我们有一个邮件地址
user@example.uucp
,规则集0的处理流程如下:
1. 由于地址以
.uucp
结尾,会匹配规则
R$+<@$=V.uucp> $#uucp $@$2 $:$1
。
2. 假设
$=V.uucp
类中包含
example
,则将地址转换为
$#uucp $@example $:user
,即采用UUCP投递方式,将邮件发送到
example
主机上的
user
用户。
再假设我们有一个邮件地址
user@[192.168.1.1]
,规则集0的处理流程如下:
1. 首先匹配规则
R<@[$+]>:$* $:$>9 <@[$1]>:$2
,对地址进行清理。
2. 然后匹配规则
R<@[$+]>:$* $#ether $@[$1] $:$2
,将地址转换为
$#ether $@[192.168.1.1] $:user
,即采用以太网投递方式,将邮件发送到
192.168.1.1
主机上的
user
用户。
4. Sendmail配置文件修改与优化建议
4.1 修改配置文件的注意事项
-
备份文件
:在修改
sendmail.cf文件之前,一定要备份原始文件,以防修改过程中出现错误导致系统无法正常运行。可以使用以下命令进行备份:
cp /etc/sendmail.cf /etc/sendmail.cf.bak
- 逐步修改 :每次只修改一个或少量的配置项,修改后进行测试,确保系统仍然正常工作。如果一次性修改多个配置项,出现问题时很难确定是哪个配置项导致的。
-
检查语法
:修改配置文件后,可以使用
sendmail -bt命令检查配置文件的语法是否正确。例如:
sendmail -bt < /etc/sendmail.cf
如果语法错误,该命令会输出相应的错误信息,方便我们进行修正。
4.2 优化配置文件的建议
4.2.1 调整日志级别
可以根据实际需求调整日志级别,以更好地监控系统运行情况。在配置文件的选项部分,找到
OL
选项,修改其值。例如,将日志级别设置为5:
OL5
日志级别越高,记录的信息越详细,但也会占用更多的系统资源。
4.2.2 优化邮件队列处理
可以调整邮件队列的相关选项,提高邮件处理效率。例如,修改邮件队列的超时时间:
Or30m # 将SMTP协议的读取超时时间设置为30分钟
OT5d # 将队列中邮件的返回时间设置为5天
合理设置这些选项可以避免邮件在队列中长时间积压,提高邮件投递的及时性。
4.2.3 加强安全设置
可以通过修改配置文件的选项部分,加强系统的安全设置。例如,设置临时文件的权限为更安全的模式:
OF0600 # 临时文件模式设置为0600,确保邮件的安全性
还可以设置拒绝高负载时的SMTP连接:
Xl5 # 如果系统平均负载超过5,拒绝SMTP连接
5. 总结
通过对Sendmail配置文件的全面解析,我们了解了从冻结配置文件到规则集和重写规则的各个方面。Sendmail的配置文件结构复杂,包含多个部分,每个部分都有其特定的功能和用途。
- 冻结配置文件 :可以提高Sendmail的启动速度,但修改配置时需要额外步骤。
- 宏和类定义 :通过定义宏和类,可以方便地共享和定制Sendmail配置。
- 规则集和重写规则 :是Sendmail的核心部分,决定了邮件地址的转换和邮件的投递方式。
- 规则集0 :是电子邮件投递的关键规则集,负责解析地址并做出投递决策。
在实际使用中,我们需要根据具体的需求和环境对Sendmail配置文件进行适当的修改和优化。同时,要注意修改配置文件的安全性和稳定性,避免因错误的配置导致系统出现问题。掌握Sendmail的配置知识,可以帮助我们更好地管理和维护邮件系统,确保电子邮件的正常投递和系统的稳定运行。
以下是一个简单的总结表格:
| 配置部分 | 主要功能 | 注意事项 |
| ---- | ---- | ---- |
| 冻结配置文件 | 提高启动速度 | 修改需执行额外命令 |
| 宏和类定义 | 定制配置 | 遵循命名规范 |
| 规则集和重写规则 | 地址转换和投递决策 | 修改需谨慎 |
| 规则集0 | 核心投递决策 | 处理多种地址格式 |
| 其他选项 | 系统设置和优化 | 根据需求调整 |
通过对这些配置部分的深入理解和合理运用,我们可以充分发挥Sendmail的功能,构建一个高效、稳定的邮件系统。
超级会员免费看
33

被折叠的 条评论
为什么被折叠?



