54、电子邮件:原理、协议与 sendmail 管理

电子邮件:原理、协议与 sendmail 管理

1. 电子邮件基础

电子邮件是网络用户常用的功能,尽管很多用户对 UNIX 了解不多,但他们喜欢使用电子邮件并从中受益。不过,用户与电子邮件之间往往是一种爱恨交织的关系,他们喜欢有电子邮件系统,但当系统出现问题时就会感到不满。而且,很多用户并不清楚电子邮件的实际工作原理,常常将其与其他网络应用(如 telnet 或 ftp)混淆。

可以将电子邮件类比为普通的地面邮件服务(蜗牛邮件),telnet 对应电话服务,ftp 对应传真服务,DNS 则像帮助解析名称、地址和电话号码关系的接线员。

1.1 电子邮件程序分类

电子邮件程序主要分为两类:
- 邮件用户代理(MUA)程序 :用户用于阅读、回复、撰写和处理电子邮件的程序,例如原始的 UNIX 邮件程序 /bin/mail 、Berkeley 邮件或其 System V 等效程序 mailx ,以及免费的 mush elm pine mh 等,还有其他商业程序。
- 邮件传输代理(MTA)程序 :负责为多个用户处理邮件传递并在机器之间转发电子邮件的程序。目前最常用的中央邮件传输程序是 sendmail ,在 UNIX 系统中它是默认的 MTA 程序。

1.2 电子邮件的传输与存储

当一封电子邮件到达目的地时,它会被放入用户的邮箱。在 UNIX 系统中,邮箱通常是一个以用户名命名的文件,默认位于 /var/mail 目录下。用户读取邮件后,邮件会被转移到用户主目录下的另一个邮箱中。

sendmail 是电子邮件的核心,也是成功实现电子邮件通信的关键管理点。两个 sendmail 程序(借助适当的邮件传送器)通过网络在机器之间传输电子邮件,使用的协议是简单邮件传输协议(SMTP)。MUA 程序则在电子邮件用户和 sendmail 之间提供接口,从用户的角度来看,它们是最关键的环节,但对整体电子邮件的影响相对较小,其重要性主要体现在本地环境中。

1.3 电子邮件消息结构

每封电子邮件消息都有一个包含收件人和发件人地址的信封,以及由头部和正文组成的消息内容。 sendmail 会解析和分析电子邮件地址,确定目的地并决定如何传递邮件。邮件可能不会立即送达最终收件人,而是可能通过多个邮件主机进行转发,具体路由主要取决于收件人的地址,有时也会受到当前网络条件的影响。

消息内容的头部包含发件人、收件人、创建时间、主题和传递标记等信息,正文与头部由一个空行分隔,包含发件人想要传达的信息。

1.4 数据编码与传输

过去,电子邮件消息通常是纯 ASCII 文本,使用的 SMTP 协议是基于 US - ASCII 字符集的 7 位协议,只能使用低 7 位数据,第 8 位始终被视为零。对于许多外语(特别是亚洲语言)以及二进制多媒体数据(如图形、程序、音频和视频等),需要有效的第 8 位。为了无损传输这些数据,消息必须先编码为 7 位数据,MIME(多用途 Internet 邮件扩展)封装提供了解决方案。

随着多媒体消息的激增,对“真正的 8 位消息传输”的需求也随之增加。SMTP 协议已扩展为支持 8 位传输,通用扩展机制 ESMTP 在 RFC 1869 中定义,允许 8 位传输的特定扩展 8BITMIME 在 RFC 1652 中定义。如果 MTA 程序无法协商 8 位数据的正确传输,它要么使用 MIME 将消息编码为 7 位数据,要么将消息退回给发件人并说明原因。 sendmail 8.6 及更高版本支持 ESMTP,8.7 及更高版本支持 8BITMIME 扩展。

1.5 电子邮件传递时间

电子邮件的传递通常非常快,时间以秒、分钟或小时计算。然而,传递时间不是一个确定的值,因为它取决于许多因素,特别是当涉及多个邮件主机时。有时传递时间可能长达数天,甚至邮件可能会丢失,但这种情况很少发生。

1.6 sendmail 地址解析与决策

