🌐

[CloudFront + ALB] 502 エラーをHost ヘッダーで解消する

に公開

はじめに

CloudFrontとALB間の接続で HTTP 502 ステータスコード (Bad Gateway) に悩まされた経験について書きたいと思います📝

今回の問題は、CloudFrontからHostヘッダーをALBに転送する ことで解消しました。

同じ問題で困っている方の参考になれば幸いです。

なお、今回のインフラはTerraformで構築しており、コード例もTerraform形式で記載しています。

前提

  • ALBのターゲット(アプリケーション)が正常に動作している
  • ALBのHTTPS:443リスナーが正常に設定されている
  • SSL証明書(ACM)が正しく関連付けられている
    • ワイルドカード証明書(*.<ドメイン名>)を使用
  • セキュリティグループでCloudFrontからALBへのHTTPS通信が許可されている
  • CloudFrontのCache BehaviorでALBが正しく参照されている

なぜ502エラーが発生していたのか

確認できた現象

今回の502エラーでは、以下のような状況が確認できました。

  • ブラウザでのエラー: 502 Bad Gateway
  • ALBアクセスログ: 空(ログなし) ← CloudFrontからのリクエストが到達していない
  • ALBターゲットの状態: healthy(アプリケーション自体は正常に動作)

ALBログが空であることが、CloudFront側の設定に問題があることを示す手がかりでした。

問題の原因

今回のケースでは、以下のような設定になっていました。

  • CloudFrontのオリジンであるALBドメイン: my-alb-123456789.ap-northeast-1.elb.amazonaws.com
  • SSL証明書のドメイン: *.example.com(ワイルドカード証明書)
  • 実際のアクセスドメイン: www.example.com

ワイルドカード証明書とALBドメインの関係

ワイルドカード証明書(*.example.com)は以下のドメインに対して有効です。

  • www.example.com
  • admin.example.com
  • example.com ❌(サブドメインなしは対象外)

ALBのオリジンドメイン(my-alb-123456789.ap-northeast-1.elb.amazonaws.com)は証明書の対象外のため、SSL/TLS接続に失敗して502エラーとなっていました。

解決方法

オリジンの SSL/TLS 証明書には、CloudFront ディストリビューションに指定したオリジンドメイン、またはオリジンリクエストのHostヘッダーと一致するドメイン名が含まれている必要があります。

参考:AWS公式ドキュメント - HTTP 502 status code (Bad Gateway)

重要になるのが、Hostヘッダーの転送です。

CloudFrontからHostヘッダー(www.example.com)をALBに転送できれば、ワイルドカード証明書との照合が成功し、SSL/TLS接続が確立されます。

CloudFrontはデフォルトでは限られたヘッダー情報のみをオリジンに転送するため、 Origin Request PolicyLegacy Cache Behavior設定 でHostヘッダーを転送することで、この問題を解決できます。

1️⃣ Origin Request Policyを使用した解決

Managed-AllViewerポリシー(ID: 216adef6-5c7f-47e4-b989-5492eafa07d3)を設定することで、すべてのHTTPヘッダー情報をオリジンに転送できます。

実装例(Terraform)

修正前の設定
# ALB Cache Behavior(修正前)
dynamic "ordered_cache_behavior" {
  for_each = var.alb_paths
  content {
    path_pattern           = ordered_cache_behavior.value
    allowed_methods        = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
    cached_methods         = ["GET", "HEAD"]
    target_origin_id       = var.alb_origin_id
    cache_policy_id        = var.alb_cache_policy_id
    viewer_protocol_policy = "redirect-to-https"
    # origin_request_policy_id が未設定のため
    # Hostヘッダーが転送されない
  }
}
修正後の設定
# ALB Cache Behavior(修正後)
dynamic "ordered_cache_behavior" {
  for_each = var.alb_paths
  content {
    path_pattern                = ordered_cache_behavior.value
    allowed_methods             = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
    cached_methods              = ["GET", "HEAD"]
    target_origin_id            = var.alb_origin_id
    cache_policy_id             = var.alb_cache_policy_id
    origin_request_policy_id    = "216adef6-5c7f-47e4-b989-5492eafa07d3"  # Managed-AllViewer
    viewer_protocol_policy      = "redirect-to-https"
  }
}

2️⃣ Cache Behavior設定を使用した解決

Origin Request Policyを使わずに、従来のCache Behavior設定でHostヘッダーを転送することも可能です。

# Legacy方式での解決例
default_cache_behavior {
  # ...他の設定...
  
  forwarded_values {
    query_string = true
    headers      = ["Host"]  # Hostヘッダーを転送
    cookies {
      forward = "all"
    }
  }
}

ただし、AWS公式ではOrigin Request Policyの使用が推奨されています。

最後に

CloudFrontとALB間の接続で HTTP 502 エラー に遭遇した場合には、Hostヘッダーの転送設定も確認してみて下さい🚀

この記事がどなたかの参考になれば幸いです。
えみり〜でした|ωΦ)ฅ

参考リンク

Discussion