Всем привет! Меня зовут Владимир и я тимлид команды по развитию и поддержке продуктов DDoS-Guard, таких как: хостинг, VDS и выделенные серверы. Сегодня я продолжу тему алкоголика инженера @analog_cat про горение, автоматизацию и не только. Расставлю все точки в сетевом вопросе и различных кейсах автоматизации сети для VDS. В этот раз я сосредоточусь на задачах сетевой маршрутизации, которые удалось решить в процессе работы.
Краткое содержание первой части
В прошлой статье мы рассказывали, что ради улучшения клиентского опыта и минимизации человеческого фактора в процессе заказа и развертывания VDS, мы решили все автоматизировать и выбрали для этого гипервизор от VMware. Этот нативный софт оказался проще в конфигурировании со стороны инженера и первичной настройки для пользователя. Выдержать баланс между удобством и безопасностью без приключений не получилось, и сегодня я расскажу о них подробнее.
Какие задачи перед нами стояли
В рамках «сетевой» части задачи нам было нужно изолировать VDS друг от друга, настроить для них шейпинг трафика, обеспечить автоматическое конфигурирование дополнительных адресов и их маршрутизацию.
Шейпинг – одна из двух возможностей ограничения скорости наряду с полисингом. При шейпинге скорость искусственно ограничивается путем буферизации лишнего трафика. Весь приходящий трафик проходит через буфер, и как раз из него шейпер с постоянной скоростью изымает пакеты. После такой фильтрации на выходе получается всегда одинаковая скорость.
Почему выбрали то, что выбрали
Другие варианты, включая Fortinet и аналогичные отечественные решения, были отклонены из-за логистических и технических причин. В результате мы приняли решение использовать нативное решение на уровне гипервизора VMware ESXi.
Изначально у нас был единственный узел подключения (edge), через который весь трафик виртуальных сетей (VDS) направлялся во внешнюю сеть интернета. Правила ограничения скорости и другие политики могли быть применены только к этому узлу.
Чтобы дать возможность отдельным пользователям устанавливать или изменять правила и политики, мы добавили несколько маршрутизаторов второго уровня (T1). Они были настроены через один основной маршрутизатор первого уровня (T0). Теперь на каждом T1 могли быть установлены индивидуальные правила ограничения скорости и необходимые политики.
Далее процесс выглядит следующим образом: создается сеть, назначается ей IP-адрес и указывается, через какой именно T1 должен проходить трафик.
Сначала схема выглядела так:
Интернет – T0 – VDS
Потом она стала выглядеть так:
Интернет – T0 – N T1 – VDS
Что обнаружилось в процессе
Мы столкнулись с ситуацией, когда у пользователя VDS есть две сети, использующие префикс /31. Как они будут маршрутизироваться?
В рамках выбранного сценария с VMware возникает особенность в том случае, когда на одной виртуальной машине оказывается больше одного IP-адреса. Дело в том, что VMware работает по принципу — на одной виртуальной машине 1 IP-адрес = 1 сетевой интерфейс.
Если на VDS требуется дополнительный IP-адрес, то необходимо к виртуальной машине добавлять еще один интерфейс и на этом интерфейсе указывать дополнительный IP-адрес. Просто так добавить интерфейс с IP-адресом нельзя, так как на виртуальной машине есть только один маршрут по умолчанию, а VMware не позволяет пропускать трафик с некорректным source IP-адресом на сетевом интерфейсе. Что же делать? Как быть?
В одном из мозговых штурмов была поднята тема с именованными таблицами маршрутизации (routing tables), которая активно используется в операционных системах на базе ядра Linux. Мы автоматизировали генерацию таблиц маршрутизации при наличии более одного сетевого интерфейса. Первичный тест показал, что подобная схема работы сети хорошо и красиво функционирует в нашем случае.
Как работают routing tables
Такая таблица состоит из сетевых маршрутов. При отправке сетевого пакета ОС «сверяется» с routing table и определяет, по какому именно маршруту ему будет наиболее оптимально передать.
Каждая запись в таблице маршрутизации состоит, как правило, из полей:
— адрес сети назначения (destination);
— маска сети назначения (netmask);
— адрес шлюза (gateway), кроме случаев описания маршрута в прямо соединенную сеть, в этом случае указывается 0.0.0.0;
— метрика маршрута (не всегда).
В экосистеме Linux это выглядит так: весь трафик, который приходит на конкретный интерфейс, маркируется, и дальше обрабатывается на основе маркировок для корректной маршрутизации трафика. Эту особенность нам пришлось хорошо изучить и проработать.
Технические детали про routing tables
Таблицы маршрутизации содержатся в мастер-таблице, она же Master Routing Table (MRT). Мастер-таблица — это файл, который содержит упорядоченный список до 256 целочисленных и именных ассоциаций. Каждая строка в файле представляет собой комбинацию числового и именованного значений, индексированных для определенной таблицы маршрутизации. Это часть системы Linux' Routing Policy DataBase (RPDB). Как упоминалось ранее, порядок обработки таблиц в списке зависит от правил маршрутизации RPDB. Основная таблица маршрутизации всегда имеет одно и то же имя файла и всегда находится в одном и том же месте: /etc/iproute2/rt_tables
Мастер-таблица содержит список всех таблиц маршрутизации на вашем сервере. В немодифицированной системе в список по умолчанию входят следующие таблицы:
Новые таблицы маршрутизации в RPDB создаются простым добавлением строки в файл rt_tables. Все, что требуется — это уникальные индекс и имя таблицы.
Когда вы создаете новую таблицу маршрутизации, вы также должны создать как минимум одно corresponding rule, указывающее на нее. Маршруты в таблице необходимо сконфигурировать для обработки любых возможных результатов.
Итого вам нужно:
добавить новую запись в основную таблицу маршрутизации;
заполнить новую таблицу маршрутизации;
создать хотя бы одно правило, указывающее на новую таблицу.
На что обратить внимание при добавлении новых таблиц маршрутизации в Мастер-таблицу:
имя и номер таблицы уникальны
значения в файле выставлены по умолчанию
новые ссылки на таблицы пронумерованы от 100 до 200
таблица «по умолчанию» на самом деле называется main
Таблицы маршрутизации имеют очень простую структуру команд. Добавить новые маршруты в существующие таблицы можно так:
ip route add {[destination ip/mask] [default]} {via [ip/mask]} {dev} [device] {table} [table ID] src [source ip]
В конечном итоге мы разработали скрипт, который анализирует число физических интерфейсов, соединенных с виртуальной системой. Если таких интерфейсов больше одного, скрипт автоматически создает таблицы маршрутизации, называемые по именам этих интерфейсов.
По такой схеме все успешно работает с одной небольшой оговоркой. При использовании именованных таблиц маршрутизации есть неопределенность, через какой из адресов будет идти исходящий трафик, если инициировать трафик с VDS на VMWare. Мы решили эту проблему использованием основного IP-адреса для подобных случаев.
Что у нас получилось
Наш подход к решению задачи в области сетевой инфраструктуры принес заметные результаты, которыми мы гордимся:
Автоматизация настройки маршрутизации: мы разработали скрипт, который интеллектуально анализирует количество физических интерфейсов, связанных с виртуальной системой. В случае наличия нескольких интерфейсов, скрипт автоматически создает соответствующие таблицы маршрутизации, что упрощает процесс конфигурации.
Стабильность и универсальность решения: наше решение основано на стандартных технологиях VMware, что обеспечивает надежную работу системы и ее гибкую адаптацию к различным сценариям использования.
Повышение производительности и удобства пользователей: мы успешно настроили шейпинг трафика, обеспечивая пользователям более высокую скорость получения VDS без ошибок в конфигурации. Процесс полностью автоматизирован, что сокращает время настройки и снижает вероятность возникновения проблем.
Новые технологические возможности: для эффективного управления сетевыми ресурсами и повышения производительности виртуальных инфраструктур.