バイパスを禁止し、CloudFrontだけを経由してApp Runnerへのアクセスを許可する方法
こんにちは!@Ryo54388667です!☺️
普段は都内でエンジニアとして業務をしてます!
主にTypeScriptやNext.jsといった技術を触っています。
今回はAWS App Runnerへの直アクセスを禁止し、CloudFrontを経由してアクセスのみ許可する方法を紹介していきます!
📌 やりたいこと
アプリのソースのあるオリジンサーバーとCDNを設定すると、CDN経由でオリジンにアクセスすることが可能になりますが、CDNを経由せず、直接オリジンサーバーにアクセスすることも可能です(バイパス)。今回はオリジンをAWS App Runner とし、CDNにCloudFront を利用してバイパスさせないようにしてみます。
メリットとしては、CDN経由が保証されれば、レスポンス速度の向上やサーバー負荷の軽減はもちろんですし、CDNにWAFの設定することもできます。設定しておいて損はないのかなと思います。ただ、余分なコストはかかりますが、そこは仕方がないですね😅
📌 方法
自分が思いつくのは下記の2つの方法でした!
- セキュリティグループによるアクセス制御(ネットワーク層)
- 特定のヘッダーによる制御(アプリケーション層)
セキュリティグループによるアクセス制御 (ネットワーク層)
大枠としては、以下のような手順です。
- CloudFrontのIPアドレスのみ許可するようなセキュリティグループを作成する
- 任意のVPCとサブネットを作成する
- 「受信ネットワークトラフィック」でプライベートエンドポイントを選択し、作成しておいたVPC、サブネット、セキュリティグループを設定する
2と3については、下記のクラメソさんの記事が非常にわかりやすかったです!
ここでは、1について補足しておきます。
始めに、この制御を考えたとき、「CloudFrontのアウトバウンドIPを制御すればいいかー」と思って調べたのですが、下記を見てギョッとしました。これを全部ぽちぽち設定するの面倒だなと。。。
CloudFrontエッジサーバーの場所とIPアドレス範囲
でもシンプルな制御方法がありました!これを解決してくれるものがCloudFrontマネージドプレフィックスリストです。
セキュリティグループのインバウンドルールにマネージドプレフィックスリストがあるので、そちらを設定します。これを作成後は2.3に移り、設定できれば完了です。
特定のヘッダーによる制御 (アプリケーション層)
大枠としては、以下のような手順です。
- CloudFrontでカスタムヘッダーを追加
- アプリのソース内で評価する
まず、1についてですが、CloudFrontのカスタムヘッダーに特定のヘッダーを追加してください。なるべく推測されにくいものを設定することをおすすめします。
あとは、自分の環境では、「オリジンリクエストポリシー - オプション」を「なし」にしないとカスタムヘッダーが転送されませんでした😇より良い設定があれば教えていただきたいところです。
2については利用している言語、フレームワークの仕様に合わせて設定してください。
今回はNext.jsを利用したケースを例示します。middleware.tsで設定するのが良いかと思います。
// src/middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
console.log('middleware.ts')
const customHeaderValue = request.headers.get(CUSTOM_HEADER_KEY_NAME);
console.log("@@@@ カスタムヘッダー @@@ : ", customHeaderValue)
if (customHeaderValue !== CUSTOM_HEADER_VALUE) {
return NextResponse.redirect(new URL('/403', request.url))
}
return NextResponse.next()
}
export const config = {
matcher: '/hogehoge',
}
App Runnerのアプリケーションログを見ると、意図通りカスタムヘッダーが転送されていることがわかります。
📌 まとめ
- セキュリティグループによるアクセス制御(ネットワーク層)
- 特定のヘッダーによる制御(アプリケーション層)
より良い方法があれば教えてください〜
最後まで読んでいただきありがとうございます!
気ままにつぶやいているので、気軽にフォローをお願いします!🥺
Discussion