image alt

Сегодня мы поговорим о зеркалировании трафика на маршрутизаторах Juniper серии MX. После свичей производства Cisco, Huawei или Arista конфигурация SPAN и RSPAN на JunOS будет казаться очень сложной, но за сложной (на первый взгляд) конфигурацией скрываются огромные возможности платформы MX в области зеркалирования трафика. Подход Juniper хоть и на первый взгляд сложен, но становится прост и понятен, если не тупо копипастить конфиги с одной коробки на другую, а понимать, что и зачем делается. Идеология JunOS предполагает использовать filter based forwarding (FBF) в целях зеркалирования, что дает нам определенную гибкость в реализации сложных схем зеркалирования трафика.

Итак, начнем. Мы рассмотрим несколько примеров зеркалирования:

1. Локальное зеркалирование с порта на порт
2. Зеркалирование на два и более потребителя
3. Зеркалирование на удаленный хост
4. Избирательное зеркалирование на два и более потребителя
5. Локальное зеркалирование L2 трафика
6. Зеркалирование L2 трафика на удаленный сервер
7. Использование более двух mirroring инстансов на одном FPC

Итак, начнем по порядку.

Локальное зеркалирование с порта на порт.

Наш тестовый стенд будет постоянно меняться — будем добавлять потребителей, изменять их желания по получаемой копии трафика и т.д. На первом этапе тестовый стенд выглядит так:

Примечание: сначала я хотел использовать генератор трафика, но потом решил, что и сгенерированные hping3 tcp/udp/icmp пакеты, отловленные на анализаторе трафика (как анализатор использовался просто хост с ubuntu server 14.04 на борту) будут более наглядны, чем просто счетчики с портов в pps (можно к примеру сравнить актуальность отправленных и принятых данных). Счетчики же надо использовать при проведении нагрузочного тестирования для проверки производительности маршрутизатора при использовании данного функционала. Но на виртуальном MX проверять производительность нет смысла — все равно все упрется в возможности сервера вируализации.

Предположим, что между серверами Server-1 (11.0.0.1) и Server-2 (12.0.0.1) есть какой то обмен трафиком. Владельцы сервера Analyzer-1 хотят видеть, что именно передается между этими двумя серверами, поэтому нам надо настроить отправку копии всего трафика между Server-1 и Server-2 на Analyzer-1 — то есть сделать локальное зеркалирование. Итак, приступим.

В теории это должно работать так: мы создаем мирроринг инстанс, в котором указываем параметры входящего трафика (с какой периодичностью зеркалировать трафик) и исходящие параметры в какой или какие порты отравить трафик. Для того, чтобы направить трафик в созданный нами инстанс надо на интерфейс или интерфейсы, с которого(-ых) мы хотим снять копию трафика повесить специальный фильтр, который и завернет наш трафик в нужный инстанс. То есть это классическая схема policy base routing-а, ну или filter base routing-а в терминах Juniper. С теорией разобрались, теперь перейдем к практике — нам надо собрать такую схему зеркалирования:

Сначала нам надо создать инстанс в иерархии [edit forwarding-options port-mirroring], который мы будем использовать для зеркалирования трафика.

[edit forwarding-options port-mirroring]
bormoglotx@RZN-PE-1# show
instance {
    SPAN-1 {
        input {
            rate 1;
            run-length 0;
        }
        family inet {
            output {
                interface ge-0/0/1.0 {
                    next-hop 169.254.0.1;
                }
            }
        }
    }

Конфигурация инстанса состоит из двух частей. Сначала разберемся с секцией input — как не трудно догадаться, это параметры входящего трафика, который должен быть отзеркалирован. Тут важными являются параметры rate и run-length. Первый параметр отвечает за то, с какой частотой будут зеркалироваться пакеты (срабатывать триггер), второй параметр отвечает за то, сколько пакетов еще будет отзеркалировано после срабатывания триггера rate.

В нашем случае rate выставлен в 1, то есть каждый пакет будет отзеркалирован. Run-length выставлен в 0-ль, так как при rate, равным 1 его наличие не играет никакой роли.

Для полноты понимания разберем значение данных параметров на более наглядном примере. Параметр rate задает частоту зеркалирования трафика, предположим rate равен 5, то есть триггер будет срабатывать на каждом 5-м пакете, а значит каждый 5-й пакет будет отзеркалирован. Теперь предположим, что run-length установлен в 4. Это говорит нам о том, что еще 4-ре пакета будут отзеркалированы, после каждого 5-го пакета. То есть сначала сработал триггер на 5-м пакете — этот пакет будет отзеркалирован, теперь еще 4-ре пакета, следующие за уже отзеркалированным, будут тоже отзеркалированы. В итоге получим, что мы зеркалируем каждый 5-й пакет плюс еще 4 следующих за ним пакета — итого 100% трафика. Изменяя эти параметры можно отзеркалировать например каждые 10 пакетов из 100 и т д (ну это больше нужно для сэмплинга, нежели зеркалирования, просто принцип работы тот же).

Если вернуться к нашему случаю, то мы и так зеркалируем каждый пакет, поэтому параметр run-length нам просто не нужен и оставлен по умолчанию равный нулю.

Для расчета процента отзеркалированного трафика можно пользоваться формулой %=((run-length+1)/rate)*100). Логично что при параметрах run-length 1 и rate 1, мы получаем зеркалирование 200% трафика или например при rate 1 и run-length 4 — 500% трафика. Огорчу вас или обрадую — больше чем 100% трафика не отзеркалируется — размножать пакеты Juniper не станет, что более чем логично. Да и придумать сценарий, когда вам необходимо сделать две копии одного и того же трафика я так и не смог (если кто знает — пишите в комментарии).

И еще один важный параметр — maximum-packet-length. Это максимальный размер пакета, который будет отзеркалирован. Если вы выставите его например в 128, то при получении пакета, больше чем 128 байт (ну к примеру 1514), от него будет отрезаны первые 128 байт и отправлены потребителю. Остальная часть пакета будет просто отброшена. Это удобно, когда вам на сервер надо отправить только заголовки и пейлоад вам не нужен. Не рекомендуется ставить менее чем 20 для ipv4.

Теперь перейдем к output параметрам. Тут в общем случае нам необходимо указать интерфейс, в который мы ходим отзеркалировать трафик. В случае, когда у нас просто p2p интерфейс, то больше ничего указывать не надо — все и так полетит. Но как мы все помним, ethernet — это далеко не p2p (если быть точным то это csma/cd), и помимо интерфейса нам надо указать адрес хоста, которому предназначен трафик, как IP, так и MAC (но до этого мы дойдем чуть позже). Я выбрал адрес из диапазона линк-локал адресов, чтобы избежать каких либо пересечений с уже имеющимися адресами — вы же можете брать любую адресацию, это абсолютно не изменит ничего в принципе работы технологии. В ethernet чтобы отправить пакет какому то хосту, маршрутизатору необходимо выяснить MAC адрес это хоста с помощью ARP. В моем же случае на стороне сервера-получателя ничего не сконфигурено — просто пустой интерфейс и получится, что маршрутизатор будет тщетно пытаться разрезолвить адрес удаленного хоста. Естественно все зеркалирование на этом закончится. Как быть в данной ситуации? Все гениальное просто — делается статическая ARP запись:

bormoglotx@RZN-PE-1# show interfaces ge-0/0/1        
description Analyzer-1;
unit 0 {
    family inet {
        address 169.254.0.0/31 {
            arp 169.254.0.1 mac 02:00:00:00:00:01;
        }
    }
}

В итоге будем иметь вот такую запись на интерфейсе:

[edit]
bormoglotx@RZN-PE-1# run show arp interface ge-0/0/1.0  
MAC Address       Address         Name                      Interface               Flags
02:00:00:00:00:01 169.254.0.1     169.254.0.1               ge-0/0/1.0              permanent

Тут хотелось бы остановиться поподробнее. Теоретически вы можете отправить трафик на какой то реальный адрес, сконфигурированный на сервере, но самым простым и наиболее гибким подходом является создание фиктивного IP адреса и ARP записи в сторону потребителя трафика — то есть попросту мы заставляем Juniper думать, что за указанным интерфейсом находится указанный нами IP/MAC адрес, что в итоге заставляет коробку тупо слать туда трафик, не разбираясь, а есть ли там реально указанный хост или нет — главное чтобы порт был в up. Использование статической ARP записи в зеркалировании имеет большое преимущество — статическая ARP запись не устаревает, а так же маршрутизатор не станет отправлять на сервер ARP запросы (которые могут попасть в дамп снимаемого трафика, что не очень хорошо).

Теперь, что бы трафик стал зеркалироваться, нам надо его как то завернуть в созданный нами инстанс. Для этого используется filter base forwarding. Мы создаем фильтр и применяем его на интересующий нас интерфейс:

[edit]
bormoglotx@RZN-PE-1# show firewall family inet filter MIRROR>>>SPAN-1
term MIRROR {
    then port-mirror-instance SPAN-1;
}

[edit]
bormoglotx@RZN-PE-1# show interfaces ge-0/0/3      
description Server-1;
unit 0 {
    family inet {
        filter {
            input MIRROR>>>SPAN-1;
            output MIRROR>>>SPAN-1;
        }
        address 11.0.0.254/24;
    }
}

Так как нам надо собрать и входящий и исходящий трафик, то мы навешиваем фильтр на на оба направления.

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

Теперь можно проверить состояние сессии зеркалирования:

bormoglotx@RZN-PE-1> show forwarding-options port-mirroring
Instance Name: SPAN-1                         
  Instance Id: 2              
  Input parameters:
    Rate                  : 1
    Run-length            : 0
    Maximum-packet-length : 0
  Output parameters:
    Family              State     Destination          Next-hop
    inet                up        ge-0/0/1.0           169.254.0.1         

Судя по всему мирроринг в работе. Давай теперь запустим 5 пакетов с Server-1 на Server-2 и посмотрим, что мы сможем отловить на анализаторе Analyzer-1:

bormoglotx@Server-1:~$ sudo hping3 -S -c 5 12.0.0.1 -d 40 -I eth1
HPING 12.0.0.1 (eth1 12.0.0.1): S set, 40 headers + 40 data bytes
len=40 ip=12.0.0.1 ttl=63 DF id=34108 sport=0 flags=RA seq=0 win=0 rtt=3.4 ms
len=40 ip=12.0.0.1 ttl=63 DF id=34121 sport=0 flags=RA seq=1 win=0 rtt=3.5 ms
len=40 ip=12.0.0.1 ttl=63 DF id=34229 sport=0 flags=RA seq=2 win=0 rtt=3.5 ms
len=40 ip=12.0.0.1 ttl=63 DF id=34471 sport=0 flags=RA seq=3 win=0 rtt=3.5 ms
len=40 ip=12.0.0.1 ttl=63 DF id=34635 sport=0 flags=RA seq=4 win=0 rtt=3.5 ms

--- 12.0.0.1 hping statistic ---
5 packets transmitted, 5 packets received, 0% packet loss

Теперь посмотрим что удалось задампить на сервере Analyzer-1:

bormoglotx@Analyzer-1:~$ sudo tcpdump -i eth1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel

Все не так радужно, из вывода видно, что у нас собственно ничего и не работает, хотя Juniper нам рапортовал в выводе выше, что все ок. Дело в том, что инстанс для зеркалирования можно создать самим (что мы и сделали) или же использовать дефолтный инстанс (он один на всю коробку). Если мы создаем инстанс сами, то мы должны ассоциировать данный инстанс с FPC, на которой мы делаем мирроринг (если порты на нескольких FPC — то значит ассоциировать с несколькими). Давайте вернем на Juniper и указем в конфигурации FPC созданный нами инстанс. Почему я на этом сделал акцент? Дело в том, что пару раз и сам на это натыкался и не мог понять в чем подвох — ведь выводы говорят, что все отлично.

[edit]
bormoglotx@RZN-PE-1# show | compare
[edit]
+  chassis {
+      fpc 0 {
+          port-mirror-instance SPAN-1;
+      }
+  }

Теперь снова проверим, работает ли зеркало:

bormoglotx@Server-1:~$ sudo hping3 -S -c 5 12.0.0.1 -d 40 -I eth1
HPING 12.0.0.1 (eth1 12.0.0.1): S set, 40 headers + 40 data bytes
len=40 ip=12.0.0.1 ttl=63 DF id=43901 sport=0 flags=RA seq=0 win=0 rtt=4.4 ms
len=40 ip=12.0.0.1 ttl=63 DF id=44117 sport=0 flags=RA seq=1 win=0 rtt=3.4 ms
len=40 ip=12.0.0.1 ttl=63 DF id=44217 sport=0 flags=RA seq=2 win=0 rtt=3.4 ms
len=40 ip=12.0.0.1 ttl=63 DF id=44412 sport=0 flags=RA seq=3 win=0 rtt=3.7 ms
len=40 ip=12.0.0.1 ttl=63 DF id=44416 sport=0 flags=RA seq=4 win=0 rtt=3.5 ms

--- 12.0.0.1 hping statistic ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 3.4/3.7/4.4 ms


bormoglotx@Analyzer-1:~$ sudo tcpdump -i eth1 -B 4096
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
14:48:43.641475 IP 11.0.0.1.2237 > 12.0.0.1.0: Flags [S], seq 1075183755:1075183795, win 512, length 40
14:48:43.642024 IP 12.0.0.1.0 > 11.0.0.1.2237: Flags [R.], seq 0, ack 1075183796, win 0, length 0
14:48:44.641981 IP 11.0.0.1.2238 > 12.0.0.1.0: Flags [S], seq 1410214066:1410214106, win 512, length 40
14:48:44.642818 IP 12.0.0.1.0 > 11.0.0.1.2238: Flags [R.], seq 0, ack 1410214107, win 0, length 0
14:48:45.642022 IP 11.0.0.1.2239 > 12.0.0.1.0: Flags [S], seq 1858880488:1858880528, win 512, length 40
14:48:45.642873 IP 12.0.0.1.0 > 11.0.0.1.2239: Flags [R.], seq 0, ack 1858880529, win 0, length 0
14:48:46.642127 IP 11.0.0.1.2240 > 12.0.0.1.0: Flags [S], seq 1472273281:1472273321, win 512, length 40
14:48:46.642947 IP 12.0.0.1.0 > 11.0.0.1.2240: Flags [R.], seq 0, ack 1472273322, win 0, length 0
14:48:47.642017 IP 11.0.0.1.2241 > 12.0.0.1.0: Flags [S], seq 1810623498:1810623538, win 512, length 40
14:48:47.642601 IP 12.0.0.1.0 > 11.0.0.1.2241: Flags [R.], seq 0, ack 1810623539, win 0, length 0
^C
10 packets captured
10 packets received by filter
0 packets dropped by kernel

В итоге весь обмен трафиком между Server-1 и Server-2 попал на анализатор, чего мы и добивались.

Двигаемся далее, наша схема изменилась и теперь у нас появился Analyzer-2, который также хочет получать весь трафик между Server-1 и Server-2:


Зеркалирование на два и более потребителя

В итоге имеем очередную задачу — надо реализовать новую схему зеркалирования, которая выглядит так:

Вроде бы ничего сложного — создадим интерфейс в сторону Analyzer-2, добавим его в инстанс и дело в шляпе.

[edit]
bormoglotx@RZN-PE-1# show interfaces ge-0/0/2                                  
description Analyzer-2;
unit 0 {
    family inet {
        address 169.254.0.2/31 {
            arp 169.254.0.3 mac 02:00:00:00:00:01;
        }
    }
}

[edit]
bormoglotx@RZN-PE-1# show forwarding-options port-mirroring instance SPAN-1    
input {
    rate 1;
    run-length 0;
}
family inet {
    output {
        interface ge-0/0/1.0 {
            next-hop 169.254.0.1;
        }
        interface ge-0/0/2.0 {
            next-hop 169.254.0.3;
        }
    }
}

Но при попытке добавить еще один порт в иерархию output в мирроринг инстанс мы получаем ошибку при коммите:

[edit]
bormoglotx@RZN-PE-1# commit check
[edit forwarding-options port-mirroring instance SPAN-1 family inet output]
  Port-mirroring configuration error
    Port-mirroring out of multiple nexthops is not allowed on this platform

error: configuration check-out failed

Страшная на первый взгляд фраза — ограничения платформы не дают нам установить сразу два next-hop-а для отзеркалированного трафика. Но это ограничение очень просто обходится, если мы воспользуемся next-hop группами.

Думаю что и так понятно, что такое next-hop группа — название говорит само за себя. Juniper MX поддерживает до 30-ти next-hop групп, в каждой из которой может быть до 16 next-hop-в. Но помимо этого, в каждый next-hop группе можно создать next-hop подгруппы. В одной next-hop группе должно быть как минимум два next-hop-а, иначе JunOS не даст сделать коммит.

Теперь перейдем к конфигурации, создадим next-hop группу:

[edit]
bormoglotx@RZN-PE-1# show forwarding-options next-hop-group Analyzer-servers                   
group-type inet;
interface ge-0/0/1.0 {
    next-hop 169.254.0.1;
}
interface ge-0/0/2.0 {
    next-hop 169.254.0.3;
}

И теперь укажем данную группу, как next-hop в ouput:

[edit]
bormoglotx@RZN-PE-1# show forwarding-options port-mirroring instance SPAN-1
input {
    rate 1;
    run-length 0;
}
family inet {
    output {
        next-hop-group Analyzer-servers;
    }
}

Весь остальной конфиг не меняется.
Перейдем к проверке. Сначала проверим, в каком состоянии next-hop группа:

bormoglotx@RZN-PE-1> show forwarding-options next-hop-group detail
Next-hop-group: Analyzer-servers               
  Type: inet           
  State: up             
  Number of members configured    : 2
  Number of members that are up   : 2
  Number of subgroups configured  : 0
  Number of subgroups that are up : 0
  Members Interfaces:                                 State
    ge-0/0/1.0             next-hop  169.254.0.1      up     
    ge-0/0/2.0             next-hop  169.254.0.3      up     

С группой все в порядке — она в работе (группа будет в up, если в ней есть хотя бы один интерфейс в up). Теперь проверим состояние сессии зеркалирования:

bormoglotx@RZN-PE-1> show forwarding-options port-mirroring SPAN-1                        
Instance Name: SPAN-1                         
  Instance Id: 2              
  Input parameters:
    Rate                  : 1
    Run-length            : 0
    Maximum-packet-length : 0
  Output parameters:
    Family              State     Destination          Next-hop
    inet                up        Analyzer-servers                    

Тоже все в порядке, но как мы уже видели раннее — это не значит, что мы сделали все правильно и у нас все взлетит. Поэтому проверим будет ли зеркалироваться трафик на два наших сервера:

bormoglotx@Server-1:~$ sudo hping3 -S -c 5 12.0.0.1 -d 40 -I eth1
HPING 12.0.0.1 (eth1 12.0.0.1): S set, 40 headers + 40 data bytes
len=40 ip=12.0.0.1 ttl=63 DF id=64150 sport=0 flags=RA seq=0 win=0 rtt=3.4 ms
len=40 ip=12.0.0.1 ttl=63 DF id=64222 sport=0 flags=RA seq=1 win=0 rtt=3.5 ms
len=40 ip=12.0.0.1 ttl=63 DF id=64457 sport=0 flags=RA seq=2 win=0 rtt=3.7 ms
len=40 ip=12.0.0.1 ttl=63 DF id=64593 sport=0 flags=RA seq=3 win=0 rtt=3.5 ms
len=40 ip=12.0.0.1 ttl=63 DF id=64801 sport=0 flags=RA seq=4 win=0 rtt=3.4 ms

--- 12.0.0.1 hping statistic ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 3.4/3.5/3.7 ms

Трафик на Analyzer-1:

bormoglotx@Analyzer-1:~$ sudo tcpdump -i eth1 -B 4096
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
15:09:36.837983 IP 11.0.0.1.2304 > 12.0.0.1.0: Flags [S], seq 1255230673:1255230713, win 512, length 40
15:09:36.839367 IP 12.0.0.1.0 > 11.0.0.1.2304: Flags [R.], seq 0, ack 1255230714, win 0, length 0
15:09:37.838115 IP 11.0.0.1.2305 > 12.0.0.1.0: Flags [S], seq 2135769685:2135769725, win 512, length 40
15:09:37.839054 IP 12.0.0.1.0 > 11.0.0.1.2305: Flags [R.], seq 0, ack 2135769726, win 0, length 0
15:09:38.838528 IP 11.0.0.1.2306 > 12.0.0.1.0: Flags [S], seq 1139555126:1139555166, win 512, length 40
15:09:38.839369 IP 12.0.0.1.0 > 11.0.0.1.2306: Flags [R.], seq 0, ack 1139555167, win 0, length 0
15:09:39.838328 IP 11.0.0.1.2307 > 12.0.0.1.0: Flags [S], seq 1181209811:1181209851, win 512, length 40
15:09:39.838924 IP 12.0.0.1.0 > 11.0.0.1.2307: Flags [R.], seq 0, ack 1181209852, win 0, length 0
15:09:40.838335 IP 11.0.0.1.2308 > 12.0.0.1.0: Flags [S], seq 1554756347:1554756387, win 512, length 40
15:09:40.838901 IP 12.0.0.1.0 > 11.0.0.1.2308: Flags [R.], seq 0, ack 1554756388, win 0, length 0
^C
10 packets captured
10 packets received by filter
0 packets dropped by kernel

И аналогичная копия трафика на Analyzer-2:

bormoglotx@Analyzer-2:~$ sudo tcpdump -i eth1 -B 4096
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
15:09:35.125093 IP 11.0.0.1.2304 > 12.0.0.1.0: Flags [S], seq 1255230673:1255230713, win 512, length 40
15:09:35.126394 IP 12.0.0.1.0 > 11.0.0.1.2304: Flags [R.], seq 0, ack 1255230714, win 0, length 0
15:09:36.125044 IP 11.0.0.1.2305 > 12.0.0.1.0: Flags [S], seq 2135769685:2135769725, win 512, length 40
15:09:36.126107 IP 12.0.0.1.0 > 11.0.0.1.2305: Flags [R.], seq 0, ack 2135769726, win 0, length 0
15:09:37.125552 IP 11.0.0.1.2306 > 12.0.0.1.0: Flags [S], seq 1139555126:1139555166, win 512, length 40
15:09:37.126418 IP 12.0.0.1.0 > 11.0.0.1.2306: Flags [R.], seq 0, ack 1139555167, win 0, length 0
15:09:38.125374 IP 11.0.0.1.2307 > 12.0.0.1.0: Flags [S], seq 1181209811:1181209851, win 512, length 40
15:09:38.125930 IP 12.0.0.1.0 > 11.0.0.1.2307: Flags [R.], seq 0, ack 1181209852, win 0, length 0
15:09:39.125320 IP 11.0.0.1.2308 > 12.0.0.1.0: Flags [S], seq 1554756347:1554756387, win 512, length 40
15:09:39.125844 IP 12.0.0.1.0 > 11.0.0.1.2308: Flags [R.], seq 0, ack 1554756388, win 0, length 0
^C
10 packets captured
10 packets received by filter
0 packets dropped by kernel

Отлично — поставленная задача выполнена, трафик льется туда, куда надо — оба потребителя получают запрошенную копию трафика.

Но сеть развивается бешеными темпами, и наша компания под зекалирование и СОРМ денег не жалеет. Теперь у нас появился еще один сервер — Analyzer-3, который тоже хочет получать копию трафика. Но сложность в том, что данный сервер подключен не локально к нашему RZN-PE-1, а в RZN-PE-2:

Зеркалирование на удаленный хост

В свете всего сказанного нам снова надо переделать схему зеркалирования, теперь она будет выглядеть вот так:

Так как сервер Analyzer-3 находится за RZN-PE-2, то теми методами, которыми мы пользовались раннее решить эту задачу не выйдет. Наша основная проблема не в том, как отзеркалировать трафик, а в том, как этот уже отзеркалированный трафик дотащить до сервера Analyzer-3, который живет за RZN-PE-2, причем сделать это прозрачно для сети, иначе мы получим проблемы (какие, увидите позже). Для этого на оборудовании Juniper принято использовать gre туннель. Идея в том, что мы делаем тоннель до удаленного хоста и весь зеркалированный трафик упаковываем в этот туннель и отправляем или прямиком на сервер или на маршрутизатор, который терминирует сервер-получатель трафика. У вас есть два варианта использования gre туннеля.

Вариант 1. На маршрутизаторе, который производит зеркалирование настраивается gre тоннель, причем как destination указывается сам адрес сервера-получателя трафика. Естественно сеть, в которой находится этот сервер (в нашем случае это Analyzer-3) должна быть известна через какой либо протокол маршрутизации (BGP или IGP — не важно) иначе gre туннель просто не взлетит. Проблема в то, что в таком сценарии трафик на сервер льется вместе с gre заголовками. Для современных систем анализа и мониторинга трафика это не должно быть проблемой — gre не IPSec и трафик не шифруется. То есть на одной чаше весов простота реализации, на второй — лишний заголовок. Возможно в каком то сценарии наличие лишнего заголовка будет не приемлемо, тогда вам придется использовать вариант 2.

Вариант 2. Между маршрутизатором, который производит зеркалирование и маршрутизатором, который терминирует сервер-получатель трафика, поднимается gre тоннель (обычно это делается на лупбеках). На стороне маршрутизатора, который производит зеркалирование от источника все так же как и было в варианте 1, а вот на стороне получателя на маршрутизаторе необходимо настроить инстанс, который будет зеркалировать полученный из gre туннеля трафик в сторону анализатора. То есть на одно зеркало у нас получается необходимо использовать один инстанс зеркалирования на источнике и второй на получателе трафика, что сильно усложняет схему. Но с другой стороны в этом сценарии на сервер льется чистый трафик, без лишних gre заголовков. Помимо этого при реализации данной схемы есть правило, которое надо строго соблюдать — маршрутизатор, который терминирует конечную точку gre тоннеля не должен иметь маршрута к хосту, который будет указан как получатель в зеркалируемом трафике (то есть получателем исходного отзеркалированного пакета). Если это условие не выполняется, то вы получите дубли пакетов — трафик будет вылетать из gre туннеля и помимо того, что будет зеркалироваться на указанный вами порт, еще будет маршрутизировать, как обычный ip пакет. И если маршрутизатор знает маршрут до хоста назначения, то трафик будет отправлен ему. Чтобы этого избежать, gre интерфейс необходимо погрузить в отдельный инстанс с типом virtual-router, хотя есть и другие способы, описанные далее. Если кому то интересно, то конфигурация, суть проблемы и как ее победить под спойлером:

Mirroring via gre problem
Конфигурация gre туннеля на стороне сервера источника:

bormoglotx@RZN-PE-1# show interfaces gr-0/0/0
description RSPAN;
unit 0 {
    tunnel {
        source 62.0.0.1;
        destination 62.0.0.2;
    }
    family inet {
        address 169.254.100.1/31;
    }
}

Изменился только адрес назначения тоннеля — стал лупбеком RZN-PE-2.
На RZN-PE-2 необходимо сначала создать gre туннель до RZN-PE-1:

bormoglotx@RZN-PE-2> show configuration interfaces gr-0/0/0
description SPAN;
unit 0 {
    tunnel {
        source 62.0.0.2;
        destination 62.0.0.1;
    }
    family inet {
        filter {
            input MIRROR-RSPAN-GE0/0/1;
        }
    }
}

Чтобы теперь с данного интерфейса трафик отправить в мирроринг инстанс, нам надо навесить на него фильтр, который имеет следующий вид:

bormoglotx@RZN-PE-2> show configuration firewall family inet filter MIRROR-RSPAN-GE0/0/1
term MIRROR {
    then port-mirror-instance RSAPN;
}

Ну и последний штрих — создание самого инстанса, привязка его к fpc и создание интерфейса, в который будет отправляться трафик:

bormoglotx@RZN-PE-2> show configuration forwarding-options port-mirroring instance RSAPN
input {
    rate 1;
}
family inet {
    output {
        interface ge-0/0/1.0 {
            next-hop 169.254.100.1;
        }
    }
}

bormoglotx@RZN-PE-2> show configuration chassis
fpc 0 {
    pic 0 {
        tunnel-services {
            bandwidth 10g;
        }
    }
    port-mirror-instance RSAPN;
}

bormoglotx@RZN-PE-2> show configuration interfaces ge-0/0/1  
description Analyzer-3;
unit 0 {
    family inet {
        address 169.254.100.0/31 {
            arp 169.254.100.1 mac 02:00:00:19:21:68;
        }
    }
}

Теперь запустим пинг между Server-1 и Server-2 и проверим, что мы отзеркалировали:

bormoglotx@Server-1:~$ ping 12.0.0.1 -I eth1
PING 12.0.0.1 (12.0.0.1) from 11.0.0.1 eth1: 56(84) bytes of data.
64 bytes from 12.0.0.1: icmp_seq=1 ttl=63 time=1.44 ms
64 bytes from 12.0.0.1: icmp_seq=1 ttl=60 time=3.24 ms (DUP!)
…
...
64 bytes from 12.0.0.1: icmp_seq=1 ttl=3 time=34.7 ms (DUP!)
^C
--- 12.0.0.1 ping statistics ---
1 packets transmitted, 1 received, +41 duplicates, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.444/17.916/34.712/9.126 ms

Часть дубликатов я удалил из вывода, но количество их можно увидеть — один валидный пакет и 41 дубль. На анализаторе трафика вы естественно увидите такую же картину:

bormoglotx@Analyzer-3:~$ sudo tcpdump -i eth1 -B 9192
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
11:52:13.275451 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1601, seq 1, length 64
11:52:13.275462 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1601, seq 1, length 64
11:52:13.276703 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1601, seq 1, length 64
…
…

Кроме зеркалирования, маршрутизатор производит еще и форвардинг пакета, полученного из gre туннеля, так как знает маршрут до адреса назначения. Чтобы это пофиксить, создаем инстанс с типом virtual router и добавим в него gre интерфейс и интерфейс, на который мы зеркалируем трафик:

[edit]
bormoglotx@RZN-PE-2# show routing-instances RSPAN-VR
description "for RSPAN use only";
instance-type virtual-router;
interface gr-0/0/0.0;
interface ge-0/0/1.0;

Снова запустим пинг и проверим работоспособность схемы. Теперь на сервере дубликатов не видно:

bormoglotx@Server-1:~$ ping 12.0.0.1 -I eth1
PING 12.0.0.1 (12.0.0.1) from 11.0.0.1 eth1: 56(84) bytes of data.
64 bytes from 12.0.0.1: icmp_seq=1 ttl=63 time=2.56 ms
64 bytes from 12.0.0.1: icmp_seq=2 ttl=63 time=8.13 ms
64 bytes from 12.0.0.1: icmp_seq=3 ttl=63 time=1.33 ms
64 bytes from 12.0.0.1: icmp_seq=4 ttl=63 time=2.09 ms
64 bytes from 12.0.0.1: icmp_seq=5 ttl=63 time=2.30 ms
^C
--- 12.0.0.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4006ms
rtt min/avg/max/mdev = 1.332/3.288/8.137/2.459 ms

Ну и отсутствие дубликатов доказывает дамп на анализаторе Analyzer-3:

bormoglotx@Analyzer-3:~$ sudo tcpdump -i eth1 -B 9192
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
11:59:12.605205 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1602, seq 1, length 64
11:59:12.605350 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1602, seq 1, length 64
11:59:13.611070 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1602, seq 2, length 64
11:59:13.612356 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1602, seq 2, length 64
11:59:14.606350 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1602, seq 3, length 64
11:59:14.606739 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1602, seq 3, length 64
11:59:15.612423 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1602, seq 4, length 64
11:59:15.612488 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1602, seq 4, length 64
11:59:16.614228 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1602, seq 5, length 64
11:59:16.614588 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1602, seq 5, length 64
^C
10 packets captured
10 packets received by filter
0 packets dropped by kernel

Кроме создания отдельного инстанса на RZN-PE-2, можно воспользоваться и другими способами. О них нигде не написано и узнал я про них просто проводя тестирование.

Можно указать в фильтре, что весь трафик из тоннеля надо отправить в discard (именно discard, так как если будет reject, то Juniper будет отправлять назад icmp сообщение о том, что пакет зафильтрован)

bormoglotx@RZN-PE-2# show firewall family inet filter MIRROR-RSPAN-GE0/0/1
term MIRROR {
    then {
        port-mirror-instance RSAPN;
        discard;
    }
}

Если верить тестам, то с таким фильтром все работает:

bormoglotx@Server-1:~$ ping 12.0.0.1 -I eth1
PING 12.0.0.1 (12.0.0.1) from 11.0.0.1 eth1: 56(84) bytes of data.
64 bytes from 12.0.0.1: icmp_seq=1 ttl=63 time=2.68 ms
64 bytes from 12.0.0.1: icmp_seq=2 ttl=63 time=1.22 ms
64 bytes from 12.0.0.1: icmp_seq=3 ttl=63 time=1.96 ms
64 bytes from 12.0.0.1: icmp_seq=4 ttl=63 time=2.30 ms
64 bytes from 12.0.0.1: icmp_seq=5 ttl=63 time=1.96 ms
^C
--- 12.0.0.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4005ms
rtt min/avg/max/mdev = 1.220/2.028/2.685/0.487 ms

На анализаторе трафик есть:

bormoglotx@Analyzer-3:~$ sudo tcpdump -i eth1 -B 9192
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
12:03:11.934805 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1604, seq 1, length 64
12:03:11.934834 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1604, seq 1, length 64
12:03:12.982685 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1604, seq 2, length 64
12:03:12.982716 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1604, seq 2, length 64
12:03:13.935027 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1604, seq 3, length 64
12:03:13.935607 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1604, seq 3, length 64
12:03:14.936859 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1604, seq 4, length 64
12:03:14.937654 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1604, seq 4, length 64
12:03:15.937650 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1604, seq 5, length 64
12:03:15.938375 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1604, seq 5, length 64
^C
10 packets captured
10 packets received by filter
0 packets dropped by kernel

Еще один вариант позволяет нам вообще не конфигурировать мирроринг инстанс для зеркалирования на RZN-PE-2. Нам надо сделать next-hop группу (если у вас будет один интерфейс, как у меня, то надо добавить какой то фейковый, чтобы JunOS дал сделать коммит), а на gre интерфейс повесить фильтр, который будет изменять next-hop для входящего трафика на нужный нам:

bormoglotx@RZN-PE-2> show configuration interfaces gr-0/0/0
description SPAN;
unit 0 {
    tunnel {
        source 62.0.0.2;
        destination 62.0.0.1;
    }
    family inet {
        filter {
            input MIRROR-RSPAN-GE0/0/1;
        }
    }
}

bormoglotx@RZN-PE-2> show configuration firewall family inet filter MIRROR-RSPAN-GE0/0/1
term MIRROR {
    then next-hop-group Analyzer-3;
}

Next-hop группа поднялась:

bormoglotx@RZN-PE-2> show forwarding-options next-hop-group Analyzer-3 detail
Next-hop-group: Analyzer-3                     
  Type: inet           
  State: up             
  Number of members configured    : 2
  Number of members that are up   : 1
  Number of subgroups configured  : 0
  Number of subgroups that are up : 0
  Members Interfaces:                                 State
    ge-0/0/1.0             next-hop  169.254.100.1    up     
    ge-0/0/100.0                                      down   

И теперь проверим нет ли у нас дубликатов и работает ли зеркалирование:

bormoglotx@Server-1:~$ ping 12.0.0.1 -I eth1 -c 5
PING 12.0.0.1 (12.0.0.1) from 11.0.0.1 eth1: 56(84) bytes of data.
64 bytes from 12.0.0.1: icmp_seq=1 ttl=63 time=3.38 ms
64 bytes from 12.0.0.1: icmp_seq=2 ttl=63 time=2.17 ms
64 bytes from 12.0.0.1: icmp_seq=3 ttl=63 time=2.14 ms
64 bytes from 12.0.0.1: icmp_seq=4 ttl=63 time=2.06 ms
64 bytes from 12.0.0.1: icmp_seq=5 ttl=63 time=1.89 ms

--- 12.0.0.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4006ms
rtt min/avg/max/mdev = 1.891/2.332/3.387/0.538 ms

Дублей нет, осталось проверить, попало ли что нибудь на анализатор:

bormoglotx@Analyzer-3:~$ sudo tcpdump -i eth1 -B 9192
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
12:19:28.306816 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1609, seq 1, length 64
12:19:28.306840 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1609, seq 1, length 64
12:19:29.306887 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1609, seq 2, length 64
12:19:29.307273 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1609, seq 2, length 64
12:19:30.308323 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1609, seq 3, length 64
12:19:30.308455 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1609, seq 3, length 64
12:19:31.309897 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1609, seq 4, length 64
12:19:31.310117 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1609, seq 4, length 64
12:19:32.313234 IP 11.0.0.1 > 12.0.0.1: ICMP echo request, id 1609, seq 5, length 64
12:19:32.313271 IP 12.0.0.1 > 11.0.0.1: ICMP echo reply, id 1609, seq 5, length 64
^C
10 packets captured
10 packets received by filter
0 packets dropped by kernel

Судя по тестам — все отрабатывает как надо. Какой из вариантов внедрять в продакшене — решать вам.

Мы же воспользуемся первым вариантом. Для начала нам надо включить туннельные сервисы, чтобы у нас появился gre интерфейс (gr-X/X/X):

bormoglotx@RZN-PE-1# show chassis fpc 0
pic 0 {
    tunnel-services {
        bandwidth 10g;
    }
}
port-mirror-instance SPAN-1;

Тут стоит немного вернуться к теории и поговорить о туннельных интерфейсах и резервировании ресурсов. В данной конфигурации я выделяю 10G под тоннельные сервисы на нулевом PIC нулевого FPC. Это не значит, что 10G от пропускной способности pfe обрезаются — это говорит о том, что тоннельные сервисы могут использовать не более 10G пропускной способности pfe, и не занятая ими часть ресурсов может использоваться под форвардинг трафика физических портов — то есть 10G на pfe шарится между туннельными сервисами и реальными интерфейсами. Но это на картах MPC. Если вы «счастливый» обладатель карты DPC (например у вас карта 4-ре десятки), то при указанном выше конфиге вы потеряете один порт (то есть из системы просто пропадет xe-порт и будет недоступен из cli, а возле порта загорится лампочка, говорящая нам что порт в туннельном режиме). К сожалению, на данных картах, как вы понимаете, ресурсы резервируются жестко, но эти карты уже давно устарели и постепенно выходят из моды, хотя их пока что навалом.

Во-вторых хотелось бы сказать о нумерации портов — если вы резервируете 1G, то номер порта будет gr-0/0/10, если вы резервируете 10G и более, то номер порта будет gr-0/0/0 (ниже показан именно такой вариант).

[edit]
bormoglotx@RZN-PE-1# run show interfaces terse | match "^(gr|lt|vt)-"
gr-0/0/0                up    up
lt-0/0/0                up    up
vt-0/0/0                up    up

На линейных картах с TRIO-чипсетом максимально возможно резервируемая полоса под туннельные сервисы — 60G.
Примечание: хотелось бы добавить, что lt и vt это разные интерфейсы. lt — logical tunnel — логический тоннель, который предназначен, как правило, для связывания логических систем или роутинг инстансов между собой — он позволяет прогнать трафик между ними, как будто эти инстансы или логические системы соединены прямым патчкордом. А вот vt — это virtual tunnel — виртуальный лупбек, который предназначен не для связывания каких то виртуальных сущностный, а для заворота трафика на pfe для повторного лукапа (например в vpls).

