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
чтобы увидеть счетчики.