使用nginx正则表达式位置匹配来动态地将URI映射到多个反向代理的不同端口

时间:2016-05-31 21:10:26

标签: reverse-proxy nginx-location

我正在使用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,然后从我的网络应用中获取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:$1;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $remote_addr;
    }

没有。我在浏览器中收到502 Bad Gateway,错误日志告诉我:

  

2016/05/31 21:02:36 [错误] 6188#0:* 3584未定义解析器解析localhost,客户端:{my-client-ip},server:localhost,request:“GET / 2222 / HTTP / 1.1“,主持人:”{nginx-ip}“

当我使用127.0.0.1代替localhost时,我得到了404.网页上写着

  

未找到   在此服务器上找不到请求的URL / 2222 /。

我正在尝试使用nginx配置吗?

重申一下,我希望能够通过nginx Web服务器启动许多(数千个)独特的反向隧道。我最初的想法是根据我想代理的其他网络应用程序改变nginx服务器的传出端口,并通过URI中的端口将请求分配给我的nginx服务器到不同的端口(通过正则表达式提取它)

2 个答案:

答案 0 :(得分:2)

为了解决我的问题,在@Cirdec的帮助下,我最终走向了另一个方向。

我没有使用URI中的路径来引用端口,而是成功地将端口用作子域。也就是说,1111.my-host-name将通过端口127.0.0.1上的localhost1111)上的反向代理发送内容。这需要使用一些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;
    }
}

现在我可以让我的网络应用程序打开反向代理隧道到我的nginx框(my-host-name)上的任意端口,并通过子域到达它们。

一步一步的例子:

  • 在我的一个网络应用程序框中,我打开了一个反向隧道,通过2222在我的nginx框(我的主机名)上移植到ssh -f -N -T -R2222:localhost:443 user@my-host-name端口
    • 在另一个网络应用程序框中,我可以通过在不同的网络应用程序框上运行1111打开到同一个nginx框(my-host-name)的另一个隧道,比如端口ssh -f -N -T -R1111:localhost:443 user@my-host-name < / LI>
  • 在我的nginx框中,我已经加载了上面的配置。我打开chrome并点击2222.my-host-name就好像我正在直接点击我的网络应用程序框的URL / IP地址(由于反向代理,它只能在防火墙后面)。点击1111.my-host-name会将我带到另一个网络应用程序框,这是完全独立的并通过一个完全独立的隧道。

答案 1 :(得分:0)

您应该可以使用url-rewriting rule组合删除指定端口的数字和named capture来提取requested_port作为{{{1}的可用变量。 1}}指令。

proxy_pass