IP-Transparenz und Direct Server Return mit NGINX und NGINX Plus als transparentem Proxy

NGINX | 14. September 2016

Dieser Blogbeitrag beschreibt, wie Sie NGINX Open Source und NGINX Plus als transparenten Proxy für den Datenverkehr zu Upstream-Servern konfigurieren. Er erläutert, wie Sie mit einem transparenten Proxy die Quell-IP-Adresse von Paketen vortäuschen können, um IP-Transparenz zu implementieren, und wie Sie für UDP-Datenverkehr einen Lastverteilungsmodus namens Direct Server Return einrichten können.

Die Informationen in diesem Beitrag gelten sowohl für NGINX Open Source als auch für NGINX Plus. Der Kürze halber beziehen wir uns im Folgenden nur auf NGINX Plus.

Anmerkung der Redaktion: Dies ist der fünfte Beitrag einer Blogreihe, in der die neuen Funktionen von NGINX Plus R10 ausführlich vorgestellt werden.

Sehen Sie sich auch unbedingt das On-Demand-Webinar „Was ist neu in NGINX Plus R10?“

Zusammenfassung

NGINX Plus fungiert als Layer-7-Reverse-Proxy. Dadurch kann NGINX Plus eine Reihe von Optimierungen und Verbesserungen auf die von ihm verwalteten Netzwerkanfragen anwenden.

Infolgedessen stellen die Upstream-Server (mit Lastverteilung) fest, dass der gesamte Datenverkehr von einer IP-Adresse des NGINX Plus-Proxys stammt. Dies stellt eine Herausforderung dar, wenn der Upstream-Server die tatsächliche Ursprungs-IP-Adresse (die des Remoteclients) ermitteln muss, beispielsweise zu Authentifizierungs- oder Protokollierungszwecken.

Für HTTP- und HTTPS-Datenverkehr gibt es wirksame Lösungen, die entweder den HTTP-Header X-Forwarded-For oder das PROXY-Protokoll verwenden. Dieser Artikel beschreibt zwei weitere Methoden für TCP- und UDP-Datenverkehr:

  • IP-Transparenz stellt sicher, dass die Upstream-Server erkennen, dass jede Verbindung von dem Remote-Client stammt, der sie initiiert hat. Sie ist auf TCP- und UDP-basierte Protokolle anwendbar.
  • Direct Server Return (DSR) sorgt außerdem dafür, dass Antworten der Upstream-Server direkt an die Remote-Clients gesendet werden und den zwischengeschalteten Load Balancer umgehen. Dieses Verfahren eignet sich für UDP-basierte Protokolle und kann durch NAT (Network Address Translation) auf dem Ursprungsserver oder einem zwischengeschalteten Router implementiert werden.

Methode 1 – IP-Transparenz Methode 2a – DSR (Router-NAT) Methode 2b – DSR (Ursprungsserver-NAT)Unterstützte Protokolle TCP- und UDP-basiert Nur UDP-basiert Nur UDP-basiertDatenverkehrsweiterleitung durch Upstream-Server Der gesamte ausgehende Datenverkehr wird an den NGINX Plus-Proxy weitergeleitet und dort terminiert Der gesamte ausgehende Datenverkehr wird über den zwischengeschalteten NGINX Plus-Server weitergeleitet Der gesamte Datenverkehr wird normal weitergeleitetLeistung Standard: Der ausgehende Datenverkehr wird am NGINX Plus-Proxy terminiert Besser: Der ausgehende Datenverkehr wird vom zwischengeschalteten NGINX Plus-Server weitergeleitet Am besten: Der ausgehende Datenverkehr wird unter Umgehung von NGINX Plus direkt an den Remote-Client weitergeleitetIntegritätsprüfungen Standardmäßig passiv; aktiv wird unterstützt Aktiv erforderlich; passiv nicht möglich Aktiv erforderlich; passiv nicht möglichErforderliche KonfigurationTCP und UDP auf dem NGINX Plus-Proxy TCP: funktioniert standardmäßig
UDP: proxy_responses 1 TCP: nicht unterstützt
UDP: proxy_responses 0 TCP: nicht unterstützt
UDP: proxy_responses 0Wie und wo werden Pakete verarbeitet? iptables terminiert auf dem NGINX Plus-Proxy tc nat schreibt auf dem zwischengeschalteten NGINX Plus-Server um tc nat schreibt auf den Upstream-Servern umNetzwerkkonfiguration auf dem NGINX Plus-Proxy iptables zum Erfassen ausgehender Pakete IP-Weiterleitung und zustandsloses NAT KeineNetzwerkkonfiguration auf dem Upstream-Server NGINX Plus als Standardroute festlegen NGINX Plus als Standardroute festlegen Zustandsloses NAT

