👻

ソースIP(呼び出し元)を返すAPIをサクッと作る(API Gateway + Lambda)

2023/11/24に公開

概要

こんにちは。
固定IP接続できているのか確かめるために、APIを呼び出すサーバーのソースIPを知りたいことありますよね。私はあります。

そんなソースIPを返すAPIをAPIGateway + Lambdaでサクッと作る方法を紹介したいと思います。

制約事項

  • ランニングコストはなるべく抑える

なので、ALBのアクセスログが〜とかは今回対象外で考えていました。

ググってみた

2015年の記事.APIGatewayでマッピングテンプレートを使って実現する方法が紹介されている.
→良さそう.ちょっと古いな...
https://dev.classmethod.jp/articles/api-gateway-client-ip/

Mock+マッピングテンプレートを使って、CloudFormationでデプロイする記事.
→これもいいな.Mockなのか...CloudFormationよりはCDKとかにしたいな...
https://blog.usize-tech.com/get-ipaddress-by-api-gateway/

SAMでやる方法.
→OpenAPI使うのか..Lambdaのコードが見当たらない...
https://qiita.com/_akira19/items/a183ff4ad9f5bfbc7d71

といった感じで方向性は見えるものの、せっかくならもう少しサクッとCDKとかで構築したいなという感じでした。

CDKで実装してみる

そもそもマッピングテンプレート必要なさそう

Lambdaのeventに、
event.requestContext.identity.sourceIp
という属性があり、sourceIpが取れることがわかりました。

どの時点からなのかはわからないですが、これをレスポンスすれば一番楽なのでは?という結論に至り、それを採用することにしました。

CDKコード

解説するほどボリュームがありませんが、

  • { ip: event.requestContext.identity.sourceIp } を返している
    ところが肝になります。
    あと、せっかくなのでNODEJS_20_Xにしてみました。
    // Lambda 関数の定義
    const myFunction = new lambda.Function(this, 'MyFunction', {
      code: lambda.Code.fromInline(`
        exports.handler = async (event) => {
          return {
            statusCode: 200,
            body: JSON.stringify({ ip: event.requestContext.identity.sourceIp }),
          };
        };
      `),
      handler: 'index.handler',
      runtime: lambda.Runtime.NODEJS_20_X,
    });

    // API Gateway の定義
    const api = new apigateway.RestApi(this, 'MyApi', {
      restApiName: 'Client IP API',
      deployOptions: {
        stageName: 'prod',
      },
    });

    // Lambda 関数への統合
    const integration = new apigateway.LambdaIntegration(myFunction, {
      requestTemplates: { "application/json": '{ "statusCode": 200 }' }
    });

    // リソースとメソッドの追加
    api.root.addMethod('GET', integration);

全体

全体のコードはこちらになります。
https://github.com/kodai305/return-source-ip

まとめ

「サクッと」という観点では過去の記事に負けないくらいサクッとしているかなと思います。
同様に、ソースIPを返すAPIを作りたい!と思った時に参考にしていただけると幸いです。

Discussion