web-dev-qa-db-ja.com

Nginx:クライアントIPをサーバーに渡すリバースプロキシ

既存のnginxリバースプロキシで、クライアントIPをサーバーに渡す必要があります(nginxからNG-Engineで提供されるフロントエンドへ、そしてこれからバックエンドへ)。多くのサイトを試しましたが、サーバーは受信しています。 127.0.0.1。追加情報(マイケルハンプトンの質問の後に追加)、仮想マシンインフラストラクチャ:

  1. クライアントブラウザ(別のVMまたはリモートデスクトップ)
  2. (VM1)nginxリバースプロキシ(動作します。少なくとも追加したHTTPSレイヤー)
  3. (VM1)自家製のフロントエンドを提供するNgEngine
  4. (VM1)Java/Spring自家製バックエンドによって提供されるRESTful API(IntelliJアイデアで実行)
  5. (VM2..x)バックエンドにデータを供給する他のサーバー(問題外)

私はドキュメントをチェックし、ここで試しました(提案されているように、X-Real-IPヘッダーの削除を含む この他の質問では )。私も追加しようとしました:

set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For

私のnginxにはreal_ipモジュール(以下のnginx -Vの出力)があり、これは私のnginx.confです...何が間違っていますか?

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
  worker_connections 768;
  # multi_accept on;
}

http {
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  keepalive_timeout 65;
  types_hash_max_size 2048;
  # server_tokens off;

  server_names_hash_bucket_size 64;
  # server_name_in_redirect off;

  include /etc/nginx/mime.types;
  default_type application/octet-stream;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
  ssl_prefer_server_ciphers on;

  gzip on;
  gzip_disable "msie6";

  server {
    listen 443 ssl;
    server_name          test-server;
    ssl_certificate      /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key  /etc/nginx/ssl/nginx.key;

    add_header              Strict-Transport-Security  "max-age=63072000; includeSubdomains; preload" always;
    add_header              X-Frame-Options            SAMEORIGIN;
    add_header              X-Content-Type-Options     nosniff;

    # allow nginx to start regardless of upstream endpoint state by using intermediary variable
    set                     $UPSTREAM_SERVICE          10.10.10.15:8080;

    location  / {
      proxy_pass               http://localhost:6789
      proxy_http_version       1.1;

      proxy_buffering          off;
      proxy_buffer_size        128k;
      proxy_busy_buffers_size  256k;
      proxy_buffers            4                   256k;
      proxy_set_header         Host                $Host;
      proxy_set_header         X-Real-IP           $remote_addr;
      proxy_set_header         X-Forwarded-For     $proxy_add_x_forwarded_for;
      proxy_set_header         X-Forwarded-Proto   $scheme;
      proxy_set_header         Upgrade             $http_upgrade;
      proxy_set_header         Connection          $http_connection;

    }
  }
}

Nginx -Vの出力:

nginx version: nginx/1.14.0 (Ubuntu)
built with OpenSSL 1.1.0g  2 Nov 2017
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-mcUg8N/nginx-1.14.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_flv_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_mp4_module --with-http_Perl_module=dynamic --with-http_random_index_module --with-http_secure_link_module --with-http_sub_module --with-http_xslt_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-headers-more-filter --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-auth-pam --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-cache-purge --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-dav-ext --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-ndk --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-echo --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-fancyindex --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/nchan --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-lua --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/rtmp --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-uploadprogress --add-dy
namic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-upstream-fair --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-subs-filter

どうもありがとうございました

4
xCovelus

既存のnginxリバースプロキシで、クライアントIPをサーバー(両方とも同じOSで実行中)に渡す必要があります。多くのサイトを試しましたが、サーバーは127.0.0.1しか受信していません。

リバースプロキシとして、バックエンドサーバーは常にnginxプロセスから接続を受信します。これは、*_passディレクティブに応じて、nginxのIPアドレス(この場合は127.0.0.1)を含みます。

そのため、クライアントアドレスを確認してもクライアントIPを取得できず、フロントエンドサーバーのIPアドレスしか取得できません。

リバースプロキシと負荷分散では、ビジネスでは、バックエンドのリバースプロキシからクライアントIPを抽出する方法がいくつかあります。

  1. 非標準de-factoX-Forwarded-For HTTP request ヘッダー。渡されたすべてのプロキシと要求元のクライアントIPアドレスが含まれます(es)。
  2. Forwarded HTTPリクエスト ヘッダーは、X-Forwarded-Forを置き換える新しい標準化された方法であり、渡されたクライアントとリクエストしているすべてのプロキシのIPアドレスも含まれます。
  3. X-Real-IP HTTPリクエストヘッダー、または任意のカスタムHTTPリクエストヘッダー。クライアントのIPアドレスを任意に含めることができます。

バックエンドアプリケーションがこれらのヘッダーのいずれかをサポートしているかどうかを確認してください。


私のnginxはreal_ipモジュールを持っています

この場合、ngx_http_realip_moduleは使用されません。 nginxがプロキシの背後にある場合に使用され、実際のクライアントIPアドレスを検証およびフェッチして、指定された変数に格納できます。

2
mforsetti

両方のコメントのおかげで、解決策を見つける方法についてより明確な考えがありました。 mforsettiからのコメントは特に役に立ちました。

バックエンドアプリケーションがこれらのヘッダーのいずれかをサポートしているかどうかを確認してください。

そしてまた:

[..]、バックエンドのリバースプロキシからクライアントIPを抽出する方法はいくつかあります:[..]

HttpServletRequest(リクエスト)の使用:

request.getRemoteAddr();

だった(まだ)プロキシIPを私に与えています。そこで、正しいヘッダーを取得するために手動で試すことにしました。

request.getHeader("X-Forwarded-For");

そして、それは私にクライアントIPを正確に与えていました。

あなたの助けに感謝します、それなしでは、私はこれを解決することができません。

0
xCovelus