Infrastruktur: Server im Rechenzentrum, Betriebssystem - Debian Squeeze, Webserver - Apache 2.2.16
Lage:
Der Live-Server wird täglich von unseren Kunden genutzt, sodass Anpassungen und Verbesserungen nicht getestet werden können. Daher möchten wir den eingehenden HTTP-Verkehr auf dem Live-Server in Echtzeit auf einen oder mehrere Remote-Server duplizieren. Der Datenverkehr muss an den lokalen Webserver (in diesem Fall Apache) UND an die Remote-Server weitergeleitet werden. Dadurch können wir Konfigurationen anpassen und anderen / aktualisierten Code auf den Remote-Servern für das Benchmarking und den Vergleich mit dem aktuellen Live-Server verwenden. Derzeit hört der Webserver ca. 60 zusätzliche Ports neben 80 und 443, aufgrund der Client-Struktur.
Frage: Wie kann diese Duplizierung auf einen oder mehrere Remote-Server implementiert werden?
Wir haben bereits versucht:
- agnoster duplicator - dies würde eine offene Sitzung pro Port erfordern, was nicht zutreffend ist. ( https://github.com/agnoster/duplicator )
- kklis proxy - leitet den Datenverkehr nur an den Remote-Server weiter, leitet ihn jedoch nicht an den lcoal-Webserver weiter. ( https://github.com/kklis/proxy )
- iptables - DNAT leitet den Datenverkehr nur weiter, nicht jedoch an den lokalen Webserver
- iptables - TEE dupliziert nur auf Servern im lokalen Netzwerk -> Die Server befinden sich aufgrund der Struktur des Datencenters nicht im selben Netzwerk
- Vorgeschlagene Alternativen für die Frage "TCP-Datenverkehr mit einem Proxy duplizieren" bei stackoverflow ( https://stackoverflow.com/questions/7247668/duplicate-tcp-traffic-with-a-proxy ) waren nicht erfolgreich. Wie bereits erwähnt, funktioniert TEE nicht mit Remoteservern außerhalb des lokalen Netzwerks. teeproxy ist nicht mehr verfügbar ( https://github.com/chrislusf/tee-proxy ) und wir konnten es nirgendwo anders finden.
- Wir haben eine zweite IP-Adresse hinzugefügt (die sich im selben Netzwerk befindet) und sie eth0: 0 zugewiesen (die primäre IP-Adresse wird eth0 zugewiesen). Kein Erfolg bei der Kombination dieser neuen IP- oder virtuellen Schnittstelle eth0: 0 mit der iptables-TEE-Funktion oder -Routen.
- vorgeschlagenen Alternativen für die Frage „duplicate eingehender TCP - Datenverkehr auf debian squeeze“ (vorausgesetzt Doppelte eingehenden TCP - Datenverkehr auf Debian Squeeze ) waren erfolglos. Die cat | nc-Sitzungen (cat / tmp / prodpipe | nc 127.0.0.1 12345 und cat / tmp / testpipe | nc 127.0.0.1 23456) werden nach jeder Anforderung / Verbindung durch einen Client ohne Benachrichtigung oder Protokoll unterbrochen. Keepalive hat diese Situation nicht geändert. TCP-Pakete wurden nicht zum fernen System transportiert.
- Zusätzliche Versuche mit mit verschiedenen Optionen von socat (HowTo: http://www.cyberciti.biz/faq/linux-unix-tcp-port-forwarding/ , https://stackoverflow.com/questions/9024227/duplicate-input- Unix-Stream-to-Multiple-TCP-Clients-using-Socat ) und ähnliche Tools waren nicht erfolgreich, da die bereitgestellte TEE-Funktion nur in FS schreibt.
- Natürlich war es auch nicht erfolgreich, zu googeln und nach diesem "Problem" oder Setup zu suchen.
Hier gehen uns die Optionen aus.
Gibt es eine Methode zum Deaktivieren der Durchsetzung von "Server im lokalen Netzwerk" der TEE-Funktion bei Verwendung von IPTABLES?
Kann unser Ziel durch unterschiedliche Nutzung von IPTABLES oder Routes erreicht werden?
Kennen Sie ein anderes Werkzeug für diesen Zweck, das getestet wurde und für diese speziellen Umstände geeignet ist?
Gibt es eine andere Quelle für Tee-Proxy (die perfekt zu unseren Anforderungen passen würde, AFAIK)?
Vielen Dank im Voraus für Ihre Antworten.
----------
bearbeiten: 05.02.2014
Hier ist das Python-Skript, das so funktioniert, wie wir es brauchen:
import socket
import SimpleHTTPServer
import SocketServer
import sys, thread, time
def main(config, errorlog):
sys.stderr = file(errorlog, 'a')
for settings in parse(config):
thread.start_new_thread(server, settings)
while True:
time.sleep(60)
def parse(configline):
settings = list()
for line in file(configline):
parts = line.split()
settings.append((int(parts[0]), int(parts[1]), parts[2], int(parts[3])))
return settings
def server(*settings):
try:
dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
dock_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
dock_socket.bind(('', settings[0]))
dock_socket.listen(5)
while True:
client_socket = dock_socket.accept()[0]
client_data = client_socket.recv(1024)
sys.stderr.write("[OK] Data received:\n %s \n" % client_data)
print "Forward data to local port: %s" % (settings[1])
local_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
local_socket.connect(('', settings[1]))
local_socket.sendall(client_data)
print "Get response from local socket"
client_response = local_socket.recv(1024)
local_socket.close()
print "Send response to client"
client_socket.sendall(client_response)
print "Close client socket"
client_socket.close()
print "Forward data to remote server: %s:%s" % (settings[2],settings[3])
remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote_socket.connect((settings[2], settings[3]))
remote_socket.sendall(client_data)
print "Close remote sockets"
remote_socket.close()
except:
print "[ERROR]: ",
print sys.exc_info()
raise
if __name__ == '__main__':
main('multiforwarder.config', 'error.log')
Die Kommentare zur Verwendung dieses Skripts:
Dieses Skript leitet eine Reihe von konfigurierten lokalen Ports an einen anderen lokalen und einen Remote-Socket-Server weiter.
Konfiguration:
Fügen Sie der Konfigurationsdatei port-forward.config die folgenden Zeilen mit Inhalten hinzu:
Fehlermeldungen werden in der Datei 'error.log' gespeichert.
Das Skript teilt die Parameter der Konfigurationsdatei auf:
Teilen Sie jede Konfigurationszeile mit Leerzeichen auf.
0: Lokaler Port zum Abhören
1: Lokaler Port zum Weiterleiten an
2: Remote-IP-Adresse des Zielservers
3: Remote-Port des Zielservers
und Rückgabe der Einstellungen