site logo

Marico's space

Nginx 反向代理 + SSL(Let's Encrypt)一站式配置指南

服务器技术 2026-04-25 23:01:30 6

👋 先说两句废话:搭过生产环境的老铁都知道,反向代理这东西属于"不装不知道,一装真香"的类型。你要是只跑一个服务还好说,一旦需要同时跑 API、Web、自动化工具……还暴露着端口裸奔,那酸爽谁用谁知道。

今天来讲讲怎么在 Ubuntu 服务器上用 Nginx 配反向代理 + 免费 SSL(Let's Encrypt),全程中文,步骤清晰,代码直接复制能用。

什么是反向代理?

先科普一下概念。Nginx 反向代理简单说就是:客户端请求先打到 Nginx,Nginx 再帮你把请求转发到后端真实服务(比如你跑在 3000 端口的 Node.js API)。

为什么要这么搞?好处多了去了:

  • 隐藏后端端口:别裸奔暴露内部端口,安全多了
  • SSL 终结:HTTPS 在 Nginx 这一层处理,后端服务不用管证书的事
  • 负载均衡:一个域名代理到多个后端服务
  • 免费 HTTPS:Let's Encrypt 证书完全免费

举个例子:你在服务器上跑了个 Node.js API(端口 3000)和 Python Flask 应用(端口 5000),有了反向代理,外部只要访问 api.example.comapp.example.com 就够了,端口?不存在的。

准备工作

  • SSH 访问你的 Linux 服务器(Ubuntu 20.04 或更新版本)
  • 一个已解析到服务器 IP 的域名
  • 基础的命令行知识

第一步:安装 Nginx 和 Certbot

先 SSH 登录服务器,更新一下包管理器,然后安装 Nginx:

sudo apt update
sudo apt upgrade -y
sudo apt install -y nginx

启动 Nginx 并设为开机自启:

sudo systemctl start nginx
sudo systemctl enable nginx

检查一下 Nginx 是否正常运行:

sudo systemctl status nginx

看到 active (running) 就稳了。接下来安装 Certbot(Let's Encrypt 客户端)和 Nginx 插件:

sudo apt install -y certbot python3-certbot-nginx

验证安装:

certbot --version

第二步:配置第一个反向代理

假设你有个后端服务跑在 localhost:3000(Node.js、Python 或者什么都行,只要是 HTTP),你想通过 api.example.com 暴露出去。

打开 Nginx 配置:

sudo nano /etc/nginx/sites-available/default

把内容全部替换成这个:

upstream backend_service {
 server localhost:3000;
 keepalive 32;
}

server {
 listen 80;
 listen [::]:80;
 server_name api.example.com;

 location / {
  proxy_pass http://backend_service;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection 'upgrade';
  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;
  proxy_cache_bypass $http_upgrade;
  proxy_redirect off;
 }
}

解释一下关键配置:

  • upstream backend_service:定义后端服务地址,改成你自己的端口
  • server_name api.example.com:换成你的真实域名
  • proxy_set_header 系列:这些 header 很关键,保证后端服务能拿到真实客户端信息(IP、协议等)

测一下配置语法:

sudo nginx -t

看到 syntax is ok 就可以 reload 了:

sudo systemctl reload nginx

现在访问 http://api.example.com 应该就能代理到你后端了。不过还是明文传输,HTTPS 走起。

第三步:Let's Encrypt SSL 免费证书

这步是精髓,一条命令搞定一切,包括自动续期:

sudo certbot --nginx -d api.example.com

Certbot 会问几个问题:

  • 输入邮箱(用于证书到期提醒)
  • 同意 Let's Encrypt 服务条款
  • 是否分享邮箱给 EFF(可选,随你)
  • 选 2(Redirect),把 HTTP 请求重定向到 HTTPS

Certbot 会自动修改 Nginx 配置,启用 HTTPS。配置大概长这样:

upstream backend_service {
 server localhost:3000;
 keepalive 32;
}

server {
 listen 80;
 listen [::]:80;
 server_name api.example.com;
 return 301 https://$server_name$request_uri;
}

server {
 listen 443 ssl http2;
 listen [::]:443 ssl http2;
 server_name api.example.com;

 ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
 ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
 include /etc/letsencrypt/options-ssl-nginx.conf;
 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

 location / {
  proxy_pass http://backend_service;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection 'upgrade';
  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;
  proxy_cache_bypass $http_upgrade;
  proxy_redirect off;
 }
}

测一下语法并 reload:

sudo nginx -t
sudo systemctl reload nginx

搞定!现在访问 https://api.example.com 就是加密连接了。证书有效期 90 天,Certbot 会通过 systemd timer 自动续期,完全不用你管。

验证一下自动续期定时器是否在跑:

sudo systemctl status certbot.timer

看到 active 就放心了。

第四步:安全加固(推荐)

光有 HTTPS 还不够,来点安全响应头,让配置更健壮。

在 HTTPS server 块里(ssl_dhparam 之后)添加:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

这些响应头分别防止:点击劫持、MIME 类型嗅探、XSS 攻击、referrer 信息泄露,并且强制 HTTPS。

限速配置

怕被 DDoS 或暴力破解?加个限速。在 server 块外面(文件顶部)添加:

limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

然后在 HTTPS server 块里应用:

limit_req zone=general burst=20 nodelay;

禁止访问敏感文件

location ~ /\. {
 deny all;
 access_log off;
 log_not_found off;
}

location ~ ~$ {
 deny all;
 access_log off;
 log_not_found off;
}

启用 Gzip 压缩

省流量加快速,在 server 块外面加:

gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss;
gzip_disable "MSIE [1-6]\.";

测一下 reload:

sudo nginx -t
sudo systemctl reload nginx

进阶:多后端服务配置

如果你要跑多个服务,配置起来也很简单,多加几个 upstream 就好:

upstream api_backend {
 server localhost:3000;
 keepalive 32;
}

upstream app_backend {
 server localhost:5000;
 keepalive 32;
}

server {
 listen 80;
 listen [::]:80;
 server_name api.example.com app.example.com;
 return 301 https://$server_name$request_uri;
}

server {
 listen 443 ssl http2;
 listen [::]:443 ssl http2;
 server_name api.example.com;

 ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
 ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
 include /etc/letsencrypt/options-ssl-nginx.conf;
 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

 location / {
  proxy_pass http://api_backend;
  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;
 }
}

server {
 listen 443 ssl http2;
 listen [::]:443 ssl http2;
 server_name app.example.com;

 ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
 ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
 include /etc/letsencrypt/options-ssl-nginx.conf;
 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

 location / {
  proxy_pass http://app_backend;
  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 反向代理 + Let's Encrypt SSL 这套组合拳,成本为零(证书免费),效果拉满。你得到了:

  • ✅ 免费 HTTPS 证书,自动续期
  • ✅ 后端端口隐藏,攻击面缩小
  • ✅ 安全响应头,防护加固
  • ✅ 可选限速,防止滥用
  • ✅ 多服务代理,一网打尽

原文链接:How to Set Up Nginx Reverse Proxy with SSL (Let's Encrypt)