【実務・中級編】 ALBにおけるHTTPリスナーとポート80番(HTTP)・443番(HTTPS)の構成 – クラウド&コンテナネットワーク実践ガイド

ALBの「80/443問題」を極める:HTTP/HTTPSリスナーの正しい作法と現場の知見

クラウドインフラの設計において、ALB(Application Load Balancer)はWebサービスの「玄関」です。しかし、この玄関の作り方を少しでも間違えると、セキュリティリスクを招いたり、ユーザー体験を損なう遅延の原因になったりします。

今日は、多くのエンジニアが「なんとなく」設定しがちな、ALBにおけるHTTP(80)とHTTPS(443)の構成について、SREの視点から「なぜそうするのか」という本質を掘り下げて解説します。

—

1. なぜ「80ポート」を捨ててはいけないのか

モダンなWeb開発では「全てHTTPSで通信する」のが常識です。しかし、ALBの設定において80番ポートを完全に無効化するのではなく、「80番で受け取り、443番へ強制リダイレクトさせる」という構成がデファクトスタンダードです。

なぜなら、ユーザーはブラウザのアドレスバーに example.com とだけ入力することがほとんどだからです。この時、ブラウザはデフォルトで http:// (80番ポート) へアクセスを試みます。ここで適切にリダイレクトを返さないと、ユーザーは「接続できません」というエラーに直面するか、あるいは不親切な体験をすることになります。

現場で実践すべきリスナー構成の黄金律

1. HTTP (80):リダイレクト専用。ターゲットグループには転送せず、即座に 301 Moved Permanently を返す。
2. HTTPS (443):本丸。TLS終端を行い、バックエンド(EC2やFargate等)へトラフィックを転送する。

—

2. リダイレクト設定の勘所(Terraformによる記述例)

IaC(Terraform)を用いて、この「80から443へのリダイレクト」を構築する場合、以下のような構成をとります。type = "redirect" を使うのが、ALBの負荷を最小化する最も賢い方法です。

# HTTP (80) リスナーの設定:リダイレクトのみを行う
resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.main.arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    type = "redirect"

    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301" # ブラウザに恒久的な変更をキャッシュさせる
    }
  }
}

# HTTPS (443) リスナーの設定:ここでTLS終端を行う
resource "aws_lb_listener" "https" {
  load_balancer_arn = aws_lb.main.arn
  port              = 443
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-TLS13-1-2-2021-06" # 最新のポリシー推奨
  certificate_arn   = var.acm_certificate_arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app.arn
  }
}

—

3. 通信シーケンスとヘッダーの正しい理解

ALBでHTTPSを終端すると、バックエンドのコンテナから見ると「自分はHTTPで通信している」ように見えます。ここで重要になるのが X-Forwarded-Proto などのヘッダーです。

通信の流れ

1. Client → https://example.com → ALB
2. ALB がTLSを剥がす(ハンドシェイク完了)。
3. ALB → Backend へリクエストを転送(この時、X-Forwarded-Proto: https を付与)。

もしバックエンド側(PythonのFastAPIやDjangoなど)で「現在HTTPSで通信しているか」を判定したい場合、request.headers をチェックする必要があります。

# FastAPIでの例:ALB経由のHTTPS判定
from fastapi import Request

@app.get("/check-protocol")
def check_protocol(request: Request):
    # ALBが付与したヘッダーを確認する
    proto = request.headers.get("x-forwarded-proto")
    if proto == "https":
        return {"status": "secure"}
    return {"status": "insecure"}

—

4. トラブルシューティングの鉄則

現場でよくある「HTTPSに繋がらない」というトラブルの9割は、設定ミスか証明書の問題です。

  • curlで詳細を叩く: -Iv オプションは必須です。Server ヘッダーや Location ヘッダーを確認し、意図したリダイレクトが行われているか見てください。
# リダイレクトの挙動を確認
    curl -Iv http://example.com
  • ACM証明書の期限とドメイン: Certificate Manager の証明書に記載されているドメインと、アクセスしているホスト名が一致しているか必ず確認してください。サブドメイン(*.example.com)の払い出し漏れは、朝の忙しい時間帯によくあるミスです。
  • Security Groupの疎通: ALBのセキュリティグループが、バックエンドに対して「HTTPポート(例: 8080など)」で通信を許可しているか確認してください。

—

まとめ:SREとしての矜持

ALBのリスナー設定は、単なるパラメータの羅列ではありません。ユーザーが最初に触れる「信頼の入り口」です。

80番で受け取り、素早く443番へ流す。そしてバックエンドには正しいヘッダー情報を渡す。この一連のフローを理解しているだけで、障害発生時の切り分けスピードは劇的に向上します。

「動けばいい」というインフラから、「なぜこう動くのか」を理解したインフラへ。皆さんの構築が、より堅牢で美しいものになることを願っています。

コメント

タイトルとURLをコピーしました