AmplifyにIP制限を設ける
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」から取得可能
Route53
- 作成したいホストゾーンを選択
- CNAMEでドメイン名を追加
- エイリアスで選択またはCFのDomainNameをコピペする
- 作成
- 設定したサブドメインで表示されることを確認
WAF
-
WebACLs作成
-
「Select a resource」でdistributionを選択
-
conditionを追加する
- 作成済のconditionがある場合は次のルール作成で選択出来る
- ない場合は「Create condition」から作成。許可するIPを設定する。
- 今回は作成済の「ip-match-condition」を利用する
-
ルールを作成する
- 任意の名前をつける
- Add conditions
- 「does」
- 「originate from an IP address in」
- 先程作成したconditionまたは既存のconditionを選択する
- 作成
- ルールを選択する
- 先程作成したルールを選択し「Add another rule」で追加する
- 今回はホワイトリスト形式としたいため、conditionにマッチするものはAllow
- 「DefaultAction」は「Block all requests ...」
困ったこと
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 アドレスベースのアクセス制限設定をする
Discussion