ブログ | NGINX

NGINX と NGINX Plus を透過プロキシとして使用した IP 透過性と直接サーバー リターン

NGINX-F5 水平黒タイプ RGB の一部
オーウェン・ギャレット サムネイル
オーウェン・ギャレット
2016 年 9 月 14 日公開

このブログ記事では、NGINX Open Source と NGINX Plus をアップストリーム サーバーへのトラフィックの透過プロキシとして構成する方法について説明します。 透過プロキシを使用してパケットの送信元 IP アドレスをスプーフィングし、IP 透過性を実装する方法と、UDP トラフィックに対して Direct Server Return と呼ばれる負荷分散モードを実装する方法について説明します。

この投稿の情報は、NGINX Open SourceNGINX Plus の両方に適用されます。 簡潔にするために、NGINX Plus のみを参照します。

編集者 – これは、NGINX Plus R10 の新機能を詳細に説明するブログ投稿シリーズの 5 番目です。

オンデマンド ウェビナー「NGINX Plus R10 の新機能」もぜひご覧ください。

まとめ

NGINX Plus はレイヤー 7 リバース プロキシとして動作します。 これにより、NGINX Plus は管理するネットワーク リクエストにさまざまな最適化と機能強化を適用できるようになります。

その結果、上流(負荷分散)サーバーは、すべてのトラフィックが NGINX Plus プロキシ上の IP アドレスから発信されていることを認識します。 これは、アップストリーム サーバーが認証やログ記録などの目的で実際の元の IP アドレス (リモート クライアントの IP アドレス) を判別する必要がある場合に課題となります。

HTTP および HTTPS トラフィックには、 X-Forwarded-For HTTP ヘッダーまたはPROXY プロトコルのいずれかを使用した効果的な回避策があります。 この記事では、TCP および UDP トラフィックに適用される 2 つの追加方法について説明します。

  • IP 透過性により、アップストリーム サーバーは、各接続がそれを開始したリモート クライアントから発信されたことを監視できるようになります。 TCP および UDP ベースのプロトコルに適用できます。
  • さらに、ダイレクト サーバー リターン(DSR) は、アップストリーム サーバーからの応答がリモート クライアントに直接送信され、中間ロード バランサーをバイパスするように調整します。 これは UDP ベースのプロトコルに適用可能であり、オリジン サーバーまたは中間ルーターで NAT (ネットワーク アドレス変換) を実行することによって実装できます。
  方法 1 – IP の透明性 方法 2a – DSR (ルーター NAT) 方法 2b – DSR (オリジン NAT)
サポートされているプロトコル TCPベースとUDPベース UDPベースのみ UDPベースのみ
上流サーバーによるトラフィックルーティング すべての出力トラフィックはNGINX Plusプロキシにルーティングされ、終了されます。 すべての出力トラフィックは中間のNGINX Plusサーバーを経由してルーティングされます すべてのトラフィックは正常にルーティングされます
パフォーマンス 標準: 出力トラフィックは NGINX Plus プロキシで終了します。 より良い方法: 出力トラフィックは中間のNGINX Plusサーバーによって転送されます ベスト: 出力トラフィックはNGINX Plusをバイパスしてリモートクライアントに直接ルーティングされます。
健康診断 デフォルトではパッシブ、アクティブはサポートされています 能動態が必要。受動態は不可能 能動態が必要。受動態は不可能
必要な構成
NGINX Plus プロキシ上の TCP と UDP TCP: デフォルトで動作します
UDP:プロキシ応答 1
TCP: サポートされていません
UDP:プロキシ応答 0
TCP: サポートされていません
UDP:プロキシ応答 0
パケットはどのように、どこで処理されますか? iptablesはNGINX Plusプロキシで終了します 中間NGINX Plusサーバー上のtc nat書き換え 上流サーバー上のtc nat の書き換え
NGINX Plus プロキシのネットワーク構成 出力パケットをキャプチャするためのiptables IP 転送とステートレス NAT なし
上流サーバーのネットワーク構成 NGINX Plusをデフォルトルートとして指定する NGINX Plusをデフォルトルートとして指定する ステートレスNAT

