现在 Docker 被广泛用在自建服务上,几个命令就能启动自己的服务,十分方便。有些服务需要开启 HTTPS 保证安全,通过反代开启 HTTPS 是一种简单又通用的方式。
本文简单介绍如何使用 Nginx 反向代理。
| 指标 | 描述 |
|---|---|
| 适用系统 | Debian 系发行版,包括 Ubuntu, Armbian,其他发行版稍改命令一般也可 |
| 走通流程时间 | 10 分钟 |
I might have made some mistakes, please let me know if I’ve gotten anything wrong!
安装 Nginx
sudo apt update && sudo apt upgrade -y && sudo apt install nginx
编写配置文件
HTTP 反代
编写 Nginx 配置文件(注意修改 vfly2.com 文件名)
sudo vim /etc/nginx/sites-available/vfly2.com
当在 80 端口收到访问 vfly2.com 的请求时,就将请求转发给 http://127.0.0.1:7456
server {
listen 80;
server_name vfly2.com;
location / {
proxy_pass http://127.0.0.1:7456;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
假设本机地址是 1.2.3.4,最终效果是:访问 http://vfly2.com 相当于访问 http://1.2.3.4:7456
简单介绍:
proxy_pass,指定后端服务的地址proxy_set_header,修改 HTTP 请求头- Host,修改前是 vfly2.com,修改后是 127.0.0.1
- X-Real-IP,修改前是 127.0.0.1 (如果不修改,后端服务收到的地址其实是 Nginx 的 IP 地址),修改后是真实的访问 IP
- X-Forwarded-For,不了解
创建软链接,使配置文件生效(新创建的配置文件执行一次就行,后续修改无须再次执行)
sudo ln -s /etc/nginx/sites-available/vfly2.com /etc/nginx/sites-enabled/vfly2.com
HTTPS 反代
如果需要使用 HTTPS,则先获取证书:[[02acme.sh]] 使用 acme.sh 申请和自动更新证书的完整指南 – 技焉洲 (yanh.tech)
申请证书
acme.sh --issue -d vfly2.com --webroot /var/www/html
安装证书
acme.sh --install-cert -d vfly2.com \
--key-file /etc/ssl/private/vfly2.com.key \
--fullchain-file /etc/ssl/certs/vfly2.com.cer
编写 Nginx 配置文件(注意修改文件名)
sudo vim /etc/nginx/sites-available/vfly2.com
# (可省略)当在 80 端口收到访问 vfly2.com 的请求时,301 重定向到 HTTPS,即 443 端口
server {
listen 80;
server_name vfly2.com;
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl;
server_name vfly2.com;
# 指定证书的路径
ssl_certificate /etc/ssl/certs/vfly2.com.cer;
ssl_certificate_key /etc/ssl/private/vfly2.com.key;
# 避免阻断 acme 的自动申请
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
proxy_pass http://127.0.0.1:7456;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
sudo ln -s /etc/nginx/sites-available/vfly2.com /etc/nginx/sites-enabled/vfly2.com
重定向
301是永久重定向,302是临时重定向
acme.sh --issue -d technique.vfly2.com --webroot /var/www/html
acme.sh --install-cert -d technique.vfly2.com \
--key-file /etc/ssl/private/technique.vfly2.com.key \
--fullchain-file /etc/ssl/certs/technique.vfly2.com.cer
sudo vim /etc/nginx/sites-available/tech
同时监听 80 和 443 上对 technique.vfly2.com 的请求
server {
listen 80;
listen 443 ssl;
server_name technique.vfly2.com;
ssl_certificate /etc/ssl/certs/technique.vfly2.com.cer;
ssl_certificate_key /etc/ssl/private/technique.vfly2.com.key;
location / {
return 301 https://yanh.tech$request_uri;
}
}
sudo ln -s /etc/nginx/sites-available/tech /etc/nginx/sites-enabled/tech
HTTP 反代缓存
创建缓存目录并设置权限
sudo mkdir -p /var/cache/nginx/{main,images} && sudo chown -R www-data:www-data /var/cache/nginx
在 Nginx 的全局配置中设置缓冲区
sudo vim /etc/nginx/nginx.conf
http {
# ...
proxy_cache_path /var/cache/nginx/main levels=1:2 keys_zone=mycache:10m max_size=1g inactive=24h use_temp_path=off;
# 如果不同站点需要不同的缓冲区,就创建多个,名称要不一样
# 图片专用缓存(2GB磁盘空间,单独配置)
proxy_cache_path /var/cache/nginx/images levels=1:2 keys_zone=imagecache:10m max_size=2g inactive=7d use_temp_path=off;
}
proxy_cache_path 是定义缓存路径和参数,只能放在 http 层级下,不能放在 server 里:
- levels=缓存目录层级
- keys_zone=缓存区名:内存占用大小(1MB内存可存约8000个key)
- max_size=磁盘缓存空间上限
- inactive=缓存保留未使用时间 60m、24h
- use_temp_path=off 避免临时目录拷贝
编写 Nginx 网站配置文件(注意修改 vfly2.com 文件名)
sudo vim /etc/nginx/sites-available/vfly2.com
server {
listen 80;
server_name vfly2.com;
location / {
# 启用缓存区
proxy_cache mycache;
# 定义缓存键
proxy_cache_key "$scheme$proxy_host$uri$is_args$args";
# 缓存有效时间设置(当后端无返回缓存头时生效)
proxy_cache_valid 200 302 30m; # 成功和重定向缓存30分钟
proxy_cache_valid 404 5m; # 404缓存5分钟
proxy_cache_valid any 10m; # 其他状态码缓存10分钟
proxy_cache_revalidate on; # 过期后向源站 revalidate
proxy_pass http://1.2.3.4:1234;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 缓存状态头(用于调试)
add_header X-Proxy-Cache $upstream_cache_status;
# add_header X-Cache-Zone $proxy_cache_zone;
# 缓存锁定机制(防止多个请求同时更新缓存)
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
# 忽略后端设置的Set-Cookie头(防止私有内容被缓存)
proxy_ignore_headers Set-Cookie;
# 以下情况不缓存:
# 1. POST请求
# 2. 带授权头的请求
# 3. URL包含敏感路径
proxy_no_cache $http_purpose $http_authorization $cookie_sessionid;
proxy_cache_bypass $http_purpose $http_authorization $cookie_sessionid;
}
# 图片路径使用独立缓存
location /images/ {
proxy_cache imagecache;
proxy_cache_valid 200 302 7d; # 图片缓存7天
proxy_pass http://1.2.3.4:12345;
}
}
取消 X-Proxy-Cache 的注释后,可以通过响应头中的 X-Proxy-Cache 字段查看缓存状态:
- HIT:缓存命中
- MISS:缓存未命中
- BYPASS:缓存被绕过
X-Cache-Zone 则可以显示使用的缓存区
如果要清理缓存,可以直接用 sudo rm -rf /var/cache/nginx/*
重启生效
检查配置
sudo nginx -t
重启生效
sudo systemctl reload nginx
当域名更改解析 IP 后,需要重启 Nginx,因为它可能缓存了 IP
安卓 APP 报错:证书验证失败
在学习 flutter 时,需要访问 https://webnote.vfly2.com/ ,安卓平台的 APP 提示证书验证失败,可是在 Windows 平台的应用就不会报错,以及浏览器上也一直没有报错,一开始以为是安卓不信任 Let’s Encrypt 的证书。
其实是:证书链不完整。Apache2 上用的证书是 key-file 和 cert-file,缺少根证书和中间证书,解决办法是用 fullchain-file 代替 cert-file 即可。
验证自己的网站证书链是否有问题,可以使用下面命令,记得改域名:
openssl s_client -connect webnote.vfly2.com:443 -servername webnote.vfly2.com
原文链接: https://yanh.tech/2024/09/tutorial-of-nginx-reverse-proxy-and-redirection/
版权声明:本博客所有文章除特別声明外,均为 AhFei 原创,采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 技焉洲 (yanh.tech) 。
保持更新 ٩(•̤̀ᵕ•̤́๑)ᵒᵏᵎᵎᵎᵎ 清晰恒益的实用技能,欢迎使用 RSS 订阅,如果能留言互动就更好了。
可在 Telegram 群组 https://t.me/vfly2 交流依文章步骤遇到的问题。

