Nginx配置HTTPS
Nginx 配置 HTTPS 与 WebSocket 实战指南:以 Let’s Encrypt 自动续期为例
摘要:在生产环境中,为多个子域名配置 HTTPS 并支持 WebSocket 长连接是常见需求。本文将基于真实案例,详细讲解如何在阿里云服务器上,使用 Certbot (Let’s Encrypt) 免费证书,为新增子域名
copaw.thoughtly.xyz配置 Nginx 反向代理。文章将涵盖从域名解析、证书申请、Nginx 配置文件编写到 WebSocket 优化的全流程,特别解决了“先申请证书后写配置”的常见场景,并提供可直接复用的配置模板。
一、背景与需求
在之前的架构中,我们已经成功运行了 claw.thoughtly.xyz,它通过 Nginx 反向代理本地 18789 端口,并完美支持 WebSocket 长连接。现在,我们需要部署一个新的服务 copaw,其需求如下:
- 新域名:
copaw.thoughtly.xyz - 后端端口:本地服务运行在
127.0.0.1:8088 - 协议要求:必须启用 HTTPS,且证书需自动续期(免费)。
- 功能依赖:应用强依赖 WebSocket,需确保长连接稳定,不被 Nginx 过早切断。
- 现有环境:服务器已安装 Nginx 和 Certbot,且其他子域名已有成功配置经验。
二、核心操作流程
步骤 1:阿里云域名解析 (DNS)
在配置服务器之前,必须确保域名已指向服务器公网 IP。
- 登录 阿里云控制台 -> 云解析 DNS。
- 找到主域名
thoughtly.xyz,点击 解析设置。 - 添加一条 A 记录:
- 主机记录:
copaw - 记录值:
<您的服务器公网 IP> - TTL:默认(通常 600 秒)
- 主机记录:
- 保存后,可在本地终端使用
ping copaw.thoughtly.xyz验证解析是否生效。
步骤 2:使用 Certbot 申请证书(关键技巧)
很多教程建议“先写配置再运行 Certbot”,但在实际操作中,先运行 Certbot 申请证书,再手动写入配置往往更灵活,尤其是当你需要自定义复杂的 WebSocket 配置时。
2.1 执行申请命令
在服务器终端直接运行:
1 | sudo certbot --nginx -d copaw.thoughtly.xyz |
预期现象与解释:
此时你可能会看到类似以下的提示:
Could not automatically find a matching server block for copaw.thoughtly.xyz.
The certificate was saved, but could not be installed.
不要惊慌!这是正常的。
- 原因:Certbot 的
--nginx插件试图自动修改 Nginx 配置,但它发现你的配置文件中还没有server_name copaw.thoughtly.xyz;这一行,所以它无法自动注入证书路径。 - 结果:虽然自动安装失败,但证书已经成功申请并保存到了
/etc/letsencrypt/live/copaw.thoughtly.xyz/目录下。 - 优势:Certbot 已经自动配置好了后台的定时任务(Systemd Timer 或 Cron),证书将在 90 天后自动续期,无需人工干预。
2.2 确认证书文件
检查证书是否生成成功:
1 | ls -l /etc/letsencrypt/live/copaw.thoughtly.xyz/ |
你应该能看到 fullchain.pem (公钥) 和 privkey.pem (私钥) 两个文件。
步骤 3:编写 Nginx 配置文件
既然证书已就位,现在我们需要手动创建 Nginx 配置,引用这些证书,并配置反向代理规则。
3.1 创建配置文件
根据系统不同,选择以下任一方式:
- Debian/Ubuntu:
sudo nano /etc/nginx/sites-available/copaw.thoughtly.xyz - CentOS/通用:
sudo nano /etc/nginx/conf.d/copaw.thoughtly.xyz.conf
3.2 填入完整配置代码
以下是经过优化的最终配置,包含了 HTTPS 强制跳转、WebSocket 支持 和 长连接超时优化。
1 | server { |
3.3 启用配置 (仅限 Debian/Ubuntu)
如果你使用的是 sites-available 模式,需要建立软链接:
1 | sudo ln -s /etc/nginx/sites-available/copaw.thoughtly.xyz /etc/nginx/sites-enabled/ |
步骤 4:测试与重载
在重启服务前,务必检查语法,防止配置错误导致 Nginx 无法启动。
1 | # 1. 语法测试 |
三、关键技术点解析
1. 为什么 WebSocket 需要特殊配置?
标准的 HTTP 请求是“短连接”,请求结束连接即断开。而 WebSocket 是“长连接”,需要保持 TCP 通道一直打开。
proxy_http_version 1.1:WebSocket 协议升级依赖于 HTTP/1.1,默认的 1.0 不支持。Upgrade和Connection头:这是客户端告诉 Nginx“我要升级协议”的关键信号。如果 Nginx 不透传这两个头给后端,握手就会失败,报错Error during WebSocket handshake: Unexpected response code: 400。
2. 超时时间的重要性
Nginx 默认的 proxy_read_timeout 是 60 秒。如果一个 WebSocket 连接在 60 秒内没有数据传输(例如用户挂机),Nginx 会主动切断连接。
- 解决方案:将
proxy_read_timeout和proxy_send_timeout设置为更大的值(如86400秒),确保长连接不会被误杀。
3. “先证书后配置”的优势
传统的 certbot --nginx 流程会让 Certbot 自动修改配置文件。但这有两个缺点:
- Certbot 生成的配置比较基础,可能不包含 WebSocket 所需的复杂 Header 和超时设置。
- 如果配置文件结构复杂,Certbot 可能会修改出错。
本方案的优势:利用 Certbot 强大的证书申请和自动续期能力,同时保留手动编写配置的灵活性,确保生产环境的绝对可控。
四、验证与运维
1. 验证 HTTPS
浏览器访问 https://copaw.thoughtly.xyz,点击地址栏锁图标,确认:
- 证书有效,颁发者为 Let’s Encrypt。
- 有效期约为 3 个月(Certbot 会自动续期)。
2. 验证 WebSocket
打开浏览器的开发者工具 (F12) -> Network (网络) -> WS。
刷新页面,观察是否有 WebSocket 连接建立:
- Status 应为
101 Switching Protocols。 - 连接应保持稳定,不会在 60 秒后自动断开。
3. 自动续期测试
虽然 Certbot 会自动运行,但我们可以手动测试续期逻辑是否正常:
1 | sudo certbot renew --dry-run |
如果输出 Congratulations, all renewals succeeded,说明自动续期机制工作正常,未来无需人工干预。
五、常见问题排查 (FAQ)
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 502 Bad Gateway | 后端服务未启动或端口错误 | 检查 127.0.0.1:8088 是否有进程监听 (netstat -tlnp | grep 8088) |
| WebSocket 握手失败 (400/426) | 缺少 Upgrade 头配置 |
检查 proxy_set_header Upgrade $http_upgrade; 是否遗漏 |
| 连接每 60 秒断开一次 | 超时时间过短 | 检查 proxy_read_timeout 是否已调大 |
| 证书过期警告 | 自动续期失败 | 检查服务器 80 端口是否开放(验证需要),手动运行 sudo certbot renew |
| 域名无法解析 | DNS 未生效 | 等待几分钟,或检查阿里云解析记录是否正确 |
结语
通过上述步骤,我们成功为 copaw.thoughtly.xyz 部署了安全的 HTTPS 环境,并完美支持了 WebSocket 长连接。这种 “Certbot 管证书,人工管配置” 的模式,既享受了自动化续期的便利,又保证了复杂业务场景下的配置灵活性,是生产环境中推荐的最佳实践。
现在,你的 claw 和 copaw 双服务都已安全上线,可以安心开展业务了!