游客发表
Nginx 配 SSL 证书,证书最烦的线生不是改配置,是证书等证书。Let's Encrypt 签发要验证域名,线生验证要通外网,证书通外网要改 DNS 或放行 80 端口。线生一套流程走下来,证书十分钟没了。线生如果只是证书临时测试,或者内网环境压根没法做 HTTP 验证,线生这十分钟纯属浪费。证书
用 OpenSSL 自己签一张,线生三十秒搞定。证书浏览器会红,线生但 curl、证书Postman、内部服务调用全都不在乎。下面直接给命令和 Nginx 配置,不绕弯。
先建个目录放证书,别跟系统证书混在一起:
mkdir -p /etc/nginx/ssl && cd /etc/nginx/ssl 一条命令生成私钥和证书,有效期 365 天:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout server.key -out server.crt \ -subj "/C=CN/ST=Beijing/L=Beijing/O=Dev/CN=test.local" 解释几个参数。-x509 表示直接输出自签证书,不走 CSR 流程。-nodes 是不给私钥加密,否则每次 Nginx 启动都要输密码,没法自动化。-subj 填证书主题,CN 写你的域名或 IP。如果是给内网 IP 用,CN 直接写 IP 地址就行,比如 CN=192.168.1.100。
生成完检查一下:
openssl x509 -in server.crt -noout -subject -dates 会输出主题和起止时间。notAfter 那行确认一下,别签了个过期的。
假设你已有 HTTP 站点,现在加 HTTPS。找到 server 块,改或加一个监听 443 的:
server { listen 443 ssl; server_name test.local; 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; location / { root /var/www/html; index index.html; } } ssl_certificate 和 ssl_certificate_key 路径别写错。Nginx 以 nginx 用户运行时,这两个文件得可读。权限建议 chmod 600 server.key,但 owner 要设成 nginx 能读的用户,或者干脆 chmod 644 图省事——反正是自签,泄露了也没人认。
改完配置先测:
nginx -t 输出 syntax is ok 和 test is successful 再 reload:
nginx -s reload 用 curl 测,加 -k 跳过证书校验:
curl -k https://test.local 返回正常内容就通了。如果想看证书细节:
echo | openssl s_client -connect test.local:443 2>/dev/null | openssl x509 -noout -text 几个实际会遇到的问题。Chrome 对自签证书拦截越来越狠,CN 和访问地址不一致直接报 NET::ERR_CERT_COMMON_NAME_INVALID。解决办法是 CN 写 IP 或域名,或者用 -addext 加 SAN 扩展:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout server.key -out server.crt \ -subj "/CN=test.local" \ -addext "subjectAltName=DNS:test.local,IP:127.0.0.1" 另一个坑是 Nginx 版本。老版本(1.15 之前)不支持 listen 443 ssl 这种写法,得写 listen 443 加 ssl on;。现在基本不用管了,但如果你在维护古董系统,记得改。
自签证书适合开发和内网。生产环境还是用 Let's Encrypt 或商业证书,别偷这个懒。浏览器红杠对用户来说就是“这网站有问题”,解释成本比申请证书高得多。
最后提一句,证书文件别提交到 Git。.gitignore 里加一行 *.key,能省掉很多麻烦。
友情链接