IP 透過性と DSR の導入とトラブルシューティングは複雑です。 標準のリバース プロキシ モードの動作がアプリケーションまたはサービスに十分でない場合にのみ、これらの構成を実装します。

導入: 標準レイヤー 7 リバース プロキシのパケット フロー

単にパケットを転送するスイッチやルーターとは異なり、NGINX Plus はレイヤー 7リバース プロキシとして動作します。 この動作モードでは、NGINX Plus は、リモート クライアントと選択されたアップストリーム サーバー間の通信を制御するために、クライアント側とアップストリーム側の TCP 接続 (HTTP および TCP トラフィック用) または UDP セッションを個別に管理します。

この図は、NGINX Plusがリバースプロキシサーバーとして機能するときに、TCPパケットとUDPデータグラムがどのように処理されるかを示しています。
標準リバースプロキシとして機能する NGINX Plus によるトラフィック処理
  1. リモート クライアントは、公開された IP アドレスとポートで NGINX Plus リバース プロキシに TCP 接続するか、UDP データグラムを直接送信します。 NGINX Plus は TCP 接続または UDP セッションを終了し、その中のリクエスト データを読み取ります。
  2. その後、NGINX Plus は、選択された(負荷分散された)アップストリーム サーバーに新しい接続(または既存のアイドル接続の再利用)を確立します。
  3. NGINX Plus がアップストリーム サーバーにリクエストを書き込むと、接続は NGINX Plus の内部 IP アドレスから発信されます。
  4. アップストリーム サーバーがリクエストに応答すると、NGINX Plus の内部 IP アドレスにデータが書き込まれます。
  5. NGINX Plus は、アップストリーム側の接続で応答データを受信します。 応答を処理または変更する場合があります (たとえば、HTTP 応答に圧縮を適用する)。
  6. その後、NGINX Plus はクライアント側の接続に応答データを書き込みます。

この標準的なリバース プロキシ モードの動作の結果、アップストリーム サーバーは、TCP および UDP トラフィックがローカル NGINX Plus プロキシから発信されていることを認識します。

レイヤー 7 リバース プロキシ モードの利点と制限

レイヤー 7 リバース プロキシ モードの動作により、HTTP および TCP トラフィックのパフォーマンスと効率が大幅に向上します (TCP 最適化、バッファリング、HTTP キープアライブの再利用を含む)。 認証やアクセス制御、レート制限、ログ記録などの目的で、アップストリーム サーバーが接続またはセッションの実際の元の IP アドレスを判別する必要がある場合、これは課題となります。

一部のプロトコルでは、NGINX Plus はX-Forwarded-For HTTP ヘッダーまたはPROXY プロトコルを使用して、アップストリーム サーバーに元の IP アドレスを提供できます。 この投稿では、NGINX Plus リリース 10 (R10)<.htmla>で導入されたproxy_bindディレクティブのtransparentパラメータによって可能になった 2 つの追加方法について説明します。

方法1: IP の透明性

IP 透過性の目的は、リバース プロキシの存在を隠し、IP パケットがクライアントの IP アドレスから発信されたことをオリジン サーバーが認識できるようにすることです。 IP 透過性は、TCP ベースおよび UDP ベースのプロトコルで使用できます。

NGINX Plus ロードバランサー上に HTTP リバースプロキシサービスを作成する

IP 透過性を実証するために、まず、いくつかの簡単な接続情報で応答する 4 つの Web サーバーの負荷分散クラスターを作成します。

  1. アップストリーム サーバーのグループ間でトラフィックを負荷分散する単純な HTTP 仮想サーバーを構成します。

    # 'http' コンテキスト内
    server {
    listen 80;
    
    location / {
    proxy_pass http://http_upstreams;
    }
    }
    
    upstream http_upstreams {
    server 172.16.0.11;
    server 172.16.0.12;
    server 172.16.0.13;
    server 172.16.0.14;
    }
    
  2. アップストリーム サーバーが接続が NGINX Plus ロード バランサーから発信されていることを確認するには、4 つの各サーバー (172.16.0.11 ~ 172.16.01.14) に、次のような接続に関する情報を返す単純な仮想サーバーを備えた NGINX Plus Web サーバーを構成します。

    # 'http' コンテキスト内
    server {
    listen 80;
    
    location / {
    return 200 "Hello from $hostname. $remote_addr:$remote_port から $server_addr:$server_port に接続しました\n";
    }
    }
    

