コンテンツにスキップ

HTTPプロキシまたはロードバランサー(NGINX)使用時の元のクライアントIPアドレスの特定

本手順では、HTTPプロキシまたはロードバランサー経由でサーバーに接続するクライアントの発信元IPアドレスを特定するために必要なNGINXの設定について説明します。これはセルフホスト型のNGINXベースノードに適用されます。

  • セルフホストのWallarm nodeがオールインワンインストーラー、AWS / GCPイメージ、またはNGINXベースのDockerイメージからインストールされている場合は、現在の手順をご利用ください。

  • セルフホストのWallarm nodeがK8s Ingress controllerとしてデプロイされている場合は、こちらの手順をご利用ください。

Wallarm nodeがリクエストのIPアドレスを特定する方法

Wallarm nodeは、NGINX変数$remote_addrからリクエスト送信元IPアドレスを読み取ります。リクエストがノードに送信される前にプロキシサーバーまたはロードバランサーを経由した場合、$remote_addrにはそのプロキシサーバーまたはロードバランサーのIPアドレスが保持されます。

バランサーの使用

Wallarm nodeが特定したリクエスト送信元IPアドレスは、Wallarm Consoleの攻撃の詳細に表示されます。

リクエスト送信元としてプロキシサーバーまたはロードバランサーのIPアドレスを使用する場合の問題点

Wallarm nodeがプロキシサーバーまたはロードバランサーのIPアドレスをリクエスト送信元のIPアドレスと見なすと、以下のWallarmの機能が正しく動作しない場合があります:

  • IPアドレスによるアプリケーションへのアクセス制御(例):

    元のクライアントIPアドレスをdenylistに登録しても、Wallarm nodeはロードバランサーのIPアドレスをリクエスト送信元のIPアドレスと見なすため、それらのIPから発生したリクエストをブロックしません。

  • ブルートフォース攻撃対策(例):

    ロードバランサーを経由するリクエストにブルートフォース攻撃の兆候がある場合、WallarmはこのロードバランサーのIPアドレスをdenylistに登録し、その結果、このロードバランサーを経由する以降のすべてのリクエストをブロックします。

  • Threat Replay Testingモジュール(例):

    WallarmはThreat Replay Testingモジュールが生成するテスト攻撃の送信元IPアドレスとしてロードバランサーのIPアドレスを認識します。そのため、テスト攻撃はロードバランサーのIPアドレスから発生した攻撃としてWallarm Consoleに表示され、さらにWallarmによる追加検査の対象となり、アプリケーションに余分な負荷がかかります。

Wallarm nodeがIPCソケット経由で接続されている場合、0.0.0.0がリクエストの送信元として扱われます。

元のクライアントIPアドレスを特定するための設定

元のクライアントIPアドレスを特定するには、NGINXモジュールngx_http_realip_moduleを使用できます。このモジュールは、Wallarm nodeがクライアントIPアドレスの取得に使用する$remote_addrの値を再定義できるようにします。

NGINXモジュールngx_http_realip_moduleは次のいずれかの方法で使用できます:

  • ロードバランサーやプロキシサーバーがリクエストに追加する特定のヘッダー(通常はX-Forwarded-For)から元のクライアントIPアドレスを読み取る。

  • ロードバランサーやプロキシサーバーがPROXYプロトコルに対応している場合、PROXYヘッダーから元のクライアントIPアドレスを読み取る。

X-Forwarded-ForX-Real-IPなど)ヘッダーを読み取るようにNGINXを設定する

