OpenSSL快速生成域名证书:含SAN的自签命令、验证与排错

给测试环境、内网系统或还没排上 CA 的域名配 HTTPS,最顺手的招是 openssl 自签证书:一条命令、两个文件。但"生成成功"不等于"浏览器不报错"------Safari 可能提示"证书名称与输入不匹配",Chrome 可能说证书无效。这篇一次讲清生成与"为什么生成完还不生效"。

四步固定顺序:生成、自查、试用、排错;跳步的代价是拿着本地文件猜半天。

一、先定边界:快速生成的是自签证书

公开受信任的证书只能由 CA 签发,浏览器只信任内置根证书库。自签证书密码学上完全可用,但不在任何浏览器的信任列表里------公开站点访客必见警告,这就是它的边界。适用范围:测试环境、内网服务、客户端会手动导入信任的场景。要"零警告",只有 CA 签发一条路。

二、一条命令:生成含 SAN 的自签域名证书

OpenSSL 1.1.1 及之后可直接用 -addext 写入 SAN:

bash 复制代码
openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout example.com.key -out example.com.crt \
  -days 365 \
  -subj "/CN=example.com" \
  -addext "subjectAltName=DNS:example.com,DNS:www.example.com,IP:192.0.2.10"

-x509 输出自签证书而非 CSR;-newkey 现场生成密钥对;-nodes 私钥不加密(记得 chmod 600);-days 是有效期;SAN 写在 -addext 里。

执行后得到 .key 与 .crt;证书的 SAN 列全了三个名字(两枚 DNS 加一个 IP),这就是后续校验的依据。

三、生成完先自查:名称、期限、私钥配对

别急着部署,先核对材料本身:

bash 复制代码
# 看主题、有效期和 SAN
openssl x509 -in example.com.crt -noout -subject -dates -ext subjectAltName

# 配对校验:两个指纹必须一致
openssl x509 -in example.com.crt -noout -pubkey | openssl sha256
openssl pkey -in example.com.key -pubout | openssl sha256

第一条输出三块:subject、dates、SAN------对照要访问的主机名,缺谁补谁。第二条是常被漏掉的配对校验:两行 sha256 一致,说明证书与私钥是同一对。

四、为什么只写 CN 会"名称不匹配"

CN 曾是浏览器校验域名的唯一字段,现在反过来了:RFC 9525 规定服务器身份只能写在 subjectAltName 里,CN-ID 已失效------现代浏览器执行的就是这条规则。

于是有最常见的坑:-subj 没问题、少了 -addext,证书没有 SAN------名称校验直接失败。Safari 证书面板给出"证书名称与输入不匹配"(Certificate name does not match input),Chrome 报 NET::ERR_CERT_COMMON_NAME_INVALID。

两个细节:CN 不能带协议前缀(https://example.com 是错的),也不建议写 IP。

五、多域名、通配符、IP:SAN 的正确写法

SAN 是逗号分隔清单,每项带类型前缀 DNS: 或 IP::

bash 复制代码
# 多域名 + 通配符 + IP 的完整写法
-addext "subjectAltName=DNS:example.com,DNS:www.example.com,DNS:*.example.com,IP:192.0.2.10"

三条规则:通配符只能占最左侧完整标签------*.example.com 不匹配 a.b.example.com,也不匹配裸的 example.com,根域要单列;用 IP 访问就把 IP 以 IP: 前缀写进 SAN;SAN 只写主机名,不带端口、路径、协议头。

六、旧版 OpenSSL:配置文件法同样一条命令

CentOS 7 自带的 OpenSSL 1.0.2 没有 -addext,改用配置文件:

ini 复制代码
# san.cnf
[req]
distinguished_name = dn
x509_extensions = v3_req
prompt = no
[dn]
CN = example.com
[v3_req]
subjectAltName = @alt
[alt]
DNS.1 = example.com
DNS.2 = www.example.com
bash 复制代码
openssl req -x509 -newkey rsa:2048 -nodes -days 365 \
  -keyout example.com.key -out example.com.crt \
  -config san.cnf

结果与命令行法等效。注意别漏写 x509_extensions 那行,否则 SAN 会悄悄丢失;生成后照旧自查。

七、放到服务里试用:读回"实际发出的证书"

材料无误后挂到服务上试,以 Nginx 为例:

nginx 复制代码
server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate     /etc/nginx/certs/example.com.crt;
    ssl_certificate_key /etc/nginx/certs/example.com.key;
}