この構成をテストすると、アップストリームは接続がローカル NGINX Plus IP アドレス (172.16.0.1) から発信されたことを報告します。

$ for i in {1..4}; do curl http://192.168.99.10 ; done dev1 からこんにちは。 172.16.0.1:42723 から 172.16.0.11:80 に接続しました。dev2 からこんにちは。 172.16.0.1:39117 から 172.16.0.12:80 に接続しました。dev3 からこんにちは。 172.16.0.1:54545 から 172.16.0.13:80 に接続しました。dev4 からこんにちは。 172.16.0.1:57020 から 172.16.0.14:80 に接続しました

IP 透過性のための NGINX Plus とアップストリームの設定

NGINX Plus R10 以降 (および NGINX Open Source 1.11.0 以降) では、アップストリーム トラフィックの送信元アドレスを偽装できます。 proxy_bindディレクティブにtransparentパラメータを含めます。 最も一般的には、送信元アドレスをリモート クライアントのアドレスに設定します。

proxy_bind $remote_addr は透過的です。

ただし、この単純な手順では、リモート クライアントへの応答 (出力) トラフィックが正しく処理されることを確認する必要があるため、大きな課題が生じます。 応答トラフィックは NGINX Plus にルーティングされ、NGINX Plus はアップストリーム TCP 接続を終了する必要があります。 その後、NGINX Plus はクライアント TCP 接続を介して応答トラフィックをリモート クライアントに送信します。

NGINX Plus ロードバランサーと各アップストリームサーバーの両方に、いくつかの構成変更を加える必要があります。

  1. NGINX Plus ロードバランサーで、ワーカー プロセスをrootとして実行するように構成し、アップストリーム ソケットを任意のアドレスにバインドできるようにします。

    /etc/nginx/nginx.confのメイン(最上位)コンテキストに、NGINX PlusワーカープロセスのIDをrootに設定するユーザーディレクティブを含めます。

    # 'main' コンテキスト内
    # 'user daemon' がデフォルトです。透過的 proxy_bind を使用して 'user root' に変更します
    user root;
    
  2. NGINX Plus ロード バランサーで、各接続がリモート クライアント アドレスから発信されていることを確認します。

    仮想サーバーの設定に、 transparentパラメータを含むproxy_bindディレクティブを追加します。

    # 'http' コンテキスト内
    server {
    listen 80;
    
    location / {
    proxy_bind $remote_addr transparent;
    proxy_pass http://http_upstreams;
    }
    }
    
  3. NGINX Plus ロード バランサーで、アップストリーム サーバーからの戻りパケットをキャプチャして NGINX Plus に配信するようにiptablesを構成します。

    この例では、 iptables コマンドip ruleコマンドを実行して、IP 範囲 172.16.0.0/28 で表されるサーバーからのポート 80 上のすべての TCP トラフィックをキャプチャします。

    # ip rule add fwmark 1 lookup 100 # ip route add local 0.0.0.0/0 dev lo table 100 # iptables -t mangle -A PREROUTING -p tcp -s 172.16.0.0/28 --sport 80 -j MARK --set-xmark 0x1/0xffffffff
    

    次のコマンドを実行して、 iptables mangle テーブルから現在の構成を一覧表示 ( -L ) します。

    # iptables -t mangle -Lチェーン PREROUTING (ポリシー ACCEPT) ターゲット prot opt ソース 宛先 MARK tcp -- 172.16.0.0/28 anywhere tcp spt:http MARK set 0x1 チェーン INPUT (ポリシー ACCEPT) ターゲット prot opt ソース 宛先 チェーン FORWARD (ポリシー ACCEPT) ターゲット prot opt ソース 宛先 チェーン OUTPUT (ポリシー ACCEPT) ターゲット prot opt ソース 宛先 チェーン POSTROUTING (ポリシー ACCEPT) ターゲット prot opt ソース 宛先
    
  4. アップストリーム サーバーで、すべての戻りトラフィックが NGINX Plus に転送されるようにルーティングを構成します。

    各アップストリーム サーバーで、既存のデフォルト ルートを削除し、デフォルト ルートを NGINX Plus ロード バランサー/リバース プロキシの IP アドレスに設定します。 この IP アドレスは、アップストリーム サーバーのインターフェースの 1 つと同じサブネット上にある必要があることに注意してください。

    #ルート del デフォルト gw 10.0.2.2 #ルート add デフォルト gw 172.16.0.1
    

    ルーティング テーブルが適切であることを確認します。

    # route -nカーネル IP ルーティング テーブル 宛先 ゲートウェイ Genmask フラグ メトリック 参照 使用 Iface 0.0.0.0 172.16.0.1 0.0.0.0 UG 0 0 0 eth2 10.0.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 172.16.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2 192.168.56.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
    

    アップストリーム サーバーが外部サーバーに接続できるようにする必要がある場合は、トラフィックを転送およびマスカレードするように新しい NGINX Plus ゲートウェイを構成する必要もあります。以下の「アップストリームが外部サーバーに到達できるようにする」を参照してください。

