Nginx 开启 HTTPS 并不复杂,核心是在虚拟主机配置中监听 443 端口、指定 SSL 证书与私钥文件,并把原来 80 端口的访问平滑迁移或跳转到加密通道。做完这些后,流量在客户端与服务器之间会通过 TLS 握手建立加密连接,防止内容被窃听或篡改。对于已经运行 HTTP 站点的场景,只需要在现有配置基础上增加 SSL 相关指令即可,不必重构整个站点结构。

一、准备SSL证书与私钥文件
启用 HTTPS 前必须先准备好证书文件和对应的私钥。证书可以来自 Let's Encrypt 这类免费 CA,也可以购买商业证书,还可以在测试环境使用 OpenSSL 生成自签名证书。无论哪种方式,最终都需要向 Nginx 提供两个核心文件:一个是包含站点公钥信息的证书文件,另一个是只有服务器自己持有的私钥文件。
以 Let's Encrypt 为例,使用 certbot 申请证书后,通常会得到 fullchain.pem 和 privkey.pem 两个文件。其中 fullchain.pem 包含站点证书和中间证书,能够组成完整证书链,适合直接交给 Nginx;privkey.pem 是对应的私钥。商业证书通常也会提供类似的文件,有时需要把站点证书和中间 CA 证书合并成一个文件。自签名证书则可以用一条 OpenSSL 命令快速生成,适合本地调试。
mkdir -p /etc/nginx/ssl openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/nginx/ssl/ipipp.com.key \ -out /etc/nginx/ssl/ipipp.com.crt \ -subj '/CN=ipipp.com'
证书文件通常可以设置为 644 权限,但私钥文件必须严格限制为 600,避免其他系统用户读取。可以使用 chmod 600 /etc/nginx/ssl/ipipp.com.key 命令收紧权限。正式环境中不要使用自签名证书,因为浏览器会直接提示不受信任,普通用户无法正常访问。
二、配置Nginx的HTTPS server块
准备好证书后,就可以在 Nginx 配置中增加一个监听 443 端口的 server 块。下面是一份基础配置,站点根目录仍指向原来的 Web 目录,但所有请求都会经过 TLS 加密。
server {
listen 443 ssl;
server_name ipipp.com;
ssl_certificate /etc/nginx/ssl/ipipp.com.crt;
ssl_certificate_key /etc/nginx/ssl/ipipp.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
location / {
root /var/www/html;
index index.html;
}
}
这里 listen 443 ssl 表示同时监听 443 端口并启用 SSL 模块。ssl_certificate 指向证书文件,ssl_certificate_key 指向私钥文件。ssl_protocols 只保留 TLSv1.2 和 TLSv1.3,能够避免旧版本 TLS 带来的安全问题。ssl_ciphers 配置了当前较为主流的加密套件,优先使用 ECDHE 前向保密算法。开启 ssl_prefer_server_ciphers 后,服务器会优先选择自己定义的加密套件顺序,减少客户端选择弱算法的可能。
如果站点需要支持 HTTP/2,可以在 listen 指令后追加 http2,例如 listen 443 ssl http2;。不同 Nginx 版本对 http2 的写法略有差异,建议以当前安装版本的官方文档为准。配置完成后先执行 nginx -t 测试语法,再通过 systemctl reload nginx 让配置生效。
三、把HTTP请求强制跳转到HTTPS
仅仅配置 443 端口还不够,如果用户直接访问 http://ipipp.com,Nginx 仍然会以明文方式响应。为了让所有访问都走加密通道,需要为 80 端口配置一个跳转 server 块。比较推荐的做法是返回 301 永久重定向。
server {
listen 80;
server_name ipipp.com;
return 301 https://$host$request_uri;
}
这里 $host 会保留用户访问时使用的域名,$request_uri 会保留原始路径和查询参数,这样跳转后不会丢失用户想访问的具体页面。使用 301 而不是 302 的原因是 301 表示永久移动,搜索引擎会逐渐把权重转移到 HTTPS 版本,对 SEO 更友好。302 则属于临时跳转,通常只在维护或调试时使用。
完成跳转后,如果希望进一步强化安全,可以增加 HSTS 响应头。它的作用是告诉浏览器以后只能通过 HTTPS 访问该域名,即使用户手动输入 http:// 也会被浏览器自动改写为 https://。配置方式如下:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
HSTS 的 max-age 单位为秒,上面的配置表示一年内都强制使用 HTTPS。includeSubDomains 表示对子域名同样生效。建议在确认 HTTPS 稳定运行后再添加 HSTS,否则一旦证书配置出错,用户在有效期内将无法通过 HTTP 访问站点。
四、优化TLS性能与稳定性
HTTPS 会增加一次 TLS 握手过程,如果每次请求都重新协商,会带来一定延迟。Nginx 可以通过会话缓存和 OCSP Stapling 等机制降低握手开销,提升用户访问速度。
ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s;
ssl_session_cache 会分配一块共享内存用于保存 TLS 会话参数,客户端在一定时间内重连时可以复用会话,省去完整的非对称加密计算。shared:SSL:10m 表示分配 10MB 内存,大约可以存储几万个会话。ssl_session_timeout 控制会话的有效时间,10 分钟在安全和性能之间比较平衡。
OCSP Stapling 的作用是由服务器代替客户端向 CA 查询证书吊销状态,并把结果附加在 TLS 握手中返回给客户端。这样浏览器就不必自己发起 OCSP 查询,既能加快握手速度,也能减少对 CA 服务器的请求压力。开启 ssl_stapling_verify 后需要配置 resolver 指向可用的 DNS 服务器,否则验证过程可能超时。
五、验证配置与常见问题排查
修改完配置后,不要直接重启 Nginx,而应该先执行 nginx -t 检查配置文件语法。如果输出 syntax is ok 和 test is successful,再执行 systemctl reload nginx 平滑加载配置。加载成功后,可以用 curl 命令快速验证 HTTPS 是否正常响应。
nginx -t systemctl reload nginx curl -I https://ipipp.com
如果 curl 返回正常的 HTTP/1.1 200 OK 或 301 状态码,说明 HTTPS 服务已经可以被访问。还可以使用 openssl s_client 查看证书链和协议版本,命令如下:
openssl s_client -connect ipipp.com:443 -servername ipipp.com
这条命令会打印出证书信息、协议版本、加密套件等内容。如果出现 unable to verify the first certificate,通常是因为证书链不完整,需要检查 ssl_certificate 是否指向了包含中间证书的 fullchain 文件。如果提示私钥不匹配,可以用下面的命令比对证书和私钥的 modulus 值是否一致。
openssl x509 -noout -modulus -in /etc/nginx/ssl/ipipp.com.crt | openssl md5 openssl rsa -noout -modulus -in /etc/nginx/ssl/ipipp.com.key | openssl md5
两行命令输出的 MD5 值应当完全相同。如果不同,说明证书和私钥不是一对,需要重新生成或重新下载匹配文件。另一个常见问题是 443 端口被防火墙或云安全组拦截,导致外部无法访问,但本机 curl 正常。这种情况需要检查 iptables、firewalld 以及云控制台的安全组规则。私钥文件权限过宽也可能导致 Nginx 启动失败或警告,务必使用 chmod 600 限制私钥权限。

