Назад | Перейти на главную страницу

iptables - отмечать и маршрутизировать определенные пакеты

Имеет отношение к этой ссылке http://lartc.org/howto/lartc.netfilter.html

Я хочу отмечать пакеты, отправленные на определенный порт (80 для простоты), и направлять их на tun0 (который создается openvpn).

Пометьте пакеты, которые wlan0 отправляет на порт 80, цифрой 1

$ iptables -A PREROUTING -i wlan0 -t mangle -p tcp --dport 80 -j MARK --set-mark 1

Добавить mytable

$ echo 201 mytable >> /etc/iproute2/rt_tables

Добавьте правило, что все пакеты, отмеченные 1, маршрутизируются mytable

$ ip rule add fwmark 1 table mytable

Добавьте правила, которые говорят, что любые пакеты, отправляемые во весь Интернет, маршрутизируются tun0

$ ip route add 128.0.0.0/1 via 10.8.0.13 dev tun0 table mytable
$ ip route add 0.0.0.0/1 via 10.8.0.13 dev tun0 table mytable

Annndd ничего не делает

Стоит упомянуть пару вещей

1) Когда я запускаю openvpn, он добавляет кучу маршрутов в таблицу main, что приводит к тому, что каждый пакет маршрутизируется через tun0. Ifconfig показывает tun0 с inet 10.8.0.14, но все маршруты, добавленные OpenVPN, предназначены для 10.8.0.13. OpenVPN также добавляет маршрут

10.8.0.13 dev tun0  proto kernel  scope link  src 10.8.0.14

Если я запускаю OpenVPN с --route-nopull и сам создаю маршруты, но для 10.8.0.14 он дает точно такой же эффект, я понятия не имею, а OpenVPN делает это с 10.8.0.13.

2) Любые маршруты, которые я добавляю в основную таблицу, работают нормально. Проблема должна заключаться в том, что iptables не маркирует пакеты или правила ip не отправляют рыночные пакеты в нужную таблицу. Очень странно.

Вывод моих текущих настроек:

$ ip route list table mytable
0.0.0.0/1 via 10.8.0.13 dev tun0 
10.8.0.13 dev tun0  proto kernel  scope link  src 10.8.0.14 
128.0.0.0/1 via 10.8.0.13 dev tun0 

$ ip rule ls
0:  from all lookup local 
32765:  from all fwmark 0x1 lookup mytable 
32766:  from all lookup main 
32767:  from all lookup default 

$ sudo iptables -t mangle -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
MARK       tcp  --  anywhere             anywhere             tcp dpt:http MARK set 0x1

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         

Очевидно, пакеты не маркируются.

Раньше я использовал iptables для фильтрации пакетов wlan0 на порт 80. Я изменил это на любой интерфейс для портов 80, все, 443,22

$ sudo iptables -L -v -t mangle
Chain PREROUTING (policy ACCEPT 10341 packets, 15M bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MARK       tcp  --  any    any     anywhere             anywhere             tcp dpt:http MARK set 0x1
27110   39M MARK       tcp  --  any    any     anywhere             anywhere             MARK set 0x1
    0     0 MARK       tcp  --  any    any     anywhere             anywhere             tcp dpt:https MARK set 0x1
    0     0 MARK       tcp  --  any    any     anywhere             anywhere             tcp dpt:ssh MARK set 0x1

Обратите внимание, что iptables перехватил 39M пакетов, но ни один из них не соответствовал правилу для портов 80, 443 или 22, хотя я обращался к службам на всех этих портах. Очень странно.

Iptables начал маркировать пакеты, когда я переключил --dport на --sport, но все равно ничего не произошло. Я знаю, что правила IP применяются по порядку, поэтому, если маршруты в mytable не работают, пакеты будут маршрутизироваться с помощью table main. Я думал, что может быть проблема с поиском DNS, но я установил серверы имен resolv.conf на Google DNS, и ничего не изменилось.

Есть ли способ увидеть мой внешний IP-адрес с помощью командной строки и без поиска DNS? Я использовал

$ curl 141.101.127.36 | grep "Your IP address"

И получение данных со страницы ошибки cloudflare dns, но, вероятно, есть более официальный способ.