# 31.4.Sendmail

Sendmail 是一款久经考验且多功能的邮件传输代理（MTA），在 UNIX® 和类 UNIX 系统中有着悠久的历史。它是 FreeBSD 基本系统的一部分，直到 FreeBSD 13，为用户提供了强大的电子邮件传输功能、广泛的定制选项，并支持复杂的路由和过滤。

## 31.4.1. 配置文件

Sendmail 的配置文件位于 **/etc/mail/** 目录中。

**/etc/mail/access**\
该访问数据库文件定义了哪些主机或 IP 地址可以访问本地邮件服务器以及它们的访问权限。列为 `OK` 的主机（默认选项）被允许向本地主机发送邮件，只要邮件的最终目的地是本地机器。列为 `REJECT` 的主机会被拒绝所有邮件连接。列为 `RELAY` 的主机被允许通过此邮件服务器发送任何目的地的邮件。列为 `ERROR` 的主机将其邮件退回并附上指定的邮件错误。列为 `SKIP` 的主机会终止当前的搜索，而不接受或拒绝邮件。列为 `QUARANTINE` 的主机将其邮件保留，并会收到指定的保留原因。

在 FreeBSD 示例配置文件 **/etc/mail/access.sample** 中，可以找到使用这些选项的 IPv4 和 IPv6 地址的示例。

要配置访问数据库，使用示例中的格式在 **/etc/mail/access** 中做条目，但不要在条目前加上注释符号（`#`）。为每个需要配置访问的主机或网络创建一个条目。匹配表格左侧的邮件发送者将受右侧动作的影响。

每当更新此文件时，必须更新其数据库并重新启动 Sendmail：

```sh
# makemap hash /etc/mail/access < /etc/mail/access
# service sendmail restart
```

**/etc/mail/aliases**\
该数据库文件包含一个虚拟邮箱列表，这些邮箱会被展开为用户、文件、程序或其他别名。以下是一些条目，说明了文件格式：

```sh
root: localuser
ftp-bugs: joe,eric,paul
bit.bucket:  /dev/null
procmail: "|/usr/local/bin/procmail"
```

冒号左侧的邮箱名称会被展开为右侧的目标。第一个条目将 `root` 邮箱展开为 `localuser` 邮箱，之后在 **/etc/mail/aliases** 数据库中查找。如果未找到匹配项，邮件将发送到 `localuser`。第二个条目显示了一个邮件列表。发送到 `ftp-bugs` 的邮件会被展开为三个本地邮箱：`joe`、`eric` 和 `paul`。可以指定远程邮箱，如 [*user@example.com*](mailto:user@example.com)。第三个条目显示了如何将邮件写入文件，在此例中为 **/dev/null**。最后一个条目展示了如何通过 UNIX® 管道将邮件发送到程序 **/usr/local/bin/procmail**。有关此文件格式的更多信息，请参考 [aliases(5)](https://man.freebsd.org/cgi/man.cgi?query=aliases\&sektion=5\&format=html)。

每当更新此文件时，运行 `newaliases` 来更新并初始化别名数据库。

**/etc/mail/sendmail.cf**\
这是 Sendmail 的主配置文件，控制着 Sendmail 的整体行为，包括从重写电子邮件地址到向远程邮件服务器打印拒绝信息。由于该配置文件非常复杂，因此在标准邮件服务器中通常不需要进行更改。

主配置文件可以通过 [m4(1)](https://man.freebsd.org/cgi/man.cgi?query=m4\&sektion=1\&format=html) 宏来构建，这些宏定义了 Sendmail 的功能和行为。有关详细信息，请参考 **/usr/src/contrib/sendmail/cf/README**。

每当对此文件进行更改时，需要重新启动 Sendmail 以使更改生效。

**/etc/mail/virtusertable**\
该数据库文件将虚拟域和用户的邮件地址映射到真实邮箱。这些邮箱可以是本地邮箱、远程邮箱、在 **/etc/mail/aliases** 中定义的别名或文件。这允许在一台机器上托管多个虚拟域。

FreeBSD 提供了一个示例配置文件 **/etc/mail/virtusertable.sample**，进一步演示其格式。以下示例演示了如何使用该格式创建自定义条目：

```sh
root@example.com                root
postmaster@example.com          postmaster@noc.example.net
@example.com                    joe
```

该文件按匹配顺序处理。当电子邮件地址与左侧地址匹配时，它将映射到右侧列出的本地邮箱。该示例中的第一个条目将特定的电子邮件地址映射到本地邮箱，而第二个条目将特定的电子邮件地址映射到远程邮箱。最后，任何来自 `example.com` 的电子邮件，如果没有匹配到前面的条目，将匹配最后一个映射并发送到本地邮箱 `joe`。创建自定义条目时，使用此格式并将其添加到 **/etc/mail/virtusertable**。每当编辑此文件时，更新其数据库并重新启动 Sendmail：

```sh
# makemap hash /etc/mail/virtusertable < /etc/mail/virtusertable
# service sendmail restart
```

**/etc/mail/relay-domains**\
在默认的 FreeBSD 安装中，Sendmail 配置为仅允许从运行 Sendmail 的主机发送邮件。例如，如果有 POP 服务器可用，用户可以从远程位置检查邮件，但无法从外部位置发送邮件。通常，在尝试后不久，你会收到来自 `MAILER-DAEMON` 的邮件，内容为 `5.7 Relaying Denied` 消息。

最直接的解决方案是将 ISP 的 FQDN 添加到 **/etc/mail/relay-domains** 中。如果需要多个地址，将每个地址单独列出：

```sh
your.isp.example.com
other.isp.example.net
users-isp.example.org
www.example.org
```

创建或编辑此文件后，通过 `service sendmail restart` 重启 Sendmail。

现在，任何通过该系统的主机发送的邮件，只要用户在系统中有账户，都会成功。这允许用户远程从系统发送邮件，而不会打开系统接收来自 Internet 的垃圾邮件。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.bsdcn.org/hanbook/di-31-zhang-dian-zi-you-jian/31.4.-sendmail.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
