Thursday, December 31, 2015

Строим отказоустойчивую сетевую инфраструктуру предприятия.

Часть 2: Соединяем Cisco и HP ProCurve при помощи MSTP.
(Update from 2016.01.05)

Часть 1: "MSTP на HP ProCurve"
Часть 3: "Тюнинг настроек пограничных портов и портов доступа на Cisco и HP ProCurve"


     Продолжаем серию для "начинающих профессионалов" :) В прошлый раз мы собрали в единую сеть все наши HP ProCurve, а сегодня настал черед подключить оставшееся оборудование Cisco к нашей схеме:
         Кроссируем наши Cisco 1, 2, 3 и 4, как показано на схеме, но один из линков в каждой группе из двух коммутаторов пока отключаем для предотвращения петли, до тех пор, пока не заработает Spanning Tree.

     Итак, на ProCurve мы настраивали MSTP, по логике мы должны настроить и на Cisco MSTP, и в интернете даже есть некоторое количество информации на тему связывания этих двух производителей, и даже официальные доки от HP и от Cisco. Но к сожалению...

     Настройка MSTP на Cisco.

      Для начала, если вы еще не читали Часть 1: "MSTP на HP ProCurve", то советую почитать! Там рассматриваются основные принципы настройки MSTP на коммутаторах, которые являются общими и для HP и для Cisco. Ну а вкратце основные рекомендации Cisco и здравого смысла по настройке MSTP такие:
  1. Использовать один регион во всей сети.
  2. Минимальное количество instances, т.е. не более числа дублирующих линков.
  3. Задавать приоритеты для root bridge.
  4. Заранее разбивать сразу весь возможный диапазон VLAN на instances.
  5. Все instances на всех коммутаторах региона должны содержать одинаковый список VLAN'ов! На Cisco в этом вопросе на помощь придёт протокол VTP v3, который умеет обслуживать не только VLAN'ы, но и instances MST. На ProCurve есть только GVRP, который является аналогом VTP V1/2, и работать с MSTP не умеет, так что все синхронизации настроек instances между коммутаторами на HP выполняются "ручками".
  6. Имя домена и ревизия конфигурации должны совпадать в регионе!
  7. На всех транках между коммутаторами должен быть разрешен весь список VLAN'ов которые обслуживает Spanning Tree.
     А так же еще есть правила для связывания ProCurve и Cisco:
  1. Cisco поддерживает 802.1s MSTP только с 2005 года, и надо убедиться, что IOS новее 2005 года. Апдейт фирмвари вообще делать полезно!
  2. Не путать Pre-STD MST с MSTP - они несовместимы.
  3. Убедиться, что на транках между Cisco и HP установлен Native/Untagged VLAN 1.
     Выполнение этих правил позволит вашей топологии Spanning Tree стабильно работать, распределять нагрузку по линкам, и не пересчитываться без критической надобности, укладывая всю сеть :)

Убеждаемся, что на транках между Cisco и ProCurve у нас разрешены все необходимые VLAN'ы, после чего приступаем:
conf t
spanning-tree mst configuration
Все делаем как и на ProCurve. Задаём имя региона, такое же как и на ProCurve, т.е. одинаковое во всём регионе:
name H2SO4
Номер ревизии конфига должен обязательно совпадать во всем регионе:
revision 1
Разбиваем наши вланы на 2 instance, абсолютно аналогично, как на ProCurve:
instance 1 vlan 1-35,101,111-500,1001-4094
instance 2 vlan 36-100,102-110,501-1000
И для профилактики, не выходя из режима конфигурации MST смотрим, что у нас получилась за конфигурация:
show pending
Pending MST configuration
Name      [H2SO4]
Revision  1     Instances configured 3

Instance  Vlans mapped
--------  ---------------------------------------------------------------------
0         none
1         1-35,101,111-500,1001-4094
2         36-100,102-110,501-1000
-------------------------------------------------------------------------------
Для сохранения конфигурации набираем exit или нажимаем CTRL-Z:
exit
В случае, если Cisco у вас главные в MST регионе, или у вас Cisco-Only сеть, то задаём параметры определяющие, что наши коммутаторы будут главными в MSTP регионе для конкретных instances, как мы делали на HP в прошлой статье, и зададим приоритеты для instances:  
Cisco 1/3:
conf t
spanning-tree mst 1 root primary
spanning-tree mst 0-1 priority 0
spanning-tree mst 2 priority 4096
Cisco 2/4:
conf t
spanning-tree mst 2 root primary
spanning-tree mst 0-1 priority 4096
spanning-tree mst 2 priority 0
Для нашей конфигурации Cisco+HP данная настройка приоритетов на Cisco не требуется, так как root bridge у нас ProCurve, и все высшие приоритеты у нас на ProCurve!
После того, как сконфигурировали ваш MSTP на всех Cisco в пределах группы, включаем его: 
spanning-tree mode mst
     Все должно легко и непринужденной взлететь, если только вы следовали инструкциям, и в вашей сети не притаился за углом сюрприз, как было в моей :)
     Я несколько дней убил пытаясь понять, почему у меня ничего не работает! В итоге, в тёмном забытом углу нашлась Cisco 3560, про которую все забыли, и которая работала в режиме PVST... Признаться я даже не предполагал, что BPDU могут вот так пролетать сквозь всю топологию, и портить жизнь. В общем её BPDU пролетали насквозь и сводили с ума Cisco на которых я включал MSTP. Постоянные пересчеты топологии, веерные блокировки портов и т.д. и т.п.

000068: 00:49:18: %SPANTREE-2-PVSTSIM_FAIL: Blocking root port Gi0/8: Inconsistent inferior PVST BPDU received on VLAN 110, claiming root 32878:0015.c6d7.9900

Gi0/7            Mstr BKN*20000     128.7    P2p Bound(PVST) *PVST_Inc

     Кстати, на HP есть такая штука, как pvst-filter, возможно ее включение спасло бы меня без поиска всех железок отправляющих неправильные BPDU.

      Итак, что же я делал... Включаю на Cisco debug принятых BPDU:

term mon
debug spanning-tree bpdu receive

И вижу вот такую картину:

002836: Jan  5 16:36:57.625: STP: MST0 rx BPDU: config protocol = mstp, packet from GigabitEthernet0/8  , linktype IEEE_SPANNING , enctype 2, encsize 17 
002837: Jan  5 16:36:57.625: STP: enc 01 80 C2 00 00 00 00 1B 3F 58 31 EF 00 89 42 42 03 
002838: Jan  5 16:36:57.625: STP: Data     000003023C1000001B3FC1A800000000001000001B3FC1A80080110000140002000F00
002839: Jan  5 16:36:57.634: STP: MST0 Gi0/8:0000 03 02 3C 1000001B3FC1A800 00000000 1000001B3FC1A800 8011 0000 1400 0200 0F00
002840: Jan  5 16:36:58.238: STP: MST0 rx BPDU: config protocol = mstp, packet from GigabitEthernet0/8  , linktype SSTP , enctype 3, encsize 22 
002841: Jan  5 16:36:58.238: STP: enc 01 00 0C CC CC CD 9C 4E 20 B2 2E 98 00 32 AA AA 03 00 00 0C 01 0B 
002842: Jan  5 16:36:58.238: STP: Data     000000000080649C4E20B22E800000000080649C4E20B22E8080180000140002000F00
002843: Jan  5 16:36:58.238: STP: MST0 Gi0/8:0000 00 00 00 80649C4E20B22E80 00000000 80649C4E20B22E80 8018 0000 1400 0200 0F00

IEEE_SPANNING - это то, что должно быть, это нормально.
А вот SSTP - это уже ненормально. Это не наш MSTP, это "чужой" Spanning-tree, который нам и портит жизнь.
Найти злодея проще простого. Первые 6 цифр в поле ENC это заголовок, он всегда одинаковый: 01 00 0C CC CC CD, а вот следующие 6 цифр это уже MAC адрес отправителя, по нему и надо искать мешающее оборудование: 9C 4E 20 B2 2E 98  - в моём случае это оказалась Cisco 3560. После отключения на ней STP все пришло в норму. MSTP забегал, и все стало хорошо.

Несколько команд для проверки конфигурации MSTP на Cisco и HP:
HP:
sh spanning-tree mst-config

  MST Configuration Identifier Information

  MST Configuration Name : H2SO4                          
  MST Configuration Revision : 1    
  MST Configuration Digest : 0xF1AD53AD5D69827DFCB5C5B5D00F6D88

  IST Mapped VLANs : 

  Instance ID Mapped VLANs                                             
  ----------- ---------------------------------------------------------
  1           1-35,101,111-500,1001-4094
  2           36-100,102-110,501-1000

Синим цветом выделена контрольная сумма, она должна совпадать при правильной и одинаковой конфигурации на HP и Cisco. Если она отличается - ищите различия. Пока она отличается, все будет работать через instance 0 и все порты будет Boundary.

Cisco:
sh spanning-tree mst configuration 

Name      [H2SO4]
Revision  1     Instances configured 3

Instance  Vlans mapped
--------  ---------------------------------------------------------------------
0         none
1         1-35,101,111-500,1001-4094
2         36-100,102-110,501-1000
-------------------------------------------------------------------------------
sh spanning-tree mst configuration digest 
Name      [H2SO4]
Revision  1     Instances configured 3
Digest          0xF1AD53AD5D69827DFCB5C5B5D00F6D88
Pre-std Digest  0x79EA425B9595B8B88B3E715854CC0CC8

     В этом случае, не мудрствуя лукаво, MSTP просто для всех instances заблокировал межкоммутаторный линк оставив его на случай аварии, что логично. Ведь этот линк менее быстрый, и больше хопов на пути до root bridge.

Немного статистики с Cisco:

sh spanning-tree mst 1

##### MST1    vlans mapped:   1-35,101,111-500,1001-4094
Interface        Role Sts Cost      Prio.Nbr Type
---------------- ---- --- --------- -------- --------------------------------
Gi0/18           Desg FWD 20000      128.18   P2p 
Gi0/20           Desg FWD 200000    128.20   P2p 
Gi0/21           Desg FWD 200000    128.21   P2p 
Gi0/22           Desg FWD 200000    128.22   P2p 
Gi0/23           Desg FWD 200000    128.23   P2p 
Gi0/24           Altn BLK 20000        128.24   P2p 
Po1                Root FWD 20000      128.36   P2p 

sh spanning-tree mst 2

##### MST2    vlans mapped:   36-100,102-110,501-1000
Interface        Role Sts Cost      Prio.Nbr Type
---------------- ---- --- --------- -------- --------------------------------
Gi0/24           Altn BLK 20000      128.24   P2p 
Po1               Root FWD 20000     128.36   P2p 

     Документации по работе оборудования HP и Cisco вместе: от HP и от Cisco
Коммутаторы в единую сеть мы собрали, по-этому в следующих заметках поговорим о настройках пользовательских портов, добавлю немного о защите сети от пользователей и петель, а так же зарезервируем доступ в интернет, почтовый релей, и подключение компании к интернету.
  1. Поговорим про BPDUGuard, BPDUFilter, PortFast и о некоторых особенностях применения этих сервисов на Cisco и HP ProCurve.
  2. Сделаем кластер из двух серверов на базе FreeBSD+CARP для раздачи интернета пользователям.
  3. Сделаем кластер из двух Debian/Ubuntu+UCARP для почтового релея, пересылающего почту между интернетом и почтовым сервером или кластером компании.
  4. Сделаем кластер из двух Cisco+HSRP в которые приходят каналы от провайдеров.

Thursday, December 24, 2015

Строим отказоустойчивую сетевую инфраструктуру предприятия.


Часть 1: Spanning Tree Protocol. MSTP на HP ProCurve




     В прошлых заметках мы немного поборолись с проблемами создаваемыми дешёвым оборудованием, а в этот раз начнём серию для "начинающих профессионалов", по построению хорошей отказоустойчивой сети из дорогого оборудования :)

     Задача состоит в том, чтобы создать сеть, в которой нет единой точки отказа. Все коммутаторы соединены минимум двумя линками с минимум двумя соседями, а все серверы подключены к двум коммутаторам. Пока не будем перегружать схему резервированием каналов связи и телефонии, оставим это для следующих заметок, а усложним задачу тем, что у нас по стечению обстоятельств в сети оборудование хоть и дорогое, но разношёрстное, не полностью совместимое по некоторым протоколам. Например Cisco и HP ProCurve... Так иногда случается: готовишься к шеститонникам, тебе сообщают, что вместо Cisco будет Huawei, а получаешь в итоге прокурвы... ;)
     Хотелось бы обратить внимание, что использовать оборудование разных производителей в сети - не самая лучшая идея! И надо всеми силами избегать зоопарка в сетевом оборудовании. Но если уж так случилось, то придётся настраивать :) В целом случай у нас не очень тяжёлый. Во-первых ProCurve далеко не плохое оборудование, да и получается, что основная LAN полностью на HP, а Cisco коммутаторы лишь "сбоку", и не будут выполнять ключевые задачи. Так что особых проблем быть не должно.
     Конечно, я преданный поклонник Cisco, ведь кто привык к VTP, HSRP и EIGRP со слезами и комом в горле пользуется GVRP, VRRP и OSPF :)

