そうだ、教祖になろう。出エジプト記 第2章2節の続き CloudFront以外からAPI Gatewayへのアクセスを閉じる
正面玄関におまわりください。
どうも「続き」とか「訂正」が多いですね。
前回の第2章2節 CloudFrontでAPI Gatewayを同一ドメイン化するではCloudFrontとAPI Gatewayを連携させました。
S3のときと同じく、CloudFrontの裏側にあるAPI Gatewayへの直接アクセスを防ぎたいと思います…
が、何がベストプラクティスなのかなかなかわからず、困りました。
思えば、毎回困ってばかりの気がします。
乳と蜜の流れる地はまだまだ遠いようです。
教祖です。
S3との連携のときは、CloudFrontがOAI(Origin Access Identity)を作ってくれて、S3のバケットポリシーまで書き換えてくれました。
しかし、いたれりつくせりはOriginがS3バケットのときだけで、API Gatewayはカスタムオリジンのため、対象外のようです。
ちぇっ。
こちらによると
API Gatewayには、APIキー認証以外にアクセス制限の機能がありません。(中略) また、API Gatewayへの直アクセスを禁止したい場合は、前述のAPIキー認証を有効化し、先日追加されたオリジンへのヘッダ追加機能でCloudFrontのオリジン設定にx-api-keyヘッダを追加、設定することで対応できます。
ということです。
APIキーは、簡単に言うとリクエストヘッダに埋め込んだ文字列が合っていればOKという仕組みです。
AWS本家だと、APIキーはあくまで利用量の管理用だから認証に利用するなよー!Cognito(認証サービス)使えよー!という記述が多くみられるので避けていたのですが、サービス間連携の認証であれば使ってもいいようです。
勝手口は閉鎖いたしました。
「リソース」でAPI Gatewayリソース下の「ANY」を選択して「メソッドリクエスト」をクリック。
「APIキーの必要性」を「true」に変更。
ステージをデプロイしなおします。
「ステージ」の「ステージの削除」をクリック。
「リソース」の「アクション」から「APIのデプロイ」をクリック。
APIキーを作ります。
API Gatewayで「APIキー」を選択、「アクション」から「APIキーの作成」をクリック。
適当な名前を入力しして、「保存」をクリック。
次に使用量プランを作ります。APIキーだけでいいかとおもったら使用量プランに紐づけないと動作しないようです。
「使用量プラン」を選択して、「作成」をクリック。
「名前」を適当に入力、「スロットリング」の「レート」、「バースト」、「クォータ」を適当に入力します。
期せずして予算管理っぽくなっていますね。
必要に応じてあとで変えましょう。
「APIステージの追加」をクリックしてデプロイしたステージを紐づけます。
「API」と「ステージ」を選択。
「次へ」。
APIキーを紐づけます。
「APIキーを使用量プランに追加」をクリック。
APIキーを登録。
「完了」。
これでAPIキーがないとアクセスできない状態になりましたので、一度直アクセスしてみます。
API GatewayのURL+/
+リソース名にアクセスします。
HTTPステータスコード403、ボディとして{"message":"Forbidden"}
が返されました。
よしよし。
次にCloudFront側です。
先にCloudFrontからのリクエストに埋め込むAPIキーを確認しておきます。
API Gatewayの「APIキー」の「表示」をクリック。
Distributionを選択して「Distribution Settings」をクリック。
「Origins and Origin Groups」タブのAPI Gatewayを選択して、「Edit」をクリック。
「Origin Custom Headers」の「Header Name」にx-api-key
、「Value」にAPI Gatewayで作成したAPIキーを入力。
「Yes, Edit」をクリックしてデプロイを待ちます。
ではアクセスしてみましょう。
CloudFrontのドメイン名+/
+リソース名にアクセスすると、
お!Lambdaの結果が表示されました。
ちょっとしたことかもしれませんが、やっぱり動くと嬉しいですね。