使用Nginx中配置CRL

在Nginx中配置证书吊销列表(CRL, Certificate Revocation List)主要用于‌双向 TLS 认证(mTLS)‌场景,以验证客户端证书是否已被证书颁发机构(CA)吊销。

以下是完整的配置指南、格式要求及自动化更新方案。

1. 核心前提与注意事项

  • ‌仅用于客户端验证‌:ssl_crl 指令仅在校验‌客户端证书‌时生效,必须配合 ssl_verify_client on 使用。它‌不‌用于检查 Nginx 自身服务器证书的吊销状态(服务器证书吊销请使用 OCSP Stapling)。
  • 格式要求‌:Nginx 仅支持 ‌PEM 格式‌的 CRL 文件。如果 CA 提供的是 DER 格式,必须转换。
  • 有效期检查‌:CRL 文件包含 Next Update 字段。如果当前时间超过该时间,Nginx 将认为 CRL 过期并拒绝加载或报错。因此必须定期更新。
  • 证书链完整性‌:如果客户端证书由中间 CA 签发,CRL 文件通常需要包含根 CA 和所有相关中间 CA 的吊销列表合并后的内容,或者启用 ssl_crl_check all(Nginx 1.19.4+)来检查整条链。

2. CRL文件准备

  • 2.1 获取 CRL

    从 CA 提供的"CRL 分发点(CRL Distribution Points)"URL 下载 CRL 文件。通常可以通过浏览器访问该 URL 或使用 wget/curl 下载。

  • 2.2 格式转换(DER 转 PEM)

    大多数 CA 发布的 CRL 默认为 DER 二进制格式,需转换为 PEM 文本格式:

    shell 复制代码
    openssl crl -inform DER -in ca.crl.der -outform PEM -out ca.crl.pem
  • 2.3 合并多个 CRL(如有必要)

    如果证书链涉及根 CA 和中间 CA,且它们分别发布 CRL,需要将它们合并到一个文件中:

    shell 复制代码
    cat root-ca.crl.pem intermediate-ca.crl.pem > combined.crl.pem
  • 2.4 权限设置

    确保 Nginx 工作进程用户(如 www-data 或 nginx)有读取权限:

    shell 复制代码
    chmod 644 /etc/nginx/ssl/ca.crl.pem
    chown root:root /etc/nginx/ssl/ca.crl.pem # 根据实际运行用户调整

3. Nginx 配置示例

在 nginx.conf 的 http 块或具体的 server 块中添加以下配置:

shell 复制代码
server {
    listen 443 ssl;
    server_name example.com;

    # 服务器自身的证书和私钥
    ssl_certificate     /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;

    # --- 双向认证与 CRL 配置开始 ---

    # 1. 指定信任的 CA 证书(用于验证客户端证书签名)
    # 必须包含签发客户端证书的根 CA 和中间 CA 公钥
    ssl_client_certificate /etc/nginx/ssl/ca-bundle.pem;

    # 2. 启用客户端证书验证
    # on: 强制要求客户端提供证书;optional: 可选提供
    ssl_verify_client on;

    # 3. 指定 CRL 文件路径(必须是绝对路径,PEM格式)
    ssl_crl /etc/nginx/ssl/ca.crl.pem;

    # 4. (可选) 设置验证深度
    # 默认为1。如果客户端证书经过中间CA签发,建议设置为2或更大
    ssl_verify_depth 2;

    # 5. (可选, Nginx 1.19.4+) 检查证书链中所有层级的吊销状态
    # 默认只检查叶子节点(客户端证书),启用all可检查中间CA是否也被吊销
    # ssl_crl_check all;

    # --- 双向认证与 CRL 配置结束 ---

    location / {
        root   /usr/share/nginx/html;
        index  index.html;

        # 可选:根据验证结果返回不同信息
        # $ssl_client_verify 变量值: SUCCESS, FAILED, NONE
        add_header X-Client-Verify $ssl_client_verify;
    }
}

4. 自动化更新 CRL

