###概要
AWSのApplication Load Balancer(ALB)を使ってWeb-App-DBの3層構成を組むことが一般的に多いと思われるが、ALBではHTTPリクエストに対してHTTPヘッダを付与することがある。非ALB構成とALB構成で付与されるHTTPリクエストヘッダの差異をネットワークキャプチャで調査してみる。
##ネットワークキャプチャコマンド
###tcpdumpをWebサーバで発行
tcpdump -i eth0 -n -tttt port <port番号> -w /tmp/web.pcap
##前提構成
#HTTPリクエストの流れ(APP,DB層は検証の目的に外れるので省略。
Clinet ===> ALB(443) ===> NGINX@WebServer(80)
#HTTPリクエストの流れ(APP,DB層は検証の目的に外れるので省略。
Clinet ===> ALB(80) ===> NGINX@WebServer(80)
#HTTPリクエストの流れ(APP,DB層は検証の目的に外れるので省略。
Clinet ===> NGINX@WebServer(80)
###検証結果
- 結果的に、ALBを経由した場合だと以下の4つのHTTPヘッダが追加付与されていることが分かる。
X-Forwarded-For
ロードバランサなどの機器を経由してWebサーバに接続するクライアントの送信元IPアドレスを特定する際のデファクトスタンダード。クライアントの送信元IPアドレスの特定は、ロードバランサなどでクライアントの送信元IPアドレスが変換された場合でも、HTTPヘッダに元のクライアントIPアドレスの情報を付加することで実現。Webサーバ側でクライアントのIPアドレスを特定するために前段のLBで付与する必要がある。
例えば以下のような構成だと、Webサーバで受け取るHTTPリクエストヘッダはX-Forwarded-For: Clinetとなる。
Clinet ===> ALB(443) ===> WebServer
上記であればSimpleだが多段プロキシ構成だと話が複雑になる。
例えば以下のような構成だと、Webサーバで受け取るHTTPリクエストヘッダはX-Forwarded-For: Clinet ALB Proxy1となる。Webサーバにリクエストを転送する主体はそれまでのアクセス元のIP(自らを含まない)をWebサーバに転送する時点でX-Forwarded-Forに付与する仕組み。
Clinet ===> ALB(443) ===> Proxy1 ===> Proxy2 ===> WebServer
この状態から、ClientのIPアドレスをフィルタする方法は各Webサーバの設定による。
X-Forwarded-Proto
プロキシまたはロードバランサーへ接続するのに使っていたクライアントのプロトコル (HTTP または HTTPS) を特定する。
X-Forwarded-Port
プロキシまたはロードバランサーへ接続するのに使っていたクライアントからの宛先ポートを特定する。
X-Forwarded-Amzn-Trace-Id
クライアントからのターゲットまたは他のサービスへの HTTP リクエストを追跡するための一意な識別子。ALBが、クライアントからのリクエストを受信すると、ターゲットにリクエストを送信する前に、[X-Amzn-Trace-Id] ヘッダーを追加、または更新する。Webサーバのアクセスログに記録することでALB側のアクセスログと比較してリクエストを特定可能
###参考URL
- https://www.infraexpert.com/study/loadbalancer11.html
- https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/X-Forwarded-Proto
- https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/X-Forwarded-Host
- https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-request-tracing.html