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


六、结语

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

相关推荐
2301_803538952 小时前
CentOS版本差异详解和系统信息查看方法
linux·运维·centos
IT策士2 小时前
第14篇 Docker Compose 开发环境最佳实践:热重载与调试
运维·docker·容器
运维老郭2 小时前
【Kubernetes 性能排查】线上服务突然变慢?SRE 的 4 层排查法
运维·云原生·kubernetes
小此方2 小时前
Re:Linux系统篇(二十四)进程篇·九:进程从创建到退出的底层机制与写时拷贝全解
linux·运维·驱动开发
物联网软硬件开发-轨物科技2 小时前
【轨物方案】告别人工运维痛点!光伏清洁检测一体化机器人,开启电站智能运维新时代
运维·机器人
春日见2 小时前
5分钟入门强化学习之蒙特卡洛(MC)算法与实现
运维·服务器·人工智能·深度学习·算法·机器学习
蜜蜜不吃糖2 小时前
解决Veeam备份数据到Backup copy服务器报错session log违反了检查约束
运维·服务器
艾莉丝努力练剑2 小时前
【Linux网络】Linux 网络编程:传输层TCP(二)
linux·运维·服务器·网络·tcp/ip·计算机网络
都在酒里2 小时前
Linux字符设备驱动开发(九):内核定时器——实现LED周期性闪烁与轮询驱动原理
linux·运维·驱动开发·交互