nginx中的TLS/SSL配置
nginx可以作为很多种不同的用途。对Web服务器来说,nginx可以直接用作https服务器,也可以用于为现有的http Web服务器作为前端代理和负载平衡的同时提供https之用。
nginx支持TLS协议的SNI扩展(Server Name Indication,简单地说这个扩展使得在同一个IP上可以以不同的证书serv不同的域名;较早前唯一的办法是签署一个通配证书,即 CNAME 中为 *.delphij.net 这样的证书)。不过,SNI扩展还必须有客户端的支持,另外本地的密码学函数库,例如OpenSSL也必须支持它。
如果启用了SSL支持,nginx便会自动识别OpenSSL并启用SNI。是否启用SNI支持,是在编译时由当时的 ssl.h 决定的(SSL_CTRL_SET_TLSEXT_HOSTNAME),如果编译时使用的OpenSSL库支持SNI,则目标系统的OpenSSL库只要支持它就可以正常使用SNI了。
FreeBSD 8.0起的所有版本附带的OpenSSL均启用了SNI支持。这一特性是OpenSSL 1.0才开始默认启用的新功能,如果系统不是 FreeBSD 并且采用的是较早版本的 OpenSSL, 可能需要自行重新编译,并在config的时候指定enable-tlsext。注意:OpenSSL在多数系统中都有重要的其他用途,重新安装OpenSSL时,最好不要与厂商采用的参数差别太大;另外还有一种解决办法是安装到不同的目录并在运行程序的时候指定搜索路径或静态联编;FreeBSD不需要做这些配置,故不再赘述。
检查nginx是否支持SNI的方法是使用 nginx -V
来查看。
nginx version: nginx/0.8.45
__TLS SNI support enabled__
configure arguments: --prefix=/usr/local/etc/nginx --with-cc-opt='-I /usr/local/include' --with-ld-opt='-L /usr/local/lib' --conf-path=/usr/local/etc/nginx/nginx.conf --sbin-path=/usr/local/sbin/nginx --pid-path=/var/run/nginx.pid --error-log-path=/var/log/nginx-error.log --user=www --group=www --with-ipv6 --http-client-body-temp-path=/var/tmp/nginx/client_body_temp --http-fastcgi-temp-path=/var/tmp/nginx/fastcgi_temp --http-proxy-temp-path=/var/tmp/nginx/proxy_temp --http-scgi-temp-path=/var/tmp/nginx/scgi_temp --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi_temp --http-log-path=/var/log/nginx-access.log --with-http_gzip_static_module --with-http_ssl_module --with-http_stub_status_module --with-pcre
以上标红的一行表示以目前的方式运行nginx时可以使用SNI。
使用SNI并不需要额外的配置,对nginx来说只需和HTTP主机一样配置多个https主机的server配置段即可。
以下是nginx中用于TLS的配置。可将其保存为一个单独的文件,例如 tls_param:
listen 443; # 端口(IPv4)
listen [::]:443; # 端口(IPv6)
ssl on; # 启用SSL
ssl_session_timeout 5m; # SSL会话超时时间
ssl_protocols TLSv1; # 只启用TLSv1
ssl_ciphers TLSv1:+HIGH:-MEDIUM:-LOW:-EXPORT:-aNULL:-eNULL:@STRENGTH # 启用的加密算法,见下
ssl_prefer_server_ciphers on; # 协商时优先使用服务器指定的加密算法
采用的加密算法集具体请参见 OpenSSL 联机手册 ciphers(1)。这里只解释采用的选项:
- TLSv1:TLSv1使用的加密算法组合
- -MEDIUM:排除中等加密强度的算法组合
- -LOW:排除低加密强度的加密算法组合
- -EXPORT:排除出口级别强度的加密算法组合
- -aNULL:排除不做身份验证的加密算法组合
- -eNULL:排除不做加密的加密算法组合
- @STRENGTH:按加密强度排序
除了上面这些配置之外,还需要和传统的http主机一样指定server_name(主机名),以及采用的证书文件和公钥/私钥对文件( ssl_certificate、ssl_certificate_key)。