Инфраструктура: серверы в центре обработки данных, ОС - Debian Squeeze, веб-сервер - Apache 2.2.16
Ситуация:
Живой сервер используется нашими клиентами каждый день, что делает невозможным тестирование настроек и улучшений. Поэтому мы хотели бы дублировать входящий HTTP-трафик на работающем сервере на один или несколько удаленных серверов в режиме реального времени. Трафик должен быть передан на локальный веб-сервер (в данном случае Apache) И на удаленный сервер (ы). Таким образом, мы можем настраивать конфигурации и использовать другой / обновленный код на удаленном сервере (ах) для сравнительного анализа и сравнения с текущим живым сервером. В настоящее время веб-сервер прослушивает ок. 60 дополнительных портов помимо 80 и 443, из-за структуры клиента.
Вопрос: Как реализовать это дублирование на одном или нескольких удаленных серверах?
Мы уже попробовали:
- Дубликатор agnoster - для этого потребуется один открытый сеанс на порт, что неприменимо. ( https://github.com/agnoster/duplicator )
- Прокси-сервер kklis - только перенаправляет трафик на удаленный сервер, но не передает его на веб-сервер 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-адрес (который находится в той же сети) и присвоили ему eth0: 0 (основной IP-адрес назначен eth0). Не удалось объединить этот новый IP или виртуальный интерфейс eth0: 0 с функцией или маршрутами iptables TEE.
- предложенные альтернативы, предложенные для вопроса «дублировать входящий tcp-трафик на сжатие Debian» ( дублирование входящего TCP-трафика на сжатие Debian ), не увенчались успехом. Сеансы cat | nc (cat / tmp / prodpipe | nc 127.0.0.1 12345 и cat / tmp / testpipe | nc 127.0.0.1 23456) прерываются после каждого запроса / подключения клиентом без какого-либо уведомления или журнала. Keepalive не изменил эту ситуацию. Пакеты TCP не были перенесены в удаленную систему.
- Дополнительные попытки с с различными вариантами SOCAT (HowTo: http://www.cyberciti.biz/faq/linux-unix-tcp-port-forwarding/ , /programming/9024227/duplicate-input- unix-stream-to-multiple-tcp-clients-using-socat ) и аналогичные инструменты оказались безуспешными, поскольку предоставленная функция TEE будет выполнять запись только в FS.
- Конечно, поиск и поиск этой «проблемы» или настройки также не увенчались успехом.
У нас заканчиваются варианты здесь.
Есть ли способ отключить принудительное использование «сервера в локальной сети» функции TEE при использовании IPTABLES?
Может ли наша цель быть достигнута путем различного использования IPTABLES или Routes?
Знаете ли вы другой инструмент для этой цели, который был протестирован и работает для этих конкретных обстоятельств?
Есть ли другой источник для 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: удаленный порт сервера назначения
и возврат настроек