CloudFront 適用済みの WordPress サイトに ALB を適用してみる

# ０．はじめに

先日、こちらの記事の対応を行ったんですが、

* [SSL 化済みの WordPress サイトに CloudFront を適用してみる \- Qiita](https://qiita.com/kusokamayarou/items/21e4bcdaa7c8dd8523ab)

EC2 への直接アクセスでのアタックがあり、CloudFront と EC2 との間に ALB を入れ、EC2 への直接アクセスを制限してみます。

こんな感じ。

![名称未設定.001.jpeg](https://qiita-image-store.s3.amazonaws.com/0/161939/73586898-051c-9990-25b1-0c781349b4b8.jpeg)

# １．ALB 用の ACM を作成する
1. 以前バージニアリージョンに ACM を作成したので、同様の手順で該当リージョンにも作成します。
    * [SSL 化済みの WordPress サイトに CloudFront を適用してみる \- Qiita](https://qiita.com/kusokamayarou/items/21e4bcdaa7c8dd8523ab#3aws-certificate-manager-%E3%81%A7%E3%81%AE%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%81%AE%E4%BD%9C%E6%88%90%E3%81%A8-dns-%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E7%99%BB%E9%8C%B2)
    * <font color="red"><b>※以前登録しているので、DNS レコードの設定は不要。</b></font>
    * ![FireShot Capture 020 - AWS Certificate Manager - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/16e6d364-5d3f-e4e6-75c4-baeb72d14f89.png)

# ２．ALB 用のセキュリティグループを作成する
1. CloudFront からのリクエストを HTTPS (443) でのみ受け入れたいので、以下のセキュリティグループを作成します。
    * タイプ：HTTPS、プロトコル：TCP、ポート範囲：443、ソース：0.0.0.0/0, ::/0
    * ![FireShot Capture 023 - セキュリティグループ - EC2 Management Console - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/d914540e-dfd0-f71f-3dd5-da5ad9f5dfa5.png)

# ３．ALB を作成する
1. 以下のページの手順に従って、ALB を作成します。
    * [ELB\(ALB\)1つで複数のバーチャルホストに対応する Host\-based routing \| システムガーディアン株式会社](https://sys-guard.com/post-15772/)
    * <font color="red"><b>注意する点は、以下。</b></font>
        * <font color="red"><b>リスナーの設定において、ホストベースの設定を行い、各ターゲットグループにちゃんと振り分ける。</b></font>
            * [Application Load Balancer のリスナー \- Elastic Load Balancing](https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-listeners.html)
        * <font color="red"><b>各ターゲットグループの設定において、ヘルスチェックの「プロトコル」と「パス」を各サイトに合わせて設定する。</b></font>
            * [AWS上にWordPressを構築してHTTPS化する方法 \- ブロックチェーンエンジニアとして生きる](https://tomokazu-kozuma.com/how-to-build-wordpress-on-aws-and-make-it-https/)
    * ![FireShot Capture 031 - EC2 Management Console - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/1ba5ea97-620f-d58b-f1fd-50c06238ec8b.png)
    * ![FireShot Capture 033 - EC2 Management Console - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/83ac2d39-5c96-3ebb-5510-a84441190e5e.png)
    * ![FireShot Capture 035 - EC2 Management Console - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/cd2785b1-f085-3d65-d0e7-f66f4cf799ea.png)
    * ![FireShot Capture 036 - EC2 Management Console - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/ac87be92-4977-b55a-1824-8334b9eb79b6.png)
    * ![FireShot Capture 037 - EC2 Management Console - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/c4b56352-1ed2-b9e6-bc0e-e8088ca506c2.png)
1. 以下のページの手順に従って、ALB のアクセスログの出力先を設定します。
    * [ALBのアクセスログ機能を設定してみた \| ナレコムAWSレシピ](https://recipe.kc-cloud.jp/archives/10675)
        * [Application Load Balancer のアクセスログ \- Elastic Load Balancing](https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-access-logs.html)
    * <font color="red"><b>以下、出力先の S3 のバケットポリシーの設定。</b></font>
    * ![FireShot Capture 039 - S3 Management Console - s3.console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/6fedece0-91f0-40a6-0941-5d7f352cd39e.png)

```json
{
    "Version": "2012-10-17",
    "Id": "PolicyXXXXXXXXXXXXX",
    "Statement": [
        {
            "Sid": "StmtXXXXXXXXXXXXX",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::582318560864:root"
            },
            "Action": "s3:PutObject",
            "Resource": [
                "arn:aws:s3:::[S3バケット名]/[プレフィックス]/AWSLogs/[アカウントID]/*"
            ]
        }
    ]
}
```

# ４．CloudFront のオリジンを EC2 から、ALB に変更する
1. 以下のオリジンを作成します。
    * Origin Domain Name : [作成した ALB の DNS 名]
    * Origin Path : -
    * Origin ID : ※「Origin Domain Name」入力により自動入力
    * Origin SSL Protocols : ※デフォルト
    * Origin Protocol Policy : 「HTTPS Only」を選択
    * Origin Response Timeout : ※デフォルト
    * Origin Keep-alive Timeout : ※デフォルト
    * HTTP Port : ※デフォルト
    * HTTPS Port : ※デフォルト
    * Origin Custom HeadersHeader NameValue :
        * x-pre-shared-key : ※任意 (最大５０文字)
            * <font color="red"><b>※６．の ALB の AWS WAF の設定に利用するので、50文字の不規則の文字列が良いかと。</b></font>
            * [AWS WAFを利用してCloudFrontのELBオリジンへ直接アクセスを制限してみた ｜ DevelopersIO](https://dev.classmethod.jp/cloud/aws/restrict-elb-origin-awswaf/)
    * ![FireShot Capture 025 - AWS CloudFront Management Console - console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/e76997ef-c7cd-c5d4-b0ef-a2dddadac66b.png)
1. 各種 Behavior において、「Origin or Origin Group」の設定を作成した ALB のオリジンに変更します。
    * ![FireShot Capture 026 - AWS CloudFront Management Console - console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/9de4534f-41ee-e84b-77bf-0ee364aed557.png)

# ５．EC2 のセキュリティグループを変更し、EC2 へのアクセスを ALB のみにする
1. ALB からの HTTPS (443) のリクエストのみ受け入れたいので、インバウンドルールをセキュリティグループに設定します。
    * タイプ：HTTPS、プロトコル：TCP、ポート範囲：443、ソース：[ALBに設定したセキュリティグループID]
    * ![FireShot Capture 024 - セキュリティグループ - EC2 Management Console - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/ec9c9d7d-1cc3-549a-2ac7-d45de9592007.png)
    * ※参考 :
        * [ELB 経由で EC2 にアクセスする \- Qiita](https://qiita.com/kasaharu/items/02564b5b139b80574f4a)
        * [EC2へのアクセスをALBからのみに制限する方法 \- ブロックチェーンエンジニアとして生きる](https://tomokazu-kozuma.com/how-to-restrict-access-to-ec-2-only-from-alb/)

# ６．ALB に AWS WAF を設定し、ALB へのアクセスを CloudFront のみにする
1. 以下のページの手順に従って、ALB に AWS WAF を設定します。
    * [AWS WAFを利用してCloudFrontのELBオリジンへ直接アクセスを制限してみた ｜ DevelopersIO](https://dev.classmethod.jp/cloud/aws/restrict-elb-origin-awswaf/)
    * <b>※ Web ACL の設定</b>
    * ![FireShot Capture 040 - AWS WAF & Shield - console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/81b5ef78-107e-5079-4e41-b62f1821ba76.png)
    * ![FireShot Capture 041 - AWS WAF & Shield - console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/ba8df71c-9c4a-534d-4f2e-ccfc6c109f75.png)
    * <b>※ Web ACL - Rule (rule-cfg-header-check) の設定</b>
    * ![FireShot Capture 042 - AWS WAF & Shield - console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/583bec8a-1bea-57af-ec25-ebc6f643b8e3.png)
    * <b>※ Web ACL - String and regex match condition (check-cf-header) の設定</b>
    * ![FireShot Capture 044 - AWS WAF & Shield - console.aws.amazon.com.png](https://qiita-image-store.s3.amazonaws.com/0/161939/db36f87a-cf10-cb0e-3b55-ac1f4bde2a13.png)

# ９９．ハマりポイント

* そこまでハマった訳ではないですが…。
<br><br>
* ALB 作成時、ターゲットグループ作成において、「登録済みに追加」ボタンを押下するのを忘れて、ウンウン唸ってました…。わかりづらかったっす…。随分と無駄な時間を…。orz…。
<br><br>
* あとは、５.の EC2 へのアクセスを ALB のみにするやり方がわからなくてかなり苦労しました…。
* セキュリティグループで出来るなんて、目から鱗!!
* 他にも色々応用できそう♪

# ＸＸ．まとめ

これで、セキュリティ的にも、パフォーマンス的にも、最適な構成になったんじゃないかと思います。
まだ残ってることとしては、ALB - EC2 間を HTTP (80) にするとかはやっても良いかなと。
そうすれば、EC2 の SSL 証明書が不要になるので、証明書の更新作業も不要になってメンテナンス作業も楽になるかと。

ただ、
ここまでやってみて思ったんですが…、Shifter 使えば全部楽になったりするんじゃ？
と思ったりも…。 

* [Shifter – Serverless Static WordPress ホスティングサービス「Shifter」](https://www.getshifter.io/japanese/)

今後その辺試してみようかとも思います。

何かご参考になれば。

では♪

👋