Я пытаюсь написать правило iptables
, которое будет перенаправлять все исходящие UDP-пакеты в локальный сокет, но мне также нужно информация о месте назначения. Я начал с
sudo iptables -t nat -A sshuttle-12300 -j RETURN --dest 127.0.0.0/8 -p udp
sudo iptables -t nat -A sshuttle-12300 -j REDIRECT --dest 0.0.0.0/0 -p udp --to-ports 15000
И это здорово, теперь я могу получать все исходящие пакеты UDP, используя сокет на порту 15000.
Теперь мне нужна информация о пункте назначения (целевой хост и номер порта), поэтому простой сокет UDP не нужен. недостаточно; нужен необработанный сокет, чтобы он получил полный IP-заголовок.
Однако, как оказалось, полученные пакеты адресованы для localhost:15000
. Это имеет смысл, потому что там находится сокет, но это не то, что мне нужно; Мне нужен хост/порт до того, как пакет был перенаправлен iptables
.
Поиск в Google привел к этому вопросус ответом, предлагающим два подхода: TPROXY
и SO_ORIGINAL_DST
, рекомендую первый, так что я попытался пойти с ним. .
Добавлено правило iptables
для TPROXY
:
sudo iptables -t mangle -A PREROUTING -j TPROXY --dest 0.0.0.0/0 -p udp --on-port 15000
Чтение из tproxy.txt, нам нужно создать прослушивающий сокет с IP_TRANSPARENT
вариант (это делается от имени пользователя root):
from socket import *
s = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)
# The IP_TRANSPARENT option isn't defined in the socket module.
# Took the value (19) from the patch in http://bugs.python.org/issue12809
s.setsockopt(SOL_IP, 19, 1)
s.bind(('0.0.0.0', 15000))
s.recv(4096) # Will hang until it receives a packet
Хорошо, теперь давайте напишем еще один скрипт для генерации тестового пакета, чтобы посмотреть, произойдет ли что-нибудь:
from socket import *
s = socket(AF_INET, SOCK_DGRAM)
s.connect(('192.168.1.1', 9001))
s.send('hello')
Но тогда на принимающей стороне ничего не происходит.Кажется, что вызов recv
завис, не получая никаких данных.
Итак, общий вопрос таков:
TPROXY
?или
Изменить: Я должен настаивать на том, что хочу перенаправлять(следовательно, перехватывать) пакеты, а не просто проверять их по мере прохождения.