IP 透過性構成のテスト

NGINX Plus にリクエストを送信して、構成をテストできるようになりました。 アップストリーム サーバーから直接ルーティングできないリモート IP アドレスからリクエストを送信していることを確認します。

$ for i in {1..4}; do curl http://192.168.99.10 ; done dev1 からこんにちは。 192.168.99.1:60729 から 172.16.0.11:80 に接続しました。dev2 からこんにちは。 192.168.99.1:43070 から 172.16.0.12:80 に接続しました。dev3 からこんにちは。 192.168.99.1:45749 から 172.16.0.13:80 に接続しました。dev4 からこんにちは。 192.168.99.1:46609 から 172.16.0.14:80 に接続しました

接続が、NGINX Plus ロードバランサーのローカル アドレスからではなく、リモート クライアントの IP アドレス (192.168.99.1) から発信されているように見えることに注目してください。

設定が機能しない場合は、以下のトラブルシューティングを参照してください。

まとめ: IP 透過性構成はどのように機能しますか?

  • NGINX Plus はリモート クライアント (192.168.99.1) から HTTP リクエストを受信します。
  • NGINX Plus は負荷分散の決定を行い、接続するアップストリーム サーバー (たとえば、172.16.0.11) を選択します。 NGINX Plus は接続する前に、アップストリーム ソケットをリモート クライアントのアドレスにバインドします。
  • アップストリーム サーバーは、リモート クライアントから直接発信されたように見える接続を受信します。
  • アップストリーム サーバーは応答し、パケットをリモート クライアントのアドレスに宛てて、NGINX Plus (デフォルト ルーター) 経由でルーティングします。
  • NGINX Plus ロードバランサーのiptablesルールはこれらのパケットをマークし、ルーティングによってローカルに配信します。
  • NGINX Plus は応答を読み取ります。
  • その後、NGINX Plus はリモート クライアントに応答を送信します。

最終的な結果として、上流サーバーの観点からは、接続はリモート クライアントから直接発信されたように見えます。

方法2: 直接サーバーリターン

Direct Server Return (DSR) は、IP 透明性の概念の拡張です。 IP 透過性では、アップストリーム サーバーはリモート クライアントから発信されたように見えるパケットを受信します。 DSR を使用すると、上流サーバーがリモート クライアントに直接応答し、返されるパケットはロード バランサーを完全にバイパスします。