sendmail 的核心问题是“将电子邮件发送到哪里以及如何发送”,它会根据配置文件中指定的规则(算法)解析电子邮件收件人的地址并做出决策。目前没有统一的电子邮件地址解析算法,由 sendmail 管理员实现最合适的算法。许多 UNIX 系统提供了高级的 sendmail 配置模板,管理员只需提供特定于站点的信息,但在某些非标准情况下,这些模板可能不够用,需要更详细的管理。

sendmail 有时会因为收件人或发件人地址不明确而拒绝电子邮件消息,最常见的原因是收件人地址拼写错误,但在某些罕见情况下,即使地址正确,也可能由于 sendmail 配置不当或其他临时问题而被退回。

2. 简单邮件传输协议(SMTP)

SMTP 是基本的电子邮件协议,基于 TCP/IP 协议族,是 sendmail 能够理解的“语言”。两个 sendmail 程序之间的对等通信实际上是 SMTP 消息的交换。

2.1 SMTP 通信示例

以下是一个使用 sendmail 详细模式的示例,展示了两个主机之间的 SMTP 通信过程:

#/usr/lib/sendmail -v mis@apollo.ph.myschool.scps.edu < indata.mail
mis@apollo.ph.myschool.scps.edu… Connecting to apollo.ph.myschool.scps.edu via ether…
Trying 146.98.8.31… connected.
220 apollo.ph.myschool.scps.edu HP Sendmail (1.38.193.4/16.2) ready at Tue, 5 Jul 1998 17:06:13 -0400
>>> HELO patsy.myschool.scps.edu
250 apollo.ph.myschool.scps.edu Hello patsy.myschool.scps.edu, pleased to meet you
>>> MAIL From:<bjl@patsy>
250 <bjl@patsy>… Sender ok
>>> RCPT To:<mis@apollo.ph.myschool.scps.edu>
250 <mis@apollo.ph.myschool.scps.edu>… Recipient ok
>>> DATA
354 Enter mail, end with "." on a line by itself
>>>.
250 Ok
>>> QUIT
221 apollo.ph.myschool.scps.edu closing connection
mis@apollo.ph.myschool.scps.edu… Sent

这个过程可以总结为以下步骤:
1. 连接阶段 :发件方的 sendmail 尝试连接到收件方的主机,显示连接信息和收件方主机的 IP 地址。
2. 准备阶段 :收件方主机发送 220 消息,表示准备好接收邮件,并提供其域名、程序名称和版本信息,以及本地日期和时间。
3. 问候阶段 :发件方的 sendmail 发送 HELO 消息,收件方以 250 消息确认发件方的主机名可接受。
4. 发件人确认阶段 :发件方发送发件人信息,收件方以 250 消息确认发件人信息。
5. 收件人确认阶段 :发件方发送收件人信息,收件方以 250 消息确认收件人信息(或返回错误信息)。
6. 数据传输阶段 :发件方发送 DATA 消息,通知收件方准备接收数据,数据传输结束时用单独一行的一个点表示。
7. 结束阶段 :发件方发送 QUIT 消息,收件方确认关闭连接,最后确认邮件已成功发送。

2.2 SMTP 通信流程

graph LR
    A[发件方 sendmail] -->|连接| B[收件方主机]
    B -->|220 准备好| A
    A -->|HELO 问候| B
    B -->|250 确认| A
    A -->|MAIL From 发件人信息| B
    B -->|250 确认| A
    A -->|RCPT To 收件人信息| B
    B -->|250 确认| A
    A -->|DATA 准备发送数据| B
    B -->|354 准备接收| A
    A -->|发送数据| B
    A -->|. 数据结束| B
    B -->|250 确认| A
    A -->|QUIT 结束通信| B
    B -->|221 关闭连接| A

3. MTA 程序 sendmail

3.1 sendmail 守护进程

sendmail 守护进程在每个完全支持电子邮件的主机上持续运行,监听端口 25 并处理传入的电子邮件。它通常在系统启动时从 rc 初始化脚本文件中调用,执行以下命令序列:

if [ -f /usr/lib/sendmail -a -f /etc/sendmail.cf ]; then
    (cd /var/spool/mqueue; rm -f nf* lf*)
    /usr/lib/sendmail -bd -q1h; echo -n "sendmail"
fi

这个脚本首先检查 sendmail 程序和配置文件 /etc/sendmail.cf 是否存在,如果存在,则清理邮件队列目录中的可能残留文件,然后以 -bd 选项启动 sendmail 作为守护进程,监听端口 25 接收传入的电子邮件, -q 选项指定邮件队列的处理频率,对于大多数系统,设置为 1 小时是一个不错的选择。

