LoginSignup
7
3

More than 5 years have passed since last update.

ElasticBeanstalk 上の NodeJS が80番ポートへのアクセスを受けるまでの流れ

Last updated at Posted at 2018-01-24

Elastic Beanstalk の NodeJS Platform でアプリケーションを作成すると
80 ポートでアクセスできる Web アプリケーションが簡単に出来上がる。

しかし NodeJS は 80 番ポートとは異なるポート 8081 番を Listen しており、
どういった経路で 80 番からのアクセスを受けているのか調べた。

ポート転送の流れ (結論)

  • iptables (PREROUTING)
    • 転送ポート: 80 --> 8080
  • nginx (Proxy)
    • 転送ポート: 8080 --> 8081
  • node (Server)

まず 80 番ポートへのアクセスを iptables が 8080 に変換し、
次に LISTEN 8080 の状態で起動している nginx が 8081 に転送、
次に LISTEN 8081 の状態で起動している NodeJS がリクエストを処理する。

一般的に 0 ~ 1023 番のポートは「well known port」と呼ばれ、Linux では root 権限がないとポートの Listen が出来ない。

root ユーザで node プロセスを動かすことは危険だが、
このようにポート転送することで一般ユーザで起動することが出来る。

ElasticBeanstalk では node プロセスは nodejs ユーザが起動していた。

上記の情報元

EC2 インスタンスに入って上記を調べた時のメモ。
関係のない出力内容は一部割愛。

iptables の設定

80 で受けたアクセスを 8080 へ転送する NAT が作成されている。
PREROUTING チェインのため EC2 インスタンスがアクセスを受けた時にまず処理される。

$ 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;

関連プロセスの Port Listen 状況

node が 8081, nginx が 8080 をそれぞれ Listen していることが分かる。

$ 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 起動時の環境変数

PORT=8081 とあるので node は 8081 を Listen する。

$ 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 ポートが Listen される。

app.js
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) {
    // 省略
});
7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3