Nginx 反向代理到路径中指定的服务器
Nginx reverse proxy to server that's specified in the path
我有一个 nginx 反向代理位置设置,如下所示:
location /192.168.0.10 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://192.168.0.10/;
}
location /192.168.0.11 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://192.168.0.11/;
}
location /192.168.0.12 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://192.168.0.12/;
}
location /192.168.0.13 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://192.168.0.13/;
}
location /192.168.0.14 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://192.168.0.14/;
}
location /192.168.0.15 {.....
这个结构重复了大约 96 次,所以我们可以对每个结构都有一个反向代理。有没有一种方法可以简化它,以便只有一个结构,并且位置路径中的 IP 神奇地出现在 proxy_pass 指令中?因为随着我们添加和删除服务器,这变得很难管理。
我认为以下正则表达式匹配位置应该有效:
location ~ ^/(?<proxy>192\.168\.0\.(?:10|11|12|13|14|15|...))(?:/(?<path>.*))?$ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://$proxy/$path;
}
你还可以优化那个非捕获组 (?:10|11|12|13|14|15|...)
,例如匹配从 10
到 105
的任何数字,它可以写成 (?:10[0-5]|[1-9]\d)
。
更新 1
根据 OP 的要求,对任何 IPv4 地址进行严格检查的 PCRE 正则表达式(仅匹配从 0.0.0.0
到 255.255.255.255
的正确 IPv4 地址,改编自 this 答案)可以是写成
location ~ "^/(?<proxy>(?:25[0-5]|2[0-4]\d|[01]?\d?\d\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))(?:/(?<path>.*))?$" {
...
}
由于大括号的使用,正则表达式模式必须用双引号引起来。
更新 2
以前的解决方案不会保留请求查询字符串,保留所有请求查询参数的更正确的解决方案是使用 proxy_pass http://$proxy/$path$is_args$args
指令:
location ~ "^/(?<proxy>(?:25[0-5]|2[0-4]\d|[01]?\d?\d\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))(?:/(?<path>.*))?$" {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://$proxy/$path$is_args$args;
}
我有一个 nginx 反向代理位置设置,如下所示:
location /192.168.0.10 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://192.168.0.10/;
}
location /192.168.0.11 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://192.168.0.11/;
}
location /192.168.0.12 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://192.168.0.12/;
}
location /192.168.0.13 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://192.168.0.13/;
}
location /192.168.0.14 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://192.168.0.14/;
}
location /192.168.0.15 {.....
这个结构重复了大约 96 次,所以我们可以对每个结构都有一个反向代理。有没有一种方法可以简化它,以便只有一个结构,并且位置路径中的 IP 神奇地出现在 proxy_pass 指令中?因为随着我们添加和删除服务器,这变得很难管理。
我认为以下正则表达式匹配位置应该有效:
location ~ ^/(?<proxy>192\.168\.0\.(?:10|11|12|13|14|15|...))(?:/(?<path>.*))?$ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://$proxy/$path;
}
你还可以优化那个非捕获组 (?:10|11|12|13|14|15|...)
,例如匹配从 10
到 105
的任何数字,它可以写成 (?:10[0-5]|[1-9]\d)
。
更新 1
根据 OP 的要求,对任何 IPv4 地址进行严格检查的 PCRE 正则表达式(仅匹配从 0.0.0.0
到 255.255.255.255
的正确 IPv4 地址,改编自 this 答案)可以是写成
location ~ "^/(?<proxy>(?:25[0-5]|2[0-4]\d|[01]?\d?\d\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))(?:/(?<path>.*))?$" {
...
}
由于大括号的使用,正则表达式模式必须用双引号引起来。
更新 2
以前的解决方案不会保留请求查询字符串,保留所有请求查询参数的更正确的解决方案是使用 proxy_pass http://$proxy/$path$is_args$args
指令:
location ~ "^/(?<proxy>(?:25[0-5]|2[0-4]\d|[01]?\d?\d\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))(?:/(?<path>.*))?$" {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
proxy_cookie_path /phpmyadmin/ /;
proxy_redirect off;
proxy_pass http://$proxy/$path$is_args$args;
}