@yy0706

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

【AWS】プライベートDNSを使って、実在するAPIへのリクエストをAPI Gatewayに向けたい

解決したいこと

【AWS】プライベートDNSを使って、実在するAPIへのリクエストをAPI Gatewayに向けたい

名前解決はできるが、API Gatewayへリクエストが届かずに403のエラーが返ってきてしまう。
原因のあたりについて、何かご教授いただきたいです。

発生している問題・エラー

"{\"message\":\"Forbidden\"}"

該当するソースコード

exports.handler = async (event) => {
    // 実在するAPIのURL
    const api_url = 'https://restcountries.com/v3.1/name/aruba?fullText=true'
    const hostname = new URL(api_url).hostname;
    const path = new URL(api_url).pathname + new URL(api_url).search;
    
    const options = {
        hostname: hostname, 
        port: 443,
        path: path,
        method: 'GET',
        rejectUnauthorized: false  // SSL証明書の検証を無効化
      };
    const res = await req(options)
        .catch(err => err)
    console.log(res);
    return {
        api_url,
        res
    }
}

自分で試したこと

以下の環境をAWSにて構築しました。

①VPC作成
 DNS 解決
 →有効
 IPv4 CIDR
 →10.0.0.0/24
 DNS ホスト名
 →有効
②実在する外部APIへのリクエストを送信するlambdaをVPCに配置
③API Gatewayへ向けるためのエンドポイントを作成
 セキュリティインバウンドルール
 →全許可
③外部APIのドメインでRoute53のホストゾーン作成 
④Aレコードを作成:③で作成したエンドポイント(エイリアス)を値に指定
⑤API Gateway作成
 エンドポイントに③で作成したものを指定
リソースポリシー全許可
POSTメソッドを作成して別のlambda関数に統合

### わかっていること
 ・Route53のログから、VPCのサブネットのIPが解決されていることは確認できた。
・ApiGatewayのログは、吐き出されていないため、おそらくApiGatewayにたどり着く前に何か起きている
 ・直接ApiGatewayのInvoke URLへリクエストしたところ、エラーにはならなかった

0 likes

1Answer

✅ 起きていることの整理
LambdaはVPC内に配置されており、restcountries.com へのリクエストは、Route53のプライベートホストゾーンで作成したAPI Gatewayのエンドポイントに解決される

名前解決はできている(Route53ログ確認済)

しかし 403 Forbidden が返され、API Gateway側のログにもアクセス記録がない

✅ 主な原因候補
❗① API Gatewayへのリクエストが署名付きではない(署名バージョン4など)
API Gatewayは、IAM認証モードやカスタムオーソライザー付きのエンドポイントに対して署名のないリクエストを送ると、403 Forbidden を返します。

特に以下のような条件下では、明示的に署名が必要です:

VPC内のLambdaなどからAPI Gatewayにアクセスしている

プライベートAPI Gateway(VPCエンドポイント経由)

リソースポリシーでVPCやVPCエンドポイントを条件指定している

認証がIAM設定になっている(Authorization: AWS4-HMAC-SHA256 の署名が必要)

🔍確認ポイント

API Gatewayの「リソースポリシー」や「認証タイプ」が「IAM」や「Cognito」になっていないか?

curl や Postman などで署名なしで叩いてもエラーになるか?

❗② VPCエンドポイントタイプとAPI Gatewayの整合性
API Gatewayが**プライベートAPI(Private endpoint)**の場合:

必ず com.amazonaws..execute-api タイプのインターフェース型VPCエンドポイントが必要

さらに、リクエスト送信元のLambdaが同じVPC内のサブネットであり、セキュリティグループの通信が許可されていることが前提です

🔍確認ポイント

VPCエンドポイントが execute-api に対応していること

セキュリティグループで Lambda ⇒ VPCエンドポイントの443ポートが許可されているか

VPCエンドポイントポリシーにて制限がかかっていないか

❗③ Lambdaからのリクエスト先が、正確なホスト名でない
DNSは restcountries.com で解決してAPI Gatewayに向かっていますが、API Gatewayのドメイン名とは異なるホスト名でアクセスしているため、ホストヘッダの不一致で403が返る場合もあります。

たとえば:

bash
コピーする
編集する
curl -H "Host: your-api-id.execute-api.ap-northeast-1.amazonaws.com"
https://restcountries.com/v3.1/name/aruba?fullText=true
のようにホスト名とルーティングパスをちゃんと合わせないとAPI Gateway側が処理できません。

🔍確認ポイント

Host ヘッダーが、実際にAPI Gatewayに設定しているカスタムドメインやステージ名と一致しているか?

curl -v でアクセスしているホスト名・ヘッダ・リダイレクト先を確認する

✅ 解決へのアプローチ例
✅ オプション1:axios / https でリクエストヘッダーを明示
js
コピーする
編集する
const options = {
hostname: "restcountries.com", // ← これはAPI Gatewayでマッピングされてるドメイン?
port: 443,
path: "/v3.1/name/aruba?fullText=true",
method: 'GET',
headers: {
Host: "your-api-id.execute-api.ap-northeast-1.amazonaws.com", // ここを合わせる
}
}
✅ オプション2:署名付きリクエスト(SigV4)を使う
bash
コピーする
編集する
aws --region ap-northeast-1 apigateway test-invoke-method
--rest-api-id abc123
--resource-id xyz789
--http-method POST
--body '{"test": "value"}'
または aws4 パッケージなどを使って署名付きリクエストをLambdaから送る。

0Like

Comments

  1. @yy0706

    Questioner

    ご回答いただきありがとうございます。
    ③が原因の可能性が高いです。
     (=Hostヘッダーの指定をする必要があった)
    また、パスにステージ名が含まれておらず、こちらも併せて直したところ200のレスポンスが返ってくることを確認できました。

    ご協力ありがとうございました!

Your answer might help someone💌