【入門編】 NATゲートウェイ配下のクライアントIP保存手法(Proxy Protocolの活用) – クラウド&コンテナネットワーク実践ガイド

こんにちは!SREとして日夜クラウドとコンテナの海を泳いでいるライターの私です。

クラウドの世界へ足を踏み入れたばかりの頃、「あれ、バックエンドのログを見たら、アクセスしてくるクライアントのIPアドレスが全部同じ(あるいはNATゲートウェイのもの)になっている……!これじゃあどこの誰だか分からないよ!」と頭を抱えた経験はありませんか?

セキュリティや可用性を高めるために、プライベートサブネットにサーバーを置き、インターネットへの出口としてNATゲートウェイを配置するのはクラウドインフラの王道です。しかし、この「NAT(Network Address Translation)」という仕組み、いわば会社の代表電話やホテルのフロントのようなもので、外に出ていくときは全員の顔(IPアドレス)を「会社の代表番号」に書き換えてしまうのです。

今回は、このNATの裏側で隠れてしまう本当の送信元IPアドレスを、バックエンドのサーバーまでしっかり届けるための秘伝のタレ――「Proxy Protocol」について、身近な例えを交えながら一歩ずつ優しく紐解いていきましょう!

—

1. なぜNATを挟むと「誰からのアクセスか」見えなくなるの?

まずは、現実世界の「郵便配達」に例えて考えてみましょう。

あなたの会社(プライベートサブネット)から、取引先(外部のWebサービス)へ大量の書類を発送するとします。社内にはたくさんの部署(クライアントサーバー)がありますが、セキュリティの都合上、個別の社員が勝手に外へ手紙を出しに行くことは許されていません。

そこで登場するのが「総務部(NATゲートウェイ)」です。
社内の各部署が書いた手紙をいったん総務部が回収し、差出人の名前をすべて「株式会社〇〇 総務部」に書き換えてから外の世界へポストに投函します。

受け取った取引先からすると、「おっ、株式会社〇〇の総務部から荷物が届いたぞ」とは分かりますが、「総務部のなかの、いったいどの部署がこの書類を作ったのか?」までは、外側の封筒を見ただけでは分かりませんよね。これが、クラウドのネットワークで起きている「送信元IPアドレスの隠蔽」の正体です。

—

2. クライアントの素性を伝える2つのアプローチ

「いやいや、アプリのアクセス解析やセキュリティ監査のために、どの部署(クライアントIP)から来たのかどうしても知りたいんだ!」という場合、主に2つの解決策があります。

1. HTTPレイヤーでの伝達 (X-Forwarded-For ヘッダー)
Web(HTTP/HTTPS)の世界で一番有名な方法です。手紙のなかに「この記事は〇〇部署が書きました」というメモ(HTTPヘッダー)を同封するイメージです。Webアプリケーションサーバーであれば比較的簡単に読み取ることができます。

2. レイヤー4(TCP)での伝達(Proxy Protocol)
今回主役として取り上げる方法です。HTTPだけでなく、TCPストリームそのもの(データベースやTCPベースの独自プロトコルなど)のレベルで、通信が始まるときに「実は本当の送信元は〇〇ですよ」という小さな名刺を一枚ペタッと貼り付けてあげる技術です。

—

3. Proxy Protocolってどんな仕組み?

Proxy Protocolは、ロードバランサー(AWSのALBやNLBなど)とバックエンドのサーバーの間で使われる、いわば「秘密の合言葉付きの挨拶」のようなものです。

通信が確立した直後、本物のデータが流れるコンテナの最前線で、ロードバランサーがバックエンドサーバーに対してこっそりこう伝えます。

> 「やあ、今から君にデータを送るけど、本当のクライアントのIPアドレスは 192.0.2.100 で、ポート番号は 54321 だからね。よろしく!」

この仕組みがあるおかげで、バックエンドサーバーは、自分が受け取った手紙の差出人がたとえNATゲートウェイやロードバランサーであったとしても、「なーんだ、本当はあそこのクライアントからだったんだな」と正確なIPアドレスを把握できるようになります。

—

4. 実務で設定してみよう:NginxでのProxy Protocol受け入れ設定

それでは、実際にインフラの現場でどのように設定するのかを見てみましょう。ここでは、ロードバランサーからのProxy Protocolを受け取る側の代表例として、Webサーバー(Nginx)の設定を覗いてみます。

NginxでProxy Protocolを有効にするには、以下のように設定ファイル(nginx.conf など)の listen ディレクティブに proxy_protocol という魔法の言葉を添えるだけです。

server {
    # ポート80で待ち受けつつ、ロードバランサーからのProxy Protocolを解釈する
    listen 80 proxy_protocol;
    
    # 443ポート(SSL/TLS)の場合も同様に指定可能
    listen 443 ssl proxy_protocol;

    server_name example.com;

    # アクセスログやアプリケーションに「本当のクライアントIP」を正しく渡すための設定
    set_real_ip_from 10.0.0.0/16; # ここにはロードバランサーやNATが存在するプライベートIPレンジを指定
    real_ip_header   proxy_protocol;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

設定のポイント

  • proxy_protocol をつけることで、Nginxは通信の最初に来る「本当のIP情報が書かれたヘッダー」を自動的に剥ぎ取り、内部で処理してくれます。
  • set_real_ip_from と real_ip_header proxy_protocol の組み合わせが非常に重要です。これにより、信頼できるルーターやロードバランサーからの情報だけを信用して、クライアントIPを上書きするようになります。

—

5. アプリケーションコード(Python)での受け取りイメージ

もし、Nginxのようなリバース proxy を挟まず、自作のTCPサーバーなどで直接クライアントの情報を扱いたい場合はどうなるでしょうか。

Proxy Protocol(v2など)の仕様自体はバイナリ形式で少々複雑ですが、主要なフレームワークやライブラリの多くは、設定を有効にするだけで自動的に解析してくれます。例えば、Pythonの非同期ネットワー킹などで自前で処理する場合のイメージは以下のようになります。

# ※概念的なイメージコードです
import socket

def handle_client_connection(client_socket):
    # Proxy Protocolの最初の数バイトから実際のクライアントIPを読み取る処理
    # (実際にはサードパーティライブラリやミドルウェアに任せるのが安全です)
    proxy_header = client_socket.recv(1024)
    
    # 解析した本当の送信元IPアドレスを取得
    true_client_ip = parse_proxy_protocol_header(proxy_header)
    
    print(f"おっ、本当のクライアントIPは {true_client_ip} ですね!")

# サーバーの起動イメージ
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('0.0.0.0', 8080))
server.listen(5)

print("Proxy Protocol対応サーバーが起動しました...")

実務の現場では、AWSのNLB(Network Load Balancer)のターゲットグループ設定画面などで「Proxy V2 Protocol」のチェックボックスをポチッと有効にし、受け取る側のコンテナ(NginxやEnvoy、Nginx Ingress Controllerなど)側でも対応するパラメータを有効にする、というアプローチが一般的です。

—

まとめ:ネットワークの「見えない壁」を正しく理解しよう

今回は、NATゲートウェイ配下で失われがちな送信元IPアドレスを、Proxy Protocolを使って鮮やかに救い出す仕組みを解説しました。

  • NATの役割: セキュリティのために社内(プライベート)のIPを隠して外へ送り出す「総務部」のような存在。
  • 課題: バックエンドから見ると、すべて同じ代表者の顔に見えてしまう。
  • 解決策: HTTPヘッダーや、L4レイヤーの Proxy Protocol を使って、通信の最初にこっそり「本当の主」の身分証をパスする。

クラウドやコンテナのネットワークは、一見すると黒魔術のように難しく感じられますが、一つひとつのパケットが「誰から誰へ、どんな手紙を運んでいるのか」を現実世界のロジックに置き換えてみると、驚くほどスッキリと理解できるようになります。

皆さんのインフラ構築やトラブルシューティングの引き出しの一つとして、ぜひこのProxy Protocolを活用してみてくださいね。それでは、また次回の技術解説でお会いしましょう!

コメント

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