Die Bereitstellung und Fehlerbehebung von IP-Transparenz und DSR ist komplex. Implementieren Sie diese Konfigurationen nur, wenn der standardmäßige Reverse-Proxy-Betrieb für Ihre Anwendung oder Ihren Dienst nicht ausreicht.

Einführung: Paketfluss in einem standardmäßigen Layer-7-Reverse-Proxy

Im Gegensatz zu einem Switch oder Router, der Pakete lediglich weiterleitet, arbeitet NGINX Plus als Layer-7-Reverse-Proxy. In diesem Betriebsmodus verwaltet NGINX Plus separate clientseitige und upstreamseitige TCP-Verbindungen (für HTTP- und TCP-Datenverkehr) oder UDP-Sitzungen, um die Kommunikation zwischen dem Remote-Client und dem ausgewählten Upstream-Server zu steuern.

Das Diagramm zeigt, wie TCP-Pakete und UDP-Datagramme von NGINX Plus verarbeitet werden, wenn es als Reverse-Proxy-Server fungiert.
Verarbeitung des Datenverkehrs mit NGINX Plus als Standard-Reverse-Proxy

  1. Remoteclients stellen TCP-Verbindungen her oder senden UDP-Datagramme direkt an den NGINX Plus-Reverse-Proxy unter dessen veröffentlichter IP-Adresse und Portnummer. NGINX Plus beendet die TCP-Verbindung bzw. UDP-Sitzung und liest die darin enthaltenen Anfragedaten.
  2. NGINX Plus stellt dann eine neue Verbindung (oder verwendet eine bestehende, inaktive Verbindung erneut) zum ausgewählten (lastverteilten) Upstream-Server her.
  3. Wenn NGINX Plus die Anfrage an den Upstream-Server sendet, wird die Verbindung von der internen IP-Adresse von NGINX Plus aus hergestellt.
  4. Wenn der Upstream-Server auf die Anfrage antwortet, sendet er Daten an die interne IP-Adresse von NGINX Plus.
  5. NGINX Plus empfängt die Antwortdaten über die Verbindung zur Upstream-Seite. Es kann die Antwort verarbeiten oder ändern (beispielsweise eine HTTP-Antwort komprimieren).
  6. NGINX Plus schreibt die Antwortdaten anschließend über die clientseitige Verbindung.

Eine Folge dieser standardmäßigen Reverse-Proxy-Betriebsart ist, dass der Upstream-Server feststellt, dass der TCP- und UDP-Datenverkehr vom lokalen NGINX Plus-Proxy stammt.

Vorteile und Einschränkungen des Layer-7-Reverse-Proxy-Modus

Der Layer-7-Reverse-Proxy-Betriebsmodus bietet erhebliche Leistungssteigerungen und Effizienzvorteile für HTTP- und TCP-Datenverkehr (einschließlich TCP-Optimierungen, Pufferung und Wiederverwendung von HTTP-Keepalive-Verbindungen). Eine Herausforderung entsteht, wenn der Upstream-Server die tatsächliche Ursprungs-IP-Adresse der Verbindung oder Sitzung ermitteln muss, etwa für die Authentifizierung und Zugriffskontrolle, die Ratenbegrenzung und die Protokollierung.

Bei einigen Protokollen kann NGINX Plus den X-Forwarded-For-HTTP-Header oder das PROXY-Protokoll verwenden, um Upstream-Servern die ursprüngliche IP-Adresse bereitzustellen. Dieser Beitrag beschreibt zwei weitere Methoden, die durch den Parameter transparent der Direktive proxy_bind ermöglicht werden, der mit NGINX Plus Release 10 (R10)<.htmla> eingeführt wurde.

Methode 1: IP-Transparenz

IP-Transparenz dient dazu, das Vorhandensein des Reverse-Proxys zu verbergen, sodass der Ursprungsserver erkennt, dass die IP-Pakete von der IP-Adresse des Clients stammen. IP-Transparenz kann mit TCP- und UDP-basierten Protokollen verwendet werden.

Erstellen eines HTTP-Reverse-Proxy-Dienstes auf dem NGINX Plus Load Balancer

Zur Veranschaulichung der IP-Transparenz erstellen wir zunächst einen Cluster aus vier Webservern mit Lastverteilung, die einige grundlegende Verbindungsinformationen zurückgeben.

  1. Konfigurieren Sie einen einfachen virtuellen HTTP-Server, der den Datenverkehr auf eine Gruppe von Upstream-Servern verteilt:
# in the 'http' context
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;
}
  1. Um zu überprüfen, ob die Upstream-Server erkennen, dass die Verbindungen vom NGINX Plus-Load-Balancer stammen, konfigurieren Sie auf jedem der vier Server (172.16.0.11 bis 172.16.01.14) einen NGINX Plus-Webserver mit einem einfachen virtuellen Server, der Informationen über die Verbindung zurückgibt, zum Beispiel:
