Отмеченные пакеты не маршрутизируются должным образом

538
GroovyDotCom

ОБНОВЛЕНИЕ: Решение: Я должен был использовать цепочку ВЫХОДА, а не цепочку ПРОГНОЗИРОВАНИЯ. Этот пример все еще не работает, но я скоро обновлю его.

Мне кажется, это должно работать. Я перемещаю все правила маршрутизации из основной таблицы в таблицу 4, а затем MARK и прямые пакеты, предназначенные для порта 80/443, в таблицу 4. Я ожидаю, что порт 80 будет работать так же, как если бы я ничего не делал, но gethostbyname просто не работает?

#!/bin/bash -x # # Reset/Flush iptables iptables -F iptables -X iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT  # Reset/Flush table 4 ip route flush table 4  # move all routing rules from the main table to table 4 ip route show table main | grep -v linkdown | while read ROUTE do ip route add table 4 $ROUTE ip route del table main $ROUTE done  # MARK all HTTP(S) destination packets with a 4 iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 4 iptables -t mangle -A PREROUTING -p tcp --dport 443 -j MARK --set-mark 4 iptables -t mangle -A PREROUTING -p udp --dport 53 -j MARK --set-mark 4  # packets marked as 4 find their routes via table 4 ip rule add fwmark 4 table 4 ip route flush cache 
0
Ваши правила iptables не будут достигнуты, потому что в основной таблице нет маршрута. Поскольку они не будут выполняться, они никогда не установят метку, указывающую на использование таблицы 4. Итак, у вас нет никакого маршрута ... Теперь вы можете сказать, какую проблему вы на самом деле намереваетесь решить со всем этим? A.B 6 лет назад 1
Таким образом, маршрут должен быть найден до выполнения предварительной маршрутизации? Это кажется неправильным, так как правило может сделать что-то для изменения маршрутизации (как в моем случае)? GroovyDotCom 6 лет назад 0
Что касается проблемы: мне нужно сделать что-то вроде прозрачного прокси через устройство TUN для всех портов, кроме HTTP, DNS. Это означает, что если приложение отправляет что-то на foo.com:22, оно должно фактически перейти на устройство TUN, а мое прокси-приложение должно действительно отправить его на foo.com:22. Так что не показано выше - это правило по умолчанию в main, которое отправляет все на мое устройство TUN. Так что у меня есть маршрут в главной таблице, но это не помогает. GroovyDotCom 6 лет назад 0
Хорошо. Я вижу сейчас. Я должен был использовать цепочку OUTPUT, а не PREROUTING. GroovyDotCom 6 лет назад 0
Я тоже попробовал, прежде чем ответить. Без изменений. Если маршрута нет, то не будет использоваться PREROUTING или OUTPUT. Вы должны инвестировать в TPROXY iptables и посмотреть, что вы можете с ним сделать. Или вы можете просто сохранить основные маршруты, таким образом, iptables должен сработать, установить fwmark и, в конце концов, будет использоваться таблица 4 A.B 6 лет назад 0

1 ответ на вопрос

2
A.B

iptables (и / или netfilter) имеет различные хуки в стеке маршрутизации. Когда пакет проходит определенный шаг в стеке маршрутизации, если там есть хук iptables, хук iptables запускается. Конечно, если пакет не достигает такого шага, не запускается ловушка iptables. Если «нет маршрута к хосту», стек маршрутизации сдается раньше и не достигает этих шагов. Вот что происходит в вашем примере после того, как вы удалили маршруты (основной таблицы) и оставили таблицу маршрутизации, которая зависит от того, какие iptables будут когда-либо использоваться. Это проблема курицы и яйца, но это не нужно делать таким образом. Вам просто нужен маршрут, любой маршрут, так что ваши правила будут запускать и изменять этот маршрут.

Я запустил ваш скрипт и получил с моими настройками:

# ip route (nothing) # ip route show table 4 default via 10.0.3.1 dev eth0  10.0.3.0/24 dev eth0 proto kernel scope link src 10.0.3.66  

Добавлены правила ВЫХОДА:

iptables -t mangle -A OUTPUT -p udp -m udp --dport 53 -j MARK --set-xmark 0x4/0xffffffff iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 53 -j MARK --set-xmark 0x4/0xffffffff iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 443 -j MARK --set-xmark 0x4/0xffffffff iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 80 -j MARK --set-xmark 0x4/0xffffffff 

Ничего не работает

Добавлен маршрут LAN и фальшивый, неправильный шлюз 10.0.3.9, которого не существует:

# ip route default via 10.0.3.9 dev eth0  10.0.3.0/24 dev eth0 scope link   # ip neigh flush dev eth0 # ping 8.8.8.8 PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. ^C --- 8.8.8.8 ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 1006ms # ip neigh 10.0.3.9 dev eth0 FAILED # ip neigh del 10.0.3.9 dev eth0 # dig +short @8.8.8.8 google.com. 172.217.22.142 # ip neigh 10.0.3.1 dev eth0 lladdr fe:d6:50:75:27:c9 REACHABLE 

Обратите внимание, что теперь использовался маршрут из таблицы 4. Но сначала необходим рабочий маршрут («на бумаге», даже если он не работает), иначе одно только решение о маршрутизации вообще не позволило бы использовать правило OUTPUT. Вы можете увидеть это, iptables-save -cчтобы увидеть счетчики.

Абсолютно верно. Переход на OUTPUT решил мою проблему, потому что у меня там был адрес. Я не показал это в своем вопросе, потому что я пытался сделать меньший пример проблемы и не думал, что эта деталь была релевантной. Спасибо! GroovyDotCom 6 лет назад 0