Інфраструктура: Сервери в Центрі обробки даних, ОС - Debian Squeeze, Веб-сервер - Apache 2.2.16
Ситуація:
Живий сервер використовується нашими клієнтами щодня, що унеможливлює тестування налаштувань та вдосконалень. Тому ми хотіли б дублювати вхідний трафік HTTP на прямому сервері на один або кілька віддалених серверів у режимі реального часу. Трафік повинен бути переданий локальному веб-серверу (у цьому випадку Apache) І віддаленому серверу. Тим самим ми можемо коригувати конфігурації та використовувати різні / оновлені коди на віддаленому сервері (серверах) для порівняльної оцінки та порівняння з поточним живим сервером. На даний момент веб-сервер слухає ок. 60 додаткових портів, крім 80 і 443, через структуру клієнта.
Питання: Як можна реалізувати це дублювання на одному або декількох віддалених серверах?
Ми вже спробували:
- копіювач agnoster - для цього потрібен один відкритий сеанс на порт, який не застосовується. ( https://github.com/agnoster/duplicator )
- kklis proxy - передає трафік лише на віддалений сервер, але не передає його на веб-сервер lcoal. ( https://github.com/kklis/proxy )
- iptables - DNAT здійснює лише пересилання трафіку, але не передає його локальному веб-серверу
- iptables - TEE робить дублювання лише серверам у локальній мережі -> сервери не розташовані в одній мережі через структуру центру обробки даних
- запропоновані альтернативи, передбачені питанням "дублювання трафіку tcp з проксі" на stackoverflow ( /programming/7247668/duplicate-tcp-traffic-with-a-proxy ), не вдалися. Як вже було сказано, TEE не працює з віддаленими серверами за межами локальної мережі. teeproxy більше не доступний ( https://github.com/chrislusf/tee-proxy ), і ми не змогли знайти його деінде.
- Ми додали другу IP-адресу (яка знаходиться в одній мережі) і призначили її et0: 0 (первинна IP-адреса призначена eth0). Не вдалося поєднати цей новий IP або віртуальний інтерфейс eth0: 0 з функцією iptables TEE або маршрутами.
- запропоновані альтернативи, передбачені питанням "дублювати вхідний трафік tcp на debian сціснути" ( Дублікат вхідного трафіку TCP на Debian Squeeze ), не вдалися. Сеанси кота | nc (cat / tmp / prodpipe | nc 127.0.0.1 12345 та cat / tmp / testpipe | nc 127.0.0.1 23456) перериваються після кожного запиту / підключення клієнтом без будь-якого повідомлення або журналу. Кіпалів не змінив цю ситуацію. Пакети TCP не транспортувалися у віддалену систему.
- Додаткові спроби з різними параметрами socat (HowTo: http://www.cyberciti.biz/faq/linux-unix-tcp-port-forwarding/ , /programming/9024227/duplicate-input- unix-stream-to-multiple-tcp-client-using-socat ) та подібні інструменти були невдалими, оскільки надана TEE функція запише лише в FS.
- Звичайно, невдало також і гуглінг, і пошук цієї "проблеми" чи налаштування.
Тут у нас не вистачає варіантів.
Чи існує спосіб відключення виконання "сервера в локальній мережі" функції TEE при використанні IPTABLES?
Чи можна досягти нашої мети за рахунок різного використання IPTABLES або маршрутів?
Чи знаєте ви інший інструмент для цієї мети, який був випробуваний і працює в цих конкретних обставинах?
Чи є інше джерело для tee-proxy (яке б ідеально відповідало нашим вимогам, AFAIK)?
Заздалегідь дякую за відповіді.
----------
редакція: 05.02.2014
ось сценарій python, який би функціонував так, як нам це потрібно:
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')
Коментарі до цього сценарію:
Цей сценарій пересилає ряд налаштованих локальних портів на інші локальні та віддалені сервери сокетів.
Конфігурація:
Додайте до конфігураційного файлу рядки port-forward.config із вмістом наступним чином:
Повідомлення про помилки зберігаються у файлі 'error.log'.
Сценарій розділяє параметри конфігураційного файлу:
Розділіть кожну конфігураційну рядок пробілами
0: локальний порт для прослуховування
1: локальний порт для переадресації на
2: віддалений ip адреса сервера призначення
3: віддалений порт сервера призначення
та параметри повернення