# in the 'http' context
server {
    listen 80;

    location / {
        return 200 "Hello from $hostname. You connected from $remote_addr:$remote_port to $server_addr:$server_portn";
    }
}

Wenn wir diese Konfiguration testen, melden die Upstream-Server, dass die Verbindungen von der lokalen IP-Adresse von NGINX Plus (172.16.0.1) ausgehen:

$ for i in {1..4}; do curl http://192.168.99.10 ; done
Hello from dev1. You connected from 172.16.0.1:42723 to 172.16.0.11:80
Hello from dev2. You connected from 172.16.0.1:39117 to 172.16.0.12:80
Hello from dev3. You connected from 172.16.0.1:54545 to 172.16.0.13:80
Hello from dev4. You connected from 172.16.0.1:57020 to 172.16.0.14:80

NGINX Plus und Ihre Upstreams für IP-Transparenz konfigurieren

NGINX Plus R10 und höher (sowie NGINX Open Source 1.11.0 und höher) kann die Quelladresse des Upstream-Datenverkehrs fälschen. Fügen Sie der Direktive transparent den Parameter proxy_bind hinzu. In der Regel legen Sie als Quelladresse die Adresse des Remoteclients fest:

proxy_bind $remote_addr transparent;

Dieser einfache Schritt stellt jedoch eine erhebliche Herausforderung dar, da Sie sicherstellen müssen, dass der Antwortdatenverkehr (ausgehender Datenverkehr) zum entfernten Client korrekt verarbeitet wird. Der Antwortdatenverkehr muss an NGINX Plus weitergeleitet werden, und NGINX Plus muss die Upstream-TCP-Verbindung beenden. Anschließend sendet NGINX Plus den Antwortdatenverkehr über die Client-TCP-Verbindung an den entfernten Client.

Sie müssen mehrere Konfigurationsänderungen vornehmen, und zwar sowohl am NGINX Plus-Load-Balancer als auch an jedem Upstream-Server:

  1. Konfigurieren Sie auf dem NGINX Plus-Load-Balancer die Worker-Prozesse so, dass sie als root ausgeführt werden, damit sie Upstream-Sockets an beliebige Adressen binden können. Fügen Sie im Hauptkontext (auf oberster Ebene) in /etc/nginx/nginx.conf die Direktive user ein, um die ID der NGINX Plus-Worker-Prozesse auf root festzulegen:
# in the 'main' context
# 'user daemon' is the default; change to 'user root' with transparent proxy_bind
user root;
  1. Stellen Sie auf dem NGINX Plus-Load-Balancer sicher, dass jede Verbindung von der Adresse des Remoteclients ausgeht. Fügen Sie der Konfiguration für den virtuellen Server die Direktive „proxy_bind“ mit dem Parameter „transparent“ hinzu:
# in the 'http' context
server {
    listen 80;

    location / {
        proxy_bind $remote_addr transparent;
        proxy_pass http://http_upstreams;
    }
}
  1. Konfigurieren Sie auf dem NGINX Plus-Load-Balancer iptables, um die Antwortpakete der Upstream-Server zu erfassen und an NGINX Plus weiterzuleiten. In diesem Beispiel führen wir die Befehle iptables und ip rule aus, um den gesamten TCP-Datenverkehr auf Port 80 von den Servern im IP-Adressbereich 172.16.0.0/28 zu erfassen:
# 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
  1. Führen Sie den folgenden Befehl aus, um mit (-L) die aktuelle Konfiguration aus der iptables-Mangle-Tabelle aufzulisten:
# iptables -t mangle -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
MARK       tcp  --  172.16.0.0/28        anywhere             tcp spt:http MARK set 0x1

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
  1. Konfigurieren Sie das Routing auf den Upstream-Servern so, dass der gesamte Rückverkehr an NGINX Plus weitergeleitet wird. Entfernen Sie auf jedem Upstream-Server alle vorhandenen Standardrouten und legen Sie als Standardroute die IP-Adresse des NGINX Plus-Load-Balancers/Reverse-Proxys fest. Beachten Sie, dass sich diese IP-Adresse im selben Subnetz wie eine der Schnittstellen des Upstream-Servers befinden muss.
# route del default gw 10.0.2.2
# route add default gw 172.16.0.1
  1. Prüfen Sie, ob die Routingtabelle plausibel aussieht:
# route -n
Kernel IP routing table
Destination   Gateway     Genmask        Flags Metric Ref Use 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
  1. Wenn Ihre Upstream-Server Verbindungen zu externen Servern herstellen können müssen, müssen Sie das neue NGINX Plus-Gateway außerdem so konfigurieren, dass es Datenverkehr weiterleitet und maskiert – siehe „Externen Zugriff für Upstream-Server aktivieren“ weiter unten.

