ngx_http_ssl_module 模块提供对 HTTPS 的必要支持。

默认不构建该模块。使用 --with-http_ssl_module 配置参数启用它。

该模块依赖 OpenSSL 库。

为降低处理器负载,建议


指令

该指令在版本 1.15.0 中被废弃。应该使用 listen 指令的 ssl 参数替代。

 

设置用于发送数据的缓冲的大小。

默认,缓冲大小是 16k。当发送大响应时,它对应最小的开销。

为最小化首字节时间,可以使用较小的值,比如:

ssl_buffer_size 4k;

 

为给定的虚拟主机指定 PEM 格式的证书文件。如果除主证书外,还需要指定中间证书,那么应该在相同的文件中按照如下顺序指定它们:前面是主证书,后面是中间证书。PEM 格式的私钥可被放置在相同的文件中。

从版本 1.11.0 开始,可以指定该指令多次,以加载不同类型的证书,比如 RSA 和 ECDSA:

仅 OpenSSL 1.0.2 或更高的版本支持不同证书的单独证书链。旧版本仅能使用一个证书链。

从版本 1.15.9 起,当使用 OpenSSL 1.0.2 或更高版本时,可以在 file 名称中,使用变量:

注意,使用变量意味着将为每次 SSL 握手加载证书,这可能对性能产生负面影响。

从 1.15.10 起,可以指定值 data:$variable,替代 file,它从变量中加载证书,而不使用中间文件。注意,不恰当地使用该语法可能产生安全隐患,比如将私钥数据写到 error log。

请记住,由于 HTTPS 协议对最大互操作性的限制,虚拟主机应该监听不同的 IP 地址

 

为给定的虚拟主机指定 PEM 格式的私钥文件。

从 1.7.9 起,可以指定值 engine:name:id,替代 file,它使用指定的 id,从 OpenSSL 引擎 name 加载私钥。

从 1.15.10 起,可以指定值 data:$variable,替代 file,它从变量中加载私钥,而不使用中间文件。注意,不恰当地使用该语法可能产生安全隐患,比如将私钥数据写到 error log。

从版本 1.15.9 起,当使用 OpenSSL 1.0.2 或更高版本时,可以在 file 名称中使用变量。

 

指定启用的加密算法。用 OpenSSL 库能理解的格式指定加密算法,比如:

使用 “openssl ciphers” 命令,查看完整列表。

cipher list 的格式 cipher list 由多个 cipher string 组成,用冒号,逗号或者空格分隔,最常用的是冒号。 cipher string 可以仅包含一个 cipher,比如 RC4-SHA。也可以仅包含一个加密算法,比如 SHA 表示列出所有用到 SHA 的 cipher。 还可以使用三个符号(+、-、!)捏合不同的 cipher,创建 cipher string,比如 MD5+DES 表示同时使用这两种算法的 cipher;!SHA 表示所有未使用 SHA 的 cipher;IDEA-CBC 表示使用 IDEA 但未使用 CBC 的所有 cipher。 OpenSSL 预定义一组通用的 cipher string,包括:

  1. DEFAULT:缺省的 cipher list
  2. ALL:所有 cipher
  3. HIGH、LOW、MEDIUM:分别代表高强度,低强度和中等强度的 cipher list,即对称加密算法的 key 的长度分别大于 128 bit、小于 128 bit 和等于 128 bit 的 cipher
  4. EXP、EXPORT、EXPORT40:前两者代表法律允许出口的加密算法,包括 key 的长度为 40 bit、56 bit 的算法;后者表示 key 的长度只有 40 bit 的加密算法
  5. eNULL、NULL:表示不加密的算法
  6. aNULL:不提供身份验证的加密算法。目前只有 DH 一种。该算法很容易被监听者、路由器等中间设备攻击,所以不提倡使用

 

指定 PEM 格式的受信任 CA 证书文件,这些证书用于验证客户端证书和 OCSP 响应(如果启用 ssl_stapling)。

证书列表将被发送到客户端。如果不希望这样,那么使用 ssl_trusted_certificate 指令。

 

设置任意 OpenSSL 配置命令

当使用 OpenSSL 1.0.2 或更高版本时,支持该指令。

可以在相同层级指定多个 ssl_conf_command 指令:

当且仅当当前层级未定义 ssl_conf_command 指令时,从前面的配置层级继承这些指令。

注意,直接配置 OpenSSL 可能导致非预期行为。

 

指定 PEM 格式的被吊销证书(CRL)文件,这些证书用于验证客户端证书。

 

指定用于 DHE 算法的 DH 参数文件。

默认不设置任何参数,因此将不使用 DHE 算法。

在版本 1.11.0 前,默认使用内置参数。

 

开启或禁用 TLS 1.3 早期数据

在早期数据中发送的请求容易受到重放攻击。为在应用程序层防止这种攻击,应该使用 $ssl_early_data 变量。

从 1.15.4 起,当使用 OpenSSL 1.1.1 或更高版本和 BoringSSL 时,支持该指令。

 

为 ECDHE 加密算法,指定曲线

当使用 OpenSSL 1.0.2 或更高版本时,可以指定多个曲线(1.11.0),比如:

特殊值 auto(1.11.0)命令 nginx 在使用 OpenSSL 1.0.2 或更高版本时,使用被构建进 OpenSSL 库的列表;使用旧版本时,使用 prime256v1

在版本 1.11.0 前,默认使用 prime256v1 曲线。

当使用 OpenSSL 1.0.2 或更高版本时,该指令设置服务端支持的曲线列表。因此,为使 ECDSA 证书发挥作用,在证书中包含使用的曲线很重要。

 

指定私钥的密码文件,每行指定一个密码。加载私钥时,按次序尝试这些密码。

比如:

 

指定当使用 SSLv3 和 TLS 协议时,服务端加密算法应优先于客户端加密算法。

 

启用指定的协议。

仅当使用 OpenSSL 1.0.1 或更高版本时,TLSv1.1 和 TLSv1.2 参数(1.1.13、1.0.12)才生效。

仅当使用 OpenSSL 1.1.1 或更高版本时,TLSv1.3 参数(1.13.0)才生效。

从 1.23.4 起,默认使用 TLSv1.3 参数。

 

如果启用,那么 server 块中的 SSL 握手将被拒绝。

比如,在下面的配置中,拒绝使用除 example.com 外的服务名称的 SSL 握手:

 

设置存储会话参数的缓存的类型和大小。缓存可以是下面的类型中的任意一个:

off       严格禁止使用会话缓存:nginx 显式地告诉客户端不重用会话

none       不允许使用会话缓存:nginx 告诉客户端可能重用会话,但不真正地在缓存中存储会话参数

builtin       OpenSSL 内置的缓存。仅能被一个工作进程使用。在会话中指定缓存大小。默认保存 20480 个会话。使用内置缓存将导致内存碎片

shared       所有工作进程共享缓存。以字节为单位指定缓存大小;1M 大约可以存储 4000 个会话。每个共享缓存可以拥有任意的名称。可以在多个虚拟主机中使用具有相同名称的缓存。它还用于自动生成、存储和定期轮换 TLS 会话票据密钥(1.23.2),除非使用 ssl_session_ticket_key 指令显式地进行配置。可以同时使用这两种缓存类型,比如:

但是仅使用共享缓存,不使用内置缓存更高效。

关于 SSL/TLS Session

每次建立新 SSL/TLS 连接都需要握手,如果会话中断,那么需要重新握手。此时,有两种方法恢复原来的 Session:

  1. Session ID

    Session ID 重用的前提是客户端和服务端都保存会话密钥。每次会话都有唯一的编号(Session ID)。会话中断,需要重连时,客户端只要给出该编号,并且服务器端拥有该记录,双方就可以重用已有的会话密钥,而不必重新生成。

    session-id

    在上图中,客户端提供 Session ID,服务端确认该编号存在,双方不再进行握手阶段剩余的步骤,而是直接使用已有的会话密钥。

    目前所有浏览器都支持 Session ID,但其缺点是:因为 Session ID 往往只保留在一台服务器上,所以如果客户端的请求发到另一台服务器,那么无法恢复会话。

    在 nginx 中,通过 ssl_session_cache 配置 Session ID 重用。

  2. Session Ticket

    session-ticket

    在 Session Ticket 复用中,服务器不用为每个会话保存状态,而是用一个 blob 数据保存状态,然后将它发送给客户端,用于维护后续连接,Session Ticket 允许服务器将状态存储委托给客户端,类似 HTTP Cookie。

    Session Ticket 是加密的数据 blob,其中包含需要重用的 TLS 连接信息,比如会话密钥等。一般使用 Ticket Key 加密它,只有服务器端知道 Ticket Key。在初始握手中,服务端将 Session Ticket 发送到客户端,客户端将其存储到本地;重用会话时,客户端将 Session Ticket 发送到服务端,服务端解密后重用会话。

    在 nginx 中,使用 ssl_session_tickets 配置 Session Ticket 复用。

 

