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 签发的所有证书了。


六、结语

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

相关推荐
布鲁飞丝10 小时前
vivo Pulsar 万亿级消息处理实践()-Ansible运维部署
运维·ansible
XR12345678810 小时前
企业全光网络架构选型技术白皮书:从物理层到运维层的全链路分析
运维·网络·架构
似的83511 小时前
一步一步学习使用FireMonkey动画() 使用TAnimator类创建动画
linux·学习·nginx
HiDev_11 小时前
【非标自动化】2、认识元器件(直线模组)
运维·自动化
龙仔72512 小时前
人大金仓 KingbaseES V8 只读账号创建完整运维笔记
运维·笔记·sql·人大金仓
我不管我就要叫小猪12 小时前
嵌入式Linux----网络通信
linux·运维·服务器
江湖有缘12 小时前
Docker实战 :使用Docker部署OneTerm堡垒机
运维·docker·容器
lpfasd12313 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
姜太小白13 小时前
【Linux】df -h 卡住问题的通用排查与解决方案总结
linux·运维·php
fengyehongWorld13 小时前
Linux 终端快捷键
linux·运维