API Gatewayで実装したAPIにおいてIPアドレスによるアクセス制限をする必要が出てきたため、その方法を調査・実装した。
結論
API GatewayのLambdaタイプオーソライザーを作成し、特定のIPアドレスにのみ認可を与えることでアクセス制限をかけることができる。
実装内容
まず、オーソライザーの本体となるLamnda関数を実装する。
exports.handler = async (event) => {
if(event.authorizationToken){
// X-forwarded-forの内容がトークンに設定されるので、
// カンマで区切りで取得したIPアドレスの一番最初の要素がアクセス元のIPアドレスになる
ip = event.authorizationToken.split(',')[0].trim();
}
else{
return generatePolicy('user', 'Deny', event.methodArn);
}
// 許可するIPアドレスのリスト
const allowIps = [
'(許可するIPアドレス)'
];
// 許可するIPアドレスに含まれているか確認
if(allowIps.includes(ip)){
return generatePolicy('user', 'Allow', event.methodArn);
}
return generatePolicy('user', 'Deny', event.methodArn);
}
const generatePolicy = (principalId, effect, resource) => {
const policyDocument = {
Version: '2012-10-17',
Statement: [
{
Action: 'execute-api:Invoke',
Effect: effect,
Resource: resource
}
]
};
return {
principalId: principalId,
policyDocument: policyDocument
};
}
IPアドレスの内容をチェックして、リストに含まれているのであれば認可を出す、という単純なものです。
ここでは許可IPアドレスをハードコーティングしていますが、実際の運用では環境変数を使うなど外部に切り出すと使い勝手が良くなると思います。
次にこの関数をデプロイするので、SAMテンプレートに下記のように定義します。
HandlerやCodeUriのあたりは各々の環境に合わせて変更をする必要があります。
IpAddressAuthorizationFunction:
Type: AWS::Serverless::Function
Properties:
Handler: checkIpAddressAuthorization/index.handler
Runtime: nodejs18.x
CodeUri: ./public
次はAPI Gatewayにオーソライザーを登録します。
Api:
Type: AWS::Serverless::Api
Properties:
Auth:
Authorizers:
IpAddressAuthorizer:
FunctionArn:
Fn::GetAtt:
- IpAddressAuthorizationFunction
- Arn
Identity:
Header: x-forwarded-for
これでx-forwarded-forヘッダーの内容がトークンとして設定され、オーソライザーの処理がIpAddressAuthorizationFunctionで実行される設定になります。
最後に、IPアドレス制限をするAPIにこのオーソライザーを使うように設定をします。
XXXXFunction:
Type: AWS::Serverless::Function
Properties:
Events:
XXXXApi:
Type: Api
Properties:
Auth:
Authorizer: IpAddressAuthorizer
OverrideApiAuth: true
また、API個別に設定するのではなく、全体で設定をする場合はデフォルトオーソライザーに設定しておくこともできます
Api:
Type: AWS::Serverless::Api
Properties:
Auth:
DefaultAuthorizer: IpAddressAuthorizer
Authorizers:
IpAddressAuthorizer:
FunctionArn:
Fn::GetAtt:
- IpAddressAuthorizationFunction
- Arn
Identity:
Header: x-forwarded-for
コンソール上で設定する場合
コンソール上ではAPI Gateway > 該当のAPI > オーソライザー > オーソライザーを作成でオーソライザーを作成できます。