如何用Nginx配合cfssl自建CA并签发HTTPS证书?

来源:JQuery教程作者:苏沐橙头衔:网络博主
导读:本期聚焦于苏沐橙创作的《如何用Nginx配合cfssl自建CA并签发HTTPS证书?》,敬请观看详情。想给内部环境的Nginx服务启用HTTPS,又不想依赖公共CA或让浏览器反复提示风险,可以通过cfssl构建私有证书体系。cfssl是Cloudflare开源的证书工具链,支持创建根证书、签发中间证书和服务器证书,适合内网、测试环境和微服务通信场景。本文介绍在Linux服务器上安装cfssl,初始化自建CA,生成CA根证书,再为Nginx签发生效的服务器证书,并完成Nginx的HTTPS配置。同时会说明如何把CA证书导入客户端信任库,消除浏览器告警。整个过程无需公网域名验证,也不依赖外部证书服务,完全离线可控。证书有效期、组织名称、SAN扩展等参数都可在JSON配置中精细调整。如果你正在为内部系统寻找一套轻量的证书签发方案,这篇文章可以帮你快速落地。

企业内网或开发测试环境往往需要HTTPS加密,但直接使用OpenSSL生成的自签名证书会在浏览器中显示不可信任警告。更专业的做法是创建一套私有CA,由该CA给Nginx等服务器签发证书,客户端只需信任这一张根证书即可。cfssl是Cloudflare开源的PKI/TLS工具,通过JSON配置文件定义证书请求和签名策略,操作比OpenSSL命令更清晰,适合快速搭建内部证书体系。

如何用Nginx配合cfssl自建CA并签发HTTPS证书?

一、安装cfssl并初始化自建CA

cfssl包含三个常用二进制:cfssl、cfssljson和cfssl-certinfo。可以从GitHub Releases获取对应平台版本,也可以使用包管理器安装。下载后赋予执行权限并放入/usr/local/bin目录。

# 下载二进制文件
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssl_1.6.4_linux_amd64 -O /usr/local/bin/cfssl
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssljson_1.6.4_linux_amd64 -O /usr/local/bin/cfssljson
chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson

安装完成后创建一个工作目录,例如/etc/cfssl,并在其中准备CA请求文件ca-csr.json。该文件定义根证书的CN、组织、加密算法和有效期。

{
  "CN": "Internal Root CA",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "O": "Example Corp",
      "OU": "Security"
    }
  ],
  "ca": {
    "expiry": "87600h"
  }
}

其中ca.expiry为87600小时,约10年。执行cfssl gencert -initca命令生成自签名根证书。

cfssl gencert -initca ca-csr.json | cfssljson -bare ca

该命令输出ca.pem和ca-key.pem。ca.pem是根证书公钥,需要分发给客户端;ca-key.pem是私钥,必须严格保护。建议将私钥权限设置为600,并备份到离线介质。

生成CA后还应创建签名配置文件ca-config.json,它规定了证书用途和有效期策略。cfssl在签发服务器证书时会读取该文件中的profiles。

{
  "signing": {
    "default": {
      "expiry": "8760h"
    },
    "profiles": {
      "server": {
        "expiry": "8760h",
        "usages": ["signing", "key encipherment", "server auth"]
      },
      "client": {
        "expiry": "8760h",
        "usages": ["signing", "key encipherment", "client auth"]
      }
    }
  }
}

server profile用于服务器证书,client profile用于客户端证书。usages中的server auth和client auth是扩展密钥用途,Nginx使用server auth即可。

二、为Nginx签发服务器证书

有了CA后,需要为Nginx域名准备CSR配置文件。假设内网域名是nginx.internal.ippipp.com,IP地址为192.168.0.1,可以在hosts字段中同时写入DNS和IP,确保证书在不同访问方式下均有效。

{
  "CN": "nginx.internal.ippipp.com",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "hosts": [
    "nginx.internal.ippipp.com",
    "192.168.0.1",
    "127.0.0.1"
  ]
}

