弹性豆茎怪异的nginx配置

时间:2014-09-27 00:24:53

标签: amazon-web-services nginx elastic-beanstalk

我正在尝试在弹性beanstalk上遵循nginx的配置,有些东西不会加起来。

  • 该实例在安全组中打开端口80,因此我假设所有传入流量都来自该端口

  • cat /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf中的nginx配置声明:

    server {
     listen 8080;
     location / {
        proxy_pass  http://nodejs;
        proxy_set_header   Connection "";
        proxy_http_version 1.1;
        proxy_set_header        Host            $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
     }
     gzip on;
    }
    

    8080端口?那个是从哪里来的?我试图搞砸它,这是实际的指令。

  • 缺少server_name,但是你输入的内容并不重要。如果我自己在server_name中添加任何值,则此服务器规则仍将匹配所有请求,即使是那些远程不能重置server_name值的请求。

  • 连接到实例本身时,似乎正在提供两个端口:

    [ec2-user @ ip-172-31-45-222~] $ sudo netstat -lnptu

    tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 22506 / nginx

    tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 22506 / nginx

然而,8080永远不会在安全组中打开,因此弹性负载平衡通过端口80进入内部。流量是否神奇地从80变为8080?任何想法在这里发生了什么?

1 个答案:

答案 0 :(得分:40)

您忘记查看该nginx配置的一部分:

upstream nodejs {
    server 127.0.0.1:8081;
    keepalive 256;
}

该部分告诉nginx制作一组名为nodejs的服务器,因为您可以阅读here

8081是运行NodeJS的端口(例如,如果您使用sample application)。

您可以通过查看Elastic Beanstalk日志验证这一点:

-------------------------------------
/var/log/nodejs/nodejs.log
-------------------------------------
Server running at http://127.0.0.1:8081/

然后,如果我们继续在nginx.conf文件中,我们可以看到你已发布的内容:

server {
    listen 8080;

    location / {
        proxy_pass  http://nodejs;
        proxy_set_header   Connection "";
        proxy_http_version 1.1;
        proxy_set_header        Host            $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    }


}

这告诉nginx使用proxy pass module将所有端口8080传递给在端口8081上运行的上游组nodejs。这意味着端口8081仅用于在本地访问它,但端口8080是什么让外部实体与nginx交谈,后者将内容传递给nodejs。

可以在this StackOverflow answer中找到一些不直接暴露NodeJS的原因。

使用端口8080,因为它是HTTP alternate port,通常用于Web代理和缓存服务器,或者用作非root用户运行Web服务器。"

这解释了港口。现在ELB的问题以及事情如何相互交谈。

由于安全组仅允许在端口80上进行访问,因此有一个iptables规则设置为将端口80转发到端口8080.这允许非root用户绑定到端口8080,因为较低的端口号需要root权限。 / p>

您可以通过运行以下内容来验证这一点:

[ec2-user@ip-xxx-xx-xx-x ~]$ sudo iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
REDIRECT   tcp  --  anywhere             anywhere             tcp dpt:http redir ports 8080

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
REDIRECT   tcp  --  anywhere             anywhere             tcp dpt:http redir ports 8080

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         

总而言之,当您加载CNAME时,负载均衡器正在将流量重新路由到端口80上的给定实例(允许通过安全组),然后iptables将其转发到端口8080,即端口8080 nginx正在使用代理将流量传递到端口8081,这是NodeJS的本地端口。

这是一张图表:

incoming connections
-> :80             - Load Balancer
-> :80             - Security group
-> :80   -> :8080  - EC2 instance, iptables forward
-> :8080 -> :8081  - nginx, proxy pass
-> :8081           - nodejs, your app

希望这有帮助。