使用 nginx 正则表达式位置匹配将 URI 动态映射到多个反向代理的不同端口
Using nginx regex location matching to dynamically map URI's to different ports for multiple reverse proxies
我正在使用 nginx 为可能位于防火墙后面的 Web 应用程序创建反向代理。对于我最初的概念验证,我使用了以下位置块来确保它有效。
location / {
proxy_pass https://localhost:2222;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
我使用 ssh -f -N -T -R2222:localhost:443 user@nginx-ip
在我的网络应用程序上打开了我的反向隧道。
这完全符合我的喜好。我在浏览器中输入 nginx-ip
,然后从我的 Web 应用程序获取 https 流量,但被 nginx-ip
等混淆了
我想允许可能有几千条反向隧道穿过几千个端口(而不是上述情况下的 2222)。阅读 nginx,I thought to use regular expressions 动态使用包含端口号的 URI proxy_pass 到该特定端口。
也就是说,我想要 https://nginx-ip/2222/
到 proxy_pass https://localhost:2222;
,我想要 https://nginx-ip/1111/
到 proxy_pass https://localhost:1111;
。
我尝试了很多变体,但据我所知,我认为这应该可行:
location ~* ^/(\d+) {
proxy_pass https://localhost:;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
没有。我在浏览器中收到 502 Bad Gateway,错误日志显示:
2016/05/31 21:02:36 [error] 6188#0: *3584 no resolver defined to resolve localhost, client: {my-client-ip}, server: localhost, request: "GET /2222/ HTTP/1.1", host: "{nginx-ip}"
当我使用 127.0.0.1
而不是 localhost
时,我得到了 404。网页上说
Not Found
The requested URL /2222/ was not found on this server.
我正在尝试的 nginx 配置是否可行?
重申一下,我希望能够通过 nginx 网络服务器启动许多(数千)个独特的反向隧道。我最初的想法是根据我想要代理的其他 Web 应用程序来改变 nginx 服务器的传出端口,并通过 URI 中的端口将请求分配到我的 nginx 服务器到不同的端口(通过正则表达式提取) .
您应该能够通过组合 url-rewriting rule to remove the digits specifying the port and a named capture 来提取 requested_port
作为 proxy_pass
指令的可用变量。
location ~* ^/(?<requested_port>\d+) {
rewrite /(\d+)(.*) / break;
proxy_pass https://localhost:$requested_port;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
为了解决我的问题,在@Cirdec 的帮助下,我最终走向了不同的方向。
我没有使用 URI 中的路径来引用端口,而是成功地将端口用作子域。也就是说,1111.my-host-name
将通过端口 1111
上的 127.0.0.1
(localhost
) 上的反向代理发送内容。这需要使用一些 DNS 通配符来帮助处理一些繁重的列表(注意:/etc/hosts
中的通配符 DNS 匹配将不起作用,但您可以对一些条目进行硬编码以测试它是否有效。
摘自我的 /etc/hosts
文件:
nginx-box-ip-address 2222.my-host-name
nginx-box-ip-address 1111.my-host-name
这与 nginx 配置配对:
server {
listen 443;
server_name ~^(?<port_subdomain>[0-9]*).my-host-name$;
# NOTE: omitted extra ssl configuration lines
location / {
proxy_pass https://127.0.0.1:$port_subdomain;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
现在我可以让我的 Web 应用程序打开反向代理隧道到我的 nginx 框(我的主机名)上的任意端口并通过子域访问它们。
一步一步的例子:
- 在我的一个 Web 应用程序框上,我使用
ssh -f -N -T -R2222:localhost:443 user@my-host-name
在我的 nginx 框(我的主机名)上打开了一个到端口 2222
的反向隧道
- 在不同的网络应用程序框上,我可以打开一个不同的隧道到同一个 nginx 框(我的主机名),比如 运行
ssh -f -N -T -R1111:localhost:443 user@my-host-name
上的端口 1111
不同的网络应用程序框
- 在我的nginx机器上,我加载了上面的配置。我打开 chrome 并点击
2222.my-host-name
就好像我直接点击了我的网络应用程序框的 URL/IP 地址(由于反向代理,它只能在防火墙后面).点击 1111.my-host-name
将我带到另一个 Web 应用程序框,它是完全独立的并且通过完全独立的隧道。
我正在使用 nginx 为可能位于防火墙后面的 Web 应用程序创建反向代理。对于我最初的概念验证,我使用了以下位置块来确保它有效。
location / {
proxy_pass https://localhost:2222;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
我使用 ssh -f -N -T -R2222:localhost:443 user@nginx-ip
在我的网络应用程序上打开了我的反向隧道。
这完全符合我的喜好。我在浏览器中输入 nginx-ip
,然后从我的 Web 应用程序获取 https 流量,但被 nginx-ip
等混淆了
我想允许可能有几千条反向隧道穿过几千个端口(而不是上述情况下的 2222)。阅读 nginx,I thought to use regular expressions 动态使用包含端口号的 URI proxy_pass 到该特定端口。
也就是说,我想要 https://nginx-ip/2222/
到 proxy_pass https://localhost:2222;
,我想要 https://nginx-ip/1111/
到 proxy_pass https://localhost:1111;
。
我尝试了很多变体,但据我所知,我认为这应该可行:
location ~* ^/(\d+) {
proxy_pass https://localhost:;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
没有。我在浏览器中收到 502 Bad Gateway,错误日志显示:
2016/05/31 21:02:36 [error] 6188#0: *3584 no resolver defined to resolve localhost, client: {my-client-ip}, server: localhost, request: "GET /2222/ HTTP/1.1", host: "{nginx-ip}"
当我使用 127.0.0.1
而不是 localhost
时,我得到了 404。网页上说
Not Found The requested URL /2222/ was not found on this server.
我正在尝试的 nginx 配置是否可行?
重申一下,我希望能够通过 nginx 网络服务器启动许多(数千)个独特的反向隧道。我最初的想法是根据我想要代理的其他 Web 应用程序来改变 nginx 服务器的传出端口,并通过 URI 中的端口将请求分配到我的 nginx 服务器到不同的端口(通过正则表达式提取) .
您应该能够通过组合 url-rewriting rule to remove the digits specifying the port and a named capture 来提取 requested_port
作为 proxy_pass
指令的可用变量。
location ~* ^/(?<requested_port>\d+) {
rewrite /(\d+)(.*) / break;
proxy_pass https://localhost:$requested_port;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
为了解决我的问题,在@Cirdec 的帮助下,我最终走向了不同的方向。
我没有使用 URI 中的路径来引用端口,而是成功地将端口用作子域。也就是说,1111.my-host-name
将通过端口 1111
上的 127.0.0.1
(localhost
) 上的反向代理发送内容。这需要使用一些 DNS 通配符来帮助处理一些繁重的列表(注意:/etc/hosts
中的通配符 DNS 匹配将不起作用,但您可以对一些条目进行硬编码以测试它是否有效。
摘自我的 /etc/hosts
文件:
nginx-box-ip-address 2222.my-host-name
nginx-box-ip-address 1111.my-host-name
这与 nginx 配置配对:
server {
listen 443;
server_name ~^(?<port_subdomain>[0-9]*).my-host-name$;
# NOTE: omitted extra ssl configuration lines
location / {
proxy_pass https://127.0.0.1:$port_subdomain;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
现在我可以让我的 Web 应用程序打开反向代理隧道到我的 nginx 框(我的主机名)上的任意端口并通过子域访问它们。
一步一步的例子:
- 在我的一个 Web 应用程序框上,我使用
ssh -f -N -T -R2222:localhost:443 user@my-host-name
在我的 nginx 框(我的主机名)上打开了一个到端口2222
的反向隧道- 在不同的网络应用程序框上,我可以打开一个不同的隧道到同一个 nginx 框(我的主机名),比如 运行
ssh -f -N -T -R1111:localhost:443 user@my-host-name
上的端口1111
不同的网络应用程序框
- 在不同的网络应用程序框上,我可以打开一个不同的隧道到同一个 nginx 框(我的主机名),比如 运行
- 在我的nginx机器上,我加载了上面的配置。我打开 chrome 并点击
2222.my-host-name
就好像我直接点击了我的网络应用程序框的 URL/IP 地址(由于反向代理,它只能在防火墙后面).点击1111.my-host-name
将我带到另一个 Web 应用程序框,它是完全独立的并且通过完全独立的隧道。