NodeJS在ElasticBeanstalk上接受对80端口的访问的过程

使用Elastic Beanstalk的NodeJS平台创建应用程序后,可以轻松地得到一个可以通过80端口访问的Web应用程序。

但是 NodeJS监听的是8081端口,而不是80端口,于是我查找了一下通过什么路径接收到来自80端口的访问。

端口转发过程(结论)

    • iptables (PREROUTING)

転送ポート: 80 –> 8080

nginx (Proxy)

転送ポート: 8080 –> 8081

node (Server)

首先,iptables将访问80号端口的请求转发到8080端口,
然后,正运行在监听8080端口的nginx将请求转发到8081端口,
接下来,正运行在监听8081端口的NodeJS将处理该请求。

通常,0到1023号端口被称为“众所周知的端口”,在Linux上如果没有root权限,则无法进行端口监听。

使用root用户运行node进程是危险的,但通过进行端口转发可以在一般用户下启动。

在 ElasticBeanstalk 上,node 进程是由 nodejs 用户启动的。

以上所述的信息来源

进入EC2实例并进行以上提到的调查时记下的笔记。
省略了与此无关的输出内容的部分。

iptables的配置

已创建一个将接收到的80端口访问转发到8080端口的NAT。
当EC2实例接收到访问时,首先会在PREROUTING链中进行处理。

$ sudo iptables -t nat -S PREROUTING -v
-A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -c 0 0 -j REDIRECT --to-ports 8080

nginx 的配置

将从 8080 接收的访问转发到 8081 的代理设置。
虽然与主题无关,但通信的 gzip 压缩和展开也在此层级进行。

$ cat /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf
upstream nodejs {
    server 127.0.0.1:8081;
}

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;
gzip_comp_level 4;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

相关进程的端口监听状态

可以看出,节点在8081上监听,nginx在8080上监听。

$ sudo netstat -anp
tcp        0      0 :::8081                     :::*                        LISTEN      2969/node
tcp        0      0 0.0.0.0:8080                0.0.0.0:*                   LISTEN      2977/nginx

NodeJS 在启动时的环境变量

由于端口是8081,因此Node会监听8081端口。

$ sudo od -S1 -An /proc/$(ps aux | grep ^nodejs | perl -anlE 'say $F[1]' | tail -1)/environ
PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin:/opt/elasticbeanstalk/node-install/node-v6.11.5-linux-x64/bin
SHELL=/bin/sh
TERM=linux
EB_NODE_COMMAND=node app.js
USER=nodejs
PWD=/var/app/current
HOME=/tmp
SHLVL=1
UPSTART_INSTANCE=
LOGNAME=nodejs
PORT=8081
UPSTART_JOB=nodejs
NODE_HOME=/opt/elasticbeanstalk/node-install/node-v6.11.5-linux-x64
_=/opt/elasticbeanstalk/node-install/node-v6.11.5-linux-x64/bin/node

NodeJS 的默认应用程序源代码

如上所示,环境变量 PORT 设置为 8081 ,因此监听 8081 端口。

var port = process.env.PORT || 3000,
    http = require('http'),
    fs = require('fs'),
    html = fs.readFileSync('index.html');

var log = function(entry) {
    fs.appendFileSync('/tmp/sample-app.log', new Date().toISOString() + ' - ' + entry + '\n');
};

var server = http.createServer(function (req, res) {
    // 省略
});
bannerAds