【入門編】 ALBにおけるX-Forwarded-Proto ヘッダーとスキームの判定 – クラウド&コンテナネットワーク実践ガイド

こんにちは!SREとして日々クラウドの荒波と格闘している筆者です。

インフラの世界へ足を踏み入れたばかりの頃、「ロードバランサー(ALB)」や「HTTPヘッダー」といった専門用語の数々に、圧倒されてしまった経験はありませんか?「なんだか難しそう……」と、そっとブラウザを閉じたくなる気持ち、とてもよく分かります。

でも、一歩ずつ紐解いていけば、ネットワークの世界も私たちの身の回りの仕組みと何ら変わりません。今回は、AWSの「ALB(Application Load Balancer)」において非常に重要な役割を持つ X-Forwarded-Proto というヘッダーと、それを使った「HTTPSへのリダイレクト」について、身近な例えを交えながら優しく解説していきますね。

それでは、さっそく仕組みを覗いてみましょう!

—

1. 郵便配達で例える「HTTPSの終端」と見えなくなるプロトコル

私たちが普段何気なく使っているWebブラウザ。URLの先頭に https:// とついていれば、通信が暗号化されて安全(セキュア)に行われている証拠ですよね。

この「安全な通信(HTTPS)」を、クラウドの世界ではどのように処理しているのでしょうか?ここで、身近な「郵便配達」に例えて考えてみましょう。

  • クライアント(あなた): 手紙に鍵をかけて(暗号化して)、郵便局の窓口へ送る人
  • ALB(ロードバランサー): 郵便局の「コンシェルジュ(受付)」
  • バックエンド(EC2やECSなどのサーバー): 奥の部屋で手紙を読み書きしている「事務スタッフ」

ここで一つ、現場の裏事情があります。それは、「セキュリティの鍵を開け閉めする作業(SSL/TLS終端)は、フロントの受付(ALB)が一手に引き受ける」というルールです。

クライアントとALBの間は、当然ピカピカに暗号化された安全な HTTPS 通信です。しかし、ALBから奥の部屋にいるバックエンドサーバーまでの通信は、社内ネットワーク(VPC内)という安全地帯を通るため、あえて負荷を軽くするために通常の HTTP(暗号化なし)に変換されて届けられるのが一般的です。

ここで、バックエンドサーバーの立場になって考えてみてください。
「あれ? 今、私に届いたこのリクエスト、お客さんは安全な HTTPS で送ってきたんだっけ? それとも普通の HTTP だったっけ?」
バックエンドからすると、ALBから受け取った通信はいつも HTTP なので、お客さんがどうやってアクセスしてきたのか、自分では分からなくなってしまうのです。

この「困った!」を解決するために、受付であるALBが、バックエンドサーバーへ手紙を渡すときにこっそり添えてくれるメモ書き。それが、今回主役となる X-Forwarded-Proto ヘッダーなのです!

—

2. X-Forwarded-Proto ヘッダーの正体と役割

X-Forwarded-Proto(エックス・フォワードド・プロトコル)は、文字通り「転送された元のプロトコル(通信手段)は何だったのか」を教えてくれる看板のようなものです。

ALBは、インターネットの向こう側からやってきたクライアントのリクエストを受け取ると、次のように心遣いをしてバックエンドへバトンタッチします。

1. クライアントが https:// でアクセスしてきた場合:
バックエンドへのリクエストに X-Forwarded-Proto: https という付箋(ヘッダー)を貼って渡します。
2. クライアントが http:// でアクセスしてきた場合:
バックエンドへのリクエストに X-Forwarded-Proto: http という付箋を貼って渡します。

バックエンドのアプリ側では、この X-Forwarded-Proto の値を確認するだけで、「あ、お客さんは安全な通信で来てくれたんだな」あるいは「おっと、まだ普通の通信だから HTTPS に案内し直さないと!」と、瞬時に判断できるようになるわけです。

—

3. 実践!「HTTPSへ強制リダイレクト」する仕組み

「すべてのアクセスを安全な HTTPS に統一したい!」というのは、現代のWebサイト運営において必須の要件です。もしユーザーが間違えて http:// でアクセスしてきたら、自動的に https:// へお引越し(リダイレクト)させてあげたいですよね。

ここで、AWSのALBの設定と、バックエンド側(アプリケーション)での実装の2つのアプローチを見ていきましょう。

アプローチA:すべてALBにお任せする(一番おすすめ!)

実は、わざわざバックエンドのプログラムをいじらなくても、ALBの「リスロワール(リスナー)ルール」機能だけで、HTTP で来たアクセスを自動的に HTTPS へリダイレクトさせることができます。

AWSマネジメントコンソールや、IaC(Terraformなど)で次のような設定を行います。