DSR はロード バランサーの負荷を軽減するため、パフォーマンス上の利点がわずかながら得られますが、いくつかの制限があります。

  • ロード バランサは戻りパケットを認識しないため、アップストリーム サーバーが応答しているか、障害が発生しているかを検出できません。
  • ロード バランサは、アップストリームを選択する前に最初のパケットを超える要求を検査できないため、ロード バランシングの決定 (コンテンツ ベースのルーティング) を行う能力は非常に制限されます。
  • ロード バランサは、SSL/TLS などのいかなる形式のネゴシエーションやステートフル処理にも参加できません。
  • キャッシュ、HTTP 多重化、ログ記録など、他のほとんどのアプリケーション配信コントローラー (ADC) 機能は、DSR では利用できません。

DSR は TCP プロトコルでは使用が制限されており、いずれにしても NGINX Plus のリバース プロキシ アーキテクチャは DSR/TCP に適用できません。

UDP プロトコルは、TCP の接続セマンティクスがなく、はるかに単純です。 NGINX Plus を構成して、DNS などの UDP プロトコルの DSR をサポートすると、パフォーマンス上のメリットが得られます。 具体的には、DSR は、NGINX Plus が応答パケットを期待して UDP ソケットを開いたままにする必要がないこと (これによりスケーラビリティが向上する)、および応答パケットが NGINX Plus のレイヤー 7 処理を完全にバイパスできること (これによりレイテンシが削減される) を意味します。

DSR 構成は IP 透過性とどう違うのでしょうか?

UDP トラフィックの IP 透過性構成と DSR 構成には、次の 3 つの違いがあります。

  • NGINX Plus は、データグラムをアップストリーム サーバーに送信するときに、リモート クライアントの IP アドレスポートの両方を偽装する必要があります ( proxy_bindポート構成)。
  • NGINX Plusは、上流サーバーからの応答データグラムを期待するように設定しないでください( proxy_responses0指令)。
  • 返されるデータグラムの送信元アドレスをロード バランサーのパブリック アドレスと一致するように書き換える追加の手順が必要です。

さらに、NGINX Plus は、アップストリーム サーバーに対してアクティブなヘルス チェックを実行するように構成する必要があります。 NGINX Plus はサーバーから送信された応答パケットを監視しないため、通常のパッシブ チェックに頼ってサーバーが正常かどうかを確認することはできません。

標準 UDP リバース プロキシ サービスの作成

DSR をデモンストレーションするには、まず、 www.example.comという名前の検索に対して異なる IP アドレスで応答する 4 つの DNS サーバーの負荷分散クラスターを作成します。

DNS サーバー間で負荷分散を行うシンプルなリバース プロキシ構成を構成します。

# 'stream' コンテキスト内
server {
listen 53 udp;

proxy_responses 1;
proxy_timeout 1s;
proxy_pass dns_upstreams;
}

upstream dns_upstreams {
server 172.16.0.11:53;
server 172.16.0.12:53;
server 172.16.0.13:53;
server 172.16.0.14:53;
}

proxy_responsesおよびproxy_timeoutディレクティブは、基本的なヘルス チェックを実装します。 アップストリーム サーバーが 1 秒以内に 1 つの応答を送信しない場合、NGINX Plus はサーバーに障害が発生したと見なし、DNS 要求を再試行します。

各 DNS サーバーがwww.example.comの検索に対して独自の IP アドレスで応答するように設定します。

$TTL 604800
@ IN SOA ns1.example.com. admin.example.com. (
2 ; シリアル
604800 ; 更新
86400 ; 再試行
2419200 ; 期限切れ
604800 ) ; ネガティブ キャッシュ TTL

example.com。    IN NS ns1.example.com。

ns1 IN A 172.16.0.11
www IN A 172.16.0.11

テストにより、NGINX Plus が DNS サーバー間でリクエストを負荷分散していることが明らかになりました。

$ for i in {1..4} ; do dig +short @192.168.99.10 www.example.com ; 完了
172.16.0.11
172.16.0.12
172.16.0.13
172.16.0.14

DSR 用の NGINX Plus と UDP アップストリームの設定

NGINX Plus R10 以降 (および NGINX Open Source 1.11.2 以降) では、アップストリーム トラフィックの送信元アドレスとポートの両方をスプーフィングできます。 proxy_bindディレクティブにtransparentパラメータを含めます。