使用cfssl和ca-config.json中的server profile签发证书,命令如下。

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server-csr.json | cfssljson -bare nginx

执行后会得到nginx.pem和nginx-key.pem。前者包含服务器证书链,后者是私钥。可以通过cfssl-certinfo验证证书信息。

cfssl-certinfo -cert nginx.pem

输出中会显示Subject、Issuer、SAN、有效期等。确认Issuer为自建CA的CN,即Internal Root CA,并且DNS和IP都在SAN列表里。

接下来配置Nginx。将nginx.pem和nginx-key.pem复制到/etc/nginx/ssl目录,然后修改server块。注意ssl_certificate指向包含证书链的文件,ssl_certificate_key指向私钥。

server {
    listen 443 ssl;
    server_name nginx.internal.ippipp.com;

    ssl_certificate     /etc/nginx/ssl/nginx.pem;
    ssl_certificate_key /etc/nginx/ssl/nginx-key.pem;

    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;

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

检查配置并重载Nginx。

nginx -t
systemctl reload nginx

此时如果客户端尚未信任根证书,访问https://nginx.internal.ippipp.com会看到不安全提示,但证书本身已经由私有CA签发。下一步要在客户端导入ca.pem。

三、客户端信任与证书生命周期管理

要让浏览器不再报警,需要把自建CA的根证书添加到客户端的信任存储中。Linux系统可以把ca.pem复制到/usr/local/share/ca-certificates/,然后执行update-ca-certificates。Windows可以双击ca.pem导入受信任的根证书颁发机构,macOS使用钥匙串访问导入并设置为始终信任。

cp ca.pem /usr/local/share/ca-certificates/internal-root-ca.crt
update-ca-certificates

完成导入后重新打开浏览器,访问Nginx服务应当显示正常的锁形图标。如果仍提示证书无效,需要检查证书的SAN是否包含访问用的域名或IP,以及系统时间是否在证书有效期内。

私有CA的证书到期后需要续期。cfssl没有自动续期机制,通常做法是重新生成证书并替换。可以编写脚本调用cfssl gencert,把生成的新证书推送到Nginx并自动reload。根证书到期则需要重新生成CA并重新分发,因此建议把根证书有效期设长,同时将私钥加密存储。

多域名或通配符证书可以通过修改hosts字段实现。例如添加*.internal.ippipp.com可以覆盖所有一级子域名,但要注意通配符不能匹配多级子域名。如果服务数量很多,还可以签发中间CA,由根CA离线保存,中间CA负责日常签发,降低根私钥暴露风险。

四、常见错误与排查思路

证书签发后Nginx启动失败,常见原因是私钥与证书不匹配。可以用openssl x509 -noout -modulus -in nginx.pem和openssl rsa -noout -modulus -in nginx-key.pem对比md5值,二者必须一致。另一个原因是ssl_certificate路径错误或权限不可读,Nginx worker进程需要读取私钥文件,建议将所属用户设置为root并给予600权限。

openssl x509 -noout -modulus -in nginx.pem | openssl md5
openssl rsa -noout -modulus -in nginx-key.pem | openssl md5

如果客户端报告证书颁发者未知,说明客户端未正确信任根证书,或者服务器只发送了叶子证书而没有中间证书。cfssl直接签发的服务器证书中通常已包含CA证书链,但如果使用中间CA则必须拼接完整链。可以使用cat nginx.pem ca.pem > chain.pem命令合并后再配置。

证书SAN不匹配时浏览器会提示存在风险,此时应回到server-csr.json补充全部域名和IP,重新签发。值得注意的是,CN字段已逐渐被浏览器忽略,SAN才是主要校验对象。

最后,自建CA虽然灵活,但私钥管理责任完全在自身。如果根私钥泄露,攻击者可以签发任意证书,必须立即吊销并更换CA。因此线上环境应结合硬件安全模块或加密文件系统存储私钥,并限制服务器物理和网络访问。

cfssl自建CANginx证书修改时间:2026-08-20 08:57:47

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。