Nginx 反代和重定向的简洁教程

现在 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 交流依文章步骤遇到的问题。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