Nginx自签名-OpenSSL

一、引言:超越简单的"一键生成"

在开发和测试环境中,我们经常需要 HTTPS。openssl req -x509 ... 这条命令确实能快速生成一个自签名证书,但它有局限性:

  • 无法支持多个域名或IP
  • 浏览器警告难以彻底消除,因为它是"自签"的,没有信任链。

本文将带你深入 OpenSSL 的世界,模拟一个私有 CA(证书颁发机构),为你自己的服务器签发证书。这种方式不仅能让你完全掌控证书内容,还能通过安装根证书一劳永逸地解决浏览器信任问题,是更专业、更灵活的做法。

💡 核心价值

掌握基于私有 CA 的自签名流程,是构建可信赖内网 HTTPS 环境的终极方案


二、核心概念:理解 PKI 信任链

在动手之前,先搞懂几个关键名词:

  • CA (Certificate Authority): 证书颁发机构,如 Let's Encrypt、DigiCert。它们是互联网的"公证处"。
  • Root CA Certificate: 根证书。这是信任的起点。操作系统和浏览器内置了数百个公共 CA 的根证书。
  • Private Key (.key): 私钥。必须严格保密,用于解密和签名。
  • CSR (Certificate Signing Request): 证书签名请求。包含公钥和你的身份信息(如域名),发送给 CA 请求签名。
  • Signed Certificate (.crt/.pem): 由 CA 签名后的证书。它证明了"这个公钥确实属于这个域名"。

我们的目标 :自己扮演 CA 的角色,创建一个私有的 Root CA,然后用它来签署我们 Nginx 服务器的证书。


三、实战:使用 OpenSSL 搭建私有 CA 并签发证书

步骤 1:准备工作

创建一个干净的工作目录,并进入:

bash 复制代码
mkdir ~/ssl-ca && cd ~/ssl-ca

步骤 2:创建私有 CA

2.1 生成 CA 的私钥 (ca.key)
bash 复制代码
# 生成一个 4096 位的 RSA 私钥,不加密(-nodes)
openssl genrsa -out ca.key 4096
2.2 生成 CA 的自签名根证书 (ca.crt)
bash 复制代码
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt \
    -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=My Internal Root CA"
  • -days 3650: 设置一个很长的有效期(10年)。
  • -subj: 直接在命令行指定证书主题信息,避免交互式输入。
    • C: 国家 (Country)
    • ST: 省/州 (State)
    • L: 城市 (Locality)
    • O: 组织 (Organization)
    • CN: 通用名称 (Common Name),这里是 CA 的名字。

现在,你拥有了自己的"公安部"(ca.keyca.crt)。

步骤 3:为 Nginx 服务器签发证书

3.1 生成服务器的私钥 (server.key)
bash 复制代码
openssl genrsa -out server.key 2048
3.2 创建服务器的 CSR (server.csr)

这是最关键的一步,我们需要在 CSR 中声明服务器的身份。

bash 复制代码
# 如果你只用一个域名
openssl req -new -key server.key -out server.csr \
    -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=your-domain.local"

# 如果你需要支持多个域名或IP(推荐方式)

为了支持多个域名/IP,我们需要一个扩展配置文件 。创建 v3.ext 文件:

复制代码
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = your-domain.local
DNS.2 = www.your-domain.local
IP.1 = 192.168.1.100
IP.2 = 127.0.0.1

在这个文件中,你可以添加任意多的 DNS.x(域名)和 IP.x(IP地址)。

然后,使用这个扩展文件生成 CSR:

bash 复制代码
openssl req -new -key server.key -out server.csr -config v3.ext -extensions v3_req
3.3 使用你的私有 CA 签署服务器证书 (server.crt)
bash 复制代码
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
    -out server.crt -days 365 -sha256 -extfile v3.ext
  • -CAcreateserial: 为 CA 创建一个序列号文件 (ca.srl),用于跟踪签发的证书。
  • -extfile v3.ext: 应用我们之前定义的扩展,使证书支持多域名/IP。

至此,我们得到了 Nginx 所需的两个文件:server.key(私钥)和 server.crt(由我们私有 CA 签名的证书)。


四、配置 Nginx

将生成的 server.keyserver.crt 复制到 Nginx 的配置目录下,例如 /etc/nginx/ssl/

bash 复制代码
sudo mkdir -p /etc/nginx/ssl
sudo cp server.key server.crt /etc/nginx/ssl/

编辑你的 Nginx 站点配置文件:

复制代码
server {
    listen 443 ssl http2;
    server_name your-domain.local; # 与证书中的 CN 或 SAN 一致

    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;

    # 基础安全设置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    root /var/www/html;
    index index.html;
    location / {
        try_files $uri $uri/ =404;
    }
}

# 强制 HTTP 跳转 HTTPS
server {
    listen 80;
    server_name your-domain.local;
    return 301 https://$host$request_uri;
}

重载 Nginx 配置:

bash 复制代码
sudo nginx -t && sudo systemctl reload nginx

五、建立信任:安装根证书

现在访问 https://your-domain.local,浏览器依然会报错,但错误信息会变成"此网站的安全证书存在问题",而不是"您的连接不是私密连接"。这是因为浏览器不认识你的私有 CA。

解决方案 :将你的 ca.crt(根证书)安装到客户端的信任库中。

在 Windows 上

  1. ca.crt 文件复制到 Windows 电脑。
  2. 双击 ca.crt -> "安装证书" -> "本地计算机" -> "将所有证书放入下列存储" -> "受信任的根证书颁发机构" -> 完成。

在 macOS 上

  1. 双击 ca.crt,它会自动在"钥匙串访问"中打开。
  2. 在左侧选择"系统"钥匙串。
  3. 找到刚导入的 "My Internal Root CA",双击打开。
  4. 展开"信任"部分,将"使用此证书时"设置为"始终信任"。

在 Linux (Ubuntu) 上

bash 复制代码
sudo cp ca.crt /usr/local/share/ca-certificates/my-root-ca.crt
sudo update-ca-certificates

效果:安装完成后,刷新浏览器,你会发现地址栏出现了灰色的锁图标!浏览器现在完全信任由你的私有 CA 签发的所有证书了。


六、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

相关推荐
ping某14 小时前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质2 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工3 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智3 天前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_3 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
施努卡机器视觉3 天前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造
程序猿阿伟3 天前
《Chrome离线扩展安装的底层逻辑与场景落地指南》
服务器·网络·chrome
之歆3 天前
现代 HTTP 客户端深度解析:Fetch 与 Axios
chrome·网络协议·http