ロードバランサーまたはプロキシサーバーが元のクライアントIPアドレスを含むX-Forwarded-ForX-Real-IPなど)ヘッダーを付加する場合、以下のとおりNGINXモジュールngx_http_realip_moduleがこのヘッダーを読み取るように設定します:

  1. Wallarm nodeとともにインストールされたNGINXの以下の設定ファイルを開きます:

    • Wallarm nodeがオールインワンインストーラーまたはAWS / GCPイメージからインストールされている場合は、/etc/nginx/sites-enabled/default
    • Wallarm nodeがNGINXベースのDockerイメージからデプロイされている場合は、NGINXの設定ファイルをローカルで作成・編集し、Dockerコンテナのパス/etc/nginx/http.d/default.confにマウントします。初期のNGINX設定ファイルのコピーおよびファイルをコンテナにマウントする手順は、WallarmのNGINXベースDockerの手順をご参照ください。
  2. NGINXのlocationコンテキストまたはそれより上位で、プロキシサーバーまたはロードバランサーのIPアドレスを指定したset_real_ip_fromディレクティブを追加します。プロキシサーバーやロードバランサーに複数のIPアドレスがある場合は、その数だけ個別のディレクティブを追加します。例:

    ...
    location / {
        wallarm_mode block;
    
        set_real_ip_from 1.2.3.4;
        set_real_ip_from 192.0.2.0/24;
    }
    ...
    
  3. 使用中のロードバランサーのドキュメントで、元のクライアントIPアドレスを渡すためにそのロードバランサーが付加するヘッダー名を確認します。最も一般的なヘッダー名はX-Forwarded-Forです。

  4. NGINXのlocationコンテキストまたはそれより上位で、前の手順で確認したヘッダー名を指定してreal_ip_headerディレクティブを追加します。例:

    ...
    location / {
        wallarm_mode block;
    
        set_real_ip_from 1.2.3.4;
        set_real_ip_from 192.0.2.0/24;
        real_ip_header X-Forwarded-For;
    }
    ...
    
  5. NGINXを再起動します:

    sudo systemctl restart nginx
    
    sudo service nginx restart
    
    sudo systemctl restart nginx
    
    sudo systemctl restart nginx
    
    sudo systemctl restart nginx
    

    NGINXはreal_ip_headerディレクティブで指定したヘッダーの値を変数$remote_addrに割り当てるため、Wallarm nodeはこの変数から元のクライアントIPアドレスを読み取ります。

  6. 設定をテストします

PROXYヘッダーを読み取るようにNGINXを設定する

ロードバランサーまたはプロキシサーバーがPROXYプロトコルに対応している場合、以下のとおりNGINXモジュールngx_http_realip_modulePROXYヘッダーを読み取るように設定できます:

  1. Wallarm nodeとともにインストールされたNGINXの以下の設定ファイルを開きます:

    • Wallarm nodeがオールインワンインストーラーまたはAWS / GCPイメージからインストールされている場合は、/etc/nginx/sites-enabled/default
    • Wallarm nodeがNGINXベースのDockerイメージからデプロイされている場合は、NGINXの設定ファイルをローカルで作成・編集し、Dockerコンテナのパス/etc/nginx/http.d/default.confにマウントします。初期のNGINX設定ファイルのコピーおよびファイルをコンテナにマウントする手順は、WallarmのNGINXベースDockerの手順をご参照ください。
  2. NGINXのserverコンテキストで、listenディレクティブにパラメーターproxy_protocolを追加します。

  3. NGINXのlocationコンテキストまたはそれより上位で、プロキシサーバーまたはロードバランサーのIPアドレスを指定したset_real_ip_fromディレクティブを追加します。プロキシサーバーやロードバランサーに複数のIPアドレスがある場合は、その数だけ個別のディレクティブを追加します。

  4. NGINXのlocationコンテキストまたはそれより上位で、値にproxy_protocolを指定してreal_ip_headerディレクティブを追加します。

    すべてのディレクティブを追加したNGINX設定ファイルの例:

    server {
        listen 80 proxy_protocol;
        server_name localhost;
    
        set_real_ip_from <IP_ADDRESS_OF_YOUR_PROXY>;
        real_ip_header proxy_protocol;
    
        ...
    }
    
    • NGINXはポート80で受信接続を待ち受けます。
    • 受信リクエストにPROXYヘッダーが含まれていない場合、このリクエストは無効と見なされるため、NGINXは受け付けません。
    • <IP_ADDRESS_OF_YOUR_PROXY>からのリクエストについて、NGINXはPROXYヘッダーで渡された送信元アドレスを変数$remote_addrに割り当てるため、Wallarm nodeはこの変数から元のクライアントIPアドレスを読み取ります。
  5. NGINXを再起動します:

    sudo systemctl restart nginx
    
    sudo service nginx restart
    
    sudo systemctl restart nginx
    
    sudo systemctl restart nginx
    
    sudo systemctl restart nginx
    
  6. 設定をテストします

元のクライアントIPアドレスをログに含めるには、NGINXのログ設定手順に従い、NGINX設定でproxy_set_headerディレクティブを追加し、log_formatディレクティブの変数一覧を編集します。

PROXYヘッダーに基づいて元のクライアントIPアドレスを特定する詳細は、NGINXのドキュメントをご参照ください。

設定のテスト

  1. 保護対象アプリケーションのアドレスにテスト攻撃を送信します:

    curl http://localhost/etc/passwd
    
    printf "PROXY TCP4 <IP_ADDRESS_OF_YOUR_PROXY> <REAL_CLIENT_IP> 0 80\r\nGET /etc/passwd\r\n\r\n" | nc localhost 80
    
  2. Wallarm Consoleを開き、攻撃の詳細に元のクライアントIPアドレスが表示されていることを確認します:

    リクエストの発信元IPアドレス

    NGINXがX-Forwarded-ForX-Real-IPなど)ヘッダーから元のアドレスを読み取った場合は、そのヘッダー値も生の攻撃データに表示されます。

    ヘッダーX-Forwarded-For