Testen der IP-Transparenzkonfiguration

Sie können die Konfiguration nun testen, indem Sie Anfragen an NGINX Plus senden. Stellen Sie sicher, dass Sie die Anfragen von einer Remote-IP-Adresse senden, die von den Upstream-Servern aus nicht direkt erreichbar ist:

$ for i in {1..4}; do curl http://192.168.99.10 ; done
Hello from dev1. You connected from 192.168.99.1:60729 to 172.16.0.11:80
Hello from dev2. You connected from 192.168.99.1:43070 to 172.16.0.12:80
Hello from dev3. You connected from 192.168.99.1:45749 to 172.16.0.13:80
Hello from dev4. You connected from 192.168.99.1:46609 to 172.16.0.14:80

Beachten Sie, dass die Verbindungen nun von der IP-Adresse des Remoteclients (192.168.99.1) zu stammen scheinen und nicht mehr von einer lokalen Adresse des NGINX Plus Load Balancers.

Wenn die Konfiguration nicht funktioniert, lesen Sie den Abschnitt „Fehlerbehebung“ weiter unten.

Zusammenfassung: Wie funktioniert die Konfiguration der IP-Transparenz?

  • NGINX Plus empfängt eine HTTP-Anfrage von einem Remote-Client (192.168.99.1).
  • NGINX Plus trifft eine Lastverteilungsentscheidung und wählt einen Upstream-Server (z. B. 172.16.0.11) aus, zu dem eine Verbindung hergestellt werden soll. Bevor NGINX Plus die Verbindung herstellt, bindet es seinen Upstream-Socket an die Adresse des Remoteclients.
  • Der Upstream-Server empfängt die Verbindung, die scheinbar direkt vom Remote-Client stammt.
  • Der Upstream-Server antwortet, adressiert die Pakete an die Adresse des Remote-Clients und leitet sie über NGINX Plus (den Standardrouter) weiter.
  • Die iptables-Regel auf dem NGINX Plus-Load-Balancer markiert diese Pakete, und das Routing stellt sie lokal zu.
  • NGINX Plus liest die Antwort.
  • NGINX Plus sendet die Antwort anschließend an den Remote-Client.

Im Ergebnis scheinen die Verbindungen aus Sicht der Upstream-Server direkt von den Remote-Clients auszugehen.

Methode 2: Direkte Serverantwort

Direct Server Return (DSR) ist eine Erweiterung des Konzepts der IP-Transparenz. Bei der IP-Transparenz empfängt der Upstream-Server Pakete, die scheinbar vom Remote-Client stammen. Bei DSR antwortet der Upstream-Server zusätzlich direkt an den Remote-Client; die Antwortpakete umgehen den Load Balancer vollständig.

DSR kann einen kleinen Leistungsvorteil bieten, da es die Last auf dem Load Balancer reduziert, bringt jedoch einige Einschränkungen mit sich:

  • Der Load Balancer sieht die Antwortpakete nie und kann daher nicht erkennen, ob der Upstream-Server antwortet oder ausgefallen ist.
  • Der Load Balancer kann eine Anfrage nicht über das erste Paket hinaus prüfen, bevor er einen Upstream-Server auswählt. Daher sind seine Möglichkeiten, Load-Balancing-Entscheidungen zu treffen (inhaltsbasiertes Routing), stark eingeschränkt.
  • Der Load Balancer kann an keiner Form von Aushandlung oder zustandsbehafteter Verarbeitung wie SSL/TLS teilnehmen.
  • Die meisten anderen Funktionen eines Application Delivery Controllers (ADC), wie Caching, HTTP-Multiplexing und Protokollierung, sind mit DSR nicht möglich.

DSR ist für TCP-Protokolle nur eingeschränkt geeignet, und die Reverse-Proxy-Architektur von NGINX Plus kann ohnehin nicht auf DSR/TCP angewendet werden.

UDP-Protokolle sind wesentlich einfacher und weisen keine der Verbindungssemantiken von TCP auf. Sie können NGINX Plus so konfigurieren, dass DSR für UDP-Protokolle wie DNS unterstützt wird, was Leistungsvorteile bieten kann. Konkret bedeutet DSR, dass NGINX Plus UDP-Sockets nicht in Erwartung eines Antwortpakets geöffnet halten muss (was die Skalierbarkeit verbessert) und Antwortpakete die Layer-7-Verarbeitung von NGINX Plus vollständig umgehen können (was die Latenz reduziert).

Wie unterscheidet sich eine DSR-Konfiguration von IP-Transparenz?