proxy_bind $remote_addr:$remote_port は透過的です。

これにより、アップストリーム サーバーは完全な送信元 IP アドレスを監視できるようになり、リモート クライアントに直接送信される応答データグラムを構築できるようになります。

アップストリーム サーバーは、正しい IP 宛先を持つ応答 (「出力」) パケットを生成しますが、送信元アドレスとしてローカル IP アドレスを使用します。 送信元アドレスは、クライアントが最初に接続した NGINX Plus ロードバランサーの IP アドレスとポートに書き換える必要があります。

2 つの方法が可能です:

  1. ルータNAT – 中間ルータ(NGINX Plusプロキシなど)で出力パケットを書き換える
  2. オリジンNAT – 各上流DNSサーバーから出るときに出力パケットを書き換える

どちらの方法でも、 tcコマンドで設定するステートレス NAT 機能が使用されます。 アップストリーム サーバーがインターネットに直接接続されている場合は (トポロジにより、戻りパケットは制御可能な中間ルーターを経由して送信されません)、オリジン NAT 方式を選択する必要があります。

DSR 用の NGINX Plus の構成

応答パケットは NGINX Plus に配信されないため、 「標準 UDP リバース プロキシ サービスの作成」で設定したヘルス チェックを無効にする必要があります。proxy_responses ディレクティブを変更し、 proxy_timeoutディレクティブを無効にします。 現在、NGINX Plus は応答を待たず、応答を受信しない場合でもアップストリーム サーバーに障害が発生したと判断することはありません。 このチェックを無効にすると、NGINX Plus はソケット リソースをすぐに再利用できるようになります。

また、 proxy_bindディレクティブの最初のパラメータに$remote_addr 変数$remote_port変数の両方を含めて、NGINX Plus がアップストリーム サーバーに送信されるデータグラム内の元の送信元アドレスと送信元ポートの両方を保持するようにします。

# 'stream' コンテキスト内
server {
listen 53 udp;

proxy_bind $remote_addr:$remote_port transparent;
proxy_responses 0;
#proxy_timeout 1s;
}

ルータ NAT – 中間ルータでの出力パケットの書き換え

単一の中間ルーターで出力パケットを書き換えることができます。 たとえば、アップストリーム サーバーが NGINX Plus ロード バランサーの背後のプライベート ネットワーク上にある場合、ロード バランサーをデフォルト ルートとして使用し、転送されるパケットを書き換えることができます。

  1. すべての送信トラフィックを NGINX Plus サーバー経由でルーティングするように各アップストリーム サーバーを構成します。

    #ルートにデフォルトの gw nginx-ip-addressを追加
    
  2. IP トラフィックを転送するように NGINX Plus サーバーを構成します。

    # sysctl -w net.ipv4.ip_forward=1
    
  3. ステートレス NAT 書き換えを実行するように NGINX Plus サーバーを構成します。

    # tc qdisc で dev eth0 ルート ハンドル 10: htb を追加します。 # tc フィルターで dev eth0 親 10: プロトコル ip prio 10 u32 に一致 ip src 172.16.0.11 に一致 ip sport 53 アクション nat egress 172.16.0.11 192.168.99.10 を追加します。 # tc フィルターで dev eth0 親 10: プロトコル ip prio 10 u32 に一致 ip src 172.16.0.12 に一致 ip sport 53 アクション nat egress 172.16.0.12 192.168.99.10 を追加します。 # tc フィルターで dev eth0 親 10:プロトコル ip prio 10 u32 に一致 ip src 172.16.0.13 に一致 ip sport を追加します。 53 アクション nat 出力 172.16.0.13 192.168.99.10 # tc フィルター追加 dev eth0 親 10: プロトコル ip 優先順位 10 u32 一致 ip src 172.16.0.14 一致 ip sport 53 アクション nat 出力 172.16.0.14 192.168.99.10
    

    各アップストリーム サーバーの適切な出力インターフェースと適切な IP アドレスが選択されていることを確認します。

