nginx配置https的核心前提是已编译--with-http_ssl_module模块,且证书路径正确、私钥无密码、权限严格(私钥600)、使用绝对路径;最小有效配置仅需listen 443 ssl、ssl_certificate和ssl_certificate_key三行,http跳转https须用独立server块监听80端口并return 301。

只要 Nginx 已编译 --with-http_ssl_module,且证书文件路径、权限、格式都正确,配置 HTTPS 就是改几行配置 + 重载服务的事。没这模块、私钥带密码、路径写错、防火墙拦着——这些才是实际卡住人的地方。
确认 Nginx 是否支持 SSL 模块
执行 nginx -V(注意是大写 V),在输出中搜索 --with-http_ssl_module。如果没出现,说明当前 Nginx 不支持 HTTPS,硬配 ssl_certificate 会直接启动失败。
- 不要试图用
nginx -t测试后再重启——没模块时-t就会报错:unknown directive "ssl_certificate" - 若缺失模块,必须重新编译:进入原始源码目录,运行
./configure --prefix=... --with-http_ssl_module,再make && make install - 已安装 OpenSSL 但没装开发包(如
libssl-dev或openssl-devel)会导致 configure 阶段静默跳过 SSL 模块,务必提前装好
证书文件路径与权限设置
证书(.crt 或 .pem)和私钥(.key)必须放在 Nginx 能读取、但不能被普通用户访问的路径下,比如 /etc/nginx/ssl/。
- 私钥文件权限必须是
600:sudo chmod 600 /etc/nginx/ssl/example.com.key,否则 Nginx 启动时报SSL_CTX_use_PrivateKey_file("...") failed - 证书文件权限建议设为
644,但即使可读也不影响安全;关键是私钥绝不能有 group/other 可读位 - 路径中不要用相对路径或波浪号(
~),Nginx 不解析 shell 符号,必须写绝对路径,例如ssl_certificate /etc/nginx/ssl/example.com.crt;
server 块中启用 HTTPS 的最小必要配置
一个能跑通的 HTTPS server 块,核心就三行:监听、证书、私钥。其余 TLS 参数属于加固项,不是启动前提。
-
listen 443 ssl http2;—— 必须带ssl关键字,否则不启用 TLS 握手 -
ssl_certificate /etc/nginx/ssl/example.com.crt;—— 注意是证书文件,不是 CA bundle;若证书链不全(比如缺中间证书),浏览器可能提示“证书不可信”,此时应把中间证书追加到.crt文件末尾 -
ssl_certificate_key /etc/nginx/ssl/example.com.key;—— 私钥必须与证书匹配,且不能加密(即无密码);若生成时用了-des3,需先用openssl rsa -in server.key.org -out server.key去密 - 别在同一个
server块里混用listen 80和ssl_certificate,Nginx 会拒绝加载
HTTP 自动跳转 HTTPS 的安全写法
跳转必须用独立的 server 块监听 80 端口,且里面**不能出现任何 ssl_* 指令**,否则 nginx -t 直接失败。
- 正确写法:
server { listen 80; server_name example.com; return 301 https://$host$request_uri; } - 错误写法:在该块里加
ssl_certificate或ssl on—— 这是新手最常复制粘贴错的地方 - 若域名有多个(如
example.com和www.example.com),server_name要列全,或用泛域名*.example.com(注意泛域名不匹配根域) - 跳转后首次访问若提示“您的连接不是私密连接”,大概率是证书链不完整或域名不匹配,不是跳转配置的问题
真正容易被忽略的是证书链完整性与域名匹配粒度:Let’s Encrypt 的 fullchain.pem 必须当 ssl_certificate 使用,而不是只用 cert.pem;通配符证书 *.example.com 对 example.com 无效,这点在测试环境经常被绕过,上线后才暴露。