sendmail 守护进程过于繁忙时,它会派生其他守护进程来协助处理电子邮件,子守护进程完成任务后会退出,但父守护进程即使空闲也会继续运行。

3.2 sendmail 命令

sendmail 是一个功能强大的 UNIX 命令,可以随时从命令行执行。“守护进程选项 -bd ”只是众多可能选项之一,它也可以像其他 UNIX 命令一样用于完成单个任务,常用于 sendmail 的测试和调试。

3.2.1 sendmail 命令的主要特点
  • 可以将消息发送给一个或多个人,根据需要在网络上路由消息。
  • 不是用户界面程序,其他 MUA 程序提供用户友好的前端, sendmail 仅用于传递预格式化的消息。
  • 在发件方,会在本地别名文件中查找收件人地址并进行别名处理,如果收件人主目录中有 .forward 文件,会将邮件转发给该文件中列出的收件人。
  • 可以直接将邮件路由到网络中的其他已知主机,具体列表取决于 sendmail 配置,也可以由相关文件维护。
3.2.2 sendmail 命令选项
选项 操作
-bd 作为守护进程运行,等待传入的 SMTP 连接。
-bi 初始化别名数据库。
-bm 以通常方式传递邮件(默认)。
-bp 打印邮件队列摘要并列出当前队列中的所有邮件。
-bt 运行地址测试模式,用于调试配置地址解析规则。
-bv 仅验证名称,不尝试收集或传递消息,通常用于验证用户或邮件列表。
-bz 创建配置冻结文件。
-n 不进行别名处理。
-hN 将跳数设置为 N,邮件每次处理时跳数增加,达到限制时邮件将返回错误消息。
-q [time] 按给定间隔处理队列中保存的消息,如果省略时间,则处理一次队列。时间可以用秒(s)、分钟(m)、小时(h)、天(d)和周(w)表示。
-t 从消息中读取收件人信息,扫描“To:”、“Cc:”和“Bcc:”行,发送前删除“Bcc:”行,并抑制参数列表中的任何地址。
-v 详细模式,显示别名扩展和 SMTP 对话等信息。
3.2.3 sendmail 依赖的文件

sendmail 依赖以下文件:
- /etc/aliases (或 /etc/mail/aliases ):别名名称的 ASCII 数据文件。
- /etc/sendmail.cf :配置文件。
- /etc/sendmail.fc :冻结配置文件。
- /etc/sendmail.st :收集的统计信息。
- /usr/lib/mailhosts :可以直接发送电子邮件的主机列表。
- /usr/lib/sendmail.hf :帮助文件。
- /var/spool/mqueue/* :临时文件和排队的邮件。
- $HOME/.forward :用户的个人邮件转发文件。
- /usr/bin/mail /usr/sbin/mailx :用于本地邮件传递。

sendmail 处理传入电子邮件时会依据这些文件,其中最重要的是配置文件 /etc/sendmail.cf ,后续将详细讨论。

3.3 sendmail 的其他组成部分

3.3.1 全局邮件别名

全局邮件别名文件 /etc/aliases (有时链接到 /etc/mail/aliases )在系统级别提供以下功能:
- 为本地用户提供别名(昵称)。
- 将邮件转发到其他主机。
- 实现邮件列表。

别名文件的基本格式为:

alias: recipient[, recipient, …]

其中, alias 是电子邮件所指向的名称, recipient 可以是另一个本地用户名、另一个别名的名称或包含用户名和主机名的完整电子邮件地址,也可以是多个收件人,用于实现邮件列表。

以下是一个别名文件的示例:

$ cat /etc/aliases
##
# Aliases can have any mix of upper and lower case on the left−hand side,
#    but the right−hand side should be proper case (usually lower)
#
#    >>>>>>>>>>          The program "newaliases" will need to be run after
#    >> NOTE >>          this file is updated for any changes to
#    >>>>>>>>>>          show through to sendmail.
#
#    @(#)aliases 2.30 SMI
##
# Following alias is required by the mail protocol, RFC 822
# Set it to the address of a HUMAN who deals with this system's mail problems.
Postmaster: root
# Alias for mailer daemon; returned messages from our MAILER−DAEMON
# should be routed to our local Postmaster.
MAILER−DAEMON: postmaster
# Aliases to handle mail to programs or files, eg news or vacation
# decode: "| /usr/bin/uudecode"
nobody: /dev/null
# Sample aliases:
# Alias for distribution list, members specified here:
#staff:wnj,mosher,sam,ecc,mckusick,sklower,olson,rwh@ernie
# Alias for distribution list, members specified elsewhere:
#keyboards: :include:/usr/jfarrell/keyboards.list
# Alias for a person, so they can receive mail by several names:
#epa:eric
#############################################################################
# Local aliases below #
#############################################################################
# The list of local aliases follows
bjl blevi

需要注意的是, sendmail 并不直接使用 /etc/aliases 文件,修改该文件后需要运行 newaliases 命令(等同于 sendmail -bi 命令)来创建 sendmail 使用的 dbm 别名文件( aliases.dir aliases.pag ),这样可以加快别名数据库的搜索速度。

3.3.2 个人邮件转发文件

除了全局邮件转发, sendmail 允许用户在其主目录下的 .forward 文件中定义个人转发规则。 sendmail 在使用 /etc/aliases 文件后、最终将邮件传递给用户之前会检查该文件,如果存在则遵循其指令,指令格式与 /etc/aliases 条目相同。

3.3.3 邮件传递程序(Mailers)

sendmail 本身并不直接处理邮件传递,除了通过 TCP/IP 网络将邮件转发到其他远程主机的情况外,它会调用其他程序(即邮件传送器)来完成邮件传递。邮件传送器的定义包含在 sendmail 配置文件中, sendmail 决定何时使用邮件传送器并提供必要的传递数据。

邮件传送器的定义在 sendmail 配置文件中由“M 配置条目”指定,其通用形式为:

M=mailer−name P=mailer−path F=mailer−flags S=send−rules R=receive−rules A=mailer−arguments

其中:
- M= :标识邮件传送器的定义配置条目,后面紧跟 sendmail 识别相应传递代理的符号名称。
- P= :指定执行邮件传递的邮件传送器程序的完整路径名。
- F= :指定某些标志,告诉 sendmail 更多关于邮件传送器的定义。
- S= :指定重写发件人地址时使用的规则集。
- R= :指定重写收件人地址时使用的规则集。
- A= :指定要提供给每个相应邮件传送器程序的命令行参数。

虽然可以定义任意数量的邮件传送器,名称也可以任意,但必须定义两个邮件传送器: local prog ,它们分别用于将电子邮件传递给本地用户和本地程序。如果它们不存在, sendmail 将无法启动并会打印相应的错误消息。

3.3.4 sendmail 配置文件

sendmail 配置文件(通常是 /etc/sendmail.cf ,有时是 /usr/lib/sendmail.cf /etc/mail/sendmail.cf )是 sendmail 的核心,它完全定义了 sendmail 的行为,主要有以下三个功能:
- 定义 sendmail 环境。
- 将地址重写为适合进一步电子邮件处理的语法。
- 将地址映射为传递电子邮件所需的指令。

配置文件中包含许多不同的配置条目来实现这些功能:
- 宏定义和选项条目定义环境。
- 重写规则将电子邮件地址从一种格式转换为另一种格式。
- 邮件传送器定义指定传递电子邮件所需的程序。

配置文件的语法简洁而复杂,大多数系统管理员甚至不愿意阅读该文件,只有少数人对修改配置感到得心应手。由于 sendmail 在启动时会读取配置文件并据此运行,因此语法是为了满足程序需求而设计的,对人类来说并不容易阅读。所有配置命令、规范、选项和变量都只有一个字符长,难以识别和记忆,很容易将单个字符命令与单个字符变量混淆。然而,为了成功管理 sendmail ,必须完全理解该配置文件。

3.3.5 冻结的 sendmail 配置文件

为了加快 sendmail 启动时读取配置数据的速度,可以创建 ASCII 配置文件 /etc/sendmail.cf 的转换 dbm 映像,这个文件称为冻结配置文件 /etc/sendmail.fc (有时是 /usr/lib/sendmail.fc )。可以使用以下命令创建冻结配置文件:

/usr/lib/sendmail -bz

3.3.6 sendmail 配置文件的重要性及管理建议

sendmail 配置文件的重要性不言而喻,它就像是 sendmail 程序的“大脑”,决定了整个电子邮件系统的运行方式。由于其语法复杂,管理起来具有一定的挑战性,以下是一些管理建议:
- 备份与版本控制 :在对配置文件进行任何修改之前,务必进行备份。可以使用版本控制系统(如 Git)来记录配置文件的修改历史,这样在出现问题时可以方便地回滚到之前的版本。
- 逐步修改与测试 :每次只对配置文件进行少量的修改,并在修改后进行充分的测试。可以使用 sendmail -bt 选项进行地址测试,确保修改不会引入新的问题。
- 参考文档与社区资源 sendmail 有丰富的文档和社区资源可供参考。在遇到问题时,可以查阅官方文档或在相关社区论坛上寻求帮助。

3.3.7 常见配置错误及解决方法

在管理 sendmail 配置文件时,可能会遇到一些常见的错误,以下是一些例子及解决方法:
| 错误类型 | 错误表现 | 解决方法 |
| ---- | ---- | ---- |
| 地址解析错误 | 邮件无法正常发送或接收,提示地址解析失败 | 检查配置文件中的地址解析规则,确保别名文件和相关配置正确。可以使用 -bt 选项进行调试。 |
| 邮件队列堆积 | 邮件队列中的邮件长时间未处理 | 检查 -q 选项的设置,确保邮件队列处理频率合理。同时,检查系统资源使用情况,确保 sendmail 有足够的资源来处理邮件。 |
| 权限问题 | sendmail 无法访问某些文件或目录 | 检查相关文件和目录的权限设置,确保 sendmail 有足够的权限进行读写操作。 |

4. 电子邮件安全与性能优化

4.1 电子邮件安全

电子邮件安全是一个重要的问题,涉及到用户隐私和系统安全。以下是一些提高电子邮件安全的建议:
- 身份验证 :使用 SMTP 身份验证机制,确保只有授权用户可以发送邮件。可以通过配置 sendmail 支持 SASL 认证来实现。
- 加密传输 :使用 SSL/TLS 加密协议对邮件传输进行加密,防止邮件内容在传输过程中被窃取。可以在 sendmail 配置文件中配置 SSL/TLS 支持。
- 反垃圾邮件 :部署反垃圾邮件系统,如 SpamAssassin,对收到的邮件进行过滤,减少垃圾邮件的干扰。可以将 SpamAssassin 与 sendmail 集成,在邮件接收阶段进行过滤。

4.2 性能优化

为了提高电子邮件系统的性能,可以采取以下措施:
- 合理配置邮件队列处理频率 :根据系统的负载情况,合理调整 -q 选项的设置,确保邮件队列能够及时处理。对于高流量的邮件服务器,可以适当缩短处理间隔。
- 优化别名数据库 :定期更新别名数据库,确保别名查询的效率。可以使用 sendmail -bi 命令重新初始化别名数据库。
- 缓存机制 :使用缓存机制来减少重复查询和处理。例如,可以使用 DNS 缓存来提高域名解析的速度。

5. 总结与展望

5.1 总结

本文详细介绍了电子邮件的基本原理、SMTP 协议以及 sendmail 程序的管理。电子邮件作为网络通信的重要工具,其核心在于 sendmail 程序,它负责邮件的路由、传递和管理。通过了解 sendmail 的守护进程、命令选项、依赖文件以及配置文件的相关知识,可以更好地管理和维护电子邮件系统。同时,为了确保系统的安全和性能,还需要采取相应的安全措施和性能优化策略。

5.2 展望

随着互联网的不断发展,电子邮件系统也在不断演进。未来,电子邮件可能会朝着更加智能化、安全化和高效化的方向发展。例如,人工智能技术可能会被应用于反垃圾邮件和邮件分类,进一步提高用户体验。同时,随着 5G 等高速网络的普及,电子邮件的传输速度和性能也将得到进一步提升。作为系统管理员,需要不断学习和掌握新的技术,以适应不断变化的需求。

graph LR
    A[电子邮件系统] --> B[sendmail 管理]
    B --> C[配置文件管理]
    B --> D[安全与性能优化]
    C --> E[备份与版本控制]
    C --> F[逐步修改与测试]
    D --> G[身份验证]
    D --> H[加密传输]
    D --> I[反垃圾邮件]
    D --> J[合理配置队列频率]
    D --> K[优化别名数据库]
    D --> L[缓存机制]

以上就是关于电子邮件系统的相关知识,希望对大家有所帮助。通过合理的管理和优化,可以确保电子邮件系统的稳定运行,为用户提供更好的服务。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值