# TerraformでのALBリスナーリダイレクト設定例
resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.main.arn
  port              = "80"
  protocol          = "HTTP"

  # ポート80(HTTP)にアクセスが来たら…
  default_action {
    type = "redirect"

    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301" # 301永続的リダイレクトでブラウザに安全なURLを覚えさせる
    }
  }
}

この設定をしておけば、ユーザーが http://example.com にアクセスした瞬間、ALBが「おっと、うちは HTTPS のみですよ!」と即座に交通整理を行い、バックエンドのサーバーに負荷をかけることなく、安全なルートへ案内してくれます。これぞSREが推すスマートな構成です。

アプローチB:アプリ側で X-Forwarded-Proto を見て判定する

「ALBの前段だけでなく、アプリケーションのコード内でも現在のスキーム(プロトコル)を正確に知りたい」というケースもあります。例えば、アプリケーションが生成するリンクのURL(パスワード再発行メールのURLなど)を動的に組み立てる場合です。

よくあるPython(FlaskやDjangoなど)やNode.jsのWebアプリでは、次のように X-Forwarded-Proto を信頼して処理を行います。

# Python (Flask) の簡単なサンプルコード
from flask import Flask, request

app = Flask(__name__)

@app.route("/")
def index():
    # ALBが付与してくれた X-Forwarded-Proto ヘッダーを覗き見する
    # ヘッダーが存在しない場合(直接アクセスなど)のフォールバックとして request.scheme も使う
    proto = request.headers.get('X-Forwarded-Proto', request.scheme)
    
    if proto == 'http':
        # もしHTTPだったら、HTTPSにリダイレクトする処理をここに書く
        # (※ALBでリダイレクト設定していない場合のフォールバックとして機能します)
        return "ただいま安全な通信(HTTPS)へご案内しています...", 301
    
    return "ようこそ!安全なHTTPS通信で接続されていますね!"

このように、フレームワークやアプリケーションは X-Forwarded-Proto ヘッダーを読み取ることで、ロードバランサーの裏側にいながらも、クライアントとの通信状態を正しく把握できるのです。

—

4. トラブルシューティング:現場でよくある「無限ループ」の罠

最後に、インフラの現場で新米エンジニアがよくハマりがちな「落とし穴」を一つシェアしておきますね。それは、「HTTPSリダイレクトの無限ループ(ERR_TOO_MANY_REDIRECTS)」です。

何が起きてしまうのか?

アプリケーション側で「もし X-Forwarded-Proto が http だったら、強制的に https にリダイレクトする」というプログラムを書いたとします。

しかし、もしALBとバックエンドの間の通信設定(ターゲットグループの設定)で、通信プロトコルやポートのルーティング設定を誤ってしまい、HTTPSでアクセスされたはずのリクエストなのに、アプリ側から見て常に http と判定されてしまう状態になったらどうなるでしょうか?

1. ユーザーが https:// でアクセスする
2. ALBがバックエンドへ転送する際、なぜか設定ミスでヘッダーが正しく伝わらない(またはアプリが無視している)
3. アプリは「あれ、HTTPで来てる!」と勘違いし、「HTTPSにリダイレクトしなさい!」とブラウザに命令する
4. ブラウザは言われた通り再度 https:// でアクセスするが、再び3に戻る……
5. 「このウェブページはリダイレクトが多すぎます」 とエラー爆誕!

どう防ぐのか?

  • まずは、ALBのリスナーでしっかりとHTTP→HTTPSのリダイレクトを完結させる(アプローチAを基本とする)。
  • アプリケーション側で判定を行う場合は、信頼できるプロキシ(この場合はALB)からの通信であること(信頼できるプロキシのIPレンジなど)をフレームワーク側(例: Expressの app.set('trust proxy', true) など)に正しく伝えてあげる。

この2点を押さえておくだけで、現場での無用なハマり時間を劇的に減らすことができますよ!

—

まとめ

いかがでしたでしょうか?今回は、クラウドの裏側で静かに働き続ける X-Forwarded-Proto ヘッダーの役割と、HTTPSリダイレクトの仕組みについて紐解いてみました。

  • クライアントとALBの間は HTTPS(暗号化)、ALBとバックエンドの間は HTTP になることが多い。
  • バックエンドがお客さんの通信手段を分かるように、ALBがこっそり添えてくれるメモが X-Forwarded-Proto ヘッダー。
  • 基本はALBのリスナー設定でスマートにリダイレクトを処理するのがおすすめ!

ネットワークやロードバランサーの挙動は、パケットの流れという「目に見えないもの」を想像する楽しさがあります。一つひとつのヘッダーの意味が分かってくると、クラウドを触るのがますます面白くなりますよ。

それでは、また次回の技術解説でお会いしましょう!快適なクラウドライフを!

コメント

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