Маркированные пакеты не маршрутизируются, как ожидалось
ОБНОВЛЕНИЕ: Решение: я должен был использовать цепочку ВЫХОДА, а не цепочку ПРОГНОЗИРОВАНИЯ. Этот пример все еще не работает, но я скоро обновлю его.
Мне кажется, это должно работать. Я переместил все правила маршрутизации из основной таблицы в таблицу 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
1 ответ
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
чтобы увидеть счетчики.