CloudflareのProxy設定でLambda→ALB通信が壊れた話
TL;DR
api.hoge.com と backend.hoge.com の両方で Cloudflare の Proxy が ON になっていました。
Browser からのリクエストはすでに Cloudflare Edge を経由して Lambda に届いています。
その Lambda が backend.hoge.com を呼び出すと、DNS は Cloudflare の Anycast IP を返すため、リクエストが再び Cloudflare Edge に向かいます。
つまり Cloudflare → Lambda → Cloudflare というCloudflare ループ になっており
Cloudflare Error 1000
DNS points to prohibited IP
が発生しました。
暫定対応として backend.hoge.com の Proxy を OFF に変更して解決しました。
最終的には Lambda → ALB を VPC内通信にする予定です。
発生したエラー
frontendからAPIを呼び出したところ 403 Forbidden が返ってきました。
レスポンスのHTMLには次のメッセージが含まれていました。
Cloudflare Error 1000
DNS points to prohibited IP
API GatewayやLambdaは正常に動作しており、ECS側にもログが出ていませんでした。
最初はALBやWAFの問題を疑っていました。
構成
LambdaはBFF(Backend for Frontend)として動作しており、
バックエンドは既存構成の都合上 ALB + ECS になっています。
LambdaからこのALBのAPIを呼び出していました。
トラブルシューティング
最初は 403 というステータスコードだったため、こんな原因を疑っていました。
- ALBのWAF
- Security Group
- ECSアプリケーションの認可
- API Gatewayの認可設定
ECSにログが出ていない
ただ、調査を進めると違和感がありました。
ALBまでリクエストが届いていれば、ECSのログに何かしら出るはずです。
今回はまったく出ていませんでした。
つまり ALBにたどり着いていない可能性が高そうです。
curlで確認
curl -v https://backend.hoge.com
レスポンスヘッダを見てみると
server: cloudflare
が含まれていました。さらにHTMLには DNS points to prohibited IP とあります。
ここでようやく Cloudflareが403を返していたことに気づきました。
公式ドキュメントを確認
Cloudflareの公式ドキュメントに Error 1000 の原因がまとめられています。
ドキュメントには「A レコードが Cloudflare 自身の IP を指している」または「別のリバースプロキシを経由して Cloudflare に二度リクエストが戻ってくる」場合に発生すると書かれています。
今回 ALB は CNAME で設定していたため、最初は「A レコードの話なので関係ない」と判断してしまいました。
Proxy ON の挙動は知っていたのですが、障害対応中の焦りから見過ごしてしまっていました。
冷静にこのドキュメントと照らし合わせていれば、もっと早く原因にたどり着けたはずです。
原因
CloudflareのDNS設定はこうなっていました。
| Record | Proxy |
|---|---|
| api.hoge.com | ON |
| backend.hoge.com | ON |
Cloudflare ループになっていた
api.hoge.com が Proxy ON のため、Browser からのリクエストはすでに Cloudflare Edge を経由して Lambda に届いています。
その Lambda が backend.hoge.com を呼び出すと、こちらも Proxy ON のため DNS は Cloudflare の Anycast IP を返します。
結果として Cloudflare → Lambda → Cloudflare というCloudflare ループになっていました。
なぜ Error 1000 になるのか
CloudflareはCloudflare ループを検出した場合、またはオリジンへの転送先が次のIPに該当する場合に Error 1000 を返します。
- CloudflareのIP自身(Cloudflare ループのループ防止)
- RFC 1918 プライベートアドレス(
10.x.x.x/172.16.x.x/192.168.x.x) - ループバックアドレス(
127.0.0.1)
今回は backend.hoge.com の DNS が Cloudflare の IP を返していたため、CloudflareのIP自身への転送と判定され DNS points to prohibited IP になっていたというわけです。
解決方法(暫定対応)
backend.hoge.com のProxy設定をOFFに変更しました。
| Record | Proxy |
|---|---|
| backend.hoge.com | OFF |
Proxy OFF にするとDNSはオリジンのCNAME(ALBのドメイン)を返すようになるので、Cloudflare ループが解消されて正常に動作しました。
学び
CloudflareはAuthoritative DNS + Reverse Proxy
Cloudflareは DNS だけでなく Reverse Proxy / CDN / WAF の機能も持っています。
Proxy ON にするとリクエストはすべて Cloudflare Edge を経由してオリジンに転送されます。
ブラウザからのリクエストにはとても便利ですが、サーバー間通信では意図しない挙動になることがあります。
Proxy設定によって通信経路が変わる
用途によって使い分ける
| 用途 | Proxy |
|---|---|
| ブラウザ → API | ON(CDN・WAFの恩恵あり) |
| サーバー → サーバー | OFF(経由するメリットがない) |
サーバー間通信で Proxy ON のドメインを呼び出すと、Cloudflare 経由のリクエストが再び Cloudflare に戻るCloudflare ループになる可能性があります。
解決方法(恒久対応)
暫定対応でいったん解消しましたが、そもそも Lambda → ALB の通信が外部DNS経由なのは微妙です。
VPC 内通信に移行することで根本的に解決します。
移行にあたっていくつか注意点があります。
- Lambda を VPC 内に配置する必要があります
- VPC 配置による Cold start への影響を測定・確認する必要があります
- セキュリティグループで Lambda → ALB 間の通信を明示的に許可する必要があります
これにより Cloudflare 依存の排除・レイテンシ削減・ネットワーク構成のシンプル化が期待できます。
考察:なぜ突然?
Cloudflareの Proxy ON の設定はもっと前から存在していました。にもかかわらず突然エラーが発生した理由は、調査した範囲では特定できませんでした。
Cloudflare 側の変更履歴を確認しましたが、この時期に Error 1000 の判定条件やプロキシの挙動を変えたという公式アナウンスは見当たりませんでした。
同じような「突然 Error 1000 が出始めた」という報告は Cloudflare コミュニティにも散見されますが、いずれも原因は個別の構成変化(DNS レコードの変更、ホスティング側の IP 変更など)によるものでした。
引き続き Cloudflare の Audit Log などを確認する予定です。何か判明したら追記します。
まとめ
Proxy ON のドメインを経由したリクエストから、さらに Proxy ON の別ドメインを呼び出すとCloudflare ループになり Error 1000 が発生します。
サーバー間通信では Proxy OFF または VPC内通信にすることで、今回のようなトラブルを防げます。