Infrastruttura: Server in Datacenter, SO - Debian Squeeze, Webserver - Apache 2.2.16
Situazione:
Il server live viene utilizzato quotidianamente dai nostri clienti, il che rende impossibile testare regolazioni e miglioramenti. Pertanto vorremmo duplicare il traffico HTTP in ingresso sul server live su uno o più server remoti in tempo reale. Il traffico deve essere passato al Webserver locale (in questo caso Apache) E ai server remoti. In questo modo possiamo regolare le configurazioni e utilizzare un codice diverso / aggiornato sui server remoti per l'analisi comparativa e il confronto con l'attuale server live. Attualmente il server web sta ascoltando circa. 60 porte aggiuntive oltre a 80 e 443, a causa della struttura del client.
Domanda: come può essere implementata questa duplicazione su uno o più server remoti?
Abbiamo già provato:
- duplicatore di agnoster: ciò richiederebbe una sessione aperta per porta che non è applicabile. ( https://github.com/agnoster/duplicator )
- proxy kklis - inoltra solo il traffico al server remoto, ma non lo passa al server web lcoal. ( https://github.com/kklis/proxy )
- iptables - DNAT inoltra solo il traffico, ma non lo passa al server web locale
- iptables - TEE duplica solo i server nella rete locale -> i server non si trovano nella stessa rete a causa della struttura del datacenter
- le alternative suggerite fornite per la domanda "traffico tcp duplicato con un proxy" su stackoverflow ( /programming/7247668/duplicate-tcp-traffic-with-a-proxy ) non hanno avuto esito positivo. Come accennato, TEE non funziona con server remoti al di fuori della rete locale. teeproxy non è più disponibile ( https://github.com/chrislusf/tee-proxy ) e non siamo riusciti a trovarlo altrove.
- Abbiamo aggiunto un secondo indirizzo IP (che si trova nella stessa rete) e l'abbiamo assegnato a eth0: 0 (l'indirizzo IP primario è assegnato a eth0). Nessun successo con la combinazione di questo nuovo IP o interfaccia virtuale eth0: 0 con la funzione o i percorsi TEE di iptables.
- le alternative suggerite fornite per la domanda "duplicare il traffico tcp in entrata su Debian Squeeze" ( duplicare il traffico TCP in entrata su Debian Squeeze ) non hanno avuto successo. Le sessioni cat | nc (cat / tmp / prodpipe | nc 127.0.0.1 12345 e cat / tmp / testpipe | nc 127.0.0.1 23456) vengono interrotte dopo ogni richiesta / connessione da parte di un client senza preavviso o registro. Keepalive non ha cambiato questa situazione. I pacchetti TCP non sono stati trasportati sul sistema remoto.
- Ulteriori tentativi con diverse opzioni di socat (HowTo: http://www.cyberciti.biz/faq/linux-unix-tcp-port-forwarding/ , /programming/9024227/duplicate-input- unix-stream-to-multiple-tcp-client-using-socat ) e strumenti simili non hanno avuto successo, perché la funzione TEE fornita scriverà solo in FS.
- Naturalmente, anche cercare su Google questo "problema" o impostazione non ha avuto successo.
Stiamo esaurendo le opzioni qui.
Esiste un metodo per disabilitare l'applicazione del "server nella rete locale" della funzione TEE quando si utilizza IPTABLES?
Il nostro obiettivo può essere raggiunto con un diverso utilizzo di IPTABLES o Route?
Conosci uno strumento diverso per questo scopo che è stato testato e funziona in queste circostanze specifiche?
Esiste una fonte diversa per tee-proxy (che si adatterebbe perfettamente ai nostri requisiti, AFAIK)?
Grazie in anticipo per le tue risposte.
----------
modifica: 05.02.2014
ecco lo script Python, che funzionerebbe nel modo in cui ne abbiamo bisogno:
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')
I commenti per utilizzare questo script:
Questo script inoltra un numero di porte locali configurate a un altro server socket locale e remoto.
Configurazione:
aggiungere al file di configurazione le righe port-forward.config con i contenuti come segue:
I messaggi di errore sono memorizzati nel file "error.log".
Lo script divide i parametri del file di configurazione:
Dividi ogni riga di configurazione con spazi
0: porta locale per ascoltare
1: porta locale per inoltrare a
2: indirizzo IP remoto del server di destinazione
3: porta remota del server di destinazione
e impostazioni di ritorno