ステートレス NAT の詳細については、 tc nat のマニュアル ページを参照してください。 設定によっては、 srcおよびegress oldパラメータに CIDR マスクを使用することで、 tcフィルタコマンドを 1 つのコマンドに減らすことができる場合があります。

現在のtcフィルター構成を表示するには、次のコマンドを実行します。

# tc フィルター show dev eth0

オリジン NAT – 各上流サーバーでの出力パケットの書き換え

アップストリーム サーバーでネットワークを構成できる場合、特にアップストリーム サーバーがインターネットに直接接続されている場合は、次の構成を使用できます。 各アップストリーム サーバーに適用する必要があります。

ステートレス NAT 書き換えを実行するように各アップストリーム サーバーを構成します。

# tc qdisc は dev eth0 ルート ハンドル 10: htb を追加します# tc フィルターは dev eth0 親 10: プロトコル ip 優先度 10 u32 に一致 ip src 172.16.0.11 に一致 ip sport 53 アクション nat 出力 172.16.0.11 192.168.99.10 に追加します

各アップストリームで適切なインターフェースと IP アドレスを選択していることを確認してください。

DSR 構成のテスト

構成をテストするには、DNS リクエストを NGINX Plus ロードバランサーに送信し、アップストリーム サーバー間で負荷分散されていることを確認します。

DSR には直接目に見える効果はありません。 proxy_responsesを使用した場合、それが機能していることを確信できます。0ディレクティブを使用して、NGINX Plus が応答パケットを期待しないように構成しますが、DNS クライアントは負荷分散された応答を受信します。 以下のトラブルシューティングで説明されているように、 tcpdump を使用してパケット フローをさらに観察できます。

まとめ: DSR 構成はどのように機能しますか?

  • NGINX Plus はリモート クライアント (192.168.99.1:ポート) から UDP データグラムを受信します。
  • NGINX Plus は負荷分散の決定を行い、データグラムの内容を書き込むアップストリーム サーバー (たとえば、172.16.0.11) を選択します。 NGINX Plus は接続する前に、アップストリーム ソケットのローカル側をリモート クライアントの IP アドレスとポートにバインドします。
  • アップストリーム サーバーは、NGINX Plus によって送信されたデータグラムを受信します。このデータグラムは、リモート クライアントのアドレスとポートから直接発信されたものと思われます。
  • アップストリーム サーバーが応答し、データグラムをリモート クライアントに送り返します。 アップストリーム サーバーは、応答データグラムの送信元 IP アドレスとポートを自身のローカル IP アドレスとポートに設定します。
  • 送信元 IP アドレス (および必要に応じてポート) は、上流サーバー (送信元 NAT構成) または中間ルーター (ルーター NAT構成) によって書き換えられます。
  • リモート クライアントは、正しい 4 タプル (送信元と宛先の IP アドレスとポート) でアドレス指定されたデータグラムを受信します。
  • NGINX Plus は応答データグラムを観察することを想定していないため、アップストリーム ソケットを直ちに閉じます。

最終的な結果として、応答パケットは NGINX Plus のレイヤー 7 処理をバイパスし、リモート クライアントに直接送信されます。


トラブルシューティング

IP 透過性または DSR が期待どおりに機能しない場合は、次の提案に従って考えられる原因を調査してください。

ルートとして実行

NGINX Plus ワーカー プロセスがrootとして実行されるように設定されていることを確認します。 そうでない場合、NGINX Plus がソケットを非ローカル アドレスにバインドしようとすると、エラー ログに次のようなエラー メッセージが表示されます。