nginx -t 通过再 reload,然后读回实际发出的证书:

bash 复制代码
openssl s_client -connect 127.0.0.1:443 -servername example.com /dev/null \
  | openssl x509 -noout -subject -ext subjectAltName

排查名称不匹配,第一步永远是先读回"实发证书",再和本地对照。没有 Nginx 也能自测:s_server 挂证书、s_client 连回环。

八、生成成功但浏览器仍报错:典型场景对照

现象 常见原因 快速验证 处理方向
证书名称与输入不匹配 / ERR_CERT_COMMON_NAME_INVALID SAN 缺失或不含访问主机名 x509 -ext subjectAltName 对照地址栏 补齐 SAN 后重签
证书不受信任 / 未知颁发者 自签证书不在信任库(预期) 看颁发者是否为自己 导入信任或换 CA 证书
同一 IP 多站点返回别人的证书 未发送 SNI,默认站点抢先应答 s_client 带 -servername 对比 修 server_name 与默认站点
用 IP 访问报名称错误 SAN 无 IP 条目 看 SAN 是否含 IP: 补 IP: 条目重签或改用域名

"证书名称与输入不匹配"是 Safari 对名称校验失败的说明:看 SAN、对照地址栏、缺谁补谁。第二行是自签的预期行为,不是配置错误。最后一行常被误判成"装错证书":同 IP 多站点未发 SNI 时默认站点抢先应答。

九、验收清单

  • openssl version ≥ 1.1.1 或配置文件法等效;
  • 生成命令含 SAN,覆盖根域、www、通配、IP;
  • x509 -ext subjectAltName 与访问地址逐一对上;
  • 证书与私钥公钥指纹一致;
  • nginx -t 通过再 reload,s_client 读回实发证书;
  • 名称校验不报错;"不受信任"视为自签预期;
  • 私钥权限 600,不进 git。

自签解决加密和名称,解决不了信任。把 SAN 写全、把实发证书读回,是成本最低的两个动作。

官方参考:OpenSSL req 文档(-addext)RFC 9525 服务身份与 SANssl.com:Common Name 与 SAN

相关推荐
2501_916008893 小时前
SSE 和 gRPC 流式接口如何抓包,调试 SSE 与 gRPC 流式接口
网络协议·计算机网络·网络安全·ios·adb·https·udp
其实防守也摸鱼3 小时前
堆叠注入(Stacked Injection)详解
服务器·数据库·windows·https·ssl
小小的木头人1 天前
CentOS 7 下 Nginx 访问自定义目录报 403 的完整排查:从端口权限到 SELinux
nginx·centos
新时代农民工~1 天前
【双机高可用部署方案-前后端部署】
java·nginx·springboot
运维全栈笔记1 天前
Nginx 模块化多业务站点通用配置模板
linux·运维·nginx
蓝胖的四次元口袋2 天前
Docker Compose多容器编排与Nginx集群实战
运维·nginx·docker compose
师傅别念了2 天前
Nginx 反向代理配置指南,看完这篇就够了
nginx
2501_915909062 天前
怎么用 FlutterFlow 把应用发布到 App Store?
android·ios·小程序·https·uni-app·iphone·webview
2501_916008893 天前
全平台抓包工具,Windows、iPhone、Linux三个平台抓包测试
网络协议·计算机网络·网络安全·ios·adb·https·udp