> 技术文档 > 深入理解HTTPS:从概念到实战优化

深入理解HTTPS:从概念到实战优化


深入理解HTTPS:从概念到实战优化

  • 一:概述
  • 二:工作流程
  • 三:创建自签名证书
  • 四:案例
    • 1)案例一:HTTPS 搭建
    • 2)案例二:HTTP/2 搭建
    • 3)案例三:HTTP 重定向 HTTPS
    • 4)案例四:网站集群 HTTPS 配置
  • 五:优化
  • 六:监控
    • 1)监控思路
    • 2)监控方式
    • 3)监控脚本
  • 总结

🌟 如果你对 HTTP 协议的基础知识(如请求/响应报文、状态码等)还不熟悉,建议先阅读:《HTTP协议完全指南:从报文到状态码》

一:概述

HTTPS = HTTP + TLS/SSL

在 HTTP 的基础上,HTTPS 增加了加密和身份验证,保障数据传输的安全性。

主要作用:

  1. 加密通信:防止数据在传输过程中被窃取或篡改
  2. 身份验证:确认服务器身份,防止钓鱼或中间人攻击
  3. 数据完整性:确保数据在传输过程中未被修改

二:工作流程

HTTPS 基于 TLS(传输层安全协议),核心流程如下:

  1. 客户端发起 HTTPS 请求
    • 浏览器访问 https://example.com
    • 告诉服务器它支持的TLS版本和加密算法 + 一个随机数
  2. 服务器返回证书
    • 证书中包含公钥、域名、颁发机构等信息 + 一个随机数
  3. 客户端验证证书
    • 检查证书是否可信(CA 签名、有效期、域名匹配)
  4. 生成会话密钥
    • 生成一个预密钥,然后用服务器的公钥加密后发给服务器,服务器用密钥解密,然后将预密钥和两个随机数组成对称密钥
  5. 加密通信
    • 后续所有 HTTP 请求和响应 都用对称密钥加密传输

三:创建自签名证书

  • .key:私钥

  • .csr:申请证书的文件,交给CA(如果指定为自签名证书 -x509 则不生成)

  • .crt:公钥 + 证书

  • .pem:公钥 + 证书

  • 一步到位

    openssl req -days 365 -x509 -sha256 -nodes -newkey rsa:2048 \\-keyout server.key -out server.crt
  • 分两步

    1. 创建私钥

      openssl genrsa -out server.key 2048
    2. 根据私钥生成证书

      • -days:指定证书有效时间(单位:天)
      • -x509:直接生成自签名证书(不用额外 CSR
      • -sha256:签名算法
      • -key:指定已有私钥位置
      • -out:指定输出证书文件位置
      openssl req -days 365 -x509 -sha256 -key server.key -out server.crt

四:案例

1)案例一:HTTPS 搭建

  1. 创建存放 SSL 证书和私钥的目录

    [root@web01 ~]# mkdir -p /etc/nginx/ssl_keys
  2. 上传证书

    [root@web01 ~]# unzip /opt/software/ssl.jackmk.cn_nginx.zip -d /etc/nginx/ssl_keys/
  3. 创建站点

    # 创建站点目录[root@web01 ~]# mkdir -p /opt/module/ssl# 创建站点 index.html[root@web01 ~]# echo \"index\" > /opt/module/ssl/index.html
  4. 创建站点配置文件

    [root@web01 ~]# vim /etc/nginx/conf.d/ssl.conf
    server { listen 443 ssl; # ssl on; # 1.15.0 以后被废弃了 server_name ssl.jackmk.cn; root /opt/module/ssl/; # ssl key ssl_certificate /etc/nginx/ssl_keys/ssl.jackmk.cn.pem; ssl_certificate_key /etc/nginx/ssl_keys/ssl.jackmk.cn.key; location / { index index.html; }}
  5. 刷新 Nginx

    nginx -tnginx -s reload
  6. 配置 hosts

    192.168.2.104 ssl.jackmk.cn
  7. 访问

    深入理解HTTPS:从概念到实战优化


2)案例二:HTTP/2 搭建