Собственно схемка нашей сети:
































     Итак, оборудование Cisco у нас уже не очень молодое, хоть и гигабитное, а вот HP приехали свежие, все с 10G линками, потому HP и будет основным ядром сети. Cisco используем как дополнение, для различных серверов которые не создают очень большого трафика. Cisco и HP так же соединим несколькими транками, хоть и без излишеств.
  1. Собираем, монтируем, кроссируем, включаем, делаем базовые настройки!
  2. Все дополнительные линки у нас пока отключены физически, что бы пока мы не настроили Spanning Tree, у нас не легла сеть от петель.
  3. Оплакивая прекрасный VTP v3 от Cisco включаем GVRP и радуемся, что хотя бы в виде динамических, но VLAN'ы у нас на всех коммутаторах одинаковые :)
  4. Разрешаем на всех транках между коммутаторами идинаковый список VLAN'ов! Одинаково нужно для того, что бы у нас не получилось, что Spanning Tree блокирует VLAN там, где он прописан на транке, как разрешенный, и пытается пропустить там, где вы его указать забыли.
  5. За неимением HSRP, настраиваем виртуальный IP VRRP для пользовательских VLAN на HP1 и HP2, чтобы шлюз по-умолчанию был всегда, если жив хотя бы один из этих коммутаторов.
     Настройка Spanning Tree на HP ProCurve.

     Настраивать будем MSTP, как наиболее логичный выбор для большой сети с большим чистом VLAN. Почему более логичный ? Да потому, что в отличие от разных вариаций PVST, в MSTP можно разбить вланы на группы привязанные к instance, и сколько вы опишете instances, столько и будет у вас процессов. В случае PVST у вас будет столько процессов, сколько всего VLAN'ов в сети, т.е. память будет поедаться тем больше, чем больше VLAN у вас есть. Например в случае 100 VLAN у вас будет 100 процессов - жуть.

     Хоть настраиваем мы ProCurve, но воспользуемся рекомендациями Cisco по настройке MSTP. Cisco рекомендует использовать один регион во всей сети, минимальное количество instances и обязательно задавать приоритеты для root bridge. Если вы не знаете, что такое регион, root bridge и instances, то лучше сначала почитать вот это: Wikipedia: Spanning Tree Protocol, после чего все станет намного легче ;)
     Так же очень настоятельно рекомендую заранее разбить сразу весь возможный диапазон VLAN на instances, потому что каждое изменение instance в последствии, когда у вас уже будет действующая сеть, будет приводить к пересчёту топологии и неприятному пропаданию или замиранию сетевого обмена в сети. Плюс если у вас будут отличаться instances на коммутаторах, то все вообще будет разваливаться, и топология пересчитываться в единственный instance 0 для взаимодействия с коммутаторами у которых не совпадают настройки.

     Итак, начинаем настраивать. Создаём два instance, с учетом того, что основные линки у нас парами, и городить число instances больше числа линков смысла нет. Убеждаемся, что spanning tree у нас отключен и начинаем конфигурить:

Настраиваем корневой HP1:
Задаём имя региона MSTP. Естественно, оно должно совпадать во всей сети:
spanning-tree config-name "H2SO4"
Номер ревизии конфига тоже должен обязательно совпадать:
spanning-tree config-revision 1
Я разбил все возможные VLAN на 2 instance в соответствии с нагрузкой на них в моей сети, примерно распределив ее поровну:
spanning-tree instance 1 vlan 1-35 101 111-500 1001-4094
spanning-tree instance 2 vlan 36-100 102-110 501-1000
Этот коммутатор будет рутом для instance 1:
spanning-tree instance 1 root primary
Общий приоритет коммутатора, точнее данного root bridge в spanning tree регионе:
spanning-tree priority 1

Настраиваем корневой HP2:
spanning-tree config-name "H2SO4"
spanning-tree config-revision 1
spanning-tree instance 1 vlan 1-35 101 111-500 1001-4094
spanning-tree instance 2 vlan 36-100 102-110 501-1000
Здесь все тоже самое, как и для HP1, но он root уже для instance 2, и приоритет этого root bridge в регионе пониже, т.е. 2
spanning-tree instance 2 root primary
spanning-tree priority 2

Настраиваем этажные коммутаторы HP Ax:
spanning-tree config-name "H2SO4"
spanning-tree config-revision 1
spanning-tree instance 1 vlan 1-35 101 111-500 1001-4094
spanning-tree instance 2 vlan 36-100 102-110 501-1000
Здесь конфиг должен быть идентичным, только не задаём никаких приоритетов, так как этажные нам не нужны во главе MSTP региона :)

Все, включаем spanning tree на всех коммутаторах:
spanning-tree enable

После ввода этой команды вы на какое-то время потеряете связь с коммутатором, пока просчитается топология Spanning Tree и все порты разблокируются. После этого можем подключать дополнительные линки и ждать их активации :)

   Все, настройка на HP ProCurve закончена, можно теперь посмотреть статистику в консоле коммутаторов :)

Итак, смотрим на HP1:
sh spanning-tree
Multiple Spanning Tree (MST) Information

  STP Enabled   : Yes
  Force Version : MSTP-operation
  IST Mapped VLANs : 1025-4094
  Switch MAC Address : 001871-b6a000
  Switch Priority    : 32768
  Max Age  : 20
  Max Hops : 20
  Forward Delay : 15

  Topology Change Count  : 9
  Time Since Last Change : 87 secs

  CST Root MAC Address : 001871-b6a000
  CST Root Priority    : 32768
  CST Root Path Cost   : 0
  CST Root Port        : This switch is root

  IST Regional Root MAC Address : 001871-b6a000
  IST Regional Root Priority    : 32768
  IST Regional Root Path Cost   : 0
  IST Remaining Hops            : 20

