从生成自签名证书到配置Nginx:OpenSSL在个人项目与内网服务中的一站式安全实践 从生成自签名证书到配置NginxOpenSSL在个人项目与内网服务中的一站式安全实践在个人项目或内网环境中我们经常需要快速搭建HTTPS服务但又不想依赖第三方证书颁发机构。这时候自签名证书就成了一个简单高效的解决方案。本文将带你从零开始使用OpenSSL生成自签名证书并完整配置Nginx服务实现本地开发环境或内网服务的安全加密访问。1. 为什么选择自签名证书自签名证书虽然不被公共CA机构认可但在以下场景中具有独特优势本地开发环境前端开发人员调试HTTPS接口时内网服务公司内部系统、测试环境等不需要对外公开的服务快速原型验证在项目初期快速搭建安全通信通道特殊设备物联网设备、嵌入式系统等难以申请正规证书的场景与Lets Encrypt等免费证书相比自签名证书的最大特点是完全自主可控不需要依赖外部服务也不受证书有效期限制可以设置很长的有效期。注意自签名证书不适合用于生产环境面向公众的服务浏览器会显示安全警告影响用户体验。2. OpenSSL基础环境准备在开始生成证书前我们需要确保系统已安装OpenSSL。大多数Linux发行版和macOS都预装了OpenSSL可以通过以下命令检查openssl version如果未安装各系统的安装方法如下Ubuntu/Debiansudo apt update sudo apt install opensslCentOS/RHELsudo yum install opensslmacOSbrew install opensslWindows 可以从 OpenSSL官网 下载安装包3. 生成自签名证书的完整流程3.1 创建CA根证书自签名证书体系的核心是建立自己的证书颁发机构(CA)。以下是创建CA的步骤生成CA私钥openssl genrsa -out ca.key 4096创建CA根证书有效期10年openssl req -new -x509 -days 3650 -key ca.key -out ca.crt执行此命令时需要填写一些基本信息Country Name (2 letter code) [AU]:CN State or Province Name (full name) [Some-State]:Beijing Locality Name (eg, city) []:Beijing Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Local CA Organizational Unit Name (eg, section) []:IT Department Common Name (e.g. server FQDN or YOUR name) []:My Local CA Email Address []:adminexample.com3.2 为服务器生成证书有了CA后我们可以为具体服务签发证书生成服务器私钥openssl genrsa -out server.key 2048创建证书签名请求(CSR)openssl req -new -key server.key -out server.csr填写信息时Common Name非常重要应该填写你将要使用该证书的域名或IP地址。创建证书扩展配置文件server.extauthorityKeyIdentifierkeyid,issuer basicConstraintsCA:FALSE keyUsage digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName alt_names [alt_names] DNS.1 localhost IP.1 127.0.0.1提示subjectAltName部分可以根据实际情况添加多个DNS和IP地址。使用CA签发服务器证书有效期1年openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -sha256 -extfile server.ext3.3 证书文件说明现在你应该有以下文件文件用途是否需保密ca.keyCA的私钥是ca.crtCA的根证书否server.key服务器的私钥是server.csr证书签名请求(可删除)否server.crt服务器的证书否4. 配置Nginx使用自签名证书有了证书文件后我们可以配置Nginx启用HTTPS4.1 基本HTTPS配置编辑Nginx配置文件通常在/etc/nginx/sites-available/default或/etc/nginx/conf.d/default.confserver { listen 443 ssl; server_name localhost; ssl_certificate /path/to/server.crt; ssl_certificate_key /path/to/server.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers on; location / { root /var/www/html; index index.html; } }4.2 优化SSL配置为了更好的安全性和性能可以添加以下配置ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_stapling on; ssl_stapling_verify on;4.3 强制HTTPS跳转如果你同时提供HTTP服务可以配置自动跳转到HTTPSserver { listen 80; server_name localhost; return 301 https://$host$request_uri; }配置完成后测试并重新加载Nginxsudo nginx -t sudo systemctl reload nginx5. 客户端信任自签名证书由于自签名证书不被公共CA机构认可我们需要手动将CA根证书导入到客户端信任库中。5.1 在浏览器中信任证书Chrome/Firefox将ca.crt导入到系统的证书存储中标记为信任的根证书颁发机构macOSsudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ca.crtWindows双击ca.crt文件选择安装证书选择本地计算机存储位置选择将所有证书放入下列存储浏览选择受信任的根证书颁发机构5.2 在移动设备上信任证书iOS将ca.crt通过邮件发送到设备点击附件安装在设置-通用-关于-证书信任设置中启用完全信任Android将ca.crt复制到设备在设置-安全-加密与凭据中安装证书6. 高级配置与问题排查6.1 证书链验证使用以下命令验证证书链是否正确openssl verify -CAfile ca.crt server.crt6.2 查看证书详细信息openssl x509 -in server.crt -text -noout6.3 常见问题解决浏览器仍然显示不安全确保客户端已正确安装并信任CA根证书检查证书中的Subject Alternative Name是否包含访问的域名/IPNginx启动失败检查证书和私钥路径是否正确确保Nginx进程有读取证书文件的权限使用nginx -t测试配置文件语法证书过期重新签发新证书考虑设置自动续期提醒7. 自动化脚本示例为了简化流程可以创建一个自动化脚本generate_cert.sh#!/bin/bash # 生成CA openssl genrsa -out ca.key 4096 openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj /CNMy Local CA # 生成服务器证书 openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr -subj /CNlocalhost cat server.ext EOF authorityKeyIdentifierkeyid,issuer basicConstraintsCA:FALSE keyUsage digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName alt_names [alt_names] DNS.1 localhost IP.1 127.0.0.1 EOF openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -sha256 -extfile server.ext # 设置文件权限 chmod 400 ca.key server.key在实际项目中我发现将证书生成过程脚本化可以大大减少人为错误特别是在需要为多个服务生成证书时。一个经验是为不同的环境开发、测试、预发布使用不同的CA这样可以更好地隔离安全边界。