1

深入浅出学习透析Nginx服务器的基本原理和配置指南「Https安全控制篇」

 1 year ago
source link: https://blog.51cto.com/alex4dream/5873716
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Https反向代理

之前的内容中我们主要针对于一些对安全性要求比较高的站点,可能会使用HTTPS(一种使用SSL通信标准的安全HTTP协议),针对于HTTP 协议和SSL标准相信大家都知道了,在这里我就不为大家进行介绍了,如果需要了解,大家可以查看一下相关的资料哈,但是对于使用Nginx配置https需要了解一下基础内容的。

生产环境一般都是购买的商业版SSL证书,本文主要是将自己配置Nginx  https证书的过程记录。我们开发过程的时候一般采用自制SSL证书。Nginx实现https需要http_ssl_module模块支持,该模块是默认编译模块,不需要我们再次编译。

Https反向代理的配置规则

  • HTTPS的默认端口号是443,不同于HTTP的默认端口(80)
  • SSL 标准需要引入安全证书,所以在Nginx.conf中你需要指定证书和它对应的 key
  • 其他和http反向代理基本一样,只是在Server部分配置有些不同。

之前案例的Http配置模板

以下是我们之前章节案例的配置基本模板信息,用于作为我们https模式的改造的标准话模板参考。

http {
upstream nginxServerConfig {
least_conn;
server www.address1.com; // 或者ip+端口 , 不需要加入http/https前缀
server www.address2.com;
server www.address3.com;
}
server {
listen 80;
location / {
proxy_pass http://loadBalanceServer;
}
}
}

配置 HTTPS 服务器

要配置 HTTPS 服务器,必须在 server 块中的 监听套接字 上启用 ssl 参数,并且指定服务器证书 和 私钥文件 的位置:

启用 SSL 功能

添加ssl指令的参数on,代表开启状态,目前新版本已经不需要进行指定了,默认可以自己检测和开启状态,此处只是说明以下有这个指令介绍。

ssl on;

注意:在 0.7.14 之前,无法为各个 socket 选择性地启用 SSL,如上所示。只能使用 ssl 指令为整个服务器启用 SSL,从而无法设置单个 HTTP/HTTPS 服务器。可以通过添加 listen 指令的 ssl 参数来解决这个问题。因此,不建议在现在的版本中使用 ssl 指令

监听默认端口修改

上面说的配置:HTTPS的默认端口号是443,不同于HTTP的默认端口(80),需要将原有的80端口的监听443端口。443为知名端口号,主要用于HTTPS协议。

需要将 listen 80; 改为 listen 443 ssl;

并且需要再后面再添加一个 ssl标识,代表着监听此类端口为Https模式协议机制。

制作SSL证书文件

我们都知道在公钥密码学(也称为非对称密码术)中,加密机制依赖于两个相关的密钥,一个公钥和一个私钥。公钥用于加密消息,而只有私钥的所有者才能解密消息。而针对于Https加密机制,需要引入证书,而证书就是针对于公钥和私钥的载体。所以我们需要配置对应的ssl证书文件。

SSL证书,就是遵守SSL安全套接层协议的服务器数字证书,由浏览器受信任的根证书颁发机构在验证服务器身份后颁发,具有网站身份验证和加密传输等功能。SSL证书并不是什么高深的技术产品,只需要成功申请下发后,安装到网站服务器即可。当你访问一个网站时,如果发现浏览器的地址栏中显示的是“https://”(绿色小锁图标),就说明这个网站已经安装部署了SSL证书

  • PEM:用ASCLL(BASE64)编码的证书;PEM扩展名用于不同类型的X.509v3文件,这些文件包含前缀为“-BEGIN …”行的ASCII(Base64)数据。
  • CER/CRT:存放公钥,没有私钥(编码方式不一定,有可能是.pem,也有可能是.der)。

在制作SSL证书之前需要线生成对应的私钥文件key信息数据。

openssl生成RSA私钥文件

openssl alexlibo -out mysecurity.key 2048

生成对应的私钥文件的基本结构信息如下:

深入浅出学习透析Nginx服务器的基本原理和配置指南「Https安全控制篇」_ssl证书

当然也可以参考​ ​使用 acme.sh 给 Nginx 安装 Let’ s Encrypt 提供的免费 SSL 证书​​​,生成对应的较为专业的SSL证书。针对于该脚本【​ ​acme.sh​​​】的github仓库地址​ ​https://github.com/acmesh-official/acme.sh,有兴趣的小伙伴可以试试看。​

生成pem文件
PEM文件格式

PEM格式通常用于数字证书认证机构(Certificate Authorities,CA),扩展名为.pem, .crt, .cer, and .key。内容为Base64编码的ASCII码文件,有类似"-----BEGIN CERTIFICATE-----" 和 "-----END CERTIFICATE-----"的头尾标记。服务器认证证书,中级认证证书和私钥都可以储存为PEM格式(认证证书其实就是公钥)。Apache和类似的服务器使用PEM格式证书。

openssl req -new -x509 -days 3650 -key mysecurity.key -out mysecurity.pem
PEM文件内容

以下就是类似的pem文件的内容

深入浅出学习透析Nginx服务器的基本原理和配置指南「Https安全控制篇」_服务器_02

添加对应的SSL证书

将生成的key、pem文件拷贝到nginx的conf目录下,为了管理多个SSL证书,可以在nginx的 conf目录下建立cert目录专门存放SSL证书相关文件。

设置ssl证书文件位置

我们采用在server指令块内部定义【ssl_certificate 指令】对应的value值,sl_certificate处写我们生成的pem文件,一般我们常见证书文件格式为:crt/pem。

ssl_certificate path/mysecurity.pem;
ssl_certificate path/mysecurity.crt;

这里注意以下:对应的证书位置是针对于nginx,conf文件的相对位置或者觉得路径也可以。

设置ssl证书私钥文件的位置

ssl_certificate_key写我们生成的key文件。配置完成后检查nginx的配置文件 然后重启Nginx.

ssl_certificate_key path/mysecurity.key;

注意:服务器证书是一个公共实体。它被发送到每个连接到服务器的客户端。私钥是一个安全实体,存储在一个访问受限的文件中,但是它对 nginx 的主进程必须是可读的。私钥也可以存储在与证书相同的文件中:

ssl_certificate xxx.cert;
ssl_certificate_key xxx.cert;

这种情况下,文件的访问也应该被限制。虽然证书和密钥存储在一个文件中,但只有证书能被发送给客户端。

SSL指令来限制连接

ssl_protocols 和 ssl_ciphers 指令来限制连接,使其仅包括 SSL/TLS 的版本和密码

ssl_protocols

默认情况下,Nginx 使用版本为 ssl_protocols TLSv1 TLSv1.1 TLSv1.2,如下所示。

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers

默认情况下,Nginx密码为 ssl_ciphers HIGH:!aNULL:!MD5

ssl_ciphers HIGH:!aNULL:!MD5
ssl_prefer_server_ciphers

指定是否使用服务器的 SSL 密码,on为开启状态

ssl_prefer_server_ciphers on;

通常不需要配置它们以上两者的值。请注意,这些指令的默认值已经被更改多次。

最终案例展示
server {
listen 443 ssl;
server_name www.address1.com;
ssl_certificate path/mysecurity.pem;
ssl_certificate_key path/mysecurity.key;
ssl_ciphers HIGH:!aNULL:!MD5;
...
}
ssl配置参数(选择性配置)
ssl的会话相关的配置
ssl_session_cache

设置ssl的session会话的缓存

启用 SSL Session 缓存可以大大减少 TLS 的反复验证,减少 TLS 握手的 roundtrip。虽然 session 缓存会占用一定内存,但是用 1M 的内存就可以缓存 4000 个连接,可以说是非常非常划算的。对于绝大多数网站和服务,要达到 4000 个同时连接本身就需要非常非常大的用户基数,因此可以放心开启。

ssl_session_cache shared:SSL:1m;
  • shared:SSL:1m:代表着缓存属于SSL之内进行共享,总体大小为1M。
ssl_session_timeout

设置ssl的会话超时时间为5分钟

ssl_session_timeout 5m;

同时建立HTTP/HTTPS 服务器

可以配置单个服务器来处理 HTTP 和 HTTPS 请求:

server {
listen 80;
listen 443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.crt;
ssl_certificate_key www.example.com.key;
...
}

基于名称的 HTTPS 服务器

当配置两个或多个 HTTPS 服务器监听单个 IP 地址时,会出现一个常见问题:

server {
listen 443 ssl;
server_name www.address1.com;
ssl_certificate address1.crt;
...
}
server {
listen 443 ssl;
server_name www.address1.org;
ssl_certificate address1.crt;
...
}

使用了此配置,浏览器会接收默认服务器的证书,即 ​ ​www.address1.com​​,而无视所请求的服务器名称。这是由 SSL 协议行为引起的。SSL连接在浏览器发送 HTTP 请求之前建立,nginx 并不知道请求的服务器名称。因此,它只能提供默认服务器的证书。最古老、最强大的解决方法是为每个 HTTPS 服务器分配一个单独的 IP 地址:

server {
listen 192.168.1.1:443 ssl;
server_name www.address1.com;
ssl_certificate address1.crt;
...
}
server {
listen 192.168.1.2:443 ssl;
server_name www.address1.org;
ssl_certificate address1.crt;
...
}

一般情况下如果作为统一的公私钥配置,那么最好是将证书文件与名称、私钥文件放置在 http 级配置,以便在所有服务器中继承其单个内存副本,如下所示

ssl_certificate mysecurity.crt;
ssl_certificate_key mysecurity.key;
server {
listen 443 ssl;
server_name www.address1.com;
...
}
server {
listen 443 ssl;
server_name www.address2.org;
...

Https服务配置模式最终案例

#HTTP服务器
server {
#监听443端口。443为知名端口号,主要用于HTTPS协议
listen 443 ssl;
#定义使用www.xx.com访问
server_name www.xx.com;
#ssl证书文件位置(常见证书文件格式为:crt/pem)
ssl_certificate cert.pem;
#ssl证书key位置
ssl_certificate_key cert.key;
#ssl配置参数(选择性配置)
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
#数字签名,此处使用MD5
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root /root;
index index.html index.htm;
}
}

HTTPS 服务器优化分析

  1. SSL 操作会消耗额外的 CPU 资源。在多处理器系统上,应该运行多个 工作进程(worker process),不得少于可用 CPU 核心的数量。大多数 CPU 密集型操作是发生在 SSL 握手时。有种方法可以最大程度地减少每个客户端执行这些操作的次数。
  • keepalive指令不会限制一个nginx worker进程到upstream服务器连接的总数量。connections参数应该设置为一个足够小的数字来让upstream服务器来处理新进来的连接。 connections参数设置每个worker进程在缓冲中保持的到upstream服务器的空闲keepalive连接的最大数量.当这个数量被突破时,最近使用最少的连接将被关闭。

启用 keepalive 连接,通过一个连接来发送多个请求,第二个是复用 SSL 会话参数,避免相同的和后续的连接发生 SSL 握手。会话存储在工作进程间共享的 SSL 会话缓存中,由 ssl_session_cache 指令配置。1MB 缓存包含约 4000 个会话。默认缓存超时时间为 5 分钟,可以用 ssl_session_timeout 指令来增加。以下是一个优化具有 10MB 共享会话缓存的多核系统的配置示例


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK