Jump to content
Калькуляторы

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 к пакету? Обгуглился но не нашел..

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Возникла задача с внешнего 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. Попробуйте поднять какую-нибудь инкапсуляцию и лить в неё.

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Нет, просто некоторые ядра при 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.

Edited by SABRE

Share this post


Link to post
Share on other sites

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

 

Используйте Ваш скрипт, но, как я и говорил, с 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 должен быть выключен.

Edited by SABRE

Share this post


Link to post
Share on other sites

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

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:

Share this post


Link to post
Share on other sites

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

#!/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

Share this post


Link to post
Share on other sites

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

Edited by SABRE

Share this post


Link to post
Share on other sites

Значит путем нехитрых манипуляций выяснилось, что на 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

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

Share this post


Link to post
Share on other sites

Если же мы плюнем на входящий трафик вообще, и попробуем копировать в 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-и скопированных пакетов пока не пробовал.

Share this post


Link to post
Share on other sites

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

Действительно на 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

Edited by SABRE

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this