На неделе закончил переконфигурирование сервера и некоторого сетевого оборудования. По сути, смена сетевого коммутатора в локальной сети офиса подвигла меня на написание данного поста.
Исторически сложилось так, что мой интернет-сервер с firewall, nat и lartc(Linux Advanced Routing & Traffic Control) работает с несколькими интернет-провайдерами. У сервера есть пара сетевых интерфейсов и пара USB - разъёмов. Поскольку выходов в интернет несколько, а количество разъёмов для подключения ограничено, приходилось использовать USB - hub. При этом интернет -кабели подключались к данному хабу через usb-ethernet конвертеры. Один USB-интерфейс используется для подключения gsm-модема через переходник USB-COM, второй - для подключения упомянутого USB-хаба. Свободный com-порт нужен для управления и опроса серверного UPS-а.
Стандарт USB всё-таки плохо приспособлен для работы с серверным оборудованием. Да, он неплох для постоянного подключения мышек, клавиатур, для временного подключения внешних устройств, а также другой hot-swap периферии на рабочей станции. Тем не менее лучше его избегать, когда требуется высокая надёжность работы подключаемого оборудования. USB хост (речь идёт о USB 2.0) использует опрос всех подключенных устройств(поллинг), при этом, даже если у конечной точки есть что передавать, она ожидает своей очереди, здесь нет механизма прерываний. В стандарте USB 3.0 устройство может уведомить хост о готовности передавать данные, что позволяет снизить нагрузку на систему хоста, а также уменьшить задержки при передаче данных. Впрочем, USB 3.0 у всех на слуху, однако его поддержка в конечных устройствах только начала появляться, к тому же новый стандарт вынужден включать в себя все недостатки прежних версий для совместимости.
Впрочем, это не научное описание работы USB-протокола, для меня всё-таки важен практический подход и я пишу всё это, может быть, для того, чтоб упорядочить собственные мысли и зафиксировать некоторые вопросы и ответы.
При подключении нового устройства к USB интерфейсу начинается процесс перечисления или описи (the USB device enumeration process) всех логических под-устройств, называемых функциями (device functions). Как пример, можно упомянуть видеокамеру с микрофоном: подключается как единое устройство к USB-коннектору, при этом система видит два логических устройства. Из теории известно, что процесс перечисления начинается посылкой сигнала reset устройству, после чего определяется возможная скорость передачи данных, все логические устройства получают 7-битные адреса. Далее определяется наличие драйверов для поддержки подкюченного устройства. А здесь процесс udev, работающий почти в каждой linux-системе, создаёт устройство (например, /dev/ttyUSB0), после чего уже можно работать с устройством. При рестарте USB - хоста заново начинается перечисление всех логических устройств. Поскольку в моём случае к USB - хосту непосредственно подключен USB-hub, поскольку имеющихся двух USB-интерфейсов недостаточно, процесс работы всего USB-хозяйства ещё усложняется. Я не раз наблюдал с помощью команды 'udevadm monitor', как отключение или подключение USB-шнурка к USB-хабу приводило к удалению и повторному добавлению всех USB-устройств в системе. При чём это происходило не всегда: иногда всего лишь одно устройство добавлялось(удалялось) в систему.
Так или иначе удаление сетевого интерфейса в системе приводило к удалению правил маршрутизации, касающихся данного интерфейса. Всё бы хорошо, если бы у меня использовался один провайдер и один адрес маршрутизатора по-умолчанию. У меня их несколько, правил маршрутизации много. Поэтому используется iproute2(реализация упомянутого lartc). Какое-то время я пытался вносить изменения в таблицу маршрутизации с помощью стандартных скриптов Gentoo, однако пришёл к выводу, что проще написать свой скрипт. Чтоб мой скрипт автоматически запускался при добавлении нового сетевого интерфейса, я добавил правило для udev:
KERNEL=="eth*", SUBSYSTEM=="net", ACTION=="add", RUN+="/path_to_script/route_rules.sh %k"
В скрипте проверяется наличие тех или иных правил и таблиц маршрутизации: если чего-то не хватает, или правило пропало при удалении/добавлении USB-устройства во время перечисления, это правило вновь добавляется. Поскольку при старте системы и при процессе перечисления USB-устройств скрипт запускается практически одновременно для каждого сетевого интерфейса, некоторые правила могут добавляться по нескольку раз - возникает ситуация гонок. Проблема гонок решается путём обработки блокировок в файловой системе сервера. Подробнее работу скрипта и особенности маршрутизации lartc я здесь описывать не буду, может быть, напишу другой пост. Сейчас я лишь обрисовал, какие проблемы существуют при работе с USB-устройствами и интернетом.
Не было бы счастья, да несчастье помогло: в локальной сети начал помирать основной сетевой коммутатор, на его замену приобрели Allied Telesys AT-GS950/24. Коммутатор имеет возможность работать с vlan-ми, поэтому я заранее решил для одной из внутренних подсетей создать отдельный vlan. При этом появилось возможность избавиться от старого коммутатора на 8 портов, который и поддерживал работу этой подсети.
Первоначально я планировал использование vlan-ов только для работы с локальной сетью, однако аппетит приходит во время еды. Я подумал: "а почему бы не избавиться от всех этих USB-ethernet конвертеров, так осложняющих мою жизнь?".
AT-GS950 поддерживает два типа vlan-ов: 'Port-based VLANs'(основанные на портах) и 'Tagged VLANs'(с поддержкой тэгирования). Хотя 'Port-based VLANs' позволяют определённому порту быть членом нескольких vlan-ов, информация передаваемая через него, была бы доступна во всех этих vlan-ах, а нам нужно vlan-ы изолировать друг от друга. Таким образом, в случае с 'Port-based VLANs' для маршрутизации между vlan-ми пришлось бы затратить по порту коммутатора и сетевому интерфейсу сервера на каждый vlan. Поэтому, чтобы иметь возможность маршрутизации между отдельными vlan-ми, используя только один порт коммутатора AT, нам нужен второй тип - 'Tagged VLANs'. Поддержка тэгируемых vlan-ов в linux давно отлажена, для неё необходимо пересобрать ядро, необходимый пункт находится здесь:
[*] Networking support --->
Networking options --->
<*> 802.1Q VLAN Support
Для добавления/удаления vlan-ов используется команда vconfig. В Gentoo для автоматического добавления новых интерфейсов в файл конфигурации сети /etc/conf.d/net нужно добавить(изменить) несколько строк:
config_eth0=( "null" )
vlans_eth0="1 2 3 4"
vconfig_eth0=( "set_name_type VLAN_PLUS_VID_NO_PAD" )
config_vlan1=( "192.168.0.1/24" )
config_vlan2=( "192.168.1.1/24" )
и т.д.
Здесь третья строка говорит о том, что названия сетевых интерфейсов в системе будут иметь имена vlan1, vlan2 и т.д., всего в примере создаётся 4 vlan-а. Теперь для поддержки vlan-ов(а точнее, протокола 802.1Q) сетевым интерфейсом сервера достаточно выполнить команду:
/etc/init.d/net.eth0 restart
В результате чего создаются необходимые нам новые интерфейсы. Теперь осталось настроить коммутатор и подключить кабели к настроенным портам. По-умолчанию, все порты являются нетэгируемыми, и все входят в vlan1. При добавлении нового vlan-а указываем, что нужный порт больше не является членом vlan1. Тот порт, к которому подключен сервер, нужно включить во все созданные vlan-ы и назначить его в каждом таком vlan-е тэгируемым. На рисунке это 14-й порт. Всего я создаю 4 vlan-а: один для локальной сети, второй для другой локальной подсетки, третий и четвёртый для интернет-соединений. При создании vlan-а для интернета достаточно двух портов: тэгируемого - для серверного порта, нетэгируемого - для порта с интернет-кабелем.
Теперь нужно открыть вкладку "Default Port VLAN & CoS" и для каждого нетэгируемого порта, который мы сделали членом нового vlan-а, нужно прописать PVID(Port VLAN Identifier), который равен номеру соответствующего vlan-а. Тэгируемый порт у меня один, для него ничего менять здесь не нужно. Сначала я пропускал этот пункт и не мог понять, что не работало. Суть здесь в том, что большинство сетевых устройств, подключаемых к коммутатору, ничего о тэгах(и о поддержке 802.1Q) не знают. Чтоб принятый от этого устройства кадр данных попал только в нужный vlan, этому кадру автоматически добавляется тэг, равный значению PVID данного порта. При передаче кадра данных из vlan-а устройству, происходит обратный процесс: тэг из кадра изымается, сетевое устройство остаётся в счастливом неведении о vlan-ах и тэгах (ignorance is bliss!).
Поскольку названия сетевых интерфейсов в системе изменились, нужно внести изменения в firewall и в правила маршрутизации. Для этого пишем:
vi /var/lib/iptables/rules-save
И выполняем команду замены:
:%s/eth2/vlan1/gc
Здесь мы поменяли названия eth2 на vlan1, для остальных интерфейсов повторяем команду, меняя их названия. После сохранения файла внесёные изменения можно воплотить в жизнь командой:
iptables-restore -c < /var/lib/iptables/rules-save
Точно также редактируем скрипт работы с таблицей маршрутизации и выполняем замену для каждого нового интерфейса vlan-а:
vi /path_to_script/route_rules.sh
:%s/eth2/vlan1/gc
Теперь я избавил сервер от USB-устройств. UPS переключил на другой сервер, gsm-модем подключил к освободившемуся com-порту. Один сетевой интерфейс теперь подключен к гигабитному порту коммутатора, и через него осуществляется маршрутизация между 4-мя vlan-ми. Второй сетевой интерфейс я оставил для подключения одного из интернет провайдеров - самого скоростного: если есть свободный интерфейс, то почему бы его не задействовать?! Изначально я раздумывал, не будет ли гигабитный линк при работе со множеством vlan-ов вносить задержки при передаче данных. Я даже сравнил длительность пингов до и после создания vlan-ов. Оказалось, что ситуация с пингами даже немного улучшилась, видимо задержки, вносимые интерфейсами и конвертерами USB, были больше. Нужно ли сейчас отслеживать ситуацию с гонками, пока не понятно, время покажет. Пока полёт нормальный. Так выглядит куча ненужного теперь оборудования.
У меня есть проблема с данным коммутатором - не могу открыть web-мордочку, по консольному порту захожу.
ОтветитьУдалитьНа сколько я помню, по консольному порту web-морду открыть не получится, там только текстовый режим отображения. Вначале надо с помощью minicom (или что-то другое, что есть в наличии) настроить порт и подключиться к свичу. Я это при первом подключении делал. А потом уже можно подключаться к web-морде с помощью браузера.
ОтветитьУдалить