Zwischen einer IP-Transparency-Konfiguration und einer DSR-Konfiguration für UDP-Datenverkehr gibt es drei Unterschiede:

  • NGINX Plus muss beim Senden von Datagrammen an Upstream-Server sowohl die IP-Adresse des Remote-Clients als auch dessen Port vortäuschen (proxy_bind-Portkonfiguration).
  • NGINX Plus darf nicht so konfiguriert sein, dass Antwortdatagramme von Upstream-Servern erwartet werden (die Direktive „proxy_responses 0“).
  • Ein zusätzlicher Schritt ist erforderlich, um die Quelladresse der Antwortdatagramme so umzuschreiben, dass sie mit der öffentlichen Adresse des Load Balancers übereinstimmt.

Zusätzlich muss NGINX Plus so konfiguriert werden, dass aktive Zustandsprüfungen für die Upstream-Server durchgeführt werden. NGINX Plus kann sich nicht auf die üblichen passiven Prüfungen verlassen, um festzustellen, ob ein Server fehlerfrei arbeitet, da NGINX Plus die vom Server gesendeten Antwortpakete nicht erfasst.

Erstellen eines standardmäßigen UDP-Reverse-Proxy-Dienstes

Um DSR zu demonstrieren, erstellen Sie zunächst einen Cluster aus vier DNS-Servern mit Lastenausgleich, die bei Abfragen des Namens www.example.com unterschiedliche IP-Adressen zurückgeben.

Konfigurieren Sie eine einfache Reverse-Proxy-Konfiguration, die die Last auf die DNS-Server verteilt:

# in the 'stream' context
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;
}

Die Direktiven proxy_responses und proxy_timeout implementieren eine einfache Integritätsprüfung. Wenn ein Upstream-Server nicht innerhalb von 1 Sekunde 1 Antwort sendet, geht NGINX Plus davon aus, dass der Server ausgefallen ist, und wiederholt die DNS-Anfrage.

Konfigurieren Sie jeden DNS-Server so, dass er auf Anfragen nach seiner eigenen IP-Adresse antwortet: www.example.com:

$TTL   	604800
@           IN          SOA         ns1.example.com. admin.example.com. (
                              2           ; Serial
                         604800           ; Refresh
                          86400           ; Retry
                        2419200           ; Expire
                         604800 )         ; Negative Cache TTL

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

ns1             IN      A       172.16.0.11
www             IN      A       172.16.0.11

Die Tests zeigen deutlich, dass NGINX Plus die Anfragen per Lastverteilung auf die DNS-Server verteilt:

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

NGINX Plus und Ihre UDP-Upstreams für DSR konfigurieren

NGINX Plus R10 und höher (sowie NGINX Open Source 1.11.2 und höher) kann sowohl die Quelladresse als auch den Quellport des Upstream-Datenverkehrs vortäuschen. Fügen Sie der Direktive transparent den Parameter proxy_bind hinzu:

proxy_bind $remote_addr:$remote_port transparent;

Dadurch kann der Upstream-Server die vollständige Quell-IP-Adresse erkennen und Antwortdatagramme erstellen, die direkt an den entfernten Client gesendet werden.

Der Upstream-Server erzeugt Antwortpakete („Egress“-Pakete) mit dem korrekten IP-Ziel, verwendet jedoch seine lokale IP-Adresse als Quelladresse. Die Quelladresse muss in die IP-Adresse und den Port des NGINX Plus Load Balancers umgeschrieben werden, mit dem sich der Client ursprünglich verbunden hat.

Es gibt zwei mögliche Methoden:

  1. Router-NAT – Schreiben Sie die ausgehenden Pakete auf einem zwischengeschalteten Router (z. B. dem NGINX Plus-Proxy) um
  2. Ursprungs-NAT – Schreibt die ausgehenden Pakete beim Verlassen der einzelnen vorgelagerten DNS-Server um

Beide Methoden verwenden die zustandslose NAT-Funktion, die Sie mit dem Befehl „tc“ konfigurieren. Wenn die Upstream-Server direkt mit dem Internet verbunden sind (die Topologie also dazu führt, dass Antwortpakete nicht über einen von Ihnen kontrollierbaren zwischengeschalteten Router gesendet werden), müssen Sie die Ursprungs-NAT-Methode auswählen.

NGINX Plus für DSR konfigurieren

Die Antwortpakete werden nicht an NGINX Plus übermittelt. Daher müssen Sie die Integritätsprüfung deaktivieren, die Sie unter „Erstellen eines standardmäßigen UDP-Reverse-Proxy-Dienstes“ konfiguriert haben: Ändern Sie die Direktive proxy_responses und deaktivieren Sie die Direktive proxy_timeout. NGINX Plus wartet nun nicht mehr auf Antworten und stuft den Upstream-Server nicht als ausgefallen ein, wenn keine Antworten eingehen. Durch das Deaktivieren dieser Prüfung kann NGINX Plus außerdem die Socket-Ressourcen sofort wiederverwenden.