設定例

以下に、一般的なロードバランサー経由でサーバーに接続するクライアントの発信元IPアドレスを特定するために必要なNGINX設定の例を示します。

Cloudflare CDN

Cloudflare CDNを使用している場合は、NGINXモジュールngx_http_realip_moduleを設定して元のクライアントIPアドレスを特定できます。

...
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2c0f:f248::/32;
set_real_ip_from 2a06:98c0::/29;

real_ip_header CF-Connecting-IP;
#real_ip_header X-Forwarded-For;
real_ip_recursive on;
...
  • 設定を保存する前に、上記の設定に記載したCloudflareのIPアドレスがCloudflareのドキュメントに記載のものと一致していることを確認してください。

  • real_ip_headerディレクティブの値には、CF-Connecting-IPまたはX-Forwarded-Forのいずれかを指定できます。Cloudflare CDNは両方のヘッダーを付加するため、どちらを読み取るようにNGINXを設定しても構いません。詳細はCloudflare CDNのドキュメントをご参照ください

Fastly CDN

Fastly CDNを使用している場合は、NGINXモジュールngx_http_realip_moduleを設定して元のクライアントIPアドレスを特定できます。

...
set_real_ip_from 23.235.32.0/20;
set_real_ip_from 43.249.72.0/22;
set_real_ip_from 103.244.50.0/24;
set_real_ip_from 103.245.222.0/23;
set_real_ip_from 103.245.224.0/24;
set_real_ip_from 104.156.80.0/20;
set_real_ip_from 146.75.0.0/16;
set_real_ip_from 151.101.0.0/16;
set_real_ip_from 157.52.64.0/18;
set_real_ip_from 167.82.0.0/17;
set_real_ip_from 167.82.128.0/20;
set_real_ip_from 167.82.160.0/20;
set_real_ip_from 167.82.224.0/20;
set_real_ip_from 172.111.64.0/18;
set_real_ip_from 185.31.16.0/22;
set_real_ip_from 199.27.72.0/21;
set_real_ip_from 199.232.0.0/16;
set_real_ip_from 2a04:4e40::/32;
set_real_ip_from 2a04:4e42::/32;

real_ip_header X-Forwarded-For;
real_ip_recursive on;
...

設定を保存する前に、上記の設定に記載したFastlyのIPアドレスがFastlyのドキュメントに記載のものと一致していることを確認してください。

HAProxy

HAProxyを使用する場合、元のクライアントIPアドレスを特定できるよう、HAProxy側とWallarm node側の双方で適切に設定する必要があります:

  • /etc/haproxy/haproxy.cfg設定ファイルの、HAProxyからWallarm nodeへの接続を担当するbackendディレクティブブロックに、option forwardfor header X-Client-IP行を挿入します。

    option forwardforディレクティブは、クライアントのIPアドレスを含むヘッダーをリクエストに追加するようHAProxyバランサーに指示します。詳細はHAProxyのドキュメントをご参照ください

    設定例:

    ...
    # リクエストを受け付けるためのパブリックIPアドレス
    frontend my_frontend
        bind <HAPROXY_IP>
        mode http
        default_backend my_backend
    
    # Wallarm nodeのバックエンド
    backend my_backend
        mode http
    option forwardfor header X-Client-IP
    server wallarm-node <WALLARM_NODE_IP>
    ...
    
    • <HAPROXY_IP>は、クライアントのリクエストを受け付けるHAProxyサーバーのIPアドレスです。
    • <WALLARM_NODE_IP>は、HAProxyサーバーからのリクエストを受け付けるWallarm nodeのIPアドレスです。
  • Wallarm nodeとともにインストールされたNGINXの設定ファイルで、モジュールngx_http_realip_moduleを次のように設定します:

    ...
    location / {
        wallarm_mode block;
    
        proxy_pass http://<APPLICATION_IP>;        
        set_real_ip_from <HAPROXY_IP1>;
        set_real_ip_from <HAPROXY_IP2>;
        real_ip_header X-Client-IP;
    }
    ...
    
    • <APPLICATION_IP>は、Wallarm nodeからのリクエストに対する保護対象アプリケーションのIPアドレスです。
    • <HAPROXY_IP1>および<HAPROXY_IP2>は、Wallarm nodeにリクエストを転送するHAProxyバランサーのIPアドレスです。