前一段时间在又发现了一个 “赛博活佛”,能提供免费 SSL 证书的 Let's Encrypt。在 GlobalSign 购买一个 SSL 证书一年要花大几千 RMB,而 Let's Encrypt 竟然免费提供,搭配 Certbot 还能自动化配置与自动续约签发新的 SSL 证书。
这篇文章记录我为前后端分离部署的一台 Web 服务器配置 Nginx 与免费的 SSL 证书。
网站服务器现状与任务目标
现状
前后端分离开发部署的两个项目,前端将 Vue.js 打包构建产物(纯静态文件)上传至服务器,使用 Node.js 的一个 CLI HTTP 工具提供 80 端口的前端访问。
后端使用 Nest.js 开发,服务器 Clone 完整仓库代码,运行构建后使用 node 运行构建产物的入口 JS 文件,后端绑定 8080 端口。
目标
使用 Nginx 托管前端项目的构建产物静态文件,并作为后端项目的反向代理服务。
使用 Certbot + Let's Encrypt 配置免费的 SSL 证书。
最终的预期为服务器仅对外开放 443 端口用于访问网站,用户通过 https://example.com 访问前端项目,通过 https://example.com/api 访问后端接口。
安装与配置 Nginx
Ubuntu 安装 Nginx
sudo apt update
sudo apt install nginx
启动 Nginx
sudo systemctl enable nginx
sudo systemctl start nginx
查看 Nginx 运行状态
systemctl status nginx
浏览器访问 http://example.com 已经能看到 Nginx 默认页面。
将前端项目的构建产物静态文件存放至 /var/www/frontend
/var/www/frontend
├── index.html
├── assets
└── favicon.ico
创建 Nginx 配置文件 /etc/nginx/sites-available/my-site
server {
listen 80;
server_name example.com;
root /var/www/frontend;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://127.0.0.1:8080/;
proxy_http_version 1.1;
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;
}
}
启用新创建的 Nginx 配置文件
sudo ln -s /etc/nginx/sites-available/my-site /etc/nginx/sites-enabled/
检查 Nginx 配置并重启
sudo nginx -t
sudo systemctl reload nginx
再次访问网站,前端的 URL 为 http://example.com,后端 URL 为 http://example.com/api/xxx,至此通过 Nginx 实现了对外只用一个 80 端口就能访问前后端服务。
安装 Certbot 并配置 SSL 证书
由于 Certbot 与 Let's Encrypt 更新频繁,传统的 apt 包管理器的软件源更新不及时,因此建议使用 Snap 安装 Certbot。
安装 Snap
sudo apt install snapd
sudo snap install core
sudo snap refresh core
安装 Certbot
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
certbot --version
snap --classic 参数的作用是关闭 Snap 的默认沙盒隔离限制,给予程序完全访问宿主机系统的权限
使用 Certbot 申请 SSL 证书
sudo certbot --nginx
Certbot 会:
- 自动识别 Nginx
- 自动修改配置
- 自动申请证书
- 自动配置 HTTPS
- 自动配置 HTTP -> HTTPS 跳转(可选)
Certbot 会在 Nginx 配置额外添加 80 端口的监听,用于 Let's Encrypt 验证域名
SSL 证书自动续期
通过 Snap 安装的 Certbot 会自动安装 systemd timer,SSL 证书配置成功后,Certbot 会自动创建定时任务用于定期检查与重新签发 SSL 证书。
查看 Certbot 定时任务
systemctl list-timers | grep certbot
测试 Certbot 重新签发 SSL 证书
sudo certbot renew --dry-run
如果成功会显示 Congratulations, all simulated renewals succeeded
至此,实现了 Nginx 使用同一个端口代理前后端项目,Certbot + Let's Encrypt 自动签发与部署 SSL 证书,不再需要手动操作了。