配置Nginx以根据端口号将代理请求反转到后端服务器

时间:2017-07-28 19:13:58

标签: nginx reverse-proxy

我在端口8888,8088,8042和8890上的一个ec2-instance中运行了四个Web应用程序,主机名为“ip-10-176-225-83.us-west-2.compute.internal”。这些Web应用程序在HTTP上。

我们的安全团队不允许从onpremise到AWS打开http端口。建议在相同的VPC子区域中设置反向代理,该子区域接收HTTPS请求并使用HTTP将其转发给后端Web服务器。

我在主机名为“ip-10-176-225-84.us-west-2.compute.internal”的同一子网中创建了一个新实例并安装了Niginx Server。

我如何配置Nginx以便它如下所示

https://ip-10-176-225-84.us-west-2.compute.internal:8080致电http://ip-10-176-225-83.us-west-2.compute.internal:8080并回复

其他端口相同

1 个答案:

答案 0 :(得分:3)

TL; DR:有几种方法可以完成你在这里寻找的东西。

在可能的情况下坚持减少attack surface的原则,除非绝对必要,否则通常最好不要将端口暴露给公共互联网。反向代理是实现此目的的绝佳方法。通常,您希望所有后端Web应用程序都通过端口443上的HTTPS进行反向代理,您可以访问每个服务:

  • 使用不同的主机名,例如app1.example.comapp2.example.com
  • 包含不同的子目录,例如example.com/app1example.com/app2

根据您选择的方法,配置可能会有很大差异,前一个方案有多个server块,后者有location块。在任何一种情况下,我们都将使用upstreamproxy_pass指令。我将举两个场景的例子。

多个主机

如果您为前端使用多个主机名(或多个端口),则需要为它们创建多个server块:

# Nginx reverse-proxy configuration
upstream app1 {
    server 10.176.225.83:8888;
}

upstream app2 {
    server 10.176.225.83:8088;
}

upstream app3 {
    server 10.176.225.83:8042;
}

upstream app4 {
    server 10.176.225.83:8890;
}

server {
    listen 443 ssl;
    server_name app1.example.com;

    ssl_certificate_key /path/to/your/ssl-key.pem;
    ssl_certificate /path/to/your/ssl-cert.pem;

    location / {
        proxy_pass http://app1;
    }
}

server {
    listen 443 ssl;
    server_name app2.example.com;

    ssl_certificate_key /path/to/your/ssl-key.pem;
    ssl_certificate /path/to/your/ssl-cert.pem;

    location / {
        proxy_pass http://app2;
    }
}

server {
    listen 443 ssl;
    server_name app3.example.com;

    ssl_certificate_key /path/to/your/ssl-key.pem;
    ssl_certificate /path/to/your/ssl-cert.pem;

    location / {
        proxy_pass http://app3;
    }
}

server {
    listen 443 ssl;
    server_name app4.example.com;

    ssl_certificate_key /path/to/your/ssl-key.pem;
    ssl_certificate /path/to/your/ssl-cert.pem;

    location / {
        proxy_pass http://app4;
    }
}

这里有几点需要注意:

  • 所有后端都已使用upstream指令在顶部定义,现在可以通过名称引用。
    • 如果您不想这样做,可以省略upstream块,proxy_pass行看起来像这样:proxy_pass http://10.176.225.83:8888;
  • 由于每个应用都在不同的主机名上提供,因此每个应用都会获得自己的server块。如果它们分别在不同的端口上提供服务,也会出现这种情况。
  • 如果您在证书中定义了多个SANs,则每个ssl_certificate块中的ssl_certificate_keyserver可以指向不同的证书,甚至是同一个证书。
  • 每个应用程序都可以从自己的主机名获得,这些主机名都指向前端服务器:
    • 应用1:https://app1.example.com
    • 应用2:https://app2.example.com
    • 应用3:https://app3.example.com
    • 应用4:https://app4.example.com

多个目录

对于使用单个主机和端口的配置,从子目录提供后端应用程序,您将使用具有多个server块的单个location块:

# Nginx reverse-proxy configuration
upstream app1 {
    server 10.176.225.83:8888;
}

upstream app2 {
    server 10.176.225.83:8088;
}

upstream app3 {
    server 10.176.225.83:8042;
}

upstream app4 {
    server 10.176.225.83:8890;
}

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate_key /path/to/your/ssl-key.pem;
    ssl_certificate /path/to/your/ssl-cert.pem;

    location /app1 {
        proxy_pass http://app1;
    }

    location /app2 {
        proxy_pass http://app2;
    }

    location /app3 {
        proxy_pass http://app3;
    }

    location /app4 {
        proxy_pass http://app4;
    }
}

这一点需要注意的一些事项:

  • 我们仍然像以前一样定义所有四个upstream服务。如果你更喜欢直接路线,你仍然可以省略它们。该指令在复杂配置中更有用。
  • 由于所有应用都是使用相同的主机名提供的,因此它们共享一个server块,但为各自的子目录分别设置location块。
  • 由于它们共享相同的主机名,因此在这种情况下,服务器证书不需要多个SAN。
  • 每个后端应用程序都可以从前端服务器上的子目录中获得:
    • 应用1:https://example.com/app1
    • 应用2:https://example.com/app2
    • 应用3:https://example.com/app3
    • 应用4:https://example.com/app4

TLS配置

在任一情况下,您都需要配置SSL证书(由公共CA签名)或内部PKI(如果适用)。如果您的应用要面向公众,则需要使用公共证书。然后你将他们的位置添加到上面的Nginx配置。

进一步阅读

对于一个真实世界的例子,你可以查看我用于Genieacs TR-069服务器的Nginx配置,implements SSLreverse proxies几个其他服务,虽然在他们的原始端口上,如果您想将它们保留在原始端口上,这可能很有用。

Nginx站点在反向代理基本配置上也有decent primer