概述
做个人项目或者小团队开发,最头疼的往往不是写代码,而是把服务部署上线。域名买了,服务跑起来了,但浏览器里全是"不安全"的红色警告,用户看了直摇头。
今天教你用 Nginx 做反向代理,加上 Certbot 自动申请 Let’s Encrypt 免费 SSL 证书。整个过程大约 15 分钟,证书自动续期,再也不用管了。
反向代理是什么?简单说就是它站在你的服务前面,替用户处理请求。用户访问 443 端口(HTTPS),它解密后把请求转发给你的后端服务。这样你的服务不用操心加密和域名绑定,专注写代码就好。
准备工作
你需要以下条件和环境:
- 一台公网 VPS:CentOS 7+、Ubuntu 20.04+ 或 Debian 11+ 都可以
- 一个已解析到服务器 IP 的域名:比如
api.example.com,在 DNS 里加一条 A 记录 - 服务器已开放 80 和 443 端口:防火墙和安全组都要放行
- root 或 sudo 权限
以下示例以 Ubuntu 22.04 为例,CentOS 用户把 apt 换成 yum 即可。
安装 Nginx
先装 Nginx,这是反向代理的核心。
sudo apt update
sudo apt install nginx -y
安装完成后,确认 Nginx 在运行:
sudo systemctl status nginx
看到 active (running) 就说明没问题。如果没启动,执行:
sudo systemctl enable nginx
sudo systemctl start nginx
安装 Certbot
Certbot 是 Let’s Encrypt 的官方客户端,能自动申请和配置证书。
sudo apt install certbot python3-certbot-nginx -y
配置 Nginx 反向代理
假设你有一个后端服务跑在 localhost:3000,你想让 api.example.com 代理到这个服务。
编辑 Nginx 配置文件:
sudo nano /etc/nginx/sites-available/api.example.com
写入以下内容:
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
保存后,创建软链接启用配置:
sudo ln -s /etc/nginx/sites-available/api.example.com /etc/nginx/sites-enabled/
测一下配置有没有语法错误:
sudo nginx -t
看到 syntax is ok 和 test is successful 就对了。然后重载 Nginx:
sudo systemctl reload nginx
申请 SSL 证书
现在配置好了 HTTP 的反向代理,接下来让 Certbot 帮你申请 HTTPS 证书并自动修改 Nginx 配置。
sudo certbot --nginx -d api.example.com
第一次运行会让你填邮箱(用于证书过期提醒)和同意协议。然后 Certbot 会自动:
- 验证你对域名的控制权
- 向 Let’s Encrypt 申请证书
- 自动修改 Nginx 配置,启用 HTTPS
- 设置 HTTP 自动跳转到 HTTPS
完成后你会看到类似这样的提示:
Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/api.example.com/fullchain.pem
验证搭建是否成功
打开浏览器,访问 https://api.example.com。如果看到你的后端服务页面,且地址栏有绿色小锁,说明一切正常。
也可以用命令行验证:
curl -I https://api.example.com
返回的状态码应该是 200,并且响应头里会包含 strict-transport-security,说明 HSTS 已经启用。
证书信息也可以用这个命令查看:
echo | openssl s_client -servername api.example.com -connect api.example.com:443 2>/dev/null | openssl x509 -noout -dates
输出会显示证书的生效日期和过期日期,Let’s Encrypt 的证书有效期为 90 天。
配置自动续期
Let’s Encrypt 的证书只有 90 天有效期,但 Certbot 自带自动续期机制。检查续期定时器:
sudo systemctl list-timers | grep certbot
应该能看到每天会自动运行续期检查。如果想手动测试续期流程(不会真的续期,只是测试):
sudo certbot renew --dry-run
看到 Congratulations, all renewals succeeded 就说明自动续期配置正确。
常见问题
问题一:申请证书时报 DNS validation failed
原因通常是 DNS 没生效,或者域名解析指向了错误的 IP。用这个命令检查:
dig api.example.com
确保返回的 IP 和你服务器公网 IP 一致。如果不一致,等 DNS 传播(通常几分钟到几小时)。
问题二:Nginx 启动报错 port 80 already in use
可能是 Apache 或其他服务占用了 80 端口。用这个命令查看:
sudo lsof -i :80
关掉占用端口的服务,或者修改 Nginx 监听端口。
问题三:后端服务返回的是原始 IP 而不是用户真实 IP
在 Nginx 配置里加上这几行就行:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
后端代码里读取 X-Real-IP 或 X-Forwarded-For 头部即可。
问题四:证书申请成功但浏览器还是显示不安全
清除浏览器缓存,或者用无痕模式重新打开。有时候浏览器会缓存之前的 HSTS 策略。也可以在地址栏手动忽略警告继续访问。
反向代理+SSL证书是部署Web服务的标配,学会这套流程,后续加服务直接复用 Nginx 配置就行。
你的服务上线了吗?有没有遇到过证书或者 Nginx 配置的问题?