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


    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;
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    配置 HTTPS 服务器

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

    启用 SSL 功能

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

    ssl on;
    
    • 1

    注意:在 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;
    
    • 1

    并且需要再后面再添加一个 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
    
    • 1

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

    在这里插入图片描述

    当然也可以参考使用 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
    
    • 1
    PEM文件内容

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

    添加对应的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;
    
    • 1

    或者

    ssl_certificate      path/mysecurity.crt;
    
    • 1

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

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

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

    ssl_certificate_key path/mysecurity.key;
    
    • 1

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

    ssl_certificate     xxx.cert;
    ssl_certificate_key xxx.cert;
    
    • 1
    • 2

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

    SSL指令来限制连接

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

    ssl_protocols

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

    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    
    • 1
    ssl_ciphers

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

    ssl_ciphers HIGH:!aNULL:!MD5
    
    • 1
    ssl_prefer_server_ciphers

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

    ssl_prefer_server_ciphers  on;
    
    • 1

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

    最终案例展示
    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;
        ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    ssl配置参数(选择性配置)
    ssl的会话相关的配置
    ssl_session_cache

    设置ssl的session会话的缓存

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

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

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

    ssl_session_timeout  5m; 
    
    • 1

    同时建立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;
        ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    基于名称的 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;
        ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    使用了此配置,浏览器会接收默认服务器的证书,即 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;
        ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    一般情况下如果作为统一的公私钥配置,那么最好是将证书文件与名称、私钥文件放置在 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;
        ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    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;
          }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    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 共享会话缓存的多核系统的配置示例

  • 相关阅读:
    [附源码]SSM计算机毕业设计基于的花店后台管理系统JAVA
    C语言之文件操作(剩余部分)
    [附源码]Python计算机毕业设计SSM科技类产品众筹系统(程序+LW)
    【c++】简单了解运算符重载
    谷歌真的“不作恶”?前员工起诉:它早已亲手打破座右铭
    圆满收官,百花齐放!2022企业级低代码应用大赛获奖结果公布
    【华为机试真题 JAVA】找终点-100
    设计模式探索:从理论到实践的编码示例 (软件设计师笔记)
    Field的使用
    php容器有哪些
  • 原文地址:https://blog.csdn.net/l569590478/article/details/127962939