📄

AmplifyにIP制限を設ける

2020/09/18に公開

Amplifyへファイヤーウォール機能の実装をするのに戸惑ったのでメモ

やりたかったこと

Amplifyでデプロイしたwebページを、特定のIPからしか閲覧出来ないようにする
(ホワイトリスト形式でIP制限をかける)

試したこと

  • Amplifyコンソールのアクセスコントロール

    • ベーシック認証のみ
  • AmplifyをWAFのリソースで選択出来ない...?

    • 自動デプロイで生成されるコンテンツやDistributionは、コンソールから見ることも触ることも出来ない...
  • CloudFrontでDistributionを作成し、Amplifyのドメインを設定してみる

こちらのissue によると、Amplifyの環境変数に謎の呪文を追加すると出来るようになるとかならないとか
  hosting機能でやってくれることを自分でやってるだけな気がしたので却下

結論 hosting + WAF

amplify add hosting で生成されるDistributionに対してWAFを設定するのが一番シンプル

hostingを作成する

Amplifyコンソールから作成出来る「Deploy」とは別のもの
1環境1つで、生成されたS3バケットとDistributionは各コンソールからいじることが出来る

$ amplify add hosting

? Select the environment setup:
  > PROD (S3 with CloudFront using HTTPS)  ※WAFを設定するためのCFが必要なのでPRODにする
? hosting bucket name
  > 任意のバケット名
? index doc for the website
  > index.html
? error doc for the website
  > error.html

$ amplify publish

S3

  • 作成されたS3バケットの「静的ウェブサイトホスティング」が無効化されていることを確認

CloudFront(CF)

  • デフォルトの*.cloudfront.comドメインで表示出来ていることを確認
  • 「Alternate Domain Names」にドメイン名を入力(例:hoge.sample.com)
  • 「CustomSSLCertificate」で証明書を選択
    • ない場合は「Request or Import a Certificate with ACM」から取得可能

スクリーンショット 2019-10-15 10.59.04.png

Route53

  • 作成したいホストゾーンを選択
  • CNAMEでドメイン名を追加
  • エイリアスで選択またはCFのDomainNameをコピペする
  • 作成
  • 設定したサブドメインで表示されることを確認

WAF

  • WebACLs作成

  • 「Select a resource」でdistributionを選択
    スクリーンショット 2019-10-15 13.18.06.png

  • conditionを追加する

    • 作成済のconditionがある場合は次のルール作成で選択出来る
    • ない場合は「Create condition」から作成。許可するIPを設定する。
    • 今回は作成済の「ip-match-condition」を利用する
      スクリーンショット 2019-10-16 10.32.36.png
  • ルールを作成する

    • 任意の名前をつける
    • Add conditions
      • 「does」
      • 「originate from an IP address in」
      • 先程作成したconditionまたは既存のconditionを選択する
    • 作成

スクリーンショット 2019-10-16 10.49.01.png

  • ルールを選択する
    • 先程作成したルールを選択し「Add another rule」で追加する
    • 今回はホワイトリスト形式としたいため、conditionにマッチするものはAllow
    • 「DefaultAction」は「Block all requests ...」

スクリーンショット 2019-10-16 10.34.02.png

困ったこと

vue-routerのhistoryモードが利用できない

AWS WAF は、指定した条件に基づいてウェブリクエストをブロックすると、CloudFront に HTTP ステータスコード 403 (Forbidden) を返します。

CloudFront は、オリジンによって返された HTTP ステータスコード 403 と、リクエストがブロックされたときに AWS WAF によって返された HTTP ステータスコード 403 とを区別できません。つまり、HTTP ステータスコード 403 のさまざまな原因に基づいて、異なるカスタムエラーページを返すことはできません。

公式ドキュメント

CloudFrontがリソースを見つけられなかった場合、 404 ではなく 403 が返ってくるが、
WAFによるアクセスブロックの 403 と区別されない仕様らしい

historyモードでルート以外のパスを叩くと403が返ってくるため、CFの設定で403の時は index.html を返すようにしていた
hashモードであればルーティング先はすべてアンカーとして渡されるため上記のエラーは起きない

ちょっと悔しいですが今回は仕方なくhashモードに切り替えました
なにか良い方法ご存知の方いらっしゃいましたら教えて下さい

参考

Amplify-CLI + Reactで超絶簡単ホスティング
CloudFront + S3 での IP アドレスベースのアクセス制限設定をする

株式会社find

Discussion