PortProxy - ReverseNAT mit Windows

Warum sollte ich einen Windows Server nutzen, um einen Dienst hinter einer anderen IP-Adresse zu veröffentlichen? Das machen doch in der Regel Loadbalancer, Reverse Proxies, Firewalls oder notfalls auch ein DSL-Router viel besser? So habe ich lange Zeit auch gedacht und daher der in Windows eingebauten Funktion nicht lange meine Aufmerksamkeit geschenkt. Die Funktion ist ab Windows 2008 verfügbar. Aber auch auf Windows 7 ist die Funktion enthalten, da beide auf dem gleichen Code basieren.

In der Not...

Und dann kam der Moment, bei dem ein Server abgebaut werden sollte und Exchange schon deinstalliert war und plötzlich bestimmte Mails nicht mehr abgekommen sind. Anscheinend hat noch jemand an eine statisch eingetragene IP-Adresse gesendet und hat sich nicht um DNS-Einträge, virtuelle IPs auf Loadbalancern und die Bekanntmachungen im Vorfeld gekümmert. Und wenn die Mails nicht regelmäßig kommen, dann finden Sie diese auch nicht auf dem alten Server im Messagetracking.

Die genauen Umstände kann ich hier nicht weiter beschreiben aber es war uns zu dem Zeitpunkt nicht möglich, die Konfiguration des den Absender zu korrigieren. Aber eine Lösung musste her. Und da kam mir ein Windows Server gerade recht, denn die neuen Exchange Server waren natürlich mittlerweile in einem ganz anderen Subnetz. Aber in dem alten Subnetz gab es noch einen Windows Server. Dem konnten wir dann einfach die alte IP-Adresse zusätzlich geben und über die Funktion PortProxy wurden die Pakete an die neuen Server weiter geleitet.

PortProxy Funktionsweise

Es handelt sich also nicht um einen "Windows SMTP-Service", der die Mails annimmt und in einer Queue ablegt um sie dann zur nächsten Station zu senden. Es handelt sich um ein fast transparentes NAT mit zwei TCP-Connections. Es ist aber kein 100% NAT, bei dem alle Pakete 1:1 durchgereicht werden. Es ist schon ein "PortProxy", der die TCP-Connection unterbricht. Damit scheidet natürlich der Einsatz für UDP, ICMP oder andere "Nicht-TCP"-Protokolle aus. Ein Aufbrechen von SSL-Verbindungen ohne den Privaten Key des Ziels ist aber nicht möglich.

Hier einmal der Mitschnitt eines Client auf Port 80 des PortProxy, der die Anfragen direkt auf ein drittes System auf Port 5050 weiter gibt. Im WireShark sieht man zwei Verbindungen.

Wobei man schon etwas Übung beim Analysieren haben muss. Aber Wireshark erkennt unter "Statistiken - Flowgraph" auch eine schönere Ansicht aller aktuell angezeigten Verbindungen:

Hier ist gut zu sehen, wie der Client erst mal einen 3-Wege Handshake aufbaut und dann der Proxy die Verbindung zum Backend startet. Dann kommt aber schon der Request von Client während der Proxy noch den Handshake zum Ziel fertig machen muss. und dann die Anfrage des Clients weitersendet.

Obwohl hier alle drei Client auf dem gleichen Subnetz sind, funktioniert dies. Der Proxy ersetzt ausgehend nämlich die Source-IP des Client durch seine eigene. Adresse und es entspricht etwas der "Single Arm Konfiguration" eines Loadbalancers. Damit sind natürlich auch die Grenzen schnell aufgezählt:

  • Backend sieht nur die IP des Proxy aber nicht den Clients
    Das führt zu Einschränkungen beim Logging und Fehlersuche.
  • Skalierung mit Source Port Limit
    Der Proxy kann ausgehend auch nicht mehr als 655235 Port verwenden. Der Service ist also schnell überlastet oder angreifbat

Das ganze funktioniert auch nur mit TCP. Der Versuch den Port 80 des PortProxy mit einem UDP-Paket zu beaufschlagen hat zwar die eingehenden Pakete angezeigt aber sonst nichts.

Nicht mal ein ICMP-Not Reachable o.ä. wurde zurück gesendet. Damit sehen Sie aber schon den Unterschied zu einem "einfachen NAT", wie dies DSL-Router machen. Da sie keine TCP-Connections halten können und auch für UDP durchgängig sein wollen, terminieren Sie nicht die Connections, sondern reichen Sie umgehend durch. Dabei bleiben natürlich auch die Sequence-Nummern erhalten.