设置用于加密和解密 TLS Session Ticket 的密钥文件。如果多台服务器间必须共享相同的密钥,那么该指令是必需的。默认使用随机生成的密钥。

如果指定多个密钥,那么仅使用第一个密钥加密 TLS Session Ticket。这允许配置密钥轮换,比如:

file 必需包含 80 或 48 字节的随机数据,可以使用如下命令创建:

根据文件大小,使用 AES256(对于 80 字节密钥,1.11.8)或 AES128(对于 40 字节密钥)进行加密。

 

启用或禁用通过 TLS Session Ticket 恢复会话。

 

指定客户端可以重用会话参数的时间。

 

指定 PEM 格式的受信任 CA 证书文件,这些证书用于验证客户端证书和 OCSP 响应(如果启用 ssl_stapling)。

ssl_client_certificate 设置的证书相比,这些证书的列表不被发送给客户端。

 

启用客户端证书验证。验证结果被保存在 $ssl_client_verify 变量中。

optional 参数(0.8.7+)请求客户端证书,如果证书存在,那么验证它。

optional_no_ca 参数(1.3.8、1.2.5)请求客户端证书,但不要求其由受信任的 CA 证书签名。主要用于 Nginx 外部的服务执行真正的证书验证的场景。通过 $ssl_client_cert 变量访问证书的内容。

 

设置客户端证书链的验证深度。


ngx_http_proxy_module 模块中与 SSL 有关的指令

指定包含 PEM 格式的证书的文件,该证书用于认证被代理的 HTTPS 服务。

从版本 1.21.0 起,可以在 file 名称中可以使用变量。

 

指定包含 PEM 格式的私钥的文件,该私钥用于认证被代理的 HTTPS 服务。

可以指定值 engine:name:id,替代 file(1.7.9),它使用指定的 id 从 OpenSSL 引擎 name 加载私钥。

从版本 1.21.0 起,可以在 file 名称中可以使用变量。

 

为到被代理的 HTTPS 服务的请求,指定启用的加密算法。用 OpenSSL 能理解的格式指定加密算法。

使用“openssl ciphers”命令查看完整列表。

 

当与被代理的 HTTPS 服务建立连接时,设置任意 OpenSSL 配置命令。

当使用 OpenSSL 1.0.2 或更高版本时,支持该指令。

在相同的层级可以指定多个 proxy_ssl_conf_command 指令。如果当前层级未定义 proxy_ssl_conf_command 指令,那么从前面的配置层级继承这些指令。

注意,直接配置 OpenSSL 可能导致非预期行为。

 

指定包含 PEM 格式的、被吊销的证书的文件,这些证书用于验证被代理的 HTTPS 服务的证书。

 

允许重写用于验证被代理的 HTTPS 服务的证书的服务名称,当与被代理的 HTTPS 服务建立连接时,通过 SNI 传递它。

默认,使用 proxy_pass URL 的 host 部分。

 

指定包含私钥的密码的文件,每行指定一个密码。加载私钥时,按次序尝试这些密码。

 

为到被代理的 HTTPS 服务的请求,启用指定的协议。

从 1.23.4 起,默认使用 TLSv1.3 参数。

 

当与被代理的 HTTPS 服务建立连接时,启用或禁用通过 TLS SNI 扩展传递服务名称。

 

决定是否重用 SSL 会话。如果错误日志中出现错误 SSL3_GET_FINISHED:digest check failed,那么尝试禁用会话重用。

 

指定包含 PEM 格式的、受信任的 CA 证书的文件,这些证书用于验证被代理的 HTTPS 服务的证书。

 

启用或禁用被代理的 HTTPS 服务证书的验证。

 

设置被代理的 HTTPS 服务证书链的验证深度。