Skip to content

HTTPS 基本原理与证书概念

  • HTTPS 定义
    HTTPS 即 "HTTP over TLS",在 HTTP 协议基础上增加 TLS(或 SSL)加密,确保数据在传输过程中的安全性。
  • 证书作用
    • 公钥证书:用于加密传输中的数据,同时向客户端证明服务器身份。
    • 私钥:配合公钥证书,保证只有持有正确私钥的一方可以解密信息。
  • 证书来源
    • 对外使用:一般需要向认证机构申请或购买,用于网站、APP、小程序等。
    • 对内使用:可以自建证书以节省成本或满足测试需求。

阿里云证书申请

  • 申请流程
    https://yundun.console.aliyun.com/
  • SSL 个人证书--->个人测试证书
  • 重点说明
    申请后的证书文件中包含公钥部分,搭配申请时生成的私钥文件共同使用.

HTTPS 服务配置

HTTPS 的配置一般分为两部分:

  1. HTTP 到 HTTPS 的重定向
    通过监听 80 端口实现将所有 HTTP 请求重定向到 HTTPS,例如:
shell
server {
    listen 80;
    server_name ssl.oldboylinux.cn;
    return 302 https://ssl.oldboylinux.cn$request_uri;
}

解释

- 当用户通过 HTTP 访问时,返回 302 状态码将请求重定向到 HTTPS 地址,保证所有流量均经过加密传输。
  1. HTTPS 全部服务配置
    如下:
shell
# 监听 80 端口的 server 块(处理 HTTP 请求并重定向到 HTTPS)
server {
    # 监听 80 端口,处理 HTTP 请求
    listen 80;

    # 定义服务器名称(域名)
    server_name ssl.oldboylinux.cn;

    # 直接返回 302 重定向,所有 HTTP 请求都会被引导到 HTTPS
    return 302 https://ssl.oldboylinux.cn$request_uri;
}

# 监听 443 端口的 server 块(处理真正的 HTTPS 站点)
server {
    # 监听 443 端口,并启用 SSL
    listen 443 ssl;

    # 定义服务器名称(支持多个域名)
    server_name ssl.oldboylinux.cn lidao.oldboylinux.cn;

    # 配置 SSL 证书文件路径
    ssl_certificate /etc/nginx/keys/ssl.oldboylinux.cn.pem;
    
    # 配置 SSL 证书的私钥文件路径
    ssl_certificate_key /etc/nginx/keys/ssl.oldboylinux.cn.key;

    # 设置网站的根目录,存放网站的静态资源
    root /app/code/ssl;

    # 配置默认的请求处理逻辑
    location / {
        # 设定默认的首页文件
        index index.html;
    }
}

解释

- `listen 443 ssl;`:启用 SSL 的 443 端口。
- `ssl_certificate` 与 `ssl_certificate_key`:指定公钥证书及对应的私钥路径。
- `root` 与 `location`:设定网站根目录及默认首页。

** 后续配置优化内容**

shell
server {
    # 监听 443 端口,并启用 SSL
    listen 443 ssl;

    # 配置 keep-alive(长连接)超时时间,单位:秒
    keepalive_timeout 70;

    # 指定 SSL/TLS 协议的版本(不包括 TLSv1.0,因为不安全)
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;

    # 配置 SSL 加密算法
    ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5;
    # 说明:
    # - `AES128-SHA`, `AES256-SHA` 等是允许使用的安全加密算法
    # - `!aNULL` 排除不安全的 null 加密算法(无身份验证)
    # - `!eNULL` 排除 null 加密算法(不加密)
    # - `!EXPORT` 排除出口级别的弱加密算法
    # - `!DES` 排除旧的 DES 加密算法(56 位密钥强度较弱)
    # - `!RC4` 排除 RC4 加密算法(已被认为不安全)
    # - `!MD5` 排除基于 MD5 的加密(已被认为存在碰撞漏洞)

    # 配置 SSL 证书文件路径(公钥)
    ssl_certificate /usr/local/nginx/conf/cert.pem;

    # 配置 SSL 证书的私钥文件路径
    ssl_certificate_key /usr/local/nginx/conf/cert.key;

    # 设置 HTTPS 会话缓存,分配 10MB 共享内存用于存储 SSL 会话缓存
    ssl_session_cache shared:SSL:10m;
    # 说明:
    # - `shared:SSL:10m` 表示分配 10MB 共享内存,可存储约 40000 个 SSL 会话
    # - 通过缓存 SSL 会话,提高 HTTPS 连接的性能,减少 SSL 握手的次数

    # 设置 SSL 会话超时时间,10 分钟(600 秒)
    ssl_session_timeout 10m;
    # 说明:
    # - 允许客户端在 10 分钟内复用已建立的 SSL 会话,减少重复握手的开销

    ...
}

HTTPS 证书监控

为避免证书过期影响服务,需要对证书有效期进行监控。示例脚本如下:

shell
date_expire=`curl -s -v -o /dev/null https://www.jd.com |& grep 'expire date' | awk -F: '{print $2}'`
date_expire_seconds=`date +%s -d "$date_expire"`
date_now_seconds=`date +%s`
# 计算剩余天数(86400 秒为一天)
days_left=`echo "($date_expire_seconds - $date_now_seconds)/86400" | bc`

解释

  • 通过 curl 获取远程站点(此处示例为 www.jd.com)的证书过期日期;
  • 利用 date 命令将日期转换为时间戳(秒数),并计算当前时间与过期时间的差值,最后转换成天数;
  • 当剩余天数低于预设(如 30 天)时,可以提前提醒或自动更新证书。

集群模式下 HTTPS 配置方案

  • 背景说明
    在多台服务器构成的集群中,HTTPS 证书及配置需要保持一致,以便所有节点使用同一套加密方案。
  • 实现思路
    • 采用统一的证书文件,并通过自动化部署工具同步配置;
    • 可以通过负载均衡器统一管理外部 HTTPS 入口,内部各节点配置为后端服务。

自建证书

对于部分内部或测试环境,可以选择自建证书,相关配置示例如下:

plain
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;

解释

  • ssl_ciphers:设置允许使用的加密算法,同时排除不安全的算法(如 null 算法、MD5 等);
  • ssl_session_cachessl_session_timeout:启用 HTTPS 会话缓存,减少重复协商,提升连接速度。

生成自建证书的命令如下:

plain
# 生成私钥 server.key(采用 IDEA 加密,密钥长度 2048 位)
openssl genrsa -idea -out server.key 2048

# 根据私钥生成自签名证书 server.crt,证书有效期设置较长(此处 36500 天,约 100 年),采用 SHA256 算法,不生成密码保护(-nodes)
openssl req -days 36500 -x509 -sha256 -nodes -newkey rsa:2048 -keyout server.key -out server.crt

解释

  • 第一条命令生成私钥,确保后续生成的证书只有持有该私钥的服务器可以解密。
  • 第二条命令生成自签名证书,适用于测试环境或内部系统,不建议在生产环境中使用自建证书。

感谢阅读,欢迎交流!