简介

有时候我们想在同一个域名上代理不同的服务,想要不加后缀的时候是一个服务或者正常页面,加后缀后又是另外一个服务或者另外一个页面,这个实现起来还是挺简单的。

本文章配置文件基于《Nginx-ui配置反向代理以及SSL

原配置文件

# -----------------------------------------------------------
# Nginx 高级反向代理模板
# 支持 WebSocket、IPv6、标准化 Forwarded 头、HTTP→HTTPS
# -----------------------------------------------------------
# 处理 WebSocket 升级:如果请求头有 Upgrade,则 Connection 设置为 upgrade,否则 close
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}
# 生成符合 RFC 7239 的标准化 Forwarded 头
map $remote_addr $proxy_forwarded_elem {
    # IPv4: 直接使用
    ~^[0-9.]+$ "for=$remote_addr";
    # IPv6: 用 [] 括起来并加引号
    ~^[0-9A-Fa-f:.]+$ "for=\"[$remote_addr]\"";
    # Unix Socket: 无法表示,用 unknown
    default "for=unknown";
}
# 如果请求已带 Forwarded 头,追加;否则新增
map $http_forwarded $proxy_add_forwarded {
    "~^(,[ \\t]*)*([!#$%&'*+.^_`|~0-9A-Za-z-]+=.*)?(;.*?)*([ \\t]*,.*?)*$" "$http_forwarded, $proxy_forwarded_elem";
    default "$proxy_forwarded_elem";
}
# -----------------------------------------------------------
# HTTP 服务器:监听 80,自动重定向到 HTTPS
# -----------------------------------------------------------
server {
    listen 80;
    listen [::]:80;
    server_name hk.ersansi.top;
    # 防止 Host 被伪造
    if ($host != $server_name) {
        return 404;
    }
    # Let's Encrypt 验证路径,需放行,不跳转
    location ~ /.well-known/acme-challenge {
        proxy_pass http://127.0.0.1:9180;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
    }
    # 其他所有请求都重定向到 HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}
# -----------------------------------------------------------
# HTTPS 服务器:监听 443,反向代理到后端
# -----------------------------------------------------------
server {
    listen 443 ssl http2;# 开启 HTTP/2
    listen [::]:443 ssl http2;
    server_name hk.ersansi.top;
    # SSL 证书
    ssl_certificate /etc/nginx/ssl/hk.ersansi.top_P256/fullchain.cer;
    ssl_certificate_key /etc/nginx/ssl/hk.ersansi.top_P256/private.key;
    # 启用 TLS 1.2 和 TLS 1.3
    ssl_protocols TLSv1.2 TLSv1.3;
    # 使用推荐的加密套件
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers on;
    # 可选:指定支持的椭圆曲线(仅 TLS 1.3)
    ssl_ecdh_curve X25519:secp256r1:secp384r1;
    # 防止 Host 被伪造
    if ($host != $server_name) {
        return 404;
    }
    # Let's Encrypt 验证路径,同样需放行
    location ~ /.well-known/acme-challenge {
        proxy_pass http://127.0.0.1:9180;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
    }
    # 主业务代理
    location / {
        proxy_pass http://127.0.0.1:9999/;# 后端服务
        proxy_http_version 1.1;# 保证支持长连接和 WebSocket
        proxy_set_header Upgrade $http_upgrade;# WebSocket 必需
        proxy_set_header Connection $connection_upgrade;# WebSocket 必需
        proxy_redirect off;# 禁止修改后端响应中的 Location
        # 常规头
        proxy_set_header Host www.ersansi.top;# 保留原始 Host
        proxy_set_header X-Real-IP $remote_addr;# 用户真实 IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;# 转发链
        proxy_set_header X-Forwarded-Proto $scheme;# 请求协议 http/https
        proxy_set_header Forwarded $proxy_add_forwarded;# 符合 RFC 7239 的标准头
    }
}

修改方法

我们需要在主业务代理下面加一个location模块

location = /qw {
    return 301 /xxhh/;
}

这个模块的作用将qw这个后缀跳转为xxhh这个后缀

然后复制主业务代理的location模块,并修改一下

location ^~ /xxhh/ {
    proxy_pass https://127.0.0.1:678;# 后端服务,端口后面加/则去掉后缀,没有斜杠则保留后缀
    proxy_http_version 1.1;# 保证支持长连接和 WebSocket
    proxy_set_header Upgrade $http_upgrade;# WebSocket 必需
    proxy_set_header Connection $connection_upgrade;# WebSocket 必需
    proxy_redirect off;# 禁止修改后端响应中的 Location
    # 常规头
    proxy_set_header Host $host;# 保留原始 Host
    proxy_set_header X-Real-IP $remote_addr;# 用户真实 IP
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;# 转发链
    proxy_set_header X-Forwarded-Proto $scheme;# 请求协议 http/https
    proxy_set_header Forwarded $proxy_add_forwarded;# 符合 RFC 7239 的标准头
}

把location这一行改一下,加^~ /后缀/,然后把proxy_pass这个代理服务也改一下即可,改这个的时候要注意后面是否需要加/,例如我现在直接访问的话是hk.ersansi.top:789/xxhh/,也就是我需要保留xxhh这个后缀才能访问到服务,所以端口后面是不用加/的,如果我的服务是hk.ersansi.top:789,不需要加/xxhh/,那么我就需要在后面加/

还有一点注意的是访问的时候是http还是https,例如我没有代理的时候访问的是https://hk.ersansi.top/xxhh/,那么在proxy_pass这里要写成https,如果我不代理的时候使用的是http则proxy_pass这里要写成http。

修改后的配置文件

# -----------------------------------------------------------
# Nginx 高级反向代理模板
# 支持 WebSocket、IPv6、标准化 Forwarded 头、HTTP→HTTPS
# -----------------------------------------------------------
# 处理 WebSocket 升级:如果请求头有 Upgrade,则 Connection 设置为 upgrade,否则 close
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}
# 生成符合 RFC 7239 的标准化 Forwarded 头
map $remote_addr $proxy_forwarded_elem {
    # IPv4: 直接使用
    ~^[0-9.]+$ "for=$remote_addr";
    # IPv6: 用 [] 括起来并加引号
    ~^[0-9A-Fa-f:.]+$ "for=\"[$remote_addr]\"";
    # Unix Socket: 无法表示,用 unknown
    default "for=unknown";
}
# 如果请求已带 Forwarded 头,追加;否则新增
map $http_forwarded $proxy_add_forwarded {
    "~^(,[ \\t]*)*([!#$%&'*+.^_`|~0-9A-Za-z-]+=.*)?(;.*?)*([ \\t]*,.*?)*$" "$http_forwarded, $proxy_forwarded_elem";
    default "$proxy_forwarded_elem";
}
# -----------------------------------------------------------
# HTTP 服务器:监听 80,自动重定向到 HTTPS
# -----------------------------------------------------------
server {
    listen 80;
    listen [::]:80;
    server_name hk.ersansi.top;
    # 防止 Host 被伪造
    if ($host != $server_name) {
        return 404;
    }
    # Let's Encrypt 验证路径,需放行,不跳转
    location ~ /.well-known/acme-challenge {
        proxy_pass http://127.0.0.1:9180;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
    }
    # 其他所有请求都重定向到 HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}
# -----------------------------------------------------------
# HTTPS 服务器:监听 443,反向代理到后端
# -----------------------------------------------------------
server {
    listen 443 ssl http2;# 开启 HTTP/2
    listen [::]:443 ssl http2;
    server_name hk.ersansi.top;
    # SSL 证书
    ssl_certificate /etc/nginx/ssl/hk.ersansi.top_P256/fullchain.cer;
    ssl_certificate_key /etc/nginx/ssl/hk.ersansi.top_P256/private.key;
    # 启用 TLS 1.2 和 TLS 1.3
    ssl_protocols TLSv1.2 TLSv1.3;
    # 使用推荐的加密套件
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers on;
    # 可选:指定支持的椭圆曲线(仅 TLS 1.3)
    ssl_ecdh_curve X25519:secp256r1:secp384r1;
    # 防止 Host 被伪造
    if ($host != $server_name) {
        return 404;
    }
    # Let's Encrypt 验证路径,同样需放行
    location ~ /.well-known/acme-challenge {
        proxy_pass http://127.0.0.1:9180;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
    }
    # 主业务代理
    location / {
        proxy_pass http://127.0.0.1:9999/;# 后端服务
        proxy_http_version 1.1;# 保证支持长连接和 WebSocket
        proxy_set_header Upgrade $http_upgrade;# WebSocket 必需
        proxy_set_header Connection $connection_upgrade;# WebSocket 必需
        proxy_redirect off;# 禁止修改后端响应中的 Location
        # 常规头
        proxy_set_header Host www.ersansi.top;# 保留原始 Host
        proxy_set_header X-Real-IP $remote_addr;# 用户真实 IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;# 转发链
        proxy_set_header X-Forwarded-Proto $scheme;# 请求协议 http/https
        proxy_set_header Forwarded $proxy_add_forwarded;# 符合 RFC 7239 的标准头
    }
    #把/qw跳转到/xxhh/
    location = /qw {
        return 301 /xxhh/;
    }
    #访问域名/xxhh的时候代理本机678端口服务,做到不同后缀代理不同端口
    location ^~ /xxhh/ {
        proxy_pass https://127.0.0.1:678;# 后端服务,端口后面加/则去掉后缀,没有斜杠则保留后缀
        proxy_http_version 1.1;# 保证支持长连接和 WebSocket
        proxy_set_header Upgrade $http_upgrade;# WebSocket 必需
        proxy_set_header Connection $connection_upgrade;# WebSocket 必需
        proxy_redirect off;# 禁止修改后端响应中的 Location
        # 常规头
        proxy_set_header Host $host;# 保留原始 Host
        proxy_set_header X-Real-IP $remote_addr;# 用户真实 IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;# 转发链
        proxy_set_header X-Forwarded-Proto $scheme;# 请求协议 http/https
        proxy_set_header Forwarded $proxy_add_forwarded;# 符合 RFC 7239 的标准头
    }
}
二维码

发表评论