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

Мне кажется, это должно работать. Я перенес все правила маршрутизации из основной таблицы в таблицу 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 ответ1

2

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .