# 31.7.高级主题

本节讨论了更复杂的话题，如邮件配置以及为整个域设置邮件服务。

## 31.7.1. 基本配置

开箱即用，用户可以向外部主机发送电子邮件，只要 **/etc/resolv.conf** 配置正确，或网络能够访问已配置的 DNS 服务器。要将邮件投递到 FreeBSD 主机上的 MTA，执行以下操作之一：

* 为域运行 DNS 服务器。
* 将邮件直接发送到主机的 FQDN。

为了让邮件直接投递到主机，主机必须拥有一个永久的静态 IP 地址，而不是动态 IP 地址。如果系统在防火墙后面，还必须配置防火墙以允许 SMTP 流量。要接收直接发送到主机的邮件，必须配置以下两项之一：

* 确保 DNS 中最低编号的 MX 记录指向主机的静态 IP 地址。
* 确保 DNS 中没有主机的 MX 记录。

以上任意一项都可以允许邮件直接投递到主机。

尝试以下操作：

```sh
# hostname
```

输出应类似于：

```sh
example.FreeBSD.org
```

```sh
# host example.FreeBSD.org
```

输出应类似于：

```sh
example.FreeBSD.org has address 204.216.27.XX
```

在此示例中，发送到 <yourlogin@example.FreeBSD.org> 的邮件应能正常工作，前提是 `example.FreeBSD.org` 上的 MTA 正常运行。请注意，[dma(8)](https://man.freebsd.org/cgi/man.cgi?query=dma\&sektion=8\&format=html) 不监听端口 25 以接收连接，因此无法在此场景中使用。

对于此示例：

```sh
# host example.FreeBSD.org
```

输出应类似于：

```sh
example.FreeBSD.org has address 204.216.27.XX
example.FreeBSD.org mail is handled (pri=10) by nevdull.FreeBSD.org
```

所有发送到 `example.FreeBSD.org` 的邮件将由 `nevdull` 收集，并在同一用户名下处理，而不是直接发送到你的主机。

上述信息由 DNS 服务器处理。携带邮件路由信息的 DNS 记录是 [邮件交换记录 (MX 记录)](https://en.wikipedia.org/wiki/MX_record)。如果没有 MX 记录，邮件将通过主机的 IP 地址直接投递到主机。

`freefall.FreeBSD.org` 的 MX 记录曾经如下所示：

```sh
freefall		MX	30	mail.crl.net
freefall		MX	40	agora.rdrop.com
freefall		MX	10	freefall.FreeBSD.org
freefall		MX	20	who.cdrom.com
```

`freefall` 有多个 MX 记录。最低的 MX 编号对应的主机接收邮件（如果可用）。如果该主机由于某种原因不可用，编号较低的下一个主机将临时接受邮件，并在更低编号的主机可用时将邮件转发。

备用 MX 主机应有独立的互联网连接，以便更有效地使用。你的 ISP 可以提供此服务。

## 31.7.2. 域的邮件配置

在为网络配置 MTA 时，所有发送到其域内主机的邮件应当被转发到 MTA，以便用户可以在主邮件服务器上接收邮件。

为了简化配置，MTA 和 MUA 所在系统上的用户账户应使用相同的 *用户名*。可以使用 [adduser(8)](https://man.freebsd.org/cgi/man.cgi?query=adduser\&sektion=8\&format=html) 创建用户账户。

> **技巧**
>
> 除了将本地用户添加到主机之外，还有一种名为虚拟用户的替代方法。像 [Cyrus](https://www.cyrusimap.org/) 和 [Dovecot](https://www.dovecot.org/) 这样的程序可以与 MTA 集成，处理用户、邮件存储，并提供 POP3 和 IMAP 访问。

MTA 必须是网络中每个工作站的指定邮件交换主机。这可以在 DNS 配置中通过 MX 记录完成：

```sh
example.FreeBSD.org	A	204.216.27.XX		; Workstation
			MX	10 nevdull.FreeBSD.org	; Mailhost
```

这样，无论 A 记录指向哪里，工作站的邮件都会被转发到 MTA，邮件将发送到 MX 主机。

这必须在 DNS 服务器上配置。如果网络没有自己的 DNS 服务器，请与 ISP 或 DNS 提供商联系。

以下是虚拟电子邮件托管的示例。

考虑一个客户，域名为 `customer1.org`，所有发送到 `customer1.org` 的邮件应发送到 `mail.myhost.com`。

DNS 记录应如下所示：

```sh
customer1.org		MX	10	mail.myhost.com
```

如果仅处理该域的电子邮件，则不需要为 `customer1.org` 创建 A 记录。然而，除非存在 A 记录，否则运行 `ping` 时将无法成功。

告诉 MTA 它应接受哪些域和/或主机名的邮件。以下任一配置适用于 Sendmail：

* 在 **/etc/mail/local-host-names** 中添加主机名，使用 `FEATURE(use_cw_file)`。
* 在 **/etc/sendmail.cf** 中添加 `Cwyour.host.com` 行。

## 31.7.3. 仅设置发送邮件

有许多情况下，用户可能只希望通过中继发送邮件。以下是一些示例：

* 计算机是台式机，需要使用像 [mail(1)](https://man.freebsd.org/cgi/man.cgi?query=mail\&sektion=1\&format=html) 这样的程序，使用 ISP 的邮件中继。
* 计算机是服务器，不处理本地邮件，但需要将所有邮件转发到中继服务器进行处理。

虽然任何 MTA 都能够满足这一需求，但仅仅为了处理邮件转发而正确配置一个功能全面的 MTA 可能会很困难。像 Sendmail 和 Postfix 这样的程序对于这个用途来说太过复杂。

此外，典型的互联网接入服务协议可能禁止用户运行“邮件服务器”。

满足这些需求的最简单方法是使用 [dma(8)](https://man.freebsd.org/cgi/man.cgi?query=dma\&sektion=8\&format=html) MTA，它包含在 [基本系统](https://docs.freebsd.org/en/books/handbook/mail/#configuring-dragonfly-mail-agent) 中。对于 13.2 及之前的系统，可能需要从 ports 安装。

除了 [dma(8)](https://man.freebsd.org/cgi/man.cgi?query=dma\&sektion=8\&format=html)，也可以使用第三方软件实现同样的功能，例如 [mail/ssmtp](https://cgit.freebsd.org/ports/tree/mail/ssmtp/)。

```sh
# cd /usr/ports/mail/ssmtp
# make install replace clean
```

安装完成后，可以通过 **/usr/local/etc/ssmtp/ssmtp.conf** 配置 [mail/ssmtp](https://cgit.freebsd.org/ports/tree/mail/ssmtp/)：

```ini
root=yourrealemail@example.com
mailhub=mail.example.com
rewriteDomain=example.com
hostname=_HOSTNAME_
```

将 `root` 的值设置为真实的电子邮件地址，将 `mail.example.com` 替换为 ISP 的发件邮件中继。某些 ISP 将其称为“外发邮件服务器”或“SMTP 服务器”。

确保禁用 Sendmail，包括发件邮件服务。

[mail/ssmtp](https://cgit.freebsd.org/ports/tree/mail/ssmtp/) 还有一些其他选项。有关更多信息，请参阅 **/usr/local/etc/ssmtp** 中的示例或 ssmtp 的手册页。

以这种方式设置 ssmtp，可以使计算机上任何需要发送邮件的软件正常工作，同时不违反 ISP 的使用政策或使计算机成为垃圾邮件发送工具。

## 31.7.4. 在 Sendmail 中设置 SMTP 认证

在 MTA 中配置 SMTP 认证提供了许多好处。SMTP 认证为 Sendmail 增加了一层安全性，并为经常更换主机的移动用户提供了使用相同 MTA 的能力，而无需每次重新配置邮件客户端的设置。

从 Ports 安装 [security/cyrus-sasl2](https://cgit.freebsd.org/ports/tree/security/cyrus-sasl2/)。此 Port 支持多个编译时选项。对于本示例中演示的 SMTP 认证方法，请确保 `LOGIN` 选项未被禁用。

安装 [security/cyrus-sasl2](https://cgit.freebsd.org/ports/tree/security/cyrus-sasl2/) 后，编辑 **/usr/local/lib/sasl2/Sendmail.conf**，如果文件不存在则创建它，并添加以下行：

```sh
pwcheck_method: saslauthd
```

接下来，安装 [security/cyrus-sasl2-saslauthd](https://cgit.freebsd.org/ports/tree/security/cyrus-sasl2-saslauthd/)，并执行以下命令：

```sh
# sysrc saslauthd_enable="YES"
```

最后，启动 saslauthd 守护进程：

```sh
# service saslauthd start
```

该守护进程充当 Sendmail 与 FreeBSD [passwd(5)](https://man.freebsd.org/cgi/man.cgi?query=passwd\&sektion=5\&format=html) 数据库进行认证的中介。这样可以避免为每个需要使用 SMTP 认证的用户创建新的用户名和密码，并保持登录密码和邮件密码一致。

接下来，编辑 **/etc/make.conf** 并添加以下行：

```ini
SENDMAIL_CFLAGS=-I/usr/local/include/sasl -DSASL
SENDMAIL_LDADD=/usr/local/lib/libsasl2.so
```

这些行为 Sendmail 提供了正确的配置选项，以便在编译时链接到 [cyrus-sasl2](https://cgit.freebsd.org/ports/tree/cyrus-sasl2/)。在重新编译 Sendmail 之前，请确保已安装 [cyrus-sasl2](https://cgit.freebsd.org/ports/tree/cyrus-sasl2/)。

通过执行以下命令重新编译 Sendmail：

```sh
# cd /usr/src/lib/libsmutil
# make cleandir && make obj && make
# cd /usr/src/lib/libsm
# make cleandir && make obj && make
# cd /usr/src/usr.sbin/sendmail
# make cleandir && make obj && make && make install
```

如果 **/usr/src** 没有发生重大变化，并且所需的共享库可用，编译应该不会出现问题。

在重新编译并重新安装 Sendmail 后，编辑 **/etc/mail/freebsd.mc** 或本地 **.mc** 文件。许多管理员选择使用 [hostname(1)](https://man.freebsd.org/cgi/man.cgi?query=hostname\&sektion=1\&format=html) 命令的输出作为 **.mc** 的名称，以保证唯一性。

添加以下行：

```sh
dnl set SASL options
TRUST_AUTH_MECH(`GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN')dnl
define(`confAUTH_MECHANISMS', `GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN')dnl
```

这些选项配置了 Sendmail 用于用户认证的不同方法。如果要使用除 pwcheck 之外的方法，请参考 Sendmail 文档。

最后，在 **/etc/mail** 目录下运行 [make(1)](https://man.freebsd.org/cgi/man.cgi?query=make\&sektion=1\&format=html)。这将运行新的 **.mc** 文件并生成一个 **.cf** 文件，文件名为 **freebsd.cf** 或本地 **.mc** 使用的名称。

然后，运行 `make install restart`，这将把文件复制到 **sendmail.cf** 并正确重启 Sendmail。

有关此过程的更多信息，请参考 **/etc/mail/Makefile**。

要测试配置，可以使用 MUA 发送一封测试邮件。如需进一步调查，可以将 Sendmail 的 `LogLevel` 设置为 `13`，并在 **/var/log/maillog** 中查看任何错误。

有关更多信息，请参阅 [SMTP authentication](http://www.sendmail.org/~ca/email/auth.html)。


---

# 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://handbook.bsdcn.org/di-31-zhang-dian-zi-you-jian/31.7.-gao-ji-zhu-ti.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.