После того, как мы создали туннельные интерфейсы, то у нас появилась возможность сконфигурировать gr-0/0/0. Так как мы выдрали вариант, в котором удаленный PE маршрутизатор не терминирует gre тоннель а просто отправляет трафик в сторону сервера, то как sourse адрес тоннеля на RZN-PE-1 мы указываем собственный лупбек, а вот как destination адрес сервера-получателя отзерклированного трафика, причем данный адрес должен быть доступен.

Собственно говоря, на сервере может быть а может и не быть адреса. Вы можете его выбрать сами и сделать статическую ARP запись, как это показано ниже:

[edit]
bormoglotx@RZN-PE-2# show | compare
[edit interfaces]
+   ge-0/0/1 {
+       description Analyzer-3;
+       unit 0 {
+           family inet {
+               address 192.168.0.0/31 {
+                   arp 192.168.0.1 mac 02:00:00:19:21:68;
+               }
+           }
+       }
+   }
[edit protocols ospf area 0.0.0.0]
      interface ge-0/0/0.0 { ... }
+     interface ge-0/0/1.0 {
+         passive;
+     }

Причем, как видно из представленной конфигурации, интерфейс добавлен как пассивный в ospf, чтобы RZN-PE-1 знал маршрут до этой сети:

[edit]
bormoglotx@RZN-PE-1# run show route 192.168.0.1

inet.0: 20 destinations, 20 routes (20 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

192.168.0.0/31     *[OSPF/10] 00:00:16, metric 3
                    > to 10.0.0.0 via ge-0/0/0.0


Теперь создадим gre тоннель на RZN-PE-1 и добавим его в next-hop группу:

[edit]
bormoglotx@RZN-PE-1# show interfaces gr-0/0/0
description RSPAN;
unit 0 {
    tunnel {
        source 62.0.0.1;
        destination 192.168.0.1;
    }
    family inet {
        address 169.254.100.1/31;
    }
}

[edit]
bormoglotx@RZN-PE-1# show forwarding-options next-hop-group Analyzer-servers
group-type inet;
interface gr-0/0/0.0;
interface ge-0/0/1.0 {
    next-hop 169.254.0.1;
}
interface ge-0/0/2.0 {
    next-hop 169.254.0.3;
}

В отличии от ge интерфейсов, gre интерфейс является p2p и поэтому указывать next-hop адрес для него нет смысла — трафик все равно вылетит с другого конца, хотя указать вы его можете.
Ну и далее все как обычно — проверим состояние сессии зеркалирования:

[edit]
bormoglotx@RZN-PE-1# run show forwarding-options next-hop-group detail          
Next-hop-group: Analyzer-servers               
  Type: inet           
  State: up             
  Number of members configured    : 3
  Number of members that are up   : 3
  Number of subgroups configured  : 0
  Number of subgroups that are up : 0
  Members Interfaces:                                 State
    gr-0/0/0.0                                        up     
    ge-0/0/1.0             next-hop  169.254.0.1      up     
    ge-0/0/2.0             next-hop  169.254.0.3      up     

Ну и теперь проверим, что трафик на удаленном сервере получается:

bormoglotx@Server-1:~$ sudo hping3 -S -c 5 12.0.0.1 -d 40 -I eth1
HPING 12.0.0.1 (eth1 12.0.0.1): S set, 40 headers + 40 data bytes
len=40 ip=12.0.0.1 ttl=63 DF id=53439 sport=0 flags=RA seq=0 win=0 rtt=8.2 ms
len=40 ip=12.0.0.1 ttl=63 DF id=53515 sport=0 flags=RA seq=1 win=0 rtt=3.5 ms
len=40 ip=12.0.0.1 ttl=63 DF id=53610 sport=0 flags=RA seq=2 win=0 rtt=3.4 ms
len=40 ip=12.0.0.1 ttl=63 DF id=53734 sport=0 flags=RA seq=3 win=0 rtt=3.8 ms
len=40 ip=12.0.0.1 ttl=63 DF id=53897 sport=0 flags=RA seq=4 win=0 rtt=3.3 ms

--- 12.0.0.1 hping statistic ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 3.3/4.4/8.2 ms


bormoglotx@Analyzer-3:~$ sudo tcpdump -i eth1 -B 4096
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
16:34:34.923370 IP 62.0.0.1 > 192.168.0.1: GREv0, length 84: IP 11.0.0.1.2894 > 12.0.0.1.0: Flags [S], seq 1149405522:1149405562, win 512, length 40
16:34:34.926586 IP 62.0.0.1 > 192.168.0.1: GREv0, length 44: IP 12.0.0.1.0 > 11.0.0.1.2894: Flags [R.], seq 0, ack 1149405563, win 0, length 0
16:34:35.923022 IP 62.0.0.1 > 192.168.0.1: GREv0, length 84: IP 11.0.0.1.2895 > 12.0.0.1.0: Flags [S], seq 1598018315:1598018355, win 512, length 40
16:34:35.923855 IP 62.0.0.1 > 192.168.0.1: GREv0, length 44: IP 12.0.0.1.0 > 11.0.0.1.2895: Flags [R.], seq 0, ack 1598018356, win 0, length 0
16:34:36.922903 IP 62.0.0.1 > 192.168.0.1: GREv0, length 84: IP 11.0.0.1.2896 > 12.0.0.1.0: Flags [S], seq 592229199:592229239, win 512, length 40
16:34:36.924048 IP 62.0.0.1 > 192.168.0.1: GREv0, length 44: IP 12.0.0.1.0 > 11.0.0.1.2896: Flags [R.], seq 0, ack 592229240, win 0, length 0
16:34:37.923278 IP 62.0.0.1 > 192.168.0.1: GREv0, length 84: IP 11.0.0.1.2897 > 12.0.0.1.0: Flags [S], seq 694611591:694611631, win 512, length 40
16:34:37.924765 IP 62.0.0.1 > 192.168.0.1: GREv0, length 44: IP 12.0.0.1.0 > 11.0.0.1.2897: Flags [R.], seq 0, ack 694611632, win 0, length 0
16:34:38.924275 IP 62.0.0.1 > 192.168.0.1: GREv0, length 84: IP 11.0.0.1.2898 > 12.0.0.1.0: Flags [S], seq 1423363395:1423363435, win 512, length 40
16:34:38.924291 IP 62.0.0.1 > 192.168.0.1: GREv0, length 44: IP 12.0.0.1.0 > 11.0.0.1.2898: Flags [R.], seq 0, ack 1423363436, win 0, length 0
^C
10 packets captured
10 packets received by filter
0 packets dropped by kernel

Но, как я и сказал — трафик gre заголовком, и если для вашего сервера это не проблема, то данный подход самый простой и гибкий.

Но как оказалось, теперь владельцам серверов-получателей отзеркалированного трафика не хочется получать весь трафик, так как его стало слишком много. Серверу Analyzer-1 нужен только TCP трафик, серверу Analyzer-2 только UDP трафик, а вот серверу Analyzer-3 нужен весь трафик, не ограничиваясь TCP/UDP. То есть теперь нам надо реализовать такую схему:

Избирательное зеркалирование на два и более потребителя

Вот тут нам понадобится туннельный интерфейс vt-0/0/0 (виртуальный лупбек) ну или можете использовать lt-0/0/0 (виртуальный тоннель), но первое более предпочтительно. Итак, замысел избирательного зеркалирования заключается в следующем — трафик с порта зеркалируется сначала в виртуальный лупбек vt-порт, а далее с данного порта раскидывается с помощью фильтра на разные next-hop группы на основании выбранных вами параметров — протоколов, портов и т д. Для лучшего понимания происходящего давайте теперь соберем данную схему. Сначала изменим мирроринг инстанс, чтобы трафик зеркалировался в виртуальный лупбек:

[edit]
bormoglotx@RZN-PE-1# show forwarding-options port-mirroring instance SPAN-1
input {
    rate 1;
    run-length 0;
}
family inet {
    output {
        interface vt-0/0/0.0;
        no-filter-check;
    }
}

Очень важным является параметр no-filter-check — эта команда позволяет нам навесить фильтр на интерфейс, в который зеркалируется трафик. По умолчанию фильтрация на этих интерфейсах запрещена. Теперь создадим сам vt-интерфейс:

[edit]
bormoglotx@RZN-PE-1# show interfaces vt-0/0/0
unit 0 {
    description SPAN-USE;
    family inet;
}

На данный интерфейс никаких адресов вы навесить не можете, а семейство адресов, которые можно на нем разрешить ограничено.

Сейчас мы получили следующую картину — весь трафик с интерфейса ge-0/0/3 направлен в порт vt-0/0/0.0. Теперь нам надо отзеркалировать этот трафик в сторону разных потребителей. Для этого сначала надо создать next-hop группы, в которые включить необходимых потребителей:

[edit]
bormoglotx@RZN-PE-1# show forwarding-options next-hop-group Analyzer-TCP                                             
group-type inet;
interface gr-0/0/0.0;
interface ge-0/0/1.0 {
    next-hop 169.254.0.1;
}

[edit]
bormoglotx@RZN-PE-1# show forwarding-options next-hop-group Analyzer-UDP    
group-type inet;
interface gr-0/0/0.0;
interface ge-0/0/2.0 {
    next-hop 169.254.0.3;
}

[edit]
bormoglotx@RZN-PE-1# show forwarding-options next-hop-group Analyzer-default
group-type inet;
interface gr-0/0/0.0;
interface ge-0/0/100.0;

Интерфейс gr-0/0/0, который предназначен для зеркалирования трафика на Analyzer-3 добавлен во все три группы. Это сделано изза того, что данный сервер хочет получать и TCP и UDP трафик, и сделать для него отдельную группу и применить ее потом в фильтре не получится. Использовать один и тот же next-hop в разных группах не запрещено. В группе Analyzer-default есть еще порт ge-0/0/100.0 — это фейковый порт, добавленный в группу для того, чтобы суметь закоммитить конфигурацию — так как в группе должно быть как минимум два интерфейса.

Теперь нам надо создать фильтр, который будет матчить трафик по нужным нам критериям и раскидывать по next-hop группам:

[edit]
bormoglotx@RZN-PE-1# show firewall family inet filter MIRROR-SORTED
term MIRROR-TCP {
    from {
        protocol tcp;
    }
    then next-hop-group Analyzer-TCP;
}
term MIRROR-UDP {
    from {
        protocol udp;
    }
    then next-hop-group Analyzer-UDP;
}
term MIRROR-DEFAUL {
    then next-hop-group Analyzer-default;
}

И прикрутим ее на vt интерфейс:

[edit]
bormoglotx@RZN-PE-1# show interfaces vt-0/0/0
unit 0 {
    description SPAN-USE;
    family inet {
        filter {
            input MIRROR-SORTED;
        }
    }
}

Проверяем нашу конструкцию. Зеркалирование в vt интерфейс в состоянии up:

bormoglotx@RZN-PE-1> show forwarding-options port-mirroring SPAN-1
Instance Name: SPAN-1                         
  Instance Id: 2              
  Input parameters:
    Rate                  : 1
    Run-length            : 0
    Maximum-packet-length : 0
  Output parameters:
    Family              State     Destination          Next-hop
    inet                up        vt-0/0/0.0    


Все группы в работе (помним, что как минимум один порт должен быть в up, чтобы группа перешла в состояние up):

bormoglotx@RZN-PE-1> show forwarding-options next-hop-group detail
Next-hop-group: Analyzer-TCP                   
  Type: inet           
  State: up             
  Number of members configured    : 2
  Number of members that are up   : 2
  Number of subgroups configured  : 0
  Number of subgroups that are up : 0
  Members Interfaces:                                 State
    gr-0/0/0.0                                        up     
    ge-0/0/1.0             next-hop  169.254.0.1      up     

Next-hop-group: Analyzer-UDP                   
  Type: inet           
  State: up             
  Number of members configured    : 2
  Number of members that are up   : 2
  Number of subgroups configured  : 0
  Number of subgroups that are up : 0
  Members Interfaces:                                 State
    gr-0/0/0.0                                        up     
    ge-0/0/2.0             next-hop  169.254.0.3      up     

Next-hop-group: Analyzer-default               
  Type: inet           
  State: up             
  Number of members configured    : 2
  Number of members that are up   : 1
  Number of subgroups configured  : 0
  Number of subgroups that are up : 0
  Members Interfaces:                                 State
    gr-0/0/0.0                                        up     
    ge-0/0/100.0                                      down   

Ну а теперь сгенериуем по 5 icmp, tcp и udp пакетов и посмотрим, что на какой сервер попадет. На всех серверах-клиентах одновременно включим tcpdump. Я использовал hping3 с ключем --rand-source, поэтому обратного трафика мы не увидим, так как снимается трафик только на порту в сторону Server-1.

Итак, смотрим что мы отловили на Analyzer-1, там должен быть только TCP:

bormoglotx@Analyzer-1:~$ sudo tcpdump -i eth1 -B 9192
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
19:58:25.457641 IP 108.215.126.169.1668 > 12.0.0.1.0: Flags [S], seq 1842749676:1842749716, win 512, length 40
19:58:26.458098 IP 230.181.170.188.1669 > 12.0.0.1.0: Flags [S], seq 1810452177:1810452217, win 512, length 40
19:58:27.459245 IP 112.6.155.46.1670 > 12.0.0.1.0: Flags [S], seq 1524555644:1524555684, win 512, length 40
19:58:28.459006 IP 50.45.169.23.1671 > 12.0.0.1.0: Flags [S], seq 1362080290:1362080330, win 512, length 40
19:58:29.459294 IP 135.146.14.177.1672 > 12.0.0.1.0: Flags [S], seq 2122009219:2122009259, win 512, length 40
^C
5 packets captured
5 packets received by filter
0 packets dropped by kernel

Теперь проверим, что же попало на Analyzer-2 (тут должен быть исключительно UDP трафик):

bormoglotx@Analyzer-2:~$ sudo tcpdump -i eth1 -B 9192
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
19:58:09.340702 IP 132.43.66.243.1121 > 12.0.0.1.0: UDP, length 40
19:58:10.341308 IP 205.172.124.143.1122 > 12.0.0.1.0: UDP, length 40
19:58:11.341239 IP 253.127.33.120.1123 > 12.0.0.1.0: UDP, length 40
19:58:12.341204 IP 246.68.75.25.1124 > 12.0.0.1.0: UDP, length 40
19:58:13.341819 IP 95.89.126.64.1125 > 12.0.0.1.0: UDP, length 40
^C
5 packets captured
5 packets received by filter
0 packets dropped by kernel

Ну и остался у на Analyzer-3, там мы ловим все подряд, суммарное количество пакетов должно быть 15 (5 UDP/ 5 TCP/ 5 ICMP):

bormoglotx@Analyzer-3:~$ sudo tcpdump -i eth1 -B 9192
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
19:58:11.782669 IP 62.0.0.1 > 192.168.0.1: GREv0, length 72: IP 132.43.66.243.1121 > 12.0.0.1.0: UDP, length 40
19:58:12.783508 IP 62.0.0.1 > 192.168.0.1: GREv0, length 72: IP 205.172.124.143.1122 > 12.0.0.1.0: UDP, length 40
19:58:13.783166 IP 62.0.0.1 > 192.168.0.1: GREv0, length 72: IP 253.127.33.120.1123 > 12.0.0.1.0: UDP, length 40
19:58:14.782758 IP 62.0.0.1 > 192.168.0.1: GREv0, length 72: IP 246.68.75.25.1124 > 12.0.0.1.0: UDP, length 40
19:58:15.783594 IP 62.0.0.1 > 192.168.0.1: GREv0, length 72: IP 95.89.126.64.1125 > 12.0.0.1.0: UDP, length 40
19:58:18.310249 IP 62.0.0.1 > 192.168.0.1: GREv0, length 100: IP 65.173.140.215 > 12.0.0.1: ICMP net 5.6.7.8 unreachable, length 76
19:58:19.311045 IP 62.0.0.1 > 192.168.0.1: GREv0, length 100: IP 171.91.95.222 > 12.0.0.1: ICMP net 5.6.7.8 unreachable, length 76
19:58:20.312496 IP 62.0.0.1 > 192.168.0.1: GREv0, length 100: IP 228.215.127.12 > 12.0.0.1: ICMP net 5.6.7.8 unreachable, length 76
19:58:21.311067 IP 62.0.0.1 > 192.168.0.1: GREv0, length 100: IP 214.149.191.71 > 12.0.0.1: ICMP net 5.6.7.8 unreachable, length 76
19:58:22.311398 IP 62.0.0.1 > 192.168.0.1: GREv0, length 100: IP 119.130.166.53 > 12.0.0.1: ICMP net 5.6.7.8 unreachable, length 76
19:58:26.186528 IP 62.0.0.1 > 192.168.0.1: GREv0, length 84: IP 108.215.126.169.1668 > 12.0.0.1.0: Flags [S], seq 1842749676:1842749716, win 512, length 40
19:58:27.187385 IP 62.0.0.1 > 192.168.0.1: GREv0, length 84: IP 230.181.170.188.1669 > 12.0.0.1.0: Flags [S], seq 1810452177:1810452217, win 512, length 40
19:58:28.188726 IP 62.0.0.1 > 192.168.0.1: GREv0, length 84: IP 112.6.155.46.1670 > 12.0.0.1.0: Flags [S], seq 1524555644:1524555684, win 512, length 40
19:58:29.188846 IP 62.0.0.1 > 192.168.0.1: GREv0, length 84: IP 50.45.169.23.1671 > 12.0.0.1.0: Flags [S], seq 1362080290:1362080330, win 512, length 40
19:58:30.188499 IP 62.0.0.1 > 192.168.0.1: GREv0, length 84: IP 135.146.14.177.1672 > 12.0.0.1.0: Flags [S], seq 2122009219:2122009259, win 512, length 40
^C
15 packets captured
15 packets received by filter
0 packets dropped by kernel

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

Выше мы зеркалировали L3 трафик, но маршрутизаторы Juniper серии MX очень гибкие устройства и они позволяют зеркалировать не только IP трафик (семейство inet/inet6), но и например L2 трафик — например vpls или l2ckt (xconnect в терминах Cisco).

Локальное зеркалирование L2 трафика

Рассмотрим простейший случай, когда вам надо подсмотреть, что передается в L2CKT-е (это конечно нехорошо делать, так как клиент, чей трафик вы завернете на анализатор, даже не узнает об этом, и делать такие вещи надо исключительно с согласия клиента). Схема проста — между RZN-PE-1 и RZN-PE-2 натянут какой то L2CKT:

То есть нам надо реализовать такую схему зеркалирования:

Между RZN-PE-1 и RZN-PE-2 натянут L2CKT, который мы и хотим прослушать:

bormoglotx@RZN-PE-1> show configuration protocols l2circuit           
neighbor 62.0.0.2 {
    interface ge-0/0/6.100 {
        virtual-circuit-id 100;
    }
}

bormoglotx@RZN-PE-1> show configuration interfaces ge-0/0/6.100
encapsulation vlan-ccc;
vlan-id 100;
family ccc {
    filter {
        input MIRROR-L2CKT-SPAN-1;
        output MIRROR-L2CKT-SPAN-1;
    }
}

Логично, что на интерфейсе включено семейство ccc — это ж L2CKT как никак. В конфигурации на нужном нам интерфейсе уже навешен фильтр в обе стороны — так как мы хотим получать весь трафик, который будет проходит по нашему L2CKT. Фильтр по сути такой же, как и был ранее, только семейство адресов не inet, а ccc:

bormoglotx@RZN-PE-1> show configuration firewall family ccc filter MIRROR-L2CKT-SPAN-1
term MIRROR {
    then port-mirror-instance SPAN-1;
}

Далее настраиваем мирроринг инстанс, который хотим использовать для зеркалирования. В секции input никаких изменений нет — все как и раньше, а вот в секции output есть существенные отличия:

bormoglotx@RZN-PE-1> show configuration forwarding-options port-mirroring instance SPAN-1
input {
    rate 1;
    run-length 0;
}
family ccc {
    output {
        interface ge-0/0/1.0;
    }
}

У нас изменилось семейство адресов — теперь это ccc. Это тянет за собой неизбежные изменения в и конфигурации интерфейса, в который мы хотим отправлять трафик. Если мы попробуем задать какой то адрес next-hop-а, как это делалось ранее на не p2p интерфейсе, то у нас ничего не получится:

bormoglotx@RZN-PE-1# set forwarding-options port-mirroring instance SPAN-1 family ccc output interface ge-0/0/1 ?  
Possible completions:
  <[Enter]>            Execute this command
+ apply-groups         Groups from which to inherit configuration data
+ apply-groups-except  Don't inherit configuration data from these groups
  no-filter-check      Do not check for filters on port-mirroring interface
  |                    Pipe through a command

У нас просто нет такой возможности. Поэтому на интерфейсе, в который нам надо отправить трафик надо включить семейство bridge или ccc:

[edit]
bormoglotx@RZN-PE-1# show interfaces ge-0/0/1   
description Analyzer-1;
encapsulation ethernet-ccc;
unit 0 {
    family ccc;
}

Семейство ccc естественно использовать проще, но если вам приспичило использовать bridge, то не забудьте про важный нюанс — интерфейс с инкапсуляцией bridge должен быть помещен в бридж-домен (номер влана в домене можно использовать нулевой (none), так вы не отберете реальные номера вланов под зеркалирование у остальных сервисов).

Все готово, проверим состояние сессии зеркалирвания:

bormoglotx@RZN-PE-1> show forwarding-options port-mirroring
Instance Name: SPAN-1                         
  Instance Id: 2              
  Input parameters:
    Rate                  : 1
    Run-length            : 0
    Maximum-packet-length : 0
  Output parameters:
    Family              State     Destination          Next-hop
    ccc                 up        ge-0/0/1.0 

Все отлично — сессия в up. Теперь запустим пинг между нашими хостами и проверим, что получится собрать на анализаторе:

bormoglotx@TEST-1> ping routing-instance VR-1 10.0.0.2 count 5
PING 10.0.0.2 (10.0.0.2): 56 data bytes
64 bytes from 10.0.0.2: icmp_seq=0 ttl=64 time=10.159 ms
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=11.136 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=9.723 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=7.754 ms
64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=10.619 ms

--- 10.0.0.2 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 7.754/9.878/11.136/1.162 ms

Вот что получилось собрать:

bormoglotx@Analyzer-1:~$ sudo tcpdump -i eth1 -B 9192
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
23:44:31.948237 IP 10.0.0.1 > 10.0.0.2: ICMP echo request, id 17420, seq 0, length 64
23:44:31.954408 IP 10.0.0.2 > 10.0.0.1: ICMP echo reply, id 17420, seq 0, length 64
23:44:32.955149 IP 10.0.0.1 > 10.0.0.2: ICMP echo request, id 17420, seq 1, length 64
23:44:32.964115 IP 10.0.0.2 > 10.0.0.1: ICMP echo reply, id 17420, seq 1, length 64
23:44:33.967789 IP 10.0.0.1 > 10.0.0.2: ICMP echo request, id 17420, seq 2, length 64
23:44:33.973388 IP 10.0.0.2 > 10.0.0.1: ICMP echo reply, id 17420, seq 2, length 64
23:44:34.975442 IP 10.0.0.1 > 10.0.0.2: ICMP echo request, id 17420, seq 3, length 64
23:44:34.980370 IP 10.0.0.2 > 10.0.0.1: ICMP echo reply, id 17420, seq 3, length 64
23:44:35.986900 IP 10.0.0.1 > 10.0.0.2: ICMP echo request, id 17420, seq 4, length 64
23:44:35.992213 IP 10.0.0.2 > 10.0.0.1: ICMP echo reply, id 17420, seq 4, length 64
^C
10 packets captured
10 packets received by filter
0 packets dropped by kernel

Собственно все пакеты попали на анализатор, чего мы и добивались.

Теперь рассмотрим более сложную схему — нам надо настроить зеркалирование для интерфейсов, находящихся в бридж-домене или в виртуальном свиче, прием отправить копию не в какой то локальный порт, как мы сделали выше, а закинуть этот трафик на удаленную коробку.

Зеркалирование L2 трафика на удаленный сервер

Первая мысль — все просто, можно ж использовать gre туннель. Но, к сожалению, gre не поддерживает инкапсуляцию ccc/tcc/vpls/bridge. Но в Junos очень много различных инструментов, которые позволяют решить одну и ту же задачу разными методами, причем иногда кажется, что сделать что то вроде не реально, но в итоге через N-ое количество времени и N-го количества скуренных мануалов все взлетает. Тут так же. Сейчас мы будем собирать вот такую сложную схему:

Объясню, что и зачем. Итак, мы зеркалируем трафик из виртуального свича (L2CKT-а или бридж-домена) в мирроринг инстанс, причем трафик зеркалиуется не в какой то физический интерфейс, а в виртуальный туннельный интерфейс lt-0/0/0. Этот интерфейс одни на коробку и его юниты создается парами, которые называются peer-unit-ми — один юнит это входной конец туннеля, второй юнит — выходной. В итоге, все что попадает в один юнит — вылетит из связанного с ним второго юнита и наоборот. На этом интерфейсе мы включим инкапсуляцию ccc и с него построим L2CKT до удаленного маршрутизатора, который терминирует сервер-получатель трафика — то есть мы просто отдадим L2 трафик через L2CKT прямиком на удаленный сервер. Для удаленного маршуртизатора это будет простой L2CKT.

Теперь перейдем к конфигурированию. Интерфейсы в сторону серверов в access, и расположены в виртуальном свиче:

bormoglotx@RZN-PE-1# wildcard range show interfaces ge-0/0/[3-4]
description Server-1;
encapsulation ethernet-bridge;
unit 0 {
    family bridge {
        filter {
            input MIRROR-BRIDGE-vSwitch-1;
        }
        interface-mode access;
        vlan-id 100;
    }
}
description Server-2;
encapsulation ethernet-bridge;
unit 0 {
    family bridge {
        filter {
            input MIRROR-BRIDGE-vSwitch-1;
        }
        interface-mode access;
        vlan-id 100;
    }
}

[edit]
bormoglotx@RZN-PE-1# show routing-instances vSwitch-1
instance-type virtual-switch;
interface ge-0/0/3.0;
interface ge-0/0/4.0;
bridge-domains {
    BD100 {
        vlan-id 100;
    }
}

На интерфейсах навешены фильтры для зеркалирования входящего трафика в инстанс SPAN-1. Фильтр ничем не отличается от ранее использованных, кроме семейства — в этом сценарии используется bridge:


[edit]
bormoglotx@RZN-PE-1# show firewall family bridge filter MIRROR-BRIDGE-vSwitch-1
term MIRROR {
    then port-mirror-instance SPAN-1;
}

Теперь создадим инстанс SPAN-1:

[edit]
bormoglotx@RZN-PE-1# show forwarding-options port-mirroring instance SPAN-1
input {
    rate 1;
    run-length 0;
}
family vpls {
    output {
        interface lt-0/0/0.0;
    }
}

Тут есть маленький нюанс. Семейство адресов указывается не bridge — такого семейства вы в конфигурации инстанса даже не найдете, а vpls. Данное семейство (VPLS) используется для зеркалирования трафика из vpls/бридж-доменов.

Далее создаем туннельный интерфейс, в который хотим отправлять трафик:

[edit]
bormoglotx@RZN-PE-1# show interfaces lt-0/0/0
unit 0 {
    description RSPAN-IN;
    encapsulation ethernet-ccc;
    peer-unit 1;
    family ccc;
}
unit 1 {
    description RSPAN-OUT;
    encapsulation ethernet-ccc;
    peer-unit 0;
    family ccc;
}

Как я написал ранее, lt интерфейс состоит из двух юнитов — в нашем случае юниты 0 и 1. Все что влетит в юнит 0 вылетит через юнит 1. Вообще с одной стороны юнит может быть как L3, например inet, а с другой как L2, например ccc — и это будет работать. У нас же с обоих концов ccc, на нулевом юните это обусловлено тем, что трафик должен зеркалироваться в инстанс с семейством ccc/bridge/vpls, а использование ccc на первом юните обусловлено тем, что с данного юнита строится L2CKT.

Далее создаем L2CKT между RZN-PE-1 и RZN-PE-2. Со стороны RZN-PE-1:

[edit]
bormoglotx@RZN-PE-1# show protocols l2circuit
neighbor 62.0.0.2 {
    interface lt-0/0/0.1 {
        virtual-circuit-id 1;
        encapsulation-type ethernet;
    }
}

Со стороны RZN-PE-2:


bormoglotx@RZN-PE-2> show configuration protocols l2circuit    
neighbor 62.0.0.1 {
    interface ge-0/0/1.0 {
        virtual-circuit-id 1;
        encapsulation-type ethernet;
    }
}

bormoglotx@RZN-PE-2> show configuration interfaces ge-0/0/1  
description Analyzer-3;
encapsulation ethernet-ccc;
unit 0 {
    family ccc;
}

Теперь можно проверить, работает ли наш «Франкенштейн». Сначала посмотрим состояние L2CKT:

[edit]
bormoglotx@RZN-PE-1# run show l2circuit connections | find ^Nei          
Neighbor: 62.0.0.2
    Interface                 Type  St     Time last up          # Up trans
    lt-0/0/0.1(vc 1)          rmt   Up     Sep  2 07:28:05 2017           1
      Remote PE: 62.0.0.2, Negotiated control-word: Yes (Null)
      Incoming label: 299840, Outgoing label: 299872
      Negotiated PW status TLV: No
      Local interface: lt-0/0/0.1, Status: Up, Encapsulation: ETHERNET
      Flow Label Transmit: No, Flow Label Receive: No

Отлично, L2CKT в работе. Далее проверяем состояние сессии зеркалирования:

[edit]
bormoglotx@RZN-PE-1# run show forwarding-options port-mirroring SPAN-1
Instance Name: SPAN-1                         
  Instance Id: 2              
  Input parameters:
    Rate                  : 1
    Run-length            : 0
    Maximum-packet-length : 0
  Output parameters:
    Family              State     Destination          Next-hop
    vpls                up        lt-0/0/0.0                            

Все отлично, теперь запустим пинг между серверами Server-1 и Server-2 и посмотрим, что попадает на анализатор трафика:

bormoglotx@Server-1:~$ ping 11.0.0.2 -I 11.0.0.1 -c 5 -i 0.2
PING 11.0.0.2 (11.0.0.2) from 11.0.0.1 : 56(84) bytes of data.
64 bytes from 11.0.0.2: icmp_seq=1 ttl=64 time=3.86 ms
64 bytes from 11.0.0.2: icmp_seq=2 ttl=64 time=2.34 ms
64 bytes from 11.0.0.2: icmp_seq=3 ttl=64 time=2.30 ms
64 bytes from 11.0.0.2: icmp_seq=4 ttl=64 time=9.56 ms
64 bytes from 11.0.0.2: icmp_seq=5 ttl=64 time=1.43 ms

--- 11.0.0.2 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 803ms
rtt min/avg/max/mdev = 1.436/3.903/9.565/2.937 ms

Теперь идем на Analyzer-3 и посмотрим, что попало в tcpdump:

bormoglotx@Analyzer-3:~$ sudo tcpdump -i eth1 -B 9192
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
10:48:46.296920 IP 11.0.0.1 > 11.0.0.2: ICMP echo request, id 2000, seq 1, length 64
10:48:46.297969 IP 11.0.0.2 > 11.0.0.1: ICMP echo reply, id 2000, seq 1, length 64
10:48:46.496380 IP 11.0.0.1 > 11.0.0.2: ICMP echo request, id 2000, seq 2, length 64
10:48:46.497647 IP 11.0.0.2 > 11.0.0.1: ICMP echo reply, id 2000, seq 2, length 64
10:48:46.700540 IP 11.0.0.1 > 11.0.0.2: ICMP echo request, id 2000, seq 3, length 64
10:48:46.700547 IP 11.0.0.2 > 11.0.0.1: ICMP echo reply, id 2000, seq 3, length 64
10:48:46.897518 IP 11.0.0.1 > 11.0.0.2: ICMP echo request, id 2000, seq 4, length 64
10:48:46.907024 IP 11.0.0.2 > 11.0.0.1: ICMP echo reply, id 2000, seq 4, length 64
10:48:47.098414 IP 11.0.0.1 > 11.0.0.2: ICMP echo request, id 2000, seq 5, length 64
10:48:47.098799 IP 11.0.0.2 > 11.0.0.1: ICMP echo reply, id 2000, seq 5, length 64
10:48:51.307134 ARP, Request who-has 11.0.0.1 tell 11.0.0.2, length 46
10:48:51.307542 ARP, Reply 11.0.0.1 is-at 00:50:01:00:07:00 (oui Unknown), length 46
^C
12 packets captured
12 packets received by filter
0 packets dropped by kernel

Ну, помимо наших пингов в дамп попал еще и arp запрос-ответ, что доказывает что весь трафик зеркалируется, что нам и надо.

Ну и в заключении вспомним, что я написал, что на одну и ту же fpc можно биндить максимум два мирроринг инстанса. Но что делать, если вам нужно использовать три инстанса?

Конечно, можно воспользоваться двумя user-defined инстансами и дефолтный инстанс (который всего один), но во-первых это не лучшее решение, ну а во вторых, что делать, если дефолтный инстанс уже занят? Естественно JunOS позволяет вам обойти это ограничение. В принципе, тут нет ничего сверхестественного — принцип работы все тот же, изменения касаются только конфигурации инстансов.

Использование более двух mirroring инстансов на одном FPC

Итак, основной смысл в создании связки между несколькими мирроринг инстансами: делается родительская инстанс и дочерние инстансы, которые на нее ссылаются. В родительском инстансе мы указываем input параметры — то есть скорость мирроринга/сэмплинга, максимальный размер пакета. В дочерних инстансах указываются уже output параметры — интерфейсы или next-hop группы, а вот input параметры наследуются от родительского инстанса, указанного в конфигурации. Без конфигов это явно непонятно, поэтому соберем такую схему зеркалирования:

Сначала создадим родительский инстанс, я назвал его просто SPAN.

bormoglotx@RZN-PE-1# show forwarding-options port-mirroring instance SPAN     
input {
    rate 1;
    run-length 0;
}

В инстансе указаны только входящие параметры зеркалирования. Больше ничего тут указывать не надо.

Теперь создадим три дочерних инстанса:

[edit]
bormoglotx@RZN-PE-1# show forwarding-options port-mirroring instance SPAN-1  
input-parameters-instance SPAN;
family inet {
    output {
        interface ge-0/0/1.0 {
            next-hop 169.254.0.1;
        }
    }
}

[edit]
bormoglotx@RZN-PE-1# show forwarding-options port-mirroring instance SPAN-2    
input-parameters-instance SPAN;
family inet {
    output {
        interface ge-0/0/2.0 {
            next-hop 169.254.0.3;
        }
    }
}

[edit]
bormoglotx@RZN-PE-1# show forwarding-options port-mirroring instance SPAN-3    
input-parameters-instance SPAN;
family inet {
    output {
        interface gr-0/0/0.0 {
    }
}

Тут уже мы указываем исходящие параметры зеркалирования. Связка между родительским и дочерним инстансом происходит с помощью следующей команды:

input-parameters-instance SPAN;

В итоге все три созданных мной инстанса SPAN-1/2/3 будут наследовать input параметры от инстанса SPAN. Как вы помните, теперь нам надо привязать инстансы к какой то (или каким то, если входящие порты на разных картах) FPC. Как я и сказал ранее — к FPC надо привязать только родительский инстанс:

bormoglotx@RZN-PE-1# show chassis fpc 0
pic 0 {
    tunnel-services {
        bandwidth 10g;
    }
}
port-mirror-instance SPAN;

Ну а далее все так же — создаем фильтры и вешаем их на входящие порты:

bormoglotx@RZN-PE-1# wildcard range show interfaces ge-0/0/[3-5]
description Server-1;
unit 0 {
    family inet {
        filter {
            input MIRROR>>>SPAN-3;
            output MIRROR>>>SPAN-3;
        }
        address 11.0.0.254/24;
    }
}
description Server-2;
unit 0 {
    family inet {
        filter {
            input MIRROR>>>SPAN-2;
            output MIRROR>>>SPAN-2;
        }
        address 12.0.0.254/24;
    }
}
description Server-3;
unit 0 {
    family inet {
        filter {
            input MIRROR>>>SPAN-1;
            output MIRROR>>>SPAN-1;
        }
        address 13.0.0.254/24;
    }
}

Обращаю внимание, что в фильтрах указываются не родительский инстанс, а дочерние инстансы:

[edit]
bormoglotx@RZN-PE-1# wildcard range show firewall family inet filter MIRROR>>>SPAN-[1-3]    
term MIRROR {
    then port-mirror-instance SPAN-1;
}
term MIRROR {
    then port-mirror-instance SPAN-2;
}
term MIRROR {
    then port-mirror-instance SPAN-3;
}

Теперь проверим состояние сессий зеркалирования:

bormoglotx@RZN-PE-1# run show forwarding-options port-mirroring
Instance Name: SPAN-1                         
  Instance Id: 3              
  Input parameters:
    Rate                  : 1
    Run-length            : 0
    Maximum-packet-length : 0
  Output parameters:
    Family              State     Destination          Next-hop
    inet                up        gr-0/0/0.0       

Instance Name: SPAN-2                         
  Instance Id: 4              
  Input parameters:
    Rate                  : 1
    Run-length            : 0
    Maximum-packet-length : 0
  Output parameters:
    Family              State     Destination          Next-hop
    inet                up        ge-0/0/2.0           169.254.0.3         

Instance Name: SPAN-3                         
  Instance Id: 5              
  Input parameters:
    Rate                  : 1
    Run-length            : 0
    Maximum-packet-length : 0
  Output parameters:
    Family              State     Destination          Next-hop
    inet                up        ge-0/0/1.0           169.254.0.1       

Из вывода видно, что сессии зеркалирования трафика в работе, а параметры обработки входящего трафика унаследованы от родительского инстанса. Собственно показывать выводы непосредственно работы я не буду в целях сокращения статьи — думаю, что после прочтения данной статьи вы сможете сами собрать такую схему и проверить ее работоспособность.

Вроде бы все, что хотел написать — написал. Если будут замечания или дополнения — пишите.

Спасибо за внимание.

Комментарии (8)


  1. alexyr
    04.09.2017 09:44

    Попала как-то ко мне одна их старая железка… И тут выяснилось, что частному лицу никак не получить доступ к официальным образам JunOS для обновления/восстановления!


    1. Tufed
      04.09.2017 12:22

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


      1. alexyr
        04.09.2017 14:44

        Так с помощью добрых людей и достал! Просто странная политика партии… Частное лицо не может официально использовать их железку?


        1. Wedmer
          04.09.2017 15:46

          Только если частное лицо официально купило и оформило лицензию на JunOS на себя.
          Вообще я как то умудрялся сливать образы, но использовать торренты сильно проще.


    1. SchmeL
      04.09.2017 13:43

      ну, КДПВ — как бы намекает )


  1. AlexanderKuzin
    05.09.2017 07:19

    На Juniper MX есть еще один вариант зеркалирования трафика на удаленный хост — механизм Flow-Tap.
    Отличатся от все остальных вариантов тем, что он не статически настраивается в конфигурации устройства, а динамически управляется через протокол DTCP (Dynamic Tasking Control Protocol).
    Внешняя система анализа может сама «заказать» себе копию интересующего её трафика.


    1. Bormoglotx Автор
      06.09.2017 17:26

      Добрый день! Да, читал про эту фичу, но еще ни разу не использовал. Возможно будет время — потестирую, так как вещь вроде интересная.


      1. AlexanderKuzin
        06.09.2017 21:44

        Я пробовал ее тестировать — работает без проблем. В недрах документации Juniper есть пример реализации DTCP на Perl.
        Но найти какую-нибудь готовую систему анализа трафика, которая бы могла управлять маршрутизатором по DTCP, я не смог.