シャッフル主任の進捗報告

興味のあるものを作ります。進捗を不定期にご報告します。

そうだ、教祖になろう。出エジプト記 第2章2節の続き CloudFront以外からAPI Gatewayへのアクセスを閉じる

正面玄関におまわりください。


どうも「続き」とか「訂正」が多いですね。
前回の第2章2節 CloudFrontでAPI Gatewayを同一ドメイン化するではCloudFrontとAPI Gatewayを連携させました。

f:id:chief-shuffle:20191201235408p:plain

S3のときと同じく、CloudFrontの裏側にあるAPI Gatewayへの直接アクセスを防ぎたいと思います…
が、何がベストプラクティスなのかなかなかわからず、困りました。
思えば、毎回困ってばかりの気がします。
乳と蜜の流れる地はまだまだ遠いようです。

教祖です。

S3との連携のときは、CloudFrontがOAI(Origin Access Identity)を作ってくれて、S3のバケットポリシーまで書き換えてくれました。
しかし、いたれりつくせりはOriginがS3バケットのときだけで、API Gatewayはカスタムオリジンのため、対象外のようです。
ちぇっ。

こちらによると

dev.classmethod.jp

API Gatewayには、APIキー認証以外にアクセス制限の機能がありません。(中略) また、API Gatewayへの直アクセスを禁止したい場合は、前述のAPIキー認証を有効化し、先日追加されたオリジンへのヘッダ追加機能でCloudFrontのオリジン設定にx-api-keyヘッダを追加、設定することで対応できます。

ということです。

APIキーは、簡単に言うとリクエストヘッダに埋め込んだ文字列が合っていればOKという仕組みです。
AWS本家だと、APIキーはあくまで利用量の管理用だから認証に利用するなよー!Cognito(認証サービス)使えよー!という記述が多くみられるので避けていたのですが、サービス間連携の認証であれば使ってもいいようです。

勝手口は閉鎖いたしました。


「リソース」でAPI Gatewayリソース下の「ANY」を選択して「メソッドリクエスト」をクリック。

f:id:chief-shuffle:20191203053223j:plain

APIキーの必要性」を「true」に変更。

f:id:chief-shuffle:20191203060022j:plain

ステージをデプロイしなおします。
「ステージ」の「ステージの削除」をクリック。

f:id:chief-shuffle:20191203053351j:plain

「リソース」の「アクション」から「APIのデプロイ」をクリック。

f:id:chief-shuffle:20191203053425j:plain

APIキーを作ります。

API Gatewayで「APIキー」を選択、「アクション」から「APIキーの作成」をクリック。

f:id:chief-shuffle:20191203052724j:plain

適当な名前を入力しして、「保存」をクリック。

f:id:chief-shuffle:20191203052734j:plain

次に使用量プランを作ります。APIキーだけでいいかとおもったら使用量プランに紐づけないと動作しないようです。

「使用量プラン」を選択して、「作成」をクリック。

f:id:chief-shuffle:20191203052746j:plain

「名前」を適当に入力、「スロットリング」の「レート」、「バースト」、「クォータ」を適当に入力します。
期せずして予算管理っぽくなっていますね。
必要に応じてあとで変えましょう。

f:id:chief-shuffle:20191203052757j:plain

APIステージの追加」をクリックしてデプロイしたステージを紐づけます。

f:id:chief-shuffle:20191203052827j:plain

API」と「ステージ」を選択。

f:id:chief-shuffle:20191203052858j:plain

「次へ」。

f:id:chief-shuffle:20191203052927j:plain

APIキーを紐づけます。
APIキーを使用量プランに追加」をクリック。

f:id:chief-shuffle:20191203052955j:plain

APIキーを登録。

f:id:chief-shuffle:20191203053024j:plain

「完了」。

f:id:chief-shuffle:20191203053033j:plain

これでAPIキーがないとアクセスできない状態になりましたので、一度直アクセスしてみます。
API GatewayのURL+/+リソース名にアクセスします。

f:id:chief-shuffle:20191203053658j:plain

HTTPステータスコード403、ボディとして{"message":"Forbidden"}が返されました。
よしよし。

次にCloudFront側です。

先にCloudFrontからのリクエストに埋め込むAPIキーを確認しておきます。
API Gatewayの「APIキー」の「表示」をクリック。

f:id:chief-shuffle:20191203054042j:plain

Distributionを選択して「Distribution Settings」をクリック。

f:id:chief-shuffle:20191203053753j:plain

「Origins and Origin Groups」タブのAPI Gatewayを選択して、「Edit」をクリック。

f:id:chief-shuffle:20191203053854j:plain

「Origin Custom Headers」の「Header Name」にx-api-key、「Value」にAPI Gatewayで作成したAPIキーを入力。

f:id:chief-shuffle:20191203054052j:plain

「Yes, Edit」をクリックしてデプロイを待ちます。

ではアクセスしてみましょう。
CloudFrontのドメイン名+/+リソース名にアクセスすると、

f:id:chief-shuffle:20191203060112j:plain

お!Lambdaの結果が表示されました。
ちょっとしたことかもしれませんが、やっぱり動くと嬉しいですね。