Поиск по этому блогу

25.07.2016

Как работают BPDUGuard и BPDUFilter

Кому-то в голову пришло, что spanning-tree можно использовать не только для построения кольцевых топологий, но и для обнаружения потенциальных петель на пользовательских портах. Возможно, тогда это казалось нормальным. Да и сейчас обладателям коммутаторов cisco и juniper настраивать spanning-tree придется в любом случае. Зато другие производители подсуетились и решили слать в пользовательские порты Loopback Detection (LBD) фреймы, но сейчас не об этом.

Условно коммутаторы можно поделить на три типа:
1. Ничего, кроме spanning-tree нет и spanning-tree на порту отключить нельзя. Это cisco.
2. Ничего, кроме spanning-tree нет, можно отключить spanning-tree глобально или на порту. Это juniper networks.
3. Можно использовать spanning-tree, можно LBD, можно отключить spanning-tree глобально или на порту. Это eltex, dlink, qtech (dcn). Про хуавей не помню, не настраивал stp на них.

Коммутаторы с отключенным глобально или на порту spanning-tree могут принимать BPDU-фреймы и передавать их дальше как обычный мультикастовый трафик с адресом назначения 01:80:C2:00:00:00. Это обязательно произойдет при передаче "нестандартных" BPDU от Cisco PVST на адрес 01:00:0C:CC:CC:CD. Был случай как-то, когда я не мог настроить MSTP между коммутаторами cisco и juniper. Оказалось, что коммутатор cisco получал через порт juniper'а помимо BPDU от MSTP еще и BPDU от Cisco PVST, которые juniper принимал на порту, где stp был отключен. Таким образом, на коммутаторах недостаточно отключить spanning-tree глобально или на порту, необходимо еще и фильтровать BPDU на адреса 01:80:C2:00:00:00 и 01:00:0C:CC:CC:CD.
На всех коммутаторах есть такой функционал "bpdufilter", но реализация у всех разная.

cisco bpdufilter и bpduguard


Bdpufilter фильтрует в обе стороны, т.е. коммутатор отбрасывает все входящие BPDU и не отправляет BPDU в порт. Логично фильтр повесить на порты, которые никак не участвуют в кольцевой топологии, с которых никогда не придет BPDU, например, на порт подключения сервера, на порт подключения маршрутизатора, на стык с провайдером. Особо странный провайдер включает на порту клиента bpduguard и отключит порт при получении bpdu от вашего коммутатора. Поэтому на операторских стыках необходимо вешать фильтр всегда.
interface GigabitEthernet1/0/1
description Server
switchport access vlan 100
switchport mode access
spanning-tree portfast edge
spanning-tree bpdufilter enable

interface GigabitEthernet1/0/2
description Router
switchport trunk encapsulation dot1q
switchport mode trunk
spanning-tree portfast edge trunk
spanning-tree bpdufilter enable

interface GigabitEthernet1/0/3
description Internet
switchport access vlan 5000
switchport mode access
spanning-tree portfast edge
spanning-tree bpdufilter enable
Чтобы при изменении топологии данные порты не проходили все возможные фазы blocking, listening, learning, а переходили сразу в forwarding, необходимо включать portfast. Да, этой дури бы не было, если можно было бы просто отключить spanning-tree на порту. Необходимо учесть, что включенный spanning-tree portfast на транковом порту работать не будет. Тут нужен spanning-tree portfast trunk или spanning-tree portfast edge trunk как в этом примере.
Очень часто видел вот такую вот конструкцию:
interface GigabitEthernet1/0/4
spanning-tree bpdufilter enable
spanning-tree bpduguard enable
В этом примере bpduguard - лишняя команда, так как она работать не будет по причине отработавшего ранее фильтра. Но так только в cisco.
Вот самый распространенный пример, когда используется bpduguard.
interface GigabitEthernet1/0/5
description User
switchport access vlan 200
switchport mode access
spanning-tree portfast edge
spanning-tree bpduguard enable
Для автоматического включения порта необходимо настроить errdisable.
errdisable recovery cause bpduguard
errdisable recovery interval 120
Нужен ли spanning-tree на порту пользователя? Нет не нужен. Но в данном примере протокол spanning-tree циской используется для того чтобы послать BPDU в порт и при получении его по какой-то причине обратно отключить порт. В случае, когда на пользовательской стороне BPDU фильтруются или потерялись, bpduguard не отработает. Увы, никакой другой альтернативы циска не предлагает, поэтому возможна такая ерундистика, когда колец нет в принципе и на всех транках настроен portfast и bpdufilter, а в сторону пользователей - bpduguard. Нормальное такое применение протокола... Круче только ситуация, когда из-за невозможности глобального отключения stp приходится настроить mstp, включить везде bpdufilter и portfast.

juniper bpdufilter и bpduguard


Я не знаю, фильтруют ли производители своими bpdufilter'ами цисковский 01:00:0C:CC:CC:CD или нет. В общем случае, рекомендуется написать фильтр с указанием двух мак-адресов и повесить по входу, например, такой:
firewall {
family inet {
filter bpdufilter {
term discard-bpdu {
from {
destination-mac-address {
01:80:c2:00:00:00/48;
01:00:0c:cc:cc:cd/48;
}
}
then {
discard;
count BPDU_FILTER;
}
}
term allow-other {
then accept;
}

}
}
}
Согласно документации, на мелких коммутаторах, кроме ex9200, можно глобально включить фильтр для портов, где spanning-tree отключен. В примере ниже для всех интерфейсов отключен spanning-tree и включена фильтрация bpdu.
ex2200> show configuration protocols mstp                
configuration-name abc;
revision-level 1;
bridge-priority 28k;
interface all {
disable;
}
msti 1 {
bridge-priority 28k;
vlan 1-4094;
}

{master:0}
ex2200> show configuration ethernet-switching-options bpdu-block
interface xstp-disabled {
drop;
}
{master:0}
Настроить bpduguard на ex2200 можно прописав пользовательские порты диапазоном, в настройках используемого протокола stp указать для созданного диапазона портов тип edge и там же включить функционал bpdu-block-on-edge. Ниже аналог цисковского конфига.
ex2200# show | compare 
[edit interfaces]
+ interface-range Users {
+ member-range ge-0/0/20 to ge-0/0/30;
+ unit 0 {
+ family ethernet-switching {
+ port-mode access;
+ vlan {
+ members 200;
+ }
+ }
+ }
+ }
[edit protocols mstp]
+ interface Users {
+ edge;
+ }
[edit protocols mstp]
+ bpdu-block-on-edge;
[edit ethernet-switching-options bpdu-block]
+ disable-timeout 120;
На juniper'е настройка spanning-tree получилась более гуманной. Там, где необходимости настраивать stp, его можно вовсе отключить, но не забыть зафильтровать возможные bpdu.

eltex bpdufilter и bpduguard


Тут все просто. Можно выключить spanning-tree глобально и все bpdu зафильтровать. Не уверен насчет цисковских только.
mes2124p(config)#no spanning-tree
mes2124p(config)#spanning-tree bpdu
filtering Specify that when spanning tree is disabled on an
interface, BPDU packets would be filtered.
flooding Specify that when spanning tree is disabled on an
interface, untagged BPDU packets would be flooded
unconditionally (Without applying VLAN rules), to all
ports with spanning tree disabled. Tagged BPDU packets
would be filtered.
mes2124p(config)#spanning-tree bpdu filtering
mes2124p(config)#exit
mes2124p#sh spanning-tree

*********************************** Process 0 ***********************************

Spanning tree disabled (BPDU filtering) mode MSTP
Default port cost method: long
Loopback guard: Disabled
Вот, собственно, что и послужило поводом к статье. Конструкция ниже заблокировала порт, так как bpduguard отрабатывает раньше, чем фильтр. Да и сам фильтр фильтрует только входящие bpdu.
mes2124p#sh run int gi1/0/23
interface gigabitethernet 1/0/23
switchport mode trunk
spanning-tree bpdu filtering
spanning-tree bpduguard enable