2015-07-20 2 views
1

В целях тестирования я хочу построить сервер, который прослушивает TCP-соединения для каждого порта (или, по крайней мере, на большинстве портов) на определенном интерфейсе (например, eth0). Доступ к серверу осуществляется через SSH до eth1, поэтому проблем нет. (Я не забочусь о UDP или других протоколах)Прослушивание КАЖДОГО порта на машине

Я хочу сделать особый вид обнаружения/анализа промежуточных пакетов, поэтому мне нужно иметь возможность полностью установить соединение. Наличие HTTP-соединения было бы лучшим, потому что «клиент» мог быть реализован как JS в браузере.

Я начал с простого причального сервера, но должен был понять, что причал должен появляться, по крайней мере, в потоке на каждый порт, который он слушает. Это приводит к проблемам, когда я хочу слушать несколько тысяч портов. Или есть способ обойти это?

Моя следующая попытка была использовать iptables:

Судо Iptables -t физ -A PREROUTING -i eth0 -p TCP -j DNAT --to-назначения 127.0.0.1: 8080`

Казалось, это сработало. Он позволяет подключаться к каждому порту, и трафик направляется на локальный порт 8080, где причал слушает. Но теперь я больше не знаю, какой порт использовался клиентом. Поскольку пристань думает, что соединение установлено через порт 8080. Есть ли способ определить реальный входной порт из причала? Я мог бы отправить порт как часть HTTP-запроса, но если клиент пытается связаться с портом 1234 .., а middlebox перенаправляет его на порт 5678. Я не могу узнать, какой порт использовался.

Я также пробовал решения для пользователей, такие как socat. Проблема была еще хуже, чем раньше. Потому что теперь пристань также видел удаленный IP как 127.0.0.1.

Или, есть ли другой способ достичь этого?

Oh and btw: У меня есть полный контроль над машиной. Поэтому я мог бы изменить ядро ​​или что-то еще. Прямо сейчас я использую Ubuntu 14.04 LTS, но если решение нуждается в чем-то другом, я могу пойти с этим.

+0

Я думаю, что это может быть оффтоп для переполнения стека. Считаете ли вы использование 'inetd' для присоединения скрипта к портам? – Sobrique

+0

Я также не уверен, что я должен попробовать суперпользователь вместо stackoverflow. Но обычно stackoverflow привлекает больше участников. Я не пробовал «inetd», я посмотрю на него. – masgo

+0

Проводная акула пассивна. Мне нужно установить соединение с полным рукопожатием TCP и т. Д. – masgo

ответ

4

NB: Это решение Python, потому что я знаю, Python, но вы можете сделать то же самое на любом языке, то обнажает основную библиотеку C getsockopt вызова.

Если вы замените DNAT правило с REDIRECT правило, вы можете использования getsockopt с опцией SO_ORIGINAL_DST для получения оригинального адреса REDIRECT -ED соединения.

Рассмотрим следующий код:

#!/usr/bin/python 

import socket 
import struct 

SO_ORIGINAL_DST = 80 

s = socket.socket() 
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
s.bind(('0.0.0.0', 2000)) 
s.listen(10) 

while True: 
    csock, caddr = s.accept() 
    orig_dst = csock.getsockopt(socket.SOL_IP, SO_ORIGINAL_DST, 16) 

    orig_port = struct.unpack('>H', orig_dst[2:4]) 
    orig_addr = socket.inet_ntoa(orig_dst[4:8]) 

    print 'connection from', caddr 
    print 'connection to', (orig_addr, orig_port) 
    print 

Если у меня есть Iptables правило, которое выглядит как:

# iptables -t nat -A PREROUTING -p tcp --dport 1500:1600 \ 
    -j REDIRECT --to-port 2000 

И в то время как код выше Python работает я соединяюсь от другого хоста к my_ip_address:1500, я вижу:

connection from ('192.168.1.20', 35790) 
connection to ('192.168.1.75', (1500,)) 

А если подключить к порту 1550 Я вижу:

connection from ('192.168.1.20', 42054) 
connection to ('192.168.1.75', (1550,)) 

который я думаю, что это именно то, что вы просили. Обратите внимание, что, насколько мне известно, это будет работать только для TCP-соединений; существуют и другие решения (возможно, с использованием цели iptables TPROXY), которые также могут работать с соединениями UDP.

+0

О, это отлично работает. Теперь мне нужно только выяснить, как получить доступ к getsockopt из java .. или как адаптировать мой сервер к чему-то вроде python или C/C++ .. но это выполнимо. – masgo

+0

Если вы удовлетворены этим ответом, подумайте о том, чтобы нажать на галочку слева от ответа. Это и способ сказать «спасибо», а также способ дать людям понять, что на ваш вопрос был дан ответ. – larsks

Смежные вопросы