Infrastruktura: serwery w centrum danych, OS - Debian Squeeze, Webserver - Apache 2.2.16
Sytuacja:
Serwer na żywo jest używany przez naszych klientów każdego dnia, co uniemożliwia testowanie poprawek i ulepszeń. Dlatego chcielibyśmy powielić przychodzący ruch HTTP na serwerze na żywo do jednego lub wielu serwerów zdalnych w czasie rzeczywistym. Ruch musi zostać przekazany do lokalnego serwera WWW (w tym przypadku Apache) ORAZ do zdalnego serwera (serwerów). W ten sposób możemy dostosować konfiguracje i użyć innego / zaktualizowanego kodu na zdalnym serwerze (serwerach) do testów porównawczych i porównania z bieżącym serwerem na żywo. Obecnie serwer nasłuchuje około. 60 dodatkowych portów oprócz 80 i 443, ze względu na strukturę klienta.
Pytanie: Jak można wdrożyć tę duplikację na jednym lub wielu zdalnych serwerach?
Próbowaliśmy już:
- powielacz agnoster - wymagałoby to jednej otwartej sesji na port, co nie ma zastosowania. ( https://github.com/agnoster/duplicator )
- kklis proxy - przesyła tylko ruch do zdalnego serwera, ale nie przekazuje go do serwera Lcoal. ( https://github.com/kklis/proxy )
- iptables - DNAT przekazuje tylko ruch, ale nie przekazuje go do lokalnego serwera WWW
- iptables - TEE duplikuje się tylko na serwerach w sieci lokalnej -> serwery nie znajdują się w tej samej sieci ze względu na strukturę centrum danych
- sugerowane alternatywy dla pytania „zduplikowany ruch TCP z proxy” na stackoverflow ( https://stackoverflow.com/questions/7247668/duplicate-tcp-traffic-with-a-proxy ) okazały się nieskuteczne. Jak wspomniano, TEE nie działa ze zdalnymi serwerami poza siecią lokalną. teeproxy nie jest już dostępny ( https://github.com/chrislusf/tee-proxy ) i nie mogliśmy go znaleźć gdzie indziej.
- Dodaliśmy drugi adres IP (który jest w tej samej sieci) i przypisaliśmy go do eth0: 0 (podstawowy adres IP jest przypisany do eth0). Bez powodzenia połączenie nowego IP lub interfejsu wirtualnego eth0: 0 z funkcją i trasami iptables TEE.
- sugerowane alternatywy dla pytania „zduplikowany przychodzący ruch TCP przy ściśnięciu Debiana” ( Zduplikowany przychodzący ruch TCP przy ściśnięciu Debiana ) nie powiodły się. Sesje cat | nc (cat / tmp / prodpipe | nc 127.0.0.1 12345 i cat / tmp / testpipe | nc 127.0.0.1 23456) są przerywane po każdym żądaniu / połączeniu przez klienta bez powiadomienia lub dziennika. Keepalive nie zmieniło tej sytuacji. Pakiety TCP nie zostały przetransportowane do systemu zdalnego.
- Dodatkowe próby z różnymi opcjami socat (HowTo: http://www.cyberciti.biz/faq/linux-unix-tcp-port-forwarding/ , https://stackoverflow.com/questions/9024227/duplicate-input- unix-stream-to-multiple-tcp-client-using-socat ) i podobne narzędzia zakończyły się niepowodzeniem, ponieważ podana funkcja TEE zapisze tylko FS.
- Oczywiście przeglądanie i wyszukiwanie tego „problemu” lub konfiguracji również nie powiodło się.
Brakuje nam tutaj opcji.
Czy istnieje metoda wyłączenia wymuszania „serwera w sieci lokalnej” funkcji TEE podczas korzystania z IPTABLES?
Czy nasz cel może zostać osiągnięty poprzez różne użycie IPTABLES lub tras?
Czy znasz inne narzędzie do tego celu, które zostało przetestowane i działa w tych konkretnych okolicznościach?
Czy istnieje inne źródło tee-proxy (które idealnie pasowałoby do naszych wymagań, AFAIK)?
Z góry dziękuję za twoje odpowiedzi.
----------
edycja: 05.02.2014
oto skrypt Pythona, który działałby tak, jak go potrzebujemy:
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')
Komentarze do użycia tego skryptu: Skrypt
ten przekazuje wiele skonfigurowanych portów lokalnych do innych lokalnych i zdalnych serwerów gniazd.
Konfiguracja:
Dodaj do pliku konfiguracyjnego linie port-forward.config z zawartością w następujący sposób:
Komunikaty o błędach są przechowywane w pliku „error.log”.
Skrypt dzieli parametry pliku konfiguracyjnego:
Podziel każdy wiersz konfiguracji spacjami
0: port lokalny, aby nasłuchiwać
1: port lokalny, aby przekazać do
2: zdalny adres IP serwera docelowego
3: zdalny port serwera docelowego
i ustawienia powrotu