setsockopt(IP_TRANSPARENT) が失敗しました (1: アップストリーム、クライアントへの接続中に操作が許可されませんでした: 192.168.99.1、サーバー: 、リクエスト: 「GET / HTTP/1.1」、アップストリーム:「http://172.16.0.11:80/」、ホスト: 「192.168.99.10」

pingでテストする

NGINX Plus プロキシからクライアントとサーバーに ping できることを確認します。 最初に必要なルーティング構成を作成し、パケットを転送するように NGINX Plus 仲介者を構成しない限り、アップストリーム サーバーはリモート クライアントの IP アドレスに ping を実行できません。

重複する IP 範囲なし

リモート クライアントが使用する IP サブネットがアップストリーム サーバーに直接接続されていないことを確認します。 そうであれば、次の 2 つの問題が発生する可能性があります。

  • Linux の「リバース パス フィルタリング」保護では、送信元 IP アドレスが別のインターフェース上のサブネットに関連付けられているため、NGINX Plus からのパケットが黙って拒否されることがあります。
  • 返信パケットはデフォルトのルートを使用せず、ローカルに接続されたリモート クライアントに直接送信されます。

どこでもtcpdumpを使用する

構成を構築し、各中間ステップをテストするときに、各サーバーでtcpdump を継続的に実行して、各段階でパケットが正しいエンドポイントに送信され、受信されていることを確認します。

$ sudo tcpdump -i 任意 -n tcpポート80

以下にリストされているチェックを使用して、異常な動作を調査します。

ルーティングテーブルを確認する

各サーバーのルーティング テーブルを慎重に確認し、特に上流サーバーに注意してください。

# route -nカーネル IP ルーティング テーブル 宛先 ゲートウェイ Genmask フラグ メトリック 参照 使用 Iface 0.0.0.0 172.16.0.1 0.0.0.0 UG 0 0 0 eth2 10.0.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 172.16.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2 192.168.56.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1

予想外のルートはありますか? フロー内のすべてのパケットが正しい宛先にルーティングされることを確認できますか? iptablesおよび Router NAT 構成では、すべての出力パケットは中間 NGINX Plus プロキシを経由してルーティングされる必要があることに注意してください。

欠落したパケット

パケットが予期せずドロップされた場合 ( tcpdumpでは、パケットが 1 台のマシンから送信されたが、別のマシンでは受信されていないことが示される)、リバース パス フィルタリングが潜在的な原因である可能性があります。 リバース パス フィルタリングを一時的に無効にするには、次のコマンドを実行します。

# for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f ; 完了

上流サーバーが外部サーバーにアクセスできるようにする

アップストリーム サーバーがプライベート ネットワーク上に存在し、NGINX Plus (または別のサーバー) をデフォルト ゲートウェイとして使用する場合は、アップストリーム サーバーが外部 (インターネット) ホストにアクセスできるようにゲートウェイを構成することをお勧めします。

ゲートウェイが上流サーバーからのパケットを転送できるように、 IP 転送を有効にする必要があります。IP 転送は通常、デフォルトでは無効になっています。 サーバーにルーティング可能な IP アドレスがない場合 (172.16.0.0/24 などのプライベート アドレスを使用する場合)、ゲートウェイ サーバーの外部インターフェイスでIP マスカレードも構成する必要があります。

# sysctl -w net.ipv4.ip_forward=1 # iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

内部のアップストリーム サーバーから外部サーバーに ping できることを確認します。

root@dev1:~# ping 8.8.8.8 PING 8.8.8.8 (8.8.8.8) 56(84) バイトのデータ。
8.8.8.8 からの 64 バイト: icmp_seq=1 ttl=61 time=6.72 ms 8.8.8.8 からの 64 バイト: icmp_seq=2 ttl=61 time=5.49 ms ^C

現在の転送、ルーティング、 iptables nat構成を表示するには、次の 3 つのコマンドを実行します。

# sysctl net.ipv4.ip_forward #ルート -n # iptables -t nat -L

NGINXからのサポートを受ける

IP 透過性または Direct Server Return の構成は複雑であり、他の中間ネットワーク デバイスがパケットをドロップしたり書き換えたりすることで展開に影響を及ぼす可能性があります。 サポートが必要な場合は、NGINX のプロフェッショナル サービスチームがお手伝いします。

NGINX Plus の IP 透過性と DSR を実際に体験してください。今すぐ30 日間の無料トライアルを開始するか、弊社にお問い合わせの上、ユースケースについてご相談ください


「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 以前の NGINX.com リンクはすべて、F5.com の同様の NGINX コンテンツにリダイレクトされます。"