简介
有时候我们想在同一个域名上代理不同的服务,想要不加后缀的时候是一个服务或者正常页面,加后缀后又是另外一个服务或者另外一个页面,这个实现起来还是挺简单的。
本文章配置文件基于《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 的标准头
}
}