HP1, как и предписано ему, стал главным в MSTP регионе.

 sh spanning-tree instance 1

  E1    10GbE-SR   2000      128      Designated Forwarding   001b3f-c1a800
  E2    10GbE-SR   2000      128      Designated Forwarding   001b3f-c1a800
  E3    10GbE-SR   2000      128      Designated Forwarding   001b3f-c1a800
  E4               Auto      128      Disabled   Disabled
  F1    10GbE-SR   2000      128      Designated Forwarding   001b3f-c1a800
  F2    10GbE-SR   2000      128      Designated Forwarding   001b3f-c1a800
  F3               Auto      128      Disabled   Disabled
  F4               Auto      128      Disabled   Disabled

sh spanning-tree instance 2

  E1    10GbE-SR   2000      128      Alternate  Blocking     001b3f-582100
  E2    10GbE-SR   2000      128      Alternate  Blocking     001b3f-57c800
  E3    10GbE-SR   2000      128      Alternate  Blocking     0019bb-11ac00
  E4               Auto      128      Disabled   Disabled
  F1    10GbE-SR   2000      128      Alternate  Blocking     0019bb-0e2b00
  F2    10GbE-SR   2000      128      Root       Forwarding   001871-b6a000
  F3               Auto      128      Disabled   Disabled
  F4               Auto      128      Disabled   Disabled

В instance 2 все пути к этажным коммутаторам помечены альтернативными и закрыты.

Смотрим на этажный HP Ax:

sh spanning-tree ins 1

 L1    10GbE-SR   2000      128      Root       Forwarding   001b3f-c1a800
 L2    10GbE-SR   2000      128      Alternate  Blocking     001871-b6a000

sh spanning-tree ins 2

  L1    10GbE-SR   2000      128      Designated Forwarding   001b3f-582100
  L2    10GbE-SR   2000      128      Root       Forwarding   001871-b6a000

Получается, что instance 2 заблокирован со стороны коммутатора HP1 и приходит на этажные коммутаторы с HP2, а сами этажные коммутаторы заблокировали instance 1 в сторону HP2, и получают его с HP1. Нагрузка распределилась по двум линкам, чего собственно мы и добивались ;) Между HP1 и HP2 ходят оба instances, налицо нехватка второго линка между HP1 и HP2 :)

Посмотрим на схему. Синим цветом instance 1, а красным instance 2:

















     Ну чтож, MSTP между HP мы подняли, в следующий раз будем пытаться подружить эту схему с Cisco :)

Wednesday, December 16, 2015

Broadcast storm или как победить "мелких поганцев" в сети. UPD. Часть 2 Часть 1


     Итак, продолжаем бороться со штормом. Сегодня поделюсь опытом использования специализированной loop-защиты на Cisco и HP ProCurve.
     Все усилия при использовании broadcast-limit на HP и storm-control на Cisco не прошли даром, ситуация в сети становится намного лучше чем без использования этих технологий, но до конца не нормализуется. На Cisco и HP есть специализированные средства борьбы с петлями, которые помогают противостоять в том числе петлям на "неуправляемом" оборудовании.

     HP ProCurve.

     На HP эта функция зовётся loop-protect, и работает по простой и надёжной технологии: в порт посылается broadcast пакет, и если он вернулся, то значит на порту петля. Современные коммутаторы отправляя broadcast пакет "во все порты" исключают из списка порт с которого получили пакет, по этому вернуться назад при "здоровой" топологии сети он не может. Такая простота протокола тем не менее позволяет безошибочно обнаруживать и блокировать петли даже, если к порту подключена целая гирлянда из неуправляемых коммутаторов.
Настраивается это чрезвычайно просто:
loop-protect A1-A24,B1-B24
A1-A24,B1-B24 - диапазон портов, на который применить настройки. Так же у этой функции есть дополнительные параметры, описывающие, что делать, если обнаружена петля:
... receiver-action send-disable - просто заблокировать порт и все,
... receiver-action send-recv-dis - заблокировать и попытаться восстановить через какое-то время.
Пример: "loop-protect A1-A24,B1-B24 receiver-action send-disable" - блокировать порты в случае обнаружения петли, и автоматически не восстанавливать. Может автоматически восстанавливать и не нужно, на самом деле, потому что петля сама скорее всего не исчезнет. Надо идти, искать ее и устранять, а потом уже поднять порт руками: int A17 enable
     Так же можно задать глобально параметры для loop-protect, определяющие таймеры и т.п:

loop-protect disable-timer - через сколько пытаться восстановить линк, после блокировки,
loop-protect mode port / vlan - режим работы, с портами или вланами,
loop-protect transmit-interval 1-10 - через сколько секунд повторять посылки пакетов для обнаружения петель, в порт,
trap, vlan и PORT-LIST - наверное понятно и без пояснений :)

     Собственно сегодня тестировал эту технологию - работает превосходно! HP почти сразу блокирует порт с D-Link'ом так, что сеть даже тряхнуть не успевает:



     Cisco.

     Spanning-tree loopguard - это нам вообще не поможет, так как эта технология основана на "потере связи по BPDU", т.е. она для межкоммутаторных линков, и от петель на неуправляемом оборудовании она никак не может помочь.

     UDLD:
Включается либо глобально для всех интерфейсов:
   conf t
      udld enable

Либо выборочно на интерфейсах:
   conf t
      interface GigabitEthernet0/1
         udld port enable

     По первому, второму и прочим впечатлениям - это работает, только интервал там 15 секунд, а не 5, как у HP, и никак не настраивается, потому сеть немного успевает тряхнуть перед блокировкой. Также у UDLD есть два режима работы: normal (просто enable) и aggressive, но в мелкой задаче блокировки петель aggressive mode нам не нужен, так что не будем в него углубляться :)

     Еще могу добавить, что на клиентских access портах Cisco неплохо бы включать BPDU Guard. BPDU Guard заблокирует порт, если вдруг поймает там BPDU, например в случае какой-либо незамысловатой петли. В общем это уже тонкости настройки STP, в какой-нибудь из следующих статей я это разберу. И BPDU Guard, и BPDU Filter и еще много чего можно разобрать :)

     Для тестов использовал HP ProCurve 5412zl и cisco 2960G. В качестве неуправляемого "мелкого поганца" использовал 8-портовый неуправляемый D-Link с петлей в его портах.

Tuesday, December 15, 2015

UnixDaemonReloader - перезапуск демонов при модификации конфигов.
(Update 2016.01.03)



     Серия "мои поделки" или "и снова изобретаем велосипед" продолжается ;)
     Занялся я в последнее время кластеризацией всевозможных сервисов. Таких как почта, прокси, VoIP и т.п. Ну чтоб и баланс нагрузки, и отказоустойчивость, ну и для опыта полезно что-то новое делать и изучать. Предприятию опять же польза :) И встала у меня задача, не только синхронизировать конфиги определённых сервисов на разных хостах, но и как-то реагировать не эти изменения... Ну допустим на мастер хосте изменили конфиг postfix, он отреплицировался на вторую ноду кластера, и что дальше ? Надо как-то передёрнуть postfix, вернее сказать ему reload. И так, и сяк я пробовал, и в скрипт синхронизации многострочные конструкции встраивал, которые определяли наличие изменений и делали разные действия, перезагружали и заставляли перечитывать конфиги разные сервисы. В общем было название этому: геморрой. Встал я как-то утром, покачал спину, и решил сделать программу которая будет сама висеть демоном, перечитывать свой конфиг перед каждым циклом работы и выполнять действия которые ей предписаны в случае изменения заданных файлов. Сказано - сделано! И название я этому сервису дал - UnixDaemonReloader :)

Конфигурацияонный файл:













     Собственно конфиг вполне простой. Описываем где у нас живёт шелл и с каким ключом он может выполнять внешние команды в таком виде: /bin/sh -c "ps ax" , затем в виде списка задаем строки с отслеживаемыми файлами и каталогами:

["/каталог", "файл", "действие", "предварительное действие", "результат предварительного действия","скрипт ошибки предварительного действия"],

["/каталог", "маска*файла*", "действие", "", "",""],
["/каталог", "!все*файлы*кроме*этого,!кроме*этого,!и*кроме*этого", "действие"]

Обновление от 2016.01.03: 
     Добавлены параметры "скрипт предварительной проверки", "результат удачной проверки" и "скрипт в случае ошибки проверки" в список файлов для отслеживания в кофигурационном файле. Скрипт предварительной проверки должен возвращать результат проверки на стандартный вывод. Например: "OK". Если Возвращенное текстовое значение равно тому что в конфиге - выполняется скрипт перезапуска, иначе после окончания попыток проверки исполнится скрипт ошибки. Смотри README.md для ознакомления с новым синтаксисом.
     PS: Вы можете добавить в скрипт предварительной проверки например проверку конфига на правильность или бекап конфига. В скрипт ошибки тоже можно добавить отправку E-Mail, SMS или возврат копии конфига из бэкапа.
     Добавлен параметр UDR_ScriptsPath, указывающий путь к предварительным скриптам.
     Добавлен параметр UDR_PreAppAttempt, указывающий количество попыток исполнения скрипта предварительной проверки, поселе чего исполняется скрипт обработки ошибки или попытки прекращаются.
     Исправлен тотальный перезапуск всего и вся после первого создания базы файлов.