Nehmen Sie außerdem sowohl die Variable $remote_addr als auch die Variable $remote_port in den ersten Parameter der Direktive proxy_bind auf, damit NGINX Plus sowohl die ursprüngliche Quelladresse als auch den ursprünglichen Quellport in den an die Upstream-Server gesendeten Datagrammen beibehält:

# in the 'stream' context
server {
    listen 53 udp;

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

Router-NAT – Umschreiben der ausgehenden Pakete auf einem zwischengeschalteten Router

Sie können ausgehende Pakete auf einem einzelnen zwischengeschalteten Router umschreiben. Wenn sich die Upstream-Server beispielsweise in einem privaten Netzwerk hinter dem NGINX Plus-Load-Balancer befinden, können Sie den Load-Balancer als Standardroute verwenden und die Pakete bei der Weiterleitung umschreiben.

  1. Konfigurieren Sie jeden Upstream-Server so, dass der gesamte ausgehende Datenverkehr über den NGINX Plus-Server geleitet wird:
# route add default gw nginx-ip-address
  1. Konfigurieren Sie den NGINX Plus-Server für die Weiterleitung von IP-Datenverkehr:
# sysctl -w net.ipv4.ip_forward=1
  1. Konfigurieren Sie den NGINX Plus-Server für die zustandslose NAT-Umschreibung:
# tc qdisc add dev eth0 root handle 10: htb
# tc filter add dev eth0 parent 10: protocol ip prio 10 u32 match ip src 172.16.0.11 match ip sport 53 action nat egress 172.16.0.11 192.168.99.10
# tc filter add dev eth0 parent 10: protocol ip prio 10 u32 match ip src 172.16.0.12 match ip sport 53 action nat egress 172.16.0.12 192.168.99.10
# tc filter add dev eth0 parent 10: protocol ip prio 10 u32 match ip src 172.16.0.13 match ip sport 53 action nat egress 172.16.0.13 192.168.99.10
# tc filter add dev eth0 parent 10: protocol ip prio 10 u32 match ip src 172.16.0.14 match ip sport 53 action nat egress 172.16.0.14 192.168.99.10
  1. Stellen Sie sicher, dass Sie die richtige ausgehende Schnittstelle und die entsprechenden IP-Adressen der einzelnen Upstream-Server auswählen.

Weitere Informationen zu zustandslosem NAT finden Sie auf der Manpage zu tc nat man page. Je nach Konfiguration können Sie die tc filter-Befehle möglicherweise auf einen einzigen Befehl reduzieren, indem Sie CIDR-Masken für die Parameter src und egress old verwenden.

Um die aktuelle tc-filter-Konfiguration anzuzeigen, führen Sie diesen Befehl aus:

# tc filter show dev eth0

Ursprungs-NAT – Umschreiben der ausgehenden Pakete auf jedem Upstream-Server

Wenn Sie die Netzwerkkonfiguration der Upstream-Server anpassen können, insbesondere wenn diese direkt mit dem Internet verbunden sind, können Sie die folgende Konfiguration verwenden. Sie muss auf jedem Upstream-Server angewendet werden.

Konfigurieren Sie jeden Upstream-Server so, dass er zustandslose NAT-Umschreibungen durchführt:

# tc qdisc add dev eth0 root handle 10: htb
# tc filter add dev eth0 parent 10: protocol ip prio 10 u32 match ip src 172.16.0.11 match ip sport 53 action nat egress 172.16.0.11 192.168.99.10

Stellen Sie sicher, dass Sie auf jedem Upstream die richtige Schnittstelle und die richtigen IP-Adressen auswählen.

Testen der DSR-Konfiguration

Um die Konfiguration zu testen, senden Sie DNS-Anfragen an den NGINX Plus-Load-Balancer und überprüfen Sie, ob sie gleichmäßig auf die Upstream-Server verteilt werden.

DSR hat keine direkt sichtbaren Auswirkungen. Sie können davon ausgehen, dass es funktioniert, wenn Sie mit der Direktive „proxy_responses 0“ NGINX Plus so konfiguriert haben, dass keine Antwortpakete erwartet werden, Ihre DNS-Clients aber dennoch Antworten mit Lastverteilung erhalten. Den Paketfluss können Sie außerdem mit tcpdump beobachten, wie weiter unten unter „Fehlerbehebung“ beschrieben.

Zusammenfassung: Wie funktioniert die DSR-Konfiguration?

  • NGINX Plus empfängt ein UDP-Datagramm von einem Remote-Client (192.168.99.1:Port).
  • NGINX Plus trifft eine Entscheidung zur Lastverteilung und wählt einen Upstream-Server (z. B. 172.16.0.11) aus, an den der Inhalt des Datagramms geschrieben wird. Bevor NGINX Plus die Verbindung herstellt, bindet es die lokale Seite des Upstream-Sockets an die IP-Adresse und den Port des Remoteclients.
  • Der Upstream-Server empfängt das von NGINX Plus gesendete Datagramm, das scheinbar direkt von der Adresse und dem Port des Remote-Clients stammt.
  • Der Upstream-Server antwortet, indem er Datagramme an den Remote-Client zurücksendet. Als Quell-IP-Adresse und -Port der Antwortdatagramme legt der Upstream-Server seine eigene lokale IP-Adresse und seinen eigenen lokalen Port fest.
  • Die Quell-IP-Adresse (und gegebenenfalls der Port) wird entweder vom Upstream-Server (Konfiguration „Ursprungs-NAT“) oder von einem zwischengeschalteten Router (Konfiguration „Router-NAT“) umgeschrieben.
  • Der Remote-Client empfängt die Datagramme, die mit dem korrekten 4‑Tupel (Quell- und Ziel-IP-Adressen sowie Ports) adressiert sind.
  • NGINX Plus erwartet keine Antwortdatagramme und schließt den Upstream-Socket sofort.

Im Ergebnis umgehen die Antwortpakete die Verarbeitung auf Layer 7 in NGINX Plus und werden direkt an den entfernten Client gesendet.

Fehlerbehebung

Wenn IP-Transparenz oder DSR nicht wie erwartet funktioniert, untersuchen Sie die möglichen Ursachen anhand der folgenden Vorschläge:

Als root ausführen

Stellen Sie sicher, dass die NGINX Plus-Worker-Prozesse für die Ausführung als root konfiguriert sind. Andernfalls wird in Ihrem Fehlerprotokoll eine Fehlermeldung ähnlich der folgenden angezeigt, wenn NGINX Plus versucht, den Socket an eine nicht lokale Adresse zu binden:

setsockopt(IP_TRANSPARENT) failed (1: Operation not permitted) while connecting to upstream, client: 192.168.99.1, server: , request: "GET / HTTP/1.1", upstream: "http://172.16.0.11:80/", host: "192.168.99.10"

Test mit ping

Überprüfen Sie, ob Sie vom NGINX Plus-Proxy aus Clients und Server anpingen können. Die Upstream-Server können entfernte Client-IP-Adressen nur dann anpingen, wenn Sie zuvor die erforderliche Routing-Konfiguration erstellen und NGINX Plus als Vermittler für die Weiterleitung von Paketen konfigurieren.

Keine überlappenden IP-Adressbereiche

Stellen Sie sicher, dass die von den Remote-Clients verwendeten IP-Subnetze nicht direkt mit den Upstream-Servern verbunden sind. Andernfalls treten wahrscheinlich zwei Probleme auf:

  • Der Linux-Schutzmechanismus „Reverse Path Filtering“ verwirft möglicherweise unbemerkt Pakete von NGINX Plus, da die Quell-IP-Adresse einem Subnetz an einer anderen Schnittstelle zugeordnet ist.
  • Antwortpakete verwenden nicht die Standardroute, sondern werden direkt an den lokal verbundenen Remote-Client gesendet.

Überall tcpdump verwenden

Während Sie die Konfiguration schrittweise aufbauen und jeden Zwischenschritt testen, führen Sie tcpdump kontinuierlich auf jedem einzelnen Server aus, um in jeder Phase zu überprüfen, ob die Pakete an die richtigen Endpunkte gesendet und von diesen empfangen werden:

$ sudo tcpdump -i any -n tcp port 80

Untersuchen Sie ungewöhnliches Verhalten mithilfe der unten aufgeführten Prüfungen.

Routingtabellen überprüfen

Überprüfen Sie sorgfältig die Routingtabellen auf jedem Server und achten Sie dabei besonders auf die Upstream-Server:

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use 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

Gibt es unerwartete Routen? Können Sie bestätigen, dass alle Pakete im Datenfluss an das richtige Ziel weitergeleitet werden? Beachten Sie, dass bei den Konfigurationen für iptables und Router-NAT alle ausgehenden Pakete über den zwischengeschalteten NGINX Plus-Proxy geleitet werden müssen.

Fehlende Pakete

Wenn Pakete unerwartet verworfen werden (tcpdump zeigt, dass sie von einem Rechner gesendet, aber von einem anderen nicht empfangen werden), könnte unbemerkt die Rückpfadfilterung dafür verantwortlich sein. Um die Rückpfadfilterung vorübergehend zu deaktivieren, führen Sie den folgenden Befehl aus:

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

Upstream-Servern den Zugriff auf externe Server ermöglichen

Wenn sich Ihre Upstream-Server in einem privaten Netzwerk befinden und NGINX Plus (oder einen anderen Server) als Standardgateway verwenden, können Sie das Gateway so konfigurieren, dass die Upstream-Server externe Hosts (im Internet) erreichen können.

Sie müssen IP-Weiterleitung aktivieren, damit das Gateway Pakete von den Upstream-Servern weiterleiten kann. Die IP-Weiterleitung ist standardmäßig in der Regel deaktiviert. Wenn die Server keine routingfähigen IP-Adressen haben (sondern private Adressen wie 172.16.0.0/24 verwenden), müssen Sie außerdem IP-Masquerading auf den externen Schnittstellen des Gateway-Servers konfigurieren:

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

Überprüfen Sie, ob Sie von Ihrem internen Upstream-Server aus einen externen Server anpingen können:

root@dev1:~# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=61 time=6.72 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=61 time=5.49 ms
^C

Um Ihre aktuelle Weiterleitungs-, Routing- und iptables nat-Konfiguration anzuzeigen, führen Sie die folgenden drei Befehle aus:

# sysctl net.ipv4.ip_forward
# route -n
# iptables -t nat -L

Unterstützung von NGINX erhalten

Die Konfiguration von IP Transparency oder Direct Server Return ist komplex, und andere zwischengeschaltete Netzwerkgeräte können die Bereitstellung beeinträchtigen, indem sie Pakete verwerfen oder anderweitig umschreiben. Wenn Sie Unterstützung benötigen, steht Ihnen das Professional-Services-Team von NGINX gerne zur Verfügung.

Testen Sie IP-Transparenz und DSR mit NGINX Plus selbst – starten Sie noch heute Ihre kostenlose 30-Tage-Testversion oder kontaktieren Sie uns, um Ihre Anwendungsfälle zu besprechen.


Teilen
Schlagwörter: F5 NGINX, Tech, 2016

Über den Autor

Owen Garrett
Owen GarrettSenior Director, Produktmanagement

Weitere Blogbeiträge von Owen Garrett

Ähnliche Blogbeiträge

Die Zukunft von NGINX: Zurück zu unseren Open-Source-Wurzeln
NGINX | 23.08.2022

Die Zukunft von NGINX: Zurück zu unseren Open-Source-Wurzeln

Beim NGINX Sprint 2022 besinnen wir uns auf unsere Open-Source-Wurzeln. Erfahren Sie mehr über die Initiativen, die wir im kommenden Jahr verfolgen, und teilen Sie uns mit, was Sie sich wünschen.

Ein Leitfaden zur Auswahl eines Ingress-Controllers, Teil 1: Ermitteln Sie Ihre Anforderungen
NGINX | 08.09.2021

Ein Leitfaden zur Auswahl eines Ingress-Controllers, Teil 1: Ermitteln Sie Ihre Anforderungen

Ein Ingress-Controller kann eines der leistungsstärksten Tools in Ihrem Kubernetes-Stack sein. Erfahren Sie, wie Sie Ihre Ingress-Anforderungen ermitteln, um die beste Option auszuwählen.

Bereitstellung des NGINX Ingress Controllers auf Amazon EKS: So haben wir getestet
NGINX | 16.08.2021

Bereitstellung des NGINX Ingress Controllers auf Amazon EKS: So haben wir getestet

Wir haben kürzlich den Lösungsleitfaden zum NGINX Ingress Controller um Empfehlungen zur Dimensionierung für Amazon Elastic Kubernetes Service (EKS) ergänzt. In diesem Blogbeitrag erläutern wir, wie wir diese Empfehlungen erarbeitet haben, und stellen Ihnen alle Informationen zur Verfügung, die Sie benötigen, um selbst ähnliche Tests durchzuführen.

Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77
NGINX | 12.12.2018

Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77

Bei der Fehlersuche bei Datenverkehrsproblemen zwischen NGINX und Upstream-Servern konnte CDN77 die benötigten Daten nur aus dem Fehlerprotokoll mit aktivierter Debug-Ausgabe beziehen, was die Leistung beeinträchtigt und riesige Dateien erzeugt. Daher entwickelte das Team ein neues benutzerdefiniertes Modul, das ausschließlich die benötigten Daten protokolliert.

Ankündigung von NGINX Plus R16
NGINX | 05.09.2018

Ankündigung von NGINX Plus R16

NGINX Plus R16 ist eine einheitliche, elastische Ingress- und Egress-Schicht für Anwendungen, die die Funktionen eines Load Balancers, API-Gateways und einer WAF vereint und neue Features wie clusterfähige Ratenbegrenzung, Schlüssel-Wert-Speicher, „Random with Two Choices“, verbessertes UDP-Load-Balancing und vieles mehr bietet.

5 Gründe für den Umstieg auf softwarebasiertes Load Balancing
NGINX | 13.10.2016

5 Gründe für den Umstieg auf softwarebasiertes Load Balancing

Entdecken Sie fünf Gründe für den Wechsel zu einem softwarebasierten Load Balancer wie NGINX Plus, darunter Kosteneinsparungen, die Einführung von DevOps und eine einheitliche Lösung für alle Umgebungen.