Перейти к содержимому
Калькуляторы

Linux. Зеркалирование трафика во VLAN

Имеется машина с одним физическим интерфейсом. Она терминирует несколько вланов.

Возникла задача с внешнего untagged интерфейса снять выборочно трафик (например, по IP-адресу) и влить этот трафик в отдельный влан, который уже на свиче вывалится в untagged порт и улетит в некую железку.

Решаю с помощью tc. С виду все просто:

#!/bin/sh
modprobe ifb numifbs=1
ip link set dev ifb0 up

tc qdisc del dev eth0 root 2>/dev/null
tc qdisc del dev eth0 ingress 2>/dev/null

tc qdisc add dev eth0 root handle 1: htb r2q 625 default 65
tc filter add dev eth0 parent 1: protocol all u32 match ip src 192.168.0.77 action mirred egress mirror dev ifb0

tc qdisc add dev eth0 ingress
tc filter add dev eth0 parent ffff: protocol all u32 match ip dst 192.168.0.77 action mirred egress mirror dev ifb0

В ifb0 трафик нормально прилетает, но как только мы пытаемся вместо ifb0 влить, к примеру, в eth0.13 - машина встает колом безо всяких сообщений об ошибках.

Пробовал лить трафик в bridge. Если бридж пустой - все ок, как только в бридж добавляю eth0.13 - машина подвисает.

Подозреваю, проблема в том, что мы пытаемся залить нетегированный трафик в тегированный интерфейс. Как-то с помощью tc можно добавить vlan tag к пакету? Обгуглился но не нашел..

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Сделайте это через iptables с помощью -j TEE, на исходящий интерфейс придётся повесить фейковый IP и создать статическую фейковую arp-запись на фейковый mac (всё это нужно, если с другой стороны просто слушают не отвечают на arp). Если это нужно для СОРМирование радиуса или телефонии, то в самый раз подойдёт

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Имеется машина с одним физическим интерфейсом. Она терминирует несколько вланов.

Возникла задача с внешнего untagged интерфейса снять выборочно трафик (например, по IP-адресу) и влить этот трафик в отдельный влан, который уже на свиче вывалится в untagged порт и улетит в некую железку.

Решаю с помощью tc. С виду все просто:

#!/bin/sh
modprobe ifb numifbs=1
ip link set dev ifb0 up

tc qdisc del dev eth0 root 2>/dev/null
tc qdisc del dev eth0 ingress 2>/dev/null

tc qdisc add dev eth0 root handle 1: htb r2q 625 default 65
tc filter add dev eth0 parent 1: protocol all u32 match ip src 192.168.0.77 action mirred egress mirror dev ifb0

tc qdisc add dev eth0 ingress
tc filter add dev eth0 parent ffff: protocol all u32 match ip dst 192.168.0.77 action mirred egress mirror dev ifb0

В ifb0 трафик нормально прилетает, но как только мы пытаемся вместо ifb0 влить, к примеру, в eth0.13 - машина встает колом безо всяких сообщений об ошибках.

Пробовал лить трафик в bridge. Если бридж пустой - все ок, как только в бридж добавляю eth0.13 - машина подвисает.

Подозреваю, проблема в том, что мы пытаемся залить нетегированный трафик в тегированный интерфейс. Как-то с помощью tc можно добавить vlan tag к пакету? Обгуглился но не нашел..

 

Есть подозрение, что оно зацикливается, т.е. матченый трафик опять попадает в правило уже при отправке в vlan. Попробуйте поднять какую-нибудь инкапсуляцию и лить в неё.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Есть подозрение, что оно зацикливается, т.е. матченый трафик опять попадает в правило уже при отправке в vlan. Попробуйте поднять какую-нибудь инкапсуляцию и лить в неё.

Хм.. очень похоже что да. Спасибо, попробую.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Попробуйте в tc filter сделать protocol ip вместо all. Либо проверяйте что-бы не было тега (или ethertype 0x800)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Неа, protocol ip тоже не катит, видимо тип протокола меняется уже после обработки tc.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Нет, просто некоторые ядра при protocol ip не берут тегированные пакеты.

Ну тогда предлагаю попробовать так:

#!/bin/sh
modprobe ifb numifbs=1
ip link set dev ifb0 up

tc qdisc del dev eth0 root 2>/dev/null
tc qdisc del dev eth0 ingress 2>/dev/null

tc qdisc add dev eth0 root handle 1: htb r2q 625 default 65
tc filter add dev eth0 parent 1: protocol all handle 800::2 u32 match u32 0x00008100 0x0000ffff at -8 action ok
tc filter add dev eth0 parent 1: protocol all handle 800::5 u32 match ip src 192.168.0.77 action mirred egress mirror dev eth0.x

tc qdisc add dev eth0 ingress
tc filter add dev eth0 parent ffff: protocol all handle 800::2 u32 match u32 0x00008100 0x0000ffff at -8 action ok
tc filter add dev eth0 parent ffff: protocol all handle 800::5 u32 match ip dst 192.168.0.77 action mirred egress mirror dev eth0.x

Или, что равносильно:

 

#!/bin/sh
modprobe ifb numifbs=1
ip link set dev ifb0 up

tc qdisc del dev eth0 root 2>/dev/null
tc qdisc del dev eth0 ingress 2>/dev/null

tc qdisc add dev eth0 root handle 1: htb r2q 625 default 65
tc filter add dev eth0 parent 1: protocol 802.1q pref 5 handle ::5 u32 match u32 0x0 0x0 at 0 action ok
tc filter add dev eth0 parent 1: protocol all pref 10 handle ::5 u32 match ip src 192.168.0.77 action mirred egress mirror dev eth0.x

tc qdisc add dev eth0 ingress
tc filter add dev eth0 parent ffff: protocol 802.1q pref 5 handle ::5 u32 match u32 0x0 0x0 at 0 action ok
tc filter add dev eth0 parent ffff: protocol all pref 10 handle ::5 u32 match ip dst 192.168.0.77 action mirred egress mirror dev eth0.x

 

Это заставит редиректиться только нетегированный трафик, а тот, что уже редиректился и соответственно с тегом будет пропускать мимо.

НО! Учтите что eth0.x ДОЛЖЕН быть создан с reorder_hdr off!

 

Хм.. очень похоже что да. Спасибо, попробую.

Что-бы убедится точно - tcpdump на ifb0 а потом пинг в eth0.13 c src 192.168.0.77.

Изменено пользователем SABRE

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

После экспериментов оказалось все гораздо проще

 

Используйте Ваш скрипт, но, как я и говорил, с protocol ip.

Он начинает работать если reorder_hdr off, вот и весь секрет. Те скрипты, что я написал фактически заменяют проверку protocol ip, делая ее вручную.

так что

ip link set dev eth0.x type vlan reorder_hdr off

И все. eth0.x - девайс, куда перенаправляете пакеты.

 

reorder_hdr заставляет ядро хранить информацию о vlan отдельно от пакета и tc u32 его не видит.

Учтите так-же что vlan-offload должен быть выключен.

Изменено пользователем SABRE

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Пока не получается

test-router scripts # ethtool -k eth0
Features for eth0:
...
rx-vlan-offload: off
tx-vlan-offload: off
...

 

cat /proc/net/vlan/eth0.13
eth0.13  VID: 13         REORDER_HDR: 0  dev->priv_flags: 1
        total frames received            0
         total bytes received            0
     Broadcast/Multicast Rcvd            0

     total frames transmitted            8
      total bytes transmitted          648
Device: eth0
INGRESS priority mappings: 0:0  1:0  2:0  3:0  4:0  5:0  6:0 7:0
EGRESS priority mappings:

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Проверил в том числе и этот вариант

#!/bin/sh
modprobe ifb numifbs=1
ip link set dev ifb0 up

tc qdisc del dev eth0 root 2>/dev/null
tc qdisc del dev eth0 ingress 2>/dev/null

tc qdisc add dev eth0 root handle 1: htb r2q 625 default 65
tc filter add dev eth0 parent 1: protocol 802.1q pref 5 handle ::5 u32 match u32 0x0 0x0 at 0 action ok
tc filter add dev eth0 parent 1: protocol all pref 10 handle ::5 u32 match ip src 192.168.0.77 action mirred egress mirror dev eth0.x

tc qdisc add dev eth0 ingress
tc filter add dev eth0 parent ffff: protocol 802.1q pref 5 handle ::5 u32 match u32 0x0 0x0 at 0 action ok
tc filter add dev eth0 parent ffff: protocol all pref 10 handle ::5 u32 match ip dst 192.168.0.77 action mirred egress mirror dev eth0.x

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

