😎

EC2にNginxをインストールしてリバースプロキシとして利用してみた

2024/01/18に公開

この記事は閉鎖済みの個人で運営していたサイトで2023/10/8に公開したものを移記したものです(移記にあたり多少編集しています)。

Nginxのリバースプロキシの設定をしたことがなかったのでやってみました。
動作確認をしたかっただけ&Nginxをあまり触ったことがないので、キャッシュなど細かな設定などは行っていません。

以下の構成で2台のEC2インスタンスを起動します。

両方ともNginxをインストールし、片方はリバースプロキシの、片方はWebサーバの役割です。

今回は AmazonLinux2023(ami-08a706ba5ea257141、al2023-ami-2023.2.20231002.0-kernel-6.1-x86_64)で起動しました。

セキュリティグループのインバウンドルールは、リバースプロキシ用インスタンスでは自宅のIPアドレスのみを許可(HTTP)、Webサーバではリバースプロキシのセキュリティグループのみを許可(HTTP)しています。アウトバウンドルールはフルオープンです。

本来ならWebサーバはプライベートサブネットに配置されると思いますが、Nginx インストール時に必要なNATゲートウェイなどの料金を嫌ってパブリックサブネットに配置しています。

まずは Session Manager を利用して両方のインスタンスに接続し、Nginx をインストールします。
AL2023ではデフォルトのパッケージ管理ツールはDNFです)。

上述していませんでしたが、インスタンスには Session Manager に必要な権限を持つIAM ロールを設定しています。Session Manager の暗号化オプションやロギングオプションを選択していなければ AmazonSSMManagedInstanceCore 管理ポリシーを有する IAM ロールであれば接続できるはずです。

sh-5.2$ sudo dnf -y update
sh-5.2$ sudo dnf -y install nginx

次に、公式ドキュメント参考にリバースプロキシ用のNginxの設定ファイルのserverディレクティブにリバースプロキシの設定を追加します。

location / {
  proxy_pass http://<Webサーバ用EC2インスタンスのプライベートIPアドレス>;
}

リバースプロキシサーバの準備が完了したので、Nginxサービスを起動します。

sh-5.2$ sudo systemctl start nginx
sh-5.2$ systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; preset: disabled)
     Active: active (running) since Sun 2023-10-08 11:12:31 UTC; 11s ago
    Process: 26457 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
    Process: 26458 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
    Process: 26459 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
   Main PID: 26460 (nginx)
      Tasks: 2 (limit: 1114)
     Memory: 2.2M
        CPU: 57ms
     CGroup: /system.slice/nginx.service
             ├─26460 "nginx: master process /usr/sbin/nginx"
             └─26461 "nginx: worker process"

Webサーバ用のコンテンツが返却されることを確認するため、Webサーバ用のNginxで表示されるページの内容を変更します。
まず、表示されるページの内容を確認するため、設定ファイルを確認します。

sh-5.2$ cat /etc/nginx/nginx.conf
(省略)
    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;
(省略)
    }

/usr/share/nginx/htmlがルートドキュメントであることがわかったので、同ディレクトリ配下のindex.htmlの内容を以下に変更します。

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Nginx Web Server!!</h1>
<p>Amazon Linux2023</p>

</body>
</html>

そして、Webサーバ用Nginxを起動します。

sh-5.2$ sudo systemctl start nginx
sh-5.2$ systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; preset: disabled)
     Active: active (running) since Sun 2023-10-08 11:20:27 UTC; 6s ago
    Process: 26021 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
    Process: 26022 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
    Process: 26023 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
   Main PID: 26024 (nginx)
      Tasks: 2 (limit: 1114)
     Memory: 2.2M
        CPU: 58ms
     CGroup: /system.slice/nginx.service
             ├─26024 "nginx: master process /usr/sbin/nginx"
             └─26025 "nginx: worker process"

最後に、リバースプロキシ用のEC2インスタンスのパブリックIPアドレスにアクセスし、Webサーバ用のEC2インスタンスのコンテンツが返却されることを確認します。

ローカルPCからcurlでリバースプロキシ用インスタンスにアクセスし、Webサーバ用インスタンスのコンテンツが返却されたことを確認できました。

$ curl <リバースプロキシ用インスタンスのパブリックIPアドレス>
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Nginx Web Server!!</h1>
<p>Amazon Linux2023</p>

</body>
</html>

やりたいことは完了したのですが、以前の記事で複数ドメインで異なるコンテンツを返却する方法を試したことがありました。

https://zenn.dev/kazu_o/articles/68e22dd370a0bb

気になったので、以下のように、あるドメインではリバースプロキシ用のインスタンスのコンテンツを返却し、あるドメインではWebサーバ用のインスタンスのコンテンツを返却することができるか試してみます。

リバースプロキシ用のインスタンスで、Nginxの設定を変更します。

    server {
        listen       80;
        listen       [::]:80;
        server_name  sub1.xxx.com;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }

    server {
        listen       80;
        listen       [::]:80;
        server_name  sub2.xxx.com;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
        location / {
          proxy_pass http://<Webサーバ用EC2インスタンスのプライベートIPアドレス>;
        }
    }

sub1.xxx.com のアクセスではリバースプロキシ用インスタンスのコンテンツが返却され、sub2.xxx.com のアクセスではWebサーバ用インスタンスのコンテンツが返却される内容です。

設定変更後、Nginxの設定を反映させます。

sh-5.2$ sudo nginx -s reload

各ドメインのAレコードにリバースプロキシ用EC2インスタンスのパブリックIPアドレスを設定します。
設定後、digやnslookコマンドで名前解決可能か確認します。

名前解決ができたらcurlでそれぞれのドメインにアクセスし、意図した挙動となるか確認します。

$ curl sub1.xxx.com     
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

$ curl sub2.xxx.com     
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Nginx Web Server!!</h1>
<p>Amazon Linux2023</p>

</body>
</html>

sub1.xxx へのアクセスでリバースプロキシ用インスタンスのコンテンツが返却され、sub2.xxx.comへのアクセスでWebサーバ用インスタンスのコンテンツが返却されることが確認できました。

Discussion