Обновление от 2015.12.23: 
UDR_PauseBefore - пауза в секундах перед запуском скрипта. Этот параметр сделан для того, что бы если вы вдруг случайно во время редактирования конфига сохранили файл "недоделанным", то у вас было время на исправление ошибки до перезапуска демона.
UDR_ScriptsPath - путь до папки со скриптами предварительной проверки.
UDR_PreAppAttempt - количество попыток исполнения файла проверки конфигурации
UDR_PauseBefore - пауза в секундах перед запуском скрипта. Этот параметр сделан для того, что бы если вы вдруг случайно во время редактирования конфига сохранили файл "недоделанным", то у вас было время на исправление ошибки до перезапуска демона.
Sleep_Time - сколько спать между циклами проверки конфигов,
SQLite_DB - путь к базе SQLite, в которой хранятся контрольные суммы файлов.

     Действия могут быть разными, не обязательно restart, reload или "kill -HUP", можно например вызвать мейлер и отправить сообщение, что дескать, файл изменили :)
     Применять, опять же, можно не только на кластерах, но и на обычных серверах, чтоб не перестартовывать сервисы руками :)

     Программа написана на Go, т.е. собрать из исходников можно под что угодно, linux, bsd, mac,  да хоть под Android.

     Исходники:
          UnixDaemonReloader Source Code

     Скомпилированные версии для FreeBSD и Linux:
          UnixDaemonReloader on SourceForge
          UnixDaemonReloader on My Google Drive

Wednesday, December 9, 2015

Broadcast storm или как победить "мелких поганцев" в сети. Часть 1 Часть 2


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

     Итак, как работает коммутатор когда все хорошо: коммутатор строит таблицы mac-адресов где каждому адресу соответствует порт, и необходимый клиенту трафик идёт уже ни как в старых хабах во все порты, а в конкретный порт в соответствии с mac-таблицей. До того, как коммутатор узнал порт, на котором живёт клиент, первая посылка идёт обычно во все порты, после чего от клиента приходит ответ и он попадает в mac-таблицу и только тогда с ним начинают работать по конкретному порту.
     Но вдруг в вашей сети по вине невнимательного сотрудника возникает петля, или происходит атака или случается какая-нибудь замысловатая неисправность оборудования, и все становится плохо... Коммутатор посылает пакет, но вместо ответа пакет возвращается назад в нескольких экземплярах с нескольких портов, и коммутатор не зная на каком порту точно живёт нужный ему mac, заботливо отправляет пакеты обратно во все порты и снова получает их умноженными и затем снова рассылает... Пакеты начинают многократно множиться, рост трафика в сети становится лавинообразным, забиваются все линки, отваливаются транки, проседают процессоры сетевого оборудования, в результате проседания процессоров разваливается SpanningTree протокол, до того момента пытавшийся блокировать все подряд, и тогда лавина трафика обрушивается на смежные сегменты вашей сети и топит их. В итоге вашей сети больше нет...
     В такой ситуации вариантов действий не так много, ведь все уже рухнуло и мониторить и искать источник трафика просто негде, так как сети нет :) Одним из вариантов действий мне видится поочередное отключение сегментов, или наоборот отключение всех сегментов и поочередное их включение, дабы обнаружить, какой сегмент был источником хаоса. Потом уже более конкретно отключать или подключать линки в найденном сегменте, в общем все грустно и долго. Время простоя может быть просто ужасным, и потому надо заранее подготовиться к такому шторму, чтоб минимизировать вред от него!

     Для начала, конечно, стоит избавиться от привычки отключать SpanningTree на оборудовании, если у вас такая привычка есть, и возможно поднастроить этот протокол в соответствии с топологией своей сети. По большому счету если вы не знаете , что там настраивать и сеть у вас небольшая, то он и по-умолчанию будет работать, и более того, почти никакие петли вашу сеть не парализуют. Почему "почти" ? Да потому, что парализуют петли, которые будут на оборудовании с включенным SpanningTree... Но у вас ведь может оказаться и не только такое оборудование :)

     Казалось бы, что может перегрузить или вообще положить такую вот сеть:

     10 гигабит между коммутаторами, гигабит каждому конечному пользователю + настроенный SpanningTree протокол, вернее даже MSTP. Так вот, ни дубль-линк между коммутаторами эту сеть не убьёт, ни кольцо на коммутаторе ядра, потому что MSTP все лишнее заблокирует. Более того, все коммутаторы тут соединены не единственными линками для повышения отказоустойчивости, и вся эта связка успешно работает благодаря MSTP. Варианты атак и неисправностей рассматривать не будем, а рассмотрим вариант, если в вашей сети есть "тупой" свитч... типа неуправляемого длинка... и петлю сделали на нём... Тут и STP, и MSTP окажутся бессильны :) Ваша сеть ляжет от этого "мелкого поганца" в считанные минуты, или вернее даже десятки секунд !:)
     Как мне кажется, защититься от неуправляемого оборудования на 100% можно лишь одним способом - запретив его к использованию в своей сети. Но если запретить и выкинуть вы не можете по каким-то причинам, например в вашей сети есть арендаторы с неподконтрольными вам сегментами, то вам следует заняться настройкой оборудования на предмет борьбы со штормом.
     Итак, STP от неуправляемого оборудования не спасает, даже наоборот, BPDU пакеты тоже размножаются со всех сторон и STP начинает хаотично блокировать и разблокировать порты с частотой раз в 2-3 секунды. Количество mac-адресов на портах особо не ограничить, ведь там свитчи, и маков может быть много и в нормальном состоянии, но зато можно ограничить броадкаст, а уж до кучи и мультикаст трафик!
     Есть на современных коммутаторах такие средства, как storm-control, broadcast limit и еще наверное какие-то варианты этой же самой методики на оборудовании разных производителей.
     Настройка broadcast-limit 10% на HP и storm-control broadcast level 10% на cisco почти полностью, вернее процентов на 80% оставляют мою сеть живой при возникновении петель на "тупом" оборудовании. Единственное, что пока меня беспокоит, что STP продолжает дурить. Все равно порты блокируются не те, что надо, и шторм с заблокированного порта продолжает штормить все равно, хоть и не сильно. Возможно, это происходит потому, что передача BPDU не блокируется при блокировке порта STP, и после блокировки инициатора шторма широковещательный шторм переходит в BPDU шторм.
     Вот пример:
     Петля на порту A5, он сразу заблокировался, и вслед за ним межкоммутаторный порт L2 тоже заблокировался. Это не парализует сеть, ведь есть дополнительные линки, но тем не менее не очень приятно, особенно если учесть, что заблокироваться вот так случайно может порт на котором важный сервер или еще что-то важное. Некоторые проблемы еще остались, но благодаря broadcast limit шторм режется почти полностью. Дело за тюнингом MSTP, но об этом в следующий раз :)

     Вот пример окошка с пингами, при включенной петле в длинк, раньше бы этих пингов вообще не было. Так что это первая победа на пути борьбы с флудом :)

Tuesday, December 8, 2015

Аутентификация в Active Directory через LDAP на Perl, php и python "своими руками"... :)


     Наверное, не только мне приходилось порой, решая задачу, приходить к неутешительному выводу, что то, что мне надо, еще никем не сделано так, как мне надо :) В такой ситуации есть три пути: плюнуть и заняться чем-нибудь другим, попытаться допилить чужое до состояния "годности" или сделать самому ;)
     Итак, лет 10 назад я уже 3 года как был сисадмином с программистскими наклонностями, и появилась у меня задача авторизовать пользователей squid-прокси в Active Directory. В общем, ничего лучше, чем ввести samba в домен и авторизовать пользователей при помощи самодельного perl скрипта через WinBind мне в голову не пришло. И в общем-то, эта связка работала безотказно на протяжении нескольких лет. Да, мой интернето-раздающий сервер был настроен на FreeBSD, а с обновлением ПО во FreeBSD тогда все было еще хуже чем сейчас... Обновлять только через portupgrade, т.е. сносить все, хоть вроде и на автомате, собирать все, половина повалится с ошибками совместимости библиотек и т.д. и т.п. в общем проще обновлять только ядро и мир, и переставлять систему раз в 5 лет. Конечно, ПО в портах FreeBSD изначально гораздо более свежее, чем в любом линуксе, но оно стремительно старело, и самба с винбиндом в том числе. Однажды настал момент, когда старый винбинд не смог авторизоваться на вновь установленном контроллере домена под управлением Windows 2008,  и тогда я понял, что от самбы с винбиндом надо уходить... :)
     Потратил я немного времени на поиски более правильного способа, и так как NTLM у нас внедрять не хотели по некоторым соображениям, я остановился на способе авторизации в AD через LDAP... Да, просто, кроссплатформенно, на любом языке программирования. Из заготовок я нашёл вот это: php.net ref.ldap.php почти то, что мне надо, только "не на том языке" ;) В итоге данный код на PHP я доработал, собрал проверку членства в группе в одну функцию, плюс встроил защиту от бесконечного цикла если группы вдруг входят друг в друга "по кругу", ну и переписал на нужные мне языки: perl и python, а недавно и на Go...

     Скрипты состоят всего из трех функций:
  1. Собственно бинд к LDAP серверу с логином и паролем авторизующегося юзера. На основе удачности или неудачности этого шага делается вывод о прохождении авторизации или её провале. Данная функция у меня оформлена как функция только в Perl скрипте, в остальных это "main" :) Если авторизация успешна, то смотрим, надо ли искать юзера в группе. Если не надо, то возвращаем "true", а если надо, идём в пункт (2).
  2. Поиск DN для юзера и для группы.
  3. Собственно, проверка на вхождения юзера в группу. Если входит - "Успех",а если нет - "уж извините" :)   
     Это не библиотеки, а примеры кода. Авось кому-то они помогут, хотя и написаны уже очень давно ;)

Follow to GitHub repository: Authentication in Active Directory over LDAP. Sample code on PHP, Perl and Python.

     Заметка про авторизацию на Go будет в скоро будущем, но не в чистом виде, а в виде хелпера для Squid, который может авторизоваться в нескольких доменах сразу :)