【Nginx】リバースプロキシサーバ構築

##目標
・Nginxを利用してリバースプロキシサーバを構築する
・Nginxのキャッシュ機能を有効化させる

##前提
・構築済みのAWS EC2サーバがあること（AWS EC2を利用することは必須ではございません）
・基本的なLINUXコマンド操作が出来ること
・WEBサーバの基礎知識があること

##利用環境
ハードウェア　：　**AWS EC2サーバ 1台**
OS（AMI）　:　**Amazon Linux 2 AMI (HVM), SSD Volume Type**
ミドルウェア　：　**Apache/2.4.43**、**nginx/1.12.2**

##完成フロー
①クライアントユーザがWEBアクセスする。
②リバースプロキシサーバ（80番ポート）がキャッシュ情報を所持していれば、
キャッシュ情報をレスポンスとして返し通信終了
\---------------------------------------------------------------------------
③キャッシュ情報を所持していない場合、WEBサーバ（8080番ポート）へポート間接続
④WEBサーバがリバースプロキシサーバへWEBページ返し、それをクライアントユーザへレスポンスとして返す。

![Untitled Diagram (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/75c5cbca-f7a4-1cc8-af2a-2ccc2ae26410.png)



##リバースプロキシサーバを利用するメリット
多様なメリットがありますが、
「キャッシュ機能によるWEBサーバの負荷軽減」が一番大きなメリットかと思います。

※リバースプロキシの基本情報やその他メリットについて
リバースプロキシとは？仕組みをわかりやすく解説
https://www.kagoya.jp/howto/network/reverse-proxy/


##作業の流れ
| 項番 | タイトル |
|:----:|:-------------|
| 1 | [利用EC2のセキュリティグループ確認](#1-利用ec2のセキュリティグループ確認) |
| 2 | [Apache(httpd)のインストールと起動](#2-apachehttpdのインストールと起動)|
| 3 | [Nginxのインストールと起動](#3-nginxのインストールと起動)|
| 4 | [リバースプロキシサーバの構築](#4-リバースプロキシサーバの構築)|
| 5 | [動作検証](#5-動作検証)|

##手順
###1. 利用EC2のセキュリティグループ確認
**①EC2のセキュリティグループを確認**
22番（SSH）、80番(リバースプロキシ用)を空けます。
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/6159378d-2fb2-d951-30d2-dca622b902a4.png)

###2. Apache(httpd)のインストールと起動
**①Apache(httpd)インストール**
`yum install httpd`実行
⇒`Complete!`と出力されること。

```bash

[root@ip-172-31-45-88 ~]# yum install httpd
Installed:
  httpd.x86_64 0:2.4.43-1.amzn2

Dependency Installed:
  apr.x86_64 0:1.6.3-5.amzn2.0.2                        apr-util.x86_64 0:1.6.1-5.amzn2.0.2                apr-util-bdb.x86_64 0:1.6.1-5.amzn2.0.2
  generic-logos-httpd.noarch 0:18.0.0-4.amzn2           httpd-filesystem.noarch 0:2.4.43-1.amzn2           httpd-tools.x86_64 0:2.4.43-1.amzn2
  mailcap.noarch 0:2.1.41-2.amzn2                       mod_http2.x86_64 0:1.15.3-2.amzn2

Complete!
```

**②httpdの起動ポート変更**
httpdはデフォルト80番ポートなので8080番ポート起動に変更します。
httpdのメイン設定ファイルである`httpd.conf`の`Listen`ディレクティブを以下のように編集します。

```bash

ファイルパス: /etc/httpd/conf/httpd.conf
```

```bash

# httpdが8080番ポートで待ち受け
Listen 8080
```

**③httpd起動**
`systemctl start httpd`でhttpd起動
⇒エラーメッセージが出力されないこと

```bash

[root@ip-172-31-45-88 ~]# systemctl start httpd
[root@ip-172-31-45-88 ~]#
```

`systemctl status httpd`でhttpdの状態確認
⇒状態が`active (running)`であること

```bash

[root@ip-172-31-45-88 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) since Mon 2020-06-15 10:54:43 UTC; 6s ago
     Docs: man:httpd.service(8)
 Main PID: 708 (httpd)
   Status: "Processing requests..."
   CGroup: /system.slice/httpd.service
           tq708 /usr/sbin/httpd -DFOREGROUND
           tq709 /usr/sbin/httpd -DFOREGROUND
           tq710 /usr/sbin/httpd -DFOREGROUND
           tq711 /usr/sbin/httpd -DFOREGROUND
           tq712 /usr/sbin/httpd -DFOREGROUND
           mq713 /usr/sbin/httpd -DFOREGROUND

Jun 15 10:54:43 ip-172-31-45-88.ap-northeast-1.compute.internal systemd[1]: Starting The Apache HTTP Server...
Jun 15 10:54:43 ip-172-31-45-88.ap-northeast-1.compute.internal systemd[1]: Started The Apache HTTP Server.
```

8080番ポートが開いているかも一応確認します。
` netstat -atn | grep 8080`実行
⇒検索がヒットすること

```bash

[root@ip-172-31-45-88 ~]# netstat -atn | grep 8080
tcp6       0      0 :::8080                 :::*                    LISTEN
```

**④WEBページ配備**
httpdのドキュメントルート(恐らく`/var/www/html`です）に適当なhtmlファイルを配備しておきます。

###3. Nginxのインストールと起動
**①Nginxインストール**
いきなりyum installを実行したら、Amazon Linux 2では利用できないパッケージとのことエラー出ました。

```bash

[root@ip-172-31-45-88 ~]# sudo yum install nginx
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                            | 3.7 kB     00:00
No package nginx available.
Error: Nothing to do


nginx is available in Amazon Linux Extra topics "nginx1.12" and "nginx1"

To use, run
# sudo amazon-linux-extras install :topic:

Learn more at
https://aws.amazon.com/amazon-linux-2/faqs/#Amazon_Linux_Extras

```

ですので言われた通り、`sudo amazon-linux-extras install nginx1.12`を実行
（エクストラパッケージというものらしい）

`Complete!`と出力されればOKです。


```bash

[root@ip-172-31-45-88 ~]# sudo amazon-linux-extras install nginx1.12
Installed:
  nginx.x86_64 1:1.12.2-2.amzn2.0.2

Dependency Installed:
  dejavu-fonts-common.noarch 0:2.33-6.amzn2                                 dejavu-sans-fonts.noarch 0:2.33-6.amzn2
  fontconfig.x86_64 0:2.13.0-4.3.amzn2                                      fontpackages-filesystem.noarch 0:1.44-8.amzn2
  gd.x86_64 0:2.0.35-26.amzn2.0.2                                           gperftools-libs.x86_64 0:2.6.1-1.amzn2
  libX11.x86_64 0:1.6.7-2.amzn2                                             libX11-common.noarch 0:1.6.7-2.amzn2
  libXau.x86_64 0:1.0.8-2.1.amzn2.0.2                                       libXpm.x86_64 0:3.5.12-1.amzn2.0.2
  libxcb.x86_64 0:1.12-1.amzn2.0.2                                          libxslt.x86_64 0:1.1.28-5.amzn2.0.2
  nginx-all-modules.noarch 1:1.12.2-2.amzn2.0.2                             nginx-filesystem.noarch 1:1.12.2-2.amzn2.0.2
  nginx-mod-http-geoip.x86_64 1:1.12.2-2.amzn2.0.2                          nginx-mod-http-image-filter.x86_64 1:1.12.2-2.amzn2.0.2
  nginx-mod-http-perl.x86_64 1:1.12.2-2.amzn2.0.2                           nginx-mod-http-xslt-filter.x86_64 1:1.12.2-2.amzn2.0.2
  nginx-mod-mail.x86_64 1:1.12.2-2.amzn2.0.2                                nginx-mod-stream.x86_64 1:1.12.2-2.amzn2.0.2

Complete!
```

**②Nginx起動**
`systemctl start nginx`でnginx起動
⇒エラーメッセージの出力がないこと

```bash

[root@ip-172-31-45-88 ~]# systemctl start nginx
[root@ip-172-31-45-88 ~]#
```

`systemctl status nginx`でnginxの状態確認
⇒状態が`active (running)`であること

```bash

[root@ip-172-31-45-88 ~]# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: active (running) since Mon 2020-06-15 11:06:52 UTC; 45s ago
  Process: 1386 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
  Process: 1383 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
  Process: 1382 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
 Main PID: 1389 (nginx)
   CGroup: /system.slice/nginx.service
           tq1389 nginx: master process /usr/sbin/nginx
           mq1391 nginx: worker process

Jun 15 11:06:52 ip-172-31-45-88.ap-northeast-1.compute.internal systemd[1]: Starting The nginx HTTP and reverse proxy server...
Jun 15 11:06:52 ip-172-31-45-88.ap-northeast-1.compute.internal nginx[1383]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
Jun 15 11:06:52 ip-172-31-45-88.ap-northeast-1.compute.internal nginx[1383]: nginx: configuration file /etc/nginx/nginx.conf test is successful
Jun 15 11:06:52 ip-172-31-45-88.ap-northeast-1.compute.internal systemd[1]: Failed to read PID from file /run/nginx.pid: Invalid argument
Jun 15 11:06:52 ip-172-31-45-88.ap-northeast-1.compute.internal systemd[1]: Started The nginx HTTP and reverse proxy server.
```

WEBブラウザでのアクセスを試してみます
EC2のグローバルIPアドレスをURL入力
⇒NginxのWelcomeページが表示されればOKです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/00877afc-1ace-ece3-1f94-0d28f3db5ebf.png)


###4. リバースプロキシサーバの構築
**①Nginxのメイン設定ファイル編集**
Nginxのメイン設定ファイルである`nginx.conf`の編集を開始します。

```bash

ファイルパス：　/etc/nginx/nginx.conf
```

まず`proxy_pass`というディレクティブにWEBサーバ（httpdへの8080番ポートローカル接続）のURLを値として記入します（該当箇所のみ抜粋）。

```bash
    server {
        location / {
            # WEBリクエストをローカルホスト8080番ポートへリダイレクト
            proxy_pass http://localhost:8080/;
        }
    }
```

更に、リバースプロキシのキャッシュ機能を有効化するため、以下のディレクティブを追加します（該当箇所のみ抜粋）（※）。

※本記事では詳細なディレクティブの内容説明を省略致します。
Nginxのキャッシュ機能詳細に関しては以下のサイトを参考にさせていただきました。

**nginx proxyキャッシュまとめ**
https://qiita.com/aosho235/items/bb1276a8c43e41edfc6f

**nginxのプロキシキャッシュ proxy_cache_path をまじめに設定したので備忘録メモ**
https://qiita.com/hidekuro/items/c5209e31a0d20f42dccc

```bash

http {
    # キャッシュファイルの保存場所等を定義
    proxy_cache_path /var/cache/nginx keys_zone=zone1:1m max_size=1g inactive=24h;

    # キャッシュの一時格納領域を定義
    proxy_temp_path  /var/cache/nginx_tmp;

    # オリジンから来るCache-Controlを無視する
    proxy_ignore_headers Cache-Control;

    server {
        location / {
            # キャッシュを有効化
            proxy_cache zone1;
            proxy_cache_valid 200 302 600s;

            # レスポンスヘッダにキャッシュヒットしたかどうかを含める
            add_header X-Nginx-Cache $upstream_cache_status;
        }
    }
}
```

**②Nginx再起動**
`systemctl restart nginx`実行

```bash

[root@ip-172-31-45-88 ~]# systemctl restart nginx
[root@ip-172-31-45-88 ~]#
```

###5. 動作検証
**①WEBブラウザアクセス**
リバースプロキシサーバとして動作しているサーバのIPアドレスをブラウザに入力します。
以下のようにhttpdのドキュメントルート(`/var/www/html`)に配備したWEBページが表示されれば、
リバースプロキシ⇔WEBサーバ間の接続が上手くいっておりOKです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/77441b04-167c-8070-b7b1-d98d7ef552bd.png)

**②キャッシュ動作検証**
リバースプロキシのキャッシュ機能が正常か検証を行います。
ブラウザの開発者モードからパケットヘッダの確認を行います。
Nginxの設定ファイル内で追加したヘッダである、`X-Nginx-Cache`の値が`HIT`(キャッシュによってレスポンスされた事を示します)であればOKです！（※）
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647616/baa92d41-0d21-3e20-8620-bf97eeed2c89.png)

※もし`MISS`(キャッシュでなくオリジナルページにアクセスしたことを表します)になったら
⇒初回アクセスであることが原因想定です。もう一度WEBリクエストをかけてください。

※もし`Expired`(キャッシュの有効期限切れ)になったら
⇒`/var/cache/nginx`配下に存在しているキャッシュ情報を削除して再度WEBアクセスしてください。