Konfiguration

Die Konfiguration des PortProxy funktioniert per Kommandozeile mit NETSH. Da Windows mittlerweile per Default auch eine Firewall aktiviert hat, müssen Sie hier natürlich auch noch das passende Loch bohren. Kleine Anekdote am Rande: NETMON schneidet Pakete schon vor der Windows Firewall mit. Sie sehen hier also schon eingehende Verbindungsversuche obwohl die Firewall diese dann ablehnt.  Hier die Zeilen um den Port 25 auf dem Server mit der IP-Adresse 192.168.100.1 auf den Server 172.16.1.1 auf Port 25 weiter zu leiten.

netsh interface portproxy add v4tov4 listenport=25 listenaddress=192.168.100.1 connectport=25 connectaddress=172.16.1.1

Natürlich können Sie auch Quell und Ziel-Port abweichen lassen und die Ziel-IP-Adresse muss nicht im gleichen Subnetz liegen. Allerdings ist durch die Konfiguration natürlich das Ziel fest vorgegeben. Es ist kein "Socks-Proxy", bei dem ein Client das Ziel steuern kann. Zudem müssen Sie natürlich in der Firewall den Port öffnen

netsh advfirewall firewall add rule name="Port25" dir=in action=allow protocol=TCP localport=25

Am besten Prüfen Sie die Funktion von einem anderen Client per "TELNET". Es sollte sich der Zielserver melden. Interessant ist, dass sich damit auch eine IPv4 zu IPv6 Umsetzung erreichen lässt.

Die aktuell eingerichteten Weiterleitungen lassen sich wie folgt schnell anzeigen:

C:\>netsh interface portproxy show all

Listen on ipv4:             Connect to ipv4:

Address         Port        Address         Port
--------------- ----------  --------------- ----------
192.168.178.8   80          192.168.178.11  5050

Auch das Entfernen geht per Kommandozeile sehr schnell und einfach:

netsh interface portproxy delete v4tov4 listenport=25 listenaddress=10.181.225.22
netsh advfirewall firewall delete rule name="Port25" dir=in protocol=TCP localport=25

Damit sind alle Tore wieder geschlossen.

Achtung IPListen und Port 443/80

Jedes System mit Windows 7 oder Windows 2008 oder neuer hat einen HTTP-Listener eingebaut, auch wenn keine IIS-Rolle installiert ist. Die Kernfunktion ist Bestandteil des Betriebssystem. Das kann aber auch bedeuten, dass etwas anderes schon den Port 443/80 oder auch einen anderen Port.

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Alle Rechte vorbehalten.

C:\>netsh http show iplisten

Vorhandene IP-Adressen in der IP-Abhörliste:
-------------------------------------------

Die Liste ist per Default erst einmal "leer" und damit "ANY" Adresse für einen Listener erreichbar. Wenn Sie hier IP-Adressen eintragen oder andere Dienste schon Ports abhören, dann könnten diese zu einem Konflikt mit PortProxy führen. Der HTTP-Listener macht es ja so einfach auch mit PowerShell einfach mal einen "Webserver" zu bauen:

Einschätzung

Interessant finde ich, dass so eine Funktion seit Windows 2008 vorhanden ist und sogar Einzug auf die Desktop-Systeme (Windows 7) gefunden hat. Es gibt natürlich keine GUI und für die meisten Administratoren ist diese Option auch unbekannt und wird vermutlich auch nicht entdeckt, wenn jemand so einen Client "umleiten" will. Als Sicherheitsrisiko möchte ich diese Funktion allerdings nicht sehen. Der Client muss schon angefasst werden, damit er auch diesen PortProxy verwendet. Und dann kann ich mit dem Client eh bessere Dienste zur "Inspizierung" von Datenverkehren nutzen, z.B. Fiddler. Dennoch kann man einen Client per HOSTS oder DNS-Einträge dazu bringen, diesen Proxy-Service zu nutzen, auf dem Man dann per NetMon/Wiresharkdie Verbindung mitschneiden kann. Wer weiß, wozu es einmal gut sein kann.

Und ich kann so eine Funktion eines Server, der z.B. schon seiner Exchange Rolle beraubt ist aber dennoch von Clients weiter genutzt wird, einfach mal auf einen noch bestehenden Server weitergeben. Das neue Ziel kann dabei sogar in einem anderen Subnetz stehen. Insofern gut, dass es diese Funktion gibt aber sie ist sicher keine Funktion, die ich dauerhaft einsetzen möchtet.

Weitere Links