# 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)。