由于 CRL 有过期时间,必须定期更新。Nginx 不会自动联网拉取最新的 CRL,需通过脚本 + Cron 实现。

  • 4.1 创建更新脚本 (update_crl.sh)

    shell 复制代码
    #!/bin/bash
    
    # 配置变量
    CRL_URL="http://ca.example.com/intermediate.crl" # 替换为实际的CRL分发点URL
    CRL_FILE="/etc/nginx/ssl/ca.crl.pem"
    TEMP_FILE="/tmp/ca.crl.tmp"
    NGINX_USER="www-data" # 替换为你的nginx运行用户
    
    # 1. 下载最新的 CRL (假设是DER格式,如果是PEM则去掉转换步骤)
    wget -q -O /tmp/ca.crl.der "$CRL_URL"
    if [ $? -ne 0 ]; then
        echo "Failed to download CRL"
        exit 1
    fi
    
    # 2. 转换为 PEM 格式
    openssl crl -inform DER -in /tmp/ca.crl.der -outform PEM -out "$TEMP_FILE"
    if [ $? -ne 0 ]; then
        echo "Failed to convert CRL format"
        exit 1
    fi
    
    # 3. 验证 CRL 是否过期 (可选但推荐)
    NEXT_UPDATE=$(openssl crl -in "$TEMP_FILE" -noout -nextupdate | cut -d= -f2)
    if [ -z "$NEXT_UPDATE" ]; then
        echo "Invalid CRL file"
        exit 1
    fi
    # 简单比较日期,如果过期则不替换
    if [[ $(date -d "$NEXT_UPDATE" +%s) -lt $(date +%s) ]]; then
        echo "CRL is expired, not updating"
        exit 1
    fi
    
    # 4. 原子替换文件 (避免Nginx读取到半写文件)
    mv "$TEMP_FILE" "$CRL_FILE"
    
    # 5. 设置权限
    chown $NGINX_USER:$NGINX_USER "$CRL_FILE"
    chmod 644 "$CRL_FILE"
    
    # 6. 平滑重载 Nginx
    # 注意:对于较新版本的Nginx,如果只是替换文件内容,通常不需要reload,
    # 新的连接握手时会重新读取文件。但为了保险起见或旧版本,建议发送reload信号。
    nginx -s reload
    
    echo "CRL updated successfully"
  • 4.2 设置定时任务 (Cron)

    编辑 crontab (crontab -e),例如每小时更新一次:

    shell 复制代码
    0 * * * * /path/to/update_crl.sh >> /var/log/crl_update.log 2>&1

5. 验证配置

  1. ‌测试配置语法‌:

    shell 复制代码
    nginx -t

    如果 CRL 文件路径错误、格式不对或已过期,这里会报错。

  2. ‌重载 Nginx‌:

    shell 复制代码
    systemctl reload nginx
  3. ‌功能测试‌:

    • ‌有效证书‌:使用未被吊销的客户端证书访问,应正常建立连接。
    • 吊销证书‌:使用已在 CRL 中的客户端证书访问,TLS 握手应失败,客户端通常收到 SSL_ERROR_REVOKED_CERT_ALERT 或 HTTP 400/495 错误。
    • 查看日志‌:检查 /var/log/nginx/error.log,若验证失败,通常会看到类似 client certificate verify error: (XX:certificate revoked) 的记录。
相关推荐
运维全栈笔记7 小时前
Ansible 自动化 Nginx 集群部署实战:动态 Inventory、滚动发布与 Role 工程化
nginx·自动化·ansible
阿标在干嘛1 天前
Nginx一个配置错误,流量损失30%!这是我们的完整排查记录
运维·nginx
IT菜鸟程2 天前
Ubuntu 下 apt 版 Nginx 升级为源码编译版本完整操作指南(1.24.0 → 1.30.4 实战)
linux·nginx·ubuntu
sbjdhjd2 天前
从 7 字符文件名拼接到二维数组取值:PHP 无参函数限制下的受控靶场复盘 | (7字符绕过)
网络·nginx·安全·网络安全·云计算·php·apache
NGINX开源社区2 天前
NGINX Gateway Fabric 2.6:F5 WAF for NGINX 集成 Gateway API
nginx·gateway·fabric
小白羊丨3 天前
HTTP/2 如何缓解 HTTP/1.1 阻塞;长连接对 Nginx 有什么影响?
网络协议·nginx·http
xixiaoyunya3 天前
Docker 容器化部署实战:从零搭建一套完整的 Nginx + Node.js + MySQL + Redis 项目环境
nginx·docker·node.js
SendTomo4 天前
【技术交流】从0到1构建一个汉字学习平台:汉字吧(hanzi8.com)的技术架构猜想
redis·mysql·nginx·php·个人开发
滨哥GPT4 天前
Codex新增文件上传后为什么小文件正常,大文件总失败?Multipart、Body Limit与Nginx限制排查
nginx·ai编程·文件上传·codex·multipart
come112344 天前
Nginx `location` 配置说明(后端开发版)
运维·nginx