证书这块最容易踩的坑不是「怎么签」,而是「选错类型」。先按场景选路线,再照抄命令。
一、选型对照表
| 场景 | 推荐方案 | 浏览器是否告警 | 有效期 |
|---|---|---|---|
| 公网站点 | 云厂商免费 DV 证书 / Let’s Encrypt | 否 | 90 天(建议自动续期) |
| 内网服务、私有仓库 | 自建 CA + 签站点证书 | 是(需手动信任 CA) | 自定义,通常 1–10 年 |
| 本地开发 | mkcert | 否(自动装根证书) | 自定义 |
| 测试环境批量域名/IP | minica | 是(需手动信任 CA) | 自定义 |
| 快速自签(一次性) | openssl x509 一步签 | 是 | 自定义 |
关键判断点:是否需要被公共信任。只要不是公网用户访问,自建 CA 就够了,不必花时间接 ACME。
二、公网站点:免费证书 + 自动续期
国内云厂商(阿里云、腾讯云等)都提供免费 DV 证书,控制台申请后下载 Nginx 格式即可:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.pem;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
}
配合强制跳转(详见 Nginx 实用配置片段):
server {
listen 80 default_server;
server_name example.com;
return 301 https://$host$request_uri;
}
三、内网服务:自建 CA 签站点证书
适合私有仓库、内部管理后台这类场景,完整八步见 准备站点证书,核心链路是:
# 1. CA 私钥 + 根证书
openssl genrsa -out root-ca.key 4096
openssl req -new -x509 -days 3650 -key root-ca.key -out root-ca.crt
# 2. 站点私钥 + CSR
openssl genrsa -out site.key 4096
openssl req -new -key site.key -out site.csr -sha256 -subj '/CN=your.domain.com'
# 3. 用 CA 签发(注意 SAN 要写全域名和 IP)
openssl x509 -req -days 750 -in site.csr -sha256 \
-CA root-ca.crt -CAkey root-ca.key -CAcreateserial \
-out site.crt -extfile site.cnf -extensions server
site.cnf 里的 SAN 是重点,漏写会导致现代浏览器报 NET::ERR_CERT_COMMON_NAME_INVALID:
[server]
authorityKeyIdentifier=keyid,issuer
basicConstraints = critical,CA:FALSE
extendedKeyUsage=serverAuth
keyUsage = critical, digitalSignature, keyEncipherment
subjectAltName = DNS:your.domain.com, IP:127.0.0.1
subjectKeyIdentifier=hash
四、本地开发:mkcert
一条命令搞定,根证书自动进系统信任库:
brew install mkcert
mkcert -key-file key.pem -cert-file cert.pem example.com *.example.com
五、批量域名/IP:minica
go install github.com/jsha/minica@latest
minica -ca-cert ca-cert.pem -ca-key ca-key.pem --domains "a.example.com,b.example.com"
minica -ca-cert ca-cert.pem -ca-key ca-key.pem --ip-addresses "127.0.0.1"
六、让客户端信任自签 CA
| 系统 | 做法 |
|---|---|
| Linux | 拷到 /usr/local/share/ca-certificates/ 后 update-ca-certificates |
| macOS | 钥匙串访问导入,设为「始终信任」 |
| Docker | 拷到 /etc/docker/certs.d/<host>/ca.crt 后重启 docker |
| Java | keytool -import -trustcacerts -keystore $JAVA_HOME/lib/security/cacerts -file root-ca.crt |
七、验收清单
-
openssl x509 -in site.crt -text -noout能看到正确的 CN 与 SAN - 私钥与证书匹配:
openssl x509 -noout -modulus -in site.crt | openssl md5与openssl rsa -noout -modulus -in site.key | openssl md5一致 -
nginx -t通过,https://访问无证书告警 - 非标准端口场景已配
error_page 497 - 证书到期前有续期提醒(自签证书建议记入运维日历)