<!-- review: finished -->

<a id="mail-core"></a>

# 邮件模块

核心邮件模块实现了邮件代理服务器的基本功能:
包括对 SMTP、IMAP 和 POP3 协议的支持、配置服务器块、邮件请求路由、用户身份验证,以及用于保护邮件连接的 SSL/TLS 支持。

本节中的其他模块扩展了此功能,允许您灵活地配置和优化邮件服务器以适应各种场景和需求。

当 [从源代码构建](https://cn.angie.software//angie/docs/installation/sourcebuild.md#sourcebuild) 时,
此模块默认不会被构建;
应使用
`--with-mail`
[构建选项](https://cn.angie.software//angie/docs/installation/sourcebuild.md#configure) 启用它。
在来自 [我们的软件仓库](https://cn.angie.software//angie/docs/installation/index.md#install-packages) 的软件包和镜像中,
该模块已包含在构建中。

<a id="configuration-example-52"></a>

## 配置示例

```nginx
worker_processes auto;

error_log /var/log/angie/error.log info;

events {
    worker_connections  1024;
}

mail {
    server_name       mail.example.com;
    auth_http         localhost:9000/cgi-bin/auth.cgi;

    imap_capabilities IMAP4rev1 UIDPLUS IDLE LITERAL+ QUOTA;

    pop3_auth         plain apop cram-md5;
    pop3_capabilities LAST TOP USER PIPELINING UIDL;

    smtp_auth         login plain cram-md5;
    smtp_capabilities "SIZE 10485760" ENHANCEDSTATUSCODES 8BITMIME DSN;
    xclient           off;

    server {
        listen   25;
        protocol smtp;
    }
    server {
        listen   110;
        protocol pop3;
        proxy_pass_error_message on;
    }
    server {
        listen   143;
        protocol imap;
    }
    server {
        listen   587;
        protocol smtp;
    }
}
```

<a id="directives-56"></a>

## 指令

<a id="index-0"></a>

<a id="m-listen"></a>

### listen

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `listen` address[:port] [`ssl`] [`proxy_protocol`] [`backlog=`number] [`rcvbuf=`size] [`sndbuf=`size] [`bind`] [`ipv6only=``on` | `off`] [`reuseport`] [`so_keepalive=`on|off|[`keepidle`]:[`keepintvl`]:[`keepcnt`]];   |
|--------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 默认值                                                                                  | —                                                                                                                                                                                                                        |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | server                                                                                                                                                                                                                   |

设置服务器将接受连接的套接字的 address 和 port。可以只指定 port,Angie 将监听所有可用的 IPv4 接口(如果启用,还包括 IPv6)。address 也可以是主机名,例如:

```nginx
listen 127.0.0.1:110;
listen *:110;
listen 110;     # 与 *:110 相同
listen localhost:110;
```

IPv6 地址用方括号指定:

```nginx
listen [::1]:110;
listen [::]:110;
```

UNIX 域套接字使用 `unix:` 前缀指定:

```nginx
listen unix:/var/run/angie.sock;
```

#### NOTE
不同的服务器必须监听不同的 address:port 对。

| `ssl`            | 指定在此端口上接受的所有连接都应在 SSL 模式下工作。                                                                                                                                                                                                                                    |
|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `proxy_protocol` | 指定在此端口上接受的所有连接都应使用 PROXY 协议。获取的信息将传递给 [身份验证服务器](https://cn.angie.software//angie/docs/configuration/modules/mail/mail_auth_http.md#mail-auth-http),并可用于 [更改客户端地址](https://cn.angie.software//angie/docs/configuration/modules/mail/mail_realip.md#mail-realip)。 |

`listen` 指令可以有几个与套接字相关的系统调用特定的附加参数。

| `backlog=`number      | 在 `listen()` 调用中设置 backlog 参数,该参数限制待处理连接队列的最大长度。默认情况下,在 FreeBSD、DragonFly BSD 和 macOS 上 backlog 设置为 -1,在其他平台上设置为 511。                                                                                                                                                                                    |
|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `rcvbuf=`size         | 为监听套接字设置接收缓冲区大小(SO_RCVBUF 选项)。                                                                                                                                                                                                                                                                           |
| `sndbuf=`size         | 为监听套接字设置发送缓冲区大小(SO_SNDBUF 选项)。                                                                                                                                                                                                                                                                           |
| `bind`                | 指示为给定的 address:port 对进行单独的 `bind()` 调用。事实上,如果有多个具有相同端口但不同地址的 `listen` 指令,并且其中一个 `listen` 指令监听给定端口的所有地址(\*:port),Angie 将只 `bind()` 到 \*:port。应该注意的是,在这种情况下将进行 `getsockname()` 系统调用以确定接受连接的地址。如果使用了 backlog、rcvbuf、sndbuf、ipv6only、reuseport 或 so_keepalive 参数,那么对于给定的 address:port 对将始终进行单独的 `bind()` 调用。 |
| `ipv6only=on` | `off` | 确定(通过 IPV6_V6ONLY 套接字选项)监听通配符地址 [::] 的 IPv6 套接字是只接受 IPv6 连接还是同时接受 IPv6 和 IPv4 连接。此参数默认开启。它只能在启动时设置一次。                                                                                                                                                                                                    |
| `multipath`           | 启用通过 [Multipath TCP](https://en.wikipedia.org/wiki/Multipath_TCP) (MPTCP)接受连接,<br/>在 Linux 内核 5.6 及更高版本中支持。                                                                                                                                                                                              |

`so_keepalive=on` | `off` | [`keepidle`]:[`keepintvl`]:[`keepcnt`]

为监听套接字配置"TCP keepalive"行为。

| `''`   | 如果省略此参数,则套接字将使用操作系统的设置   |
|--------|--------------------------|
| `on`   | 为套接字开启 `SO_KEEPALIVE` 选项 |
| `off`  | 为套接字关闭 `SO_KEEPALIVE` 选项 |

某些操作系统支持使用 `TCP_KEEPIDLE`、`TCP_KEEPINTVL` 和 `TCP_KEEPCNT` 套接字选项
在每个套接字的基础上设置 TCP keepalive 参数。在这些系统上,可以使用
`keepidle`、`keepintvl` 和 `keepcnt` 参数进行配置。可以省略一个或两个参数,在这种
情况下,相应套接字选项的系统默认设置将生效。

例如,

```nginx
so_keepalive=30m::10
```

将空闲超时(`TCP_KEEPIDLE`)设置为 30 分钟,将探测间隔(`TCP_KEEPINTVL`)保留为系统默认值,并将探测次数(`TCP_KEEPCNT`)设置为 10 次探测。

不同的服务器必须监听不同的 address:port 对。

<a id="index-1"></a>

<a id="m-mail"></a>

### mail

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `mail` { ... }   |
|--------------------------------------------------------------------------------------|------------------|
| 默认值                                                                                  | —                |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | main             |

提供配置文件上下文,在其中指定邮件服务器指令。

<a id="index-2"></a>

<a id="max-commands"></a>

### max_commands

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `max_commands` number;   |
|--------------------------------------------------------------------------------------|--------------------------|
| 默认值                                                                                  | `max_commands 1000;`     |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | mail, server             |

设置身份验证期间发出的最大命令数,以增强对 DoS 攻击的防护。

<a id="index-3"></a>

<a id="m-max-errors"></a>

### max_errors

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `max_errors` number;   |
|--------------------------------------------------------------------------------------|------------------------|
| 默认值                                                                                  | `max_errors 5;`        |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | mail, server           |

设置协议错误的次数,超过此次数后将关闭连接。

<a id="index-4"></a>

<a id="m-protocol"></a>

### protocol

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `protocol` imap | pop3 | smtp;   |
|--------------------------------------------------------------------------------------|----------------------------------|
| 默认值                                                                                  | —                                |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | server                           |

设置代理服务器的协议。支持的协议有 [IMAP](https://cn.angie.software//angie/docs/configuration/modules/mail/mail_imap.md#mail-imap)、[POP3](https://cn.angie.software//angie/docs/configuration/modules/mail/mail_pop3.md#mail-pop3) 和 [SMTP](https://cn.angie.software//angie/docs/configuration/modules/mail/mail_smtp.md#mail-smtp)。

如果未设置该指令,可以根据 `listen` 指令中指定的知名端口自动检测协议:

```console
imap: 143, 993
pop3: 110, 995
smtp: 25, 587, 465
```

当 [从源代码构建](https://cn.angie.software//angie/docs/installation/sourcebuild.md#sourcebuild) 时,可以使用
`‑‑without‑mail_imap_module`、`‑‑without‑mail_pop3_module` 和
`‑‑without‑mail_smtp_module` [构建选项](https://cn.angie.software//angie/docs/installation/sourcebuild.md#configure) 禁用不需要的协议。

<a id="index-5"></a>

<a id="m-resolver"></a>

### resolver

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `resolver` address ... [`valid=`time] [`ipv4=``on` | `off`] [`ipv6=``on` | `off`] [`status_zone=`zone] | `off`;   |
|--------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|
| 默认值                                                                                  | `resolver off;`                                                                                                   |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | mail, server                                                                                                      |

配置用于查找客户端主机名的名称服务器,以将其传递给 [身份验证服务器](https://cn.angie.software//angie/docs/configuration/modules/mail/mail_auth_http.md#mail-auth-http),并在代理 SMTP 时用于 [XCLIENT](https://cn.angie.software//angie/docs/configuration/modules/mail/mail_proxy.md#m-xclient) 命令。例如:

```nginx
resolver 127.0.0.53 [::1]:5353;
```

特殊值 `off` 会禁用客户端主机名解析,并取消继承的指令值。

地址可以指定为域名或 IP 地址,带有可选端口。如果未指定端口,则使用端口 53。名称服务器以轮询方式查询。

#### NOTE
建议使用本地可信解析器，例如 `127.0.0.53` (systemd-resolved)，而非
公共解析器（如 `8.8.8.8`）。公共解析器会将 DNS 查询暴露给第三方，
并增加缓存投毒攻击的风险。

#### NOTE
指令值会被嵌套块继承,
并且可以在嵌套块中根据需要进行覆盖。
在单个块内,指令只能指定一次。
如果重复指定,则最后一次定义生效。

默认情况下,Angie 使用响应的 TTL 值来缓存答案。如果
未指定 `resolver` 指令且不执行动态 DNS 查询(例如,在 [Proxy](https://cn.angie.software//angie/docs/configuration/modules/mail/mail_proxy.md#mail-proxy) 中使用固定名称而不使用
变量时),则不需要指定解析器:名称将在启动时
使用系统解析器进行解析。可选的 `valid` 参数允许
覆盖此行为:

| `valid`   |  *可选* 参数,允许覆盖缓存条目的有效期   |
|-----------|-------------------------|
```nginx
resolver 127.0.0.53 [::1]:5353 valid=30s;
```

默认情况下,Angie 在解析时会同时查找 IPv4 和 IPv6 地址。

| `ipv4=off`    | 禁用 IPv4 地址查找                       |
|---------------|------------------------------------|
| `ipv6=off`    | 禁用 IPv6 地址查找                       |
| `status_zone` | *可选* 参数,在指定区域中启用 DNS 服务器请求和响应信息的收集 |

<a id="index-6"></a>

<a id="m-resolver-timeout"></a>

### resolver_timeout

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `resolver_timeout` time;   |
|--------------------------------------------------------------------------------------|----------------------------|
| 默认值                                                                                  | `resolver_timeout 30s;`    |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | mail, server               |

设置名称解析的超时时间,例如:

```nginx
resolver_timeout 5s;
```

<a id="index-7"></a>

<a id="m-server"></a>

### server

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `server` { ... }   |
|--------------------------------------------------------------------------------------|--------------------|
| 默认值                                                                                  | —                  |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | mail               |

设置服务器的配置。

<a id="index-8"></a>

<a id="m-server-name"></a>

### server_name

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `server_name` name;     |
|--------------------------------------------------------------------------------------|-------------------------|
| 默认值                                                                                  | `server_name hostname`; |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | mail, server            |

设置服务器名称,用于:

* POP3/SMTP 服务器的初始问候语;
* SASL CRAM-MD5 认证期间的盐值;
* 连接到 SMTP 后端时的 EHLO 命令,如果启用了 [XCLIENT](https://cn.angie.software//angie/docs/configuration/modules/mail/mail_proxy.md#m-xclient) 命令的传递。

如果未指定该指令,则使用机器的 hostname。

<a id="index-9"></a>

<a id="m-timeout"></a>

### timeout

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `timeout` time;   |
|--------------------------------------------------------------------------------------|-------------------|
| 默认值                                                                                  | `timeout 60s;`    |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | mail, server      |

设置开始代理到后端之前使用的超时时间。