если перенаправлять на ifb и смотреть tcpdump, пакеты с метками есть?

Изменено пользователем SABRE

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Значит путем нехитрых манипуляций выяснилось, что на ingress трафик не работает фильтр по 802.1q

 

Делаю:

tc qdisc add dev eth0 ingress
tc filter add dev eth0 parent ffff: protocol 802.1q pref 5 handle ::5 u32 match u32 0x0 0x0 at 0 action ok
tc filter add dev eth0 parent ffff: protocol all pref 10 handle ::5 u32 match ip src 10.44.1.2 action mirred egress mirror dev ifb0

 

По идее этот фильтр должен отметать dot1q пакеты, и зеркалить все остальные пакеты от машины 10.44.1.2

В tcpdump видим:

tcpdump -e -i ifb0
15:03:53.892584 08:9e:01:2e:8e:14 (oui Unknown) > 00:22:4d:9d:d1:7d (oui Unknown), ethertype 802.1Q (0x8100), length 78: vlan 101, p 0, ethertype IPv4, 10.44.1.2 > www.yandex.ru: ICMP echo request, id 1, seq 578, length 40
15:03:54.906829 08:9e:01:2e:8e:14 (oui Unknown) > 00:22:4d:9d:d1:7d (oui Unknown), ethertype 802.1Q (0x8100), length 78: vlan 101, p 0, ethertype IPv4, 10.44.1.2 > www.yandex.ru: ICMP echo request, id 1, seq 579, length 40

 

Аналогичный фильтр на исходящий в vlan101 трафик работает, пакетов с dst=10.44.1.2 на ifb0 не попадает.

 

Попробуем зеркалить только ip-пакеты от 10.44.1.2:

tc qdisc add dev eth0 ingress
tc filter add dev eth0 parent ffff: protocol 802.1q pref 5 handle ::5 u32 match u32 0x0 0x0 at 0 action ok
tc filter add dev eth0 parent ffff: protocol ip pref 10 handle ::5 u32 match ip src 10.44.1.2 action mirred egress mirror dev ifb0

 

tcpdump:

15:07:01.930482 08:9e:01:2e:8e:14 (oui Unknown) > 00:22:4d:9d:d1:7d (oui Unknown), ethertype 802.1Q (0x8100), length 78: vlan 101, p 0, ethertype IPv4, 10.44.1.2 > www.yandex.ru: ICMP echo request, id 1, seq 764, length 40
15:07:02.930611 08:9e:01:2e:8e:14 (oui Unknown) > 00:22:4d:9d:d1:7d (oui Unknown), ethertype 802.1Q (0x8100), length 78: vlan 101, p 0, ethertype IPv4, 10.44.1.2 > www.yandex.ru: ICMP echo request, id 1, seq 765, length 40

та же петрушка.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если же мы плюнем на входящий трафик вообще, и попробуем копировать в vlan только исходящий с машины трафик:

tc qdisc add dev eth0 root handle 1: htb r2q 625 default 65
tc filter add dev eth0 parent 1: protocol 802.1q pref 5 handle ::5 u32 match u32 0x0 0x0 at 0 action ok
tc filter add dev eth0 parent 1: protocol all pref 10 handle ::5 u32 match ip src 192.168.0.77 action mirred egress mirror dev eth0.13

то получаем тыкву.

Изменять mac-и скопированных пакетов пока не пробовал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Что ж, тогда последний вариант.

Действительно на 3.11.0 ни ethtool ни reorder_hdr не влияют на наличие тега в самом пакете.

Раз тег все-равно убирается из пакета, u32 тут уже не в помощь:

tc qdisc add dev eth0 root handle 1: htb r2q 625 default 65
tc filter add dev eth0 parent 1: protocol all pref 3 handle 0x5 basic match 'meta (vlan eq 13 )' action ok
tc filter add dev eth0 parent 1: protocol all pref 10 handle ::5 u32 match ip src 192.168.0.77 action mirred egress mirror dev eth0.13

Изменено пользователем SABRE

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

а можно попробовать посмотреть в сторону bpf-матчей в netfilter/tc.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А чем вас всех не устраивает вариант с iptables ... -j TEE ...? это 100% рабочий вариант и без геморроя

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Гость
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Вставить в виде обычного текста

  Разрешено не более 75 смайлов.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.