GCP HTTPS負荷分散からクライアントIPを抽出

プロキシを利用した場合、一般的にサービスが受け取る接続元IPはプロキシのIPになります。
じっさいの接続元IPはヘッダーなどから抽出する必要があります。

GCPのHTTPSロードバランサーの場合、 ターゲットプロキシの表にヘッダーの仕様を掲載しています。
クライアントのIPはX-Forwarded-Forに記録されています。

なお、GCPのプロキシには複数の製品があり、HTTPSロードバランサーはGKEのingressにより自動作成されます。ほかにGKEにはLoadBalancerが作成するプロキシがありますが、これはTCPプロキシであり、まったく挙動が異なります。

nginxでX-Forwarded-ForからIP抽出

nginxで接続元IPを加工するには、 ngx_http_realip_moduleを利用します。
GCP HTTPS LBの設定例は以下のようになります。

server {
    set_real_ip_from <external-ip>/32;
    set_real_ip_from 130.211.0.0/22;
    set_real_ip_from 35.191.0.0/16;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;

X-Forwarded-Forは改竄しうるヘッダーであるため、set_real_ip_fromで信用するリクエストのネットワークアドレスを指定します。
GCPの X-Forwarded-Forの仕様によると、フロントエンドプロキシのアドレスは130.211.0.0/2235.191.0.0/16です。

また、X-Forwarded-Forには経由レイヤのIPも含まれているため、real_ip_recursive onでプロキシのIPを除去する必要があります。
除去対象のアドレスはset_real_ip_fromを参照しています。 フロントエンド・プロキシのほか、外部IPも除去する必要があり、<external-ip>/32の形式で実IPを指定しておきます。外部IPは構成により異なるため、あらかじめ調べておきます。

この設定により、configで参照する$remote_addrもX-Forwarded-Forから抽出した値になります。

中馬崇尋
Chuma Takahiro