server { listen 443 ssl http2; # 只要加上这个就行 server_name ssl.jackmk.cn; root /opt/module/ssl/; # ssl key ssl_certificate /etc/nginx/ssl_keys/ssl.jackmk.cn.pem; ssl_certificate_key /etc/nginx/ssl_keys/ssl.jackmk.cn.key; location / { index index.html; }}

3)案例三:HTTP 重定向 HTTPS

  1. 创建存放 SSL 证书和私钥的目录

    [root@web01 ~]# mkdir -p /etc/nginx/ssl_keys
  2. 上传证书

    • ssl.jackmk.cn.key:私钥
    • ssl.jackmk.cn.pem:证书 + 公钥
    [root@web01 ~]# unzip /opt/software/ssl.jackmk.cn_nginx.zip -d /etc/nginx/ssl_keys/
  3. 创建站点

    # 创建站点目录[root@web01 ~]# mkdir -p /opt/module/ssl# 创建站点 index.html[root@web01 ~]# echo \"index\" > /opt/module/ssl/index.html
  4. 创建站点配置文件

    [root@web01 ~]# vim /etc/nginx/conf.d/ssl.conf
    server { listen 80; server_name ssl.jackmk.cn; return 301 https://ssl.jackmk.cn$request_uri; #rewrite ^(.*)$ https://ssl.jackmk.cn$1 permanent;}server { listen 443 ssl; # ssl on; # 1.15.0 以后被废弃了 server_name ssl.jackmk.cn; root /opt/module/ssl/; # ssl key ssl_certificate /etc/nginx/ssl_keys/ssl.jackmk.cn.pem; ssl_certificate_key /etc/nginx/ssl_keys/ssl.jackmk.cn.key; location / { index index.html; }}
  5. 刷新 Nginx

    [root@web01 ~]# nginx -t[root@web01 ~]# nginx -s reload
  6. 配置 hosts

    192.168.2.104 ssl.jackmk.cn
  7. 访问

    此时如果请求 http://ssl.jackmk.cn 会自动跳转至 http://ssl.jackmk.cn

4)案例四:网站集群 HTTPS 配置

1)部署 web01web02

  1. 创建存放 SSL 证书和私钥的目录

    mkdir -p /etc/nginx/ssl_keys
  2. 创建私钥以及证书

    # 1. 切换目录cd /etc/nginx/ssl_keys# 2. 创建私钥openssl genrsa -out ssl.key 2048# 3. 创建证书openssl req -days 365 -x509 -sha256 -key ssl.key -out ssl.crt
  3. 创建站点

    # 创建站点目录mkdir -p /opt/module/ssl# 创建站点 index.htmlecho \"web01\" > /opt/module/ssl/index.htmlorecho \"web02\" > /opt/module/ssl/index.html
  4. 创建站点配置文件

    如果是 https -> http 那么就不需要配置 ssl keys

    vim /etc/nginx/conf.d/ssl.conf
    server { listen 443 ssl; server_name ssl.cn; root /opt/module/ssl/; # ssl keys ssl_certificate /etc/nginx/ssl_keys/ssl.crt; ssl_certificate_key /etc/nginx/ssl_keys/ssl.key; location / { index index.html; }}
  5. 刷新 Nginx

    nginx -tnginx -s reload

2)部署 lb01

  1. 创建存放 SSL 证书和私钥的目录

    [root@lb01 ~]# mkdir -p /etc/nginx/ssl_keys
  2. 创建私钥以及证书

    # 1. 切换目录[root@lb01 ~]# cd /etc/nginx/ssl_keys# 2. 创建私钥[root@lb01 ssl_keys]# openssl genrsa -out ssl.key 2048# 3. 创建证书[root@lb01 ssl_keys]# openssl req -days 365 -x509 -sha256 -key ssl.key -out ssl.crt
  3. 创建配置文件

    [root@lb01 ~]# vim /etc/nginx/conf.d/ssl.conf
    upstream ssl_pools { server 192.168.2.104:443; server 192.168.2.105:443;}server { listen 80; server_name ssl.cn; return 301 https://ssl.cn$request_uri;}server { listen 443 ssl; server_name ssl.cn; # ssl keys ssl_certificate /etc/nginx/ssl_keys/ssl.crt; ssl_certificate_key /etc/nginx/ssl_keys/ssl.key; location / { proxy_pass https://ssl_pools; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-Ip $remote_addr; }}
  4. 刷新 Nginx

    [root@lb01 ~]# nginx -t[root@lb01 ~]# nginx -s reload
  5. 配置 hosts

    192.168.2.102 ssl.cn
  6. 访问

    深入理解HTTPS:从概念到实战优化


五:优化

主要是针对 SSL/TLS 加密连接做了一些安全和性能优化。

  • listen 443 ssl

    • 作用:开启 HTTPS 服务,监听 443 端口,并启用 SSL 模块。(没有这行,就算配了证书也不会启用 HTTPS)
  • keepalive_timeout 70

    • 作用:设置 长连接保持时间为 70 秒。

    • 好处

      • 客户端和服务端之间如果频繁请求(比如网页加载很多小文件),可以复用连接,减少握手开销。

      • 设置过短会导致频繁握手,过长又会占用资源。70s 算是折中优化。

  • ssl_protocols TLSv1 TLSv1.1 TLSv1.2

    • 作用:指定允许使用的 TLS 协议版本。

    • 这里启用了 TLSv1、TLSv1.1、TLSv1.2,但注意:

      • TLSv1 和 TLSv1.1 已过时(安全性差),现代浏览器和安全规范(如 PCI DSS)都建议关闭。
      • 最佳实践是只保留 TLSv1.2+,甚至启用 TLSv1.3(性能更好)
      ssl_protocols TLSv1.2 TLSv1.3;
  • ssl_ciphers ...

    • 作用:指定允许使用的加密算法套件。
    • 配置里显式排除了:
      • !aNULL → 禁止匿名算法
      • !eNULL → 禁止无加密算法
      • !EXPORT → 禁止出口级弱加密
      • !DES!RC4!MD5 → 禁止已知不安全的算法
  • ssl_certificate / ssl_certificate_key

    • 作用:指定服务器证书和私钥。
    • cert.pem → 公钥证书
    • cert.key → 对应的私钥
  • ssl_session_cache shared:SSL:10m

    • 作用:配置 SSL 会话缓存。Nginx 在 10MB 的共享内存里存储 SSL 会话信息。
    • 好处
      • 客户端下次访问时可以复用会话,不必重新完整握手(节省 CPU 和握手延迟)。
      • 10MB 大约能缓存 4 万次会话(每个会话约 256B)。
  • ssl_session_timeout 10m

    • 作用:设置 SSL 会话的过期时间(10 分钟)。
    • 好处:在这段时间内,同一个客户端可以复用 TLS 会话,避免再次握手,提高性能。
server { listen 443 ssl; keepalive_timeout 70; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5; ssl_certificate /usr/local/nginx/conf/cert.pem; ssl_certificate_key /usr/local/nginx/conf/cert.key; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ...}

六:监控

主要针对 HTTPS 证书过期监控方案整理

1)监控思路

  • 通过命令获取证书的过期日期
  • 将证书过期日期与当前日期对比
  • 计算剩余天数(如小于 30 天报警)

2)监控方式

  • 本地证书检查

    • openssl x509:调用 opensslx509 子命令,主要用于 查看、转换、管理 X.509 证书
    • -in :指定输入文件,也就是要读取的证书文件。
    • -noout:默认 openssl x509 会把证书的所有内容(包括公钥、签发者、使用者等)都打印出来。 加了 -noout 表示 不要输出证书本身的 Base64 内容,只输出你后面指定的信息。
    • -dates:输出证书的有效期信息:
    openssl x509 -in /etc/nginx/ssl_keys/ssl.crt -noout -dates
    notBefore=Aug 22 16:52:34 2025 GMT # 证书开始生效的时间notAfter=Aug 22 16:52:34 2026 GMT # 证书过期的时间
  • curl 远程监控

    curl -Lv https://www.baidu.com |& grep \'expire date\'

3)监控脚本

  • 检查单个指定的网站的 HTTPS 证书过期时间

    vim check_https_cert.shchmod 755 check_https_cert.sh
    #!/bin/bash#=============================# 1. 基础变量# URL: 定义指定的网站# LANG: 临时改为英文环境,避免 date 解析报错#=============================URL=\"https://www.jd.com\"export LANG=\"en_US.UTF-8\"#=============================# 2. 获取证书过期时间戳# curl -Lv:显示详细信息并跟随重定向# egrep \'expire date\':提取证书过期时间#=============================EXPIRE_DATE_RAW=$(curl -Lv \"${URL}\" -o /dev/null 2>&1 | grep -i \'expire date\' | awk -F \'date:|GMT\' \'{print $2}\')EXPIRE_SECOND=$(date -d \"${EXPIRE_DATE_RAW}\" +%s)#=============================# 3. 获取当前时间戳#=============================NOW_SECOND=$(date +%s)#=============================# 4. 计算剩余天数#=============================EXPIRE_DAYS=$(( (EXPIRE_SECOND - NOW_SECOND) / 86400 ))#=============================# 5. 输出结果#=============================if [ \"${EXPIRE_DAYS}\" -le 300 ]; then echo \"[警告] ${URL} 的 HTTPS 证书即将过期,还有 ${EXPIRE_DAYS} 天\"else echo \"[正常] ${URL} 的 HTTPS 证书还剩 ${EXPIRE_DAYS} 天\"fi
  • 检查多个指定网站的HTTPS 证书过期时间

    vim check_https_cert.shchmod 755 check_https_cert.sh
    #!/bin/bash#=============================# 1. 基础变量# LANG: 临时改为英文环境,避免 date 解析报错# URLS: 定义要检测的多个网站#=============================URLS=(\"https://www.jd.com\" \"https://www.baidu.com\" \"https://www.taobao.com\")export LANG=\"en_US.UTF-8\"#=============================# 2. 遍历检测每个 URL 的证书有效期#=============================for URL in \"${URLS[@]}\"; do # 2.1 获取证书过期时间(原始格式) EXPIRE_DATE_RAW=$(curl -Lv \"${URL}\" -o /dev/null 2>&1 | grep -i \'expire date\' | awk -F \'date:|GMT\' \'{print $2}\') # 2.2 转换为时间戳 EXPIRE_SECOND=$(date -d \"${EXPIRE_DATE_RAW}\" +%s) # 2.3 当前时间戳 NOW_SECOND=$(date +%s) # 2.4 计算剩余天数 EXPIRE_DAYS=$(( (EXPIRE_SECOND - NOW_SECOND) / 86400 )) #============================= # 3. 输出结果 #============================= if [ \"${EXPIRE_DAYS}\" -le 300 ]; then echo \"[警告] ${URL} 的 HTTPS 证书即将过期,还有 ${EXPIRE_DAYS} 天\" else echo \"[正常] ${URL} 的 HTTPS 证书还剩 ${EXPIRE_DAYS} 天\" fidone

总结

本文从理论到实践,详细阐述了HTTPS如何为HTTP协议提供加密、认证和完整性保护,从而构筑现代Web安全的核心防线。我们不仅剖析了TLS握手的工作流程,动手创建了自签名证书,更通过多个渐进式的实战案例(单点HTTPS/HTTP2、重定向、集群配置)展示了如何在复杂的生产环境中应用它。

  • 💎 核心价值:HTTPS已不再是可选项,而是现代网站的标配。它保护用户隐私、提升网站信誉(浏览器安全标识🔒)、同时也是使用HTTP/2等现代协议的前提条件。

  • ⚙️ 实践意义:本文提供的案例和优化、监控方案,源自于真实的运维场景。正确地配置HTTPS(如选择安全的密码套件、开启HSTS、配置重定向)和建立有效的监控(如证书过期监控),是保障服务稳定性和安全性的关键。

  • 🔮 未来方向:安全是一个持续的过程。TLS协议版本和推荐的加密套件也在不断更新以应对新的威胁。自动化(如使用Let’s Encrypt自动续期证书)和更严格的安全策略(如预加载HSTS)是未来的发展趋势。