Consul + iptables = :3

През 2010 г. компанията Wargaming имаше 50 сървъра и проста мрежова структура: бекенд, фронтенд и защитна стена. Броят на сървърите нарастваше, структурата се усложняваше: стейджинг, изолирани VLAN с ACL, след това VPN с VRF, VLAN с ACL на L2, VRF с ACL на L3. Завъртя ли ви се главата? По-нататък ще стане по-забавно.

Когато сървърите станаха 16 000, работата с такова количество хетерогенни сегменти стана невъзможна. Затова измислихме друго решение. Взехме стека Netfilter, добавихме Consul като източник на данни и получихме бърза разпределена защитна стена. Заменихме ACL на рутерите и я използвахме като външна и вътрешна защитна стена. За динамично управление на инструмента разработихме система BEFW, която приложихме навсякъде: от управление на достъпа на потребителите до изолиране на мрежовите сегменти един от друг.

Consul + iptables = :3

Как всичко това работи и защо трябва да обърнете внимание на тази система, ще разкаже Иван Агарков (annmuor) — ръководител на групата за инфраструктурна безопасност в подразделението Maintenance в Минския център за разработка на компанията. Иван е фен на SELinux, обича Perl и пише код. Като ръководител на групата по ИБ, редовно работи с логове, резервни копия и R&D, за да защитава Wargaming от хакери и да осигурява работата на всички игрови сървъри в компанията.

Пуснете видеото

Историческа справка

Преди да разкажа как го направихме, ще ви разкажа как стигнахме до това и защо стана необходимо. За това ще се пренесем 9 години назад: 2010 г., току-що се появили World of Tanks. Компанията Wargaming имаше около 50 сървъра.

Consul + iptables = :3
График на растежа на сървърите на компанията.

Имахме мрежова структура. За времето си тя беше оптимална.

Consul + iptables = :3
Мрежова структура от 2010 г.

На фронтенда живеят лошите, които искат да ни счупят, но там има защитна стена. На бекенда няма защитна стена, но там има 50 сървъра, всички ги познаваме. Всичко работи добре.

През 4 години паркът от сървъри нарасна 100 пъти, до 5000. Появиха се първите изолирани мрежи — стейджинги: те не могат да влизат в продукция, а там често се въртеше нещо, което можеше да е опасно.

Consul + iptables = :3
Мрежова структура от 2014 г.

По инерция използвахме същите устройства, и цялата работа се извършваше на изолирани VLAN: към VLAN се пишат ACL, които разрешават или забраняват определена връзка.

През 2016 година броят на сървърите достигна 8000. Wargaming придоби други студия, появиха се нови партньорски мрежи. Те изглежда са наши, но не съвсем: за партньорите VLAN често не работи, е принуден да се използва VPN с VRF, изолацията става по-сложна. Смес от изолации ACL нараства.

Consul + iptables = :3
Мрежов модел през 2016.

До началото на 2018 година броят на машините нарасна до 16 000. Сегментите бяха 6, а останалите не ги броихме, включително затворените, в които се съхраняваха финансови данни. Появиха се контейнерни мрежи (Kubernetes), DevOps, облачни мрежи, свързани чрез VPN, например от ИВС. Правилата бяха твърде много — беше болезнено.

Consul + iptables = :3
Мрежов модел и методи за изолация през 2018.

За изолация използвахме: VLAN с ACL на L2, VRF с ACL на L3, VPN и много други. Прекалено много.

Проблеми

Всички работят с ACL и VLAN. Какво не е наред? На този въпрос ще отговори Гаролд, който скрива болката си.

Consul + iptables = :3

Имаше много проблеми, но масови — пет.

  • Геометричен растеж на цената за нови правила. Всяко ново правило се добавяше по-дълго от предишното, защото първо трябваше да се провери дали вече има такова правило.
  • Няма файрвол вътре в сегментите. Сегментите бяха отделени един от друг, вътре вече нямаше достатъчно ресурси.
  • Правилата се прилагаха дълго. Ръчно едно локално правило операторите можеха да напишат за час. Глобалното отнемаше няколко дни.
  • Трудности с одита на правилата. По-точно, той беше невъзможен. Първите правила бяха написани още през 2010 година, а голяма част от техните автори вече не работиха в компанията.
  • Ниско ниво на контрол над инфраструктурата. Това е основният проблем — не знаехме какво всъщност се случва при нас.

Така изглеждаше мрежовият инженер през 2018 година, когато чу: „Трябва още малко ACL“.

Consul + iptables = :3

Решения

В началото на 2018 година беше решено да се направи нещо по въпроса.

Цената на интеграциите непрекъснато расте. Отправната точка беше, че големите дата центрове престанаха да поддържат изолирани VLAN и ACL, защото свърши паметта на устройствата.

Решение: премахна се човешкият фактор и максимално се автоматизира предоставянето на достъп.

Новите правила се прилагат дълго. Решение: да се ускори прилагането на правилата, да бъде разпределено и паралелно. За това е нужна разпределена система, за да могат правилата да се доставят сами, без rsync или SFTP на хиляда системи.

Отсъствие на файрвол вътре в сегментите. Пожарната стена в сегментите започна да ни идва, когато в рамките на една и съща мрежа се появяваха различни услуги. Решение: използване на пожарна стена на ниво хост — host-based firewalls. Практически навсякъде имаме Linux, и навсякъде има iptables, това не е проблем.

Трудности с аудитите на правилата. Решение: да съхраняваме всички правила на едно място за преглед и управление, така ще можем да извършваме всички аудити.

Ниско ниво на контрол над инфраструктурата. Решение: да проведем инвентаризация на всички услуги и достъпи между тях.

Това е повече административен процес, отколкото технически. Понякога имаме 200-300 нови версии седмично, особено по време на промоции и празници. Въпреки това, това е само за един от нашите DevOps екипи. С толкова много версии е невъзможно да разберем какви порти, IP, интеграции са нужни. Затова ни бяха необходими специално обучени сервисни мениджъри, които да питат екипите: „Какво всъщност имате и защо го повдигнахте?“

След всичко, което пуснахме, мрежовият инженер през 2019 година започна да изглежда така.

Consul + iptables = :3

Consul

Решихме, че всичко, което намерихме с помощта на сервисните мениджъри, ще поставим в Consul и оттам ще пишем правилата на iptables.

Как решихме да го направим?

  • Събираме всички услуги, мрежи и потребители.
  • Ще създадем на тяхна основа правила за iptables.
  • Автоматизираме контрола.
  • ….
  • ПЕЧАЛБА.

Consul не е отдалечен API, той може да работи на всеки възел и да пише в iptables. Остава само да измислим автоматични средства за контрол, които да почистват излишното, и голяма част от проблемите ще бъдат решени! Останалото ще се доработи в процеса.

Защо Consul?

Доказа се добре. През 2014-15 година го използвахме като бекенд за Vault, в който съхраняваме пароли.

Не губи данни.. По време на използването на Consul не загуби данни нито при една авария. Това е огромен плюс за системата за управление на пожарната стена.

P2P свързванията ускоряват разпространението на промените.. С P2P всички промени идват бързо, не е нужно да чакаме часове.

Удобен REST API. Ние също разгледахме Apache ZooKeeper, но той няма REST API, ще трябва да поставим костил.

Работи както като хранилище на ключове (KV), така и като каталог (Service Discovery).. Може да съхранява веднага услуги, каталози, дата-центрове. Това е удобно не само за нас, но и за съседните екипи, тъй като строим глобална услуга, мислим мащабно.

Написан е на Go, който е част от стека на Wargaming. Обичаме този език, имаме много Go-разработчици.

Мощна система ACL. С помощта на ACL в Consul можете да управлявате кой и какво да записва. Гарантираме, че правилата на защитната стена няма да се пресичат и няма да имаме проблеми с това.

Но Consul има и недостатъци.

  • Не мащабира в рамките на дата центъра, освен ако нямате бизнес версия. Мащабира се само чрез федерация.
  • Много е зависим от качеството на мрежата и натоварването на сървърите. Consul няма да работи нормално в ролята на сървър на натоварен сървър, ако в мрежата има забавяния, например, несигурна скорост. Това е свързано с P2P връзките и моделите на разпространение на актуализациите.
  • Трудности с мониторинга на наличността. В статуса на Consul може да се казва, че всичко е наред, а той вече е умрял.

Повечето от тези проблеми решихме по време на експлоатацията на Consul, затова и го избрахме. В компанията има планове за алтернативен бекенд, но ние научихме как да се справяме с проблемите и засега живеем с Consul.

Как работи Consul

В условен дата център ще инсталираме сървъри — от три до пет. Един или два сървъра не са достатъчни: те няма да могат да организират кворум и да решат кой е прав, когато данните не съвпадат. Повече от пет няма смисъл, производителността ще спадне.

Consul + iptables = :3

Клиентите се свързват към сървърите в произволен ред: същите агенти, само с флага server = false.

Consul + iptables = :3

След това клиентите получават списък с P2P връзки и изграждат връзки помежду си.

Consul + iptables = :3

На глобално ниво свързваме няколко дата центъра помежду им. Те също се свързват P2P и комуникират.

Consul + iptables = :3

Когато искаме да вземем данни от друг дата център, заявките отиват от сървър до сървър. Тази схема се нарича протокол Serf. Протоколът Serf, както и Consul, е разработка на HashiCorp.

Няколко важни факта за Consul

Consul разполага с документация, описваща неговата работа. Ще посоча само избрани факти, които е добре да знаете.

Сървърите на Consul избират майстор от гласуващите. Consul избира майстор от списъка със сървъри за всеки дата център и всички заявки отиват само към него, независимо от броя на сървърите. Засядането на майстора не води до избиране отново. Ако майстор не е избран, заявките не се обслужват.

Искате ли хоризонтално мащабиране? Съжаляваме, но не.

Запитът към другия дата център преминава от майстор на майстор, независимо от това на кой сървър е пристигнал. Избраният майстор получава 100% от товара, освен товара за пренасочване на запитвания. Актуалната версия на данните е налична при всички сървъри в дата центъра, но само един от тях отговаря.

Единственият начин за мащабиране е да активирате stale-режима на клиента.

В stale-режима може да се отговаря без кворум. Това е режим, в който се отказваме от консистентността на данните, но четем малко по-бързо от обикновено, и всеки сървър отговаря. Разбира се, записът е възможен само през майстора.

Consul не копира данни между дата центровете.. При събиране на федерация, всеки сървър ще има само своите данни. За останалите данни той винаги се обръща към някой друг.

Атомарността на операциите не е гарантирана извън транзакция.. Помнете, че не само вие можете да променяте нещо. Ако искате да направите нещо различно, проведете транзакция с блокиране.

Блокиращите операции не гарантират блокировка.. Запитването преминава от майстор на майстор, а не директно, следователно няма гаранция, че блокировката ще заработи, когато я правите, например, в друг дата център.

ACL също не гарантира достъп (в много случаи).. ACL може да не сработи, защото се съхранява в един дата център на федерацията — в дата центъра на ACL (Primary DC). Ако дата центърът не отговори, ACL няма да работи.

Един зациклен майстор ще доведе до зацикляне на цялата федерация.. Например, в федерацията има 10 дата центъра, и в един от тях мрежата е слаба, а един майстор спира. Всички, които комуникират с него, ще зациклят: запитването продължава, но отговор няма, а нишката зацикля. Няма да успеете да разберете кога това ще се случи, просто след час или два цялата федерация ще се срине. Нищо не можете да направите по въпроса.

Статусът, кворумът и изборите се обработват от отделен поток. Повторни избори няма да има, статусът няма да покаже нищо. Мислите, че вашият Consul работи, запитвате и нищо не се случва — отговор няма. В същото време статусът показва, че всичко е наред.

Срещали сме се с този проблем, и ни се е налагало да преустрояваме конкретни части от дата центровете, за да го избегнем.

В бизнес версията Consul Enterprise нямат някои от недостатъците, изброени по-горе.Той предлага много полезни функции: избор на гласуващи, разпределение, мащабиране. Има само едно "но" — системата за лицензиране за разпределената система е много скъпа.

Лайфхак: rm -rf /var/lib/consul — лекарство за всички проблеми на агента. Ако нещо не работи, просто изтрийте данните си и ги заредете от копие. Най-вероятно Consul ще проработи.

BEFW

Сега да поговорим за това, какво добавихме към Consul.

BEFW — това е акроним от BackEndFireWall. Трябваше да дам име на продукта, когато създавах хранилището, за да сложа първоначалните тестови комити. Такова име и остана.

Шаблони на правила

Правилата са написани на синтаксиса на iptables.

  • -N BEFW
  • -P INPUT DROP
  • -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
  • -A INPUT -i lo -j ACCEPT
  • -A INPUT -j BEFW

Всичко отива в веригата BEFW, освен ESTABLISHED, RELATED и localhost. Шаблонът може да бъде какъвто и да е, това е просто пример.

Какво е полезно BEFW?

Услуги

Имаме услуга, винаги има порт, нод, на който работи. От своя нод можем локално да питаме агента и да разберем, че имаме някаква услуга. Може също така да добавяме тагове.

Consul + iptables = :3

Всяка услуга, която е стартирана и регистрирана в Consul, се превръща в правило на iptables. Имаме SSH — отваряме порт 22. Bash скриптът е прост: curl и iptables, повече нищо не е необходимо.

Клиенти

Как да отворим достъп не на всички, а селективно? По името на услугата да се събират IP списъци в KV хранилище.

Consul + iptables = :3

Например, искаме да позволя на всички от десетата мрежа да получат достъп до услугата SSH_TCP_22. Добавяме едно малко поле TTL? и сега имаме времеви разрешения, например, за един ден.

Достъпи

Свързваме услуги и клиенти: имаме услуга, за всяка е готово KV хранилище. Сега не даваме достъп на всички, а селективно.

Consul + iptables = :3

Групи

Ако всеки път пишем хиляди IP за достъпи, ще се уморим. Ще измислим групи — отделен subset в KV. Ще го наречем Alias (или групи) и ще съхраняваме там групи по същия принцип.

Consul + iptables = :3

Свързваме: сега можем да отворим SSH не конкретно на P2P, а на цяла група или множество групи. По същия начин има TTL — можем временно да добавяме и премахваме от групата.

Consul + iptables = :3

Интеграция

Нашият проблем — човешкият фактор и автоматизацията. Засега го решихме така.

Consul + iptables = :3

Работим с Puppet и переносим все, что касается системы (код приложений). В puppetdb (обычный PostgreSQL) хранится список сервисов, которые запущены, и их можно найти по типу ресурса. Также можно узнать, к кому и куда обращаются запросы. У нас есть система pull request и merge request для этого.

Мы разработали befw-sync — простое решение для переноса данных. Сначала sync cookies обращаются в puppetdb, где настроен HTTP API: запрашиваем доступные сервисы и что нужно сделать. После этого делают запрос в Consul.

Интеграция существует? Да: мы написали правила и разрешили принимать Pull Request. Нужен какой-то порт или нужно добавить хост в группу? Pull Request, ревью — больше никаких «Найдите 200 других ACL и попробуйте что-нибудь с этим сделать».

Оптимизация

Пинг localhost с пустой цепочкой правил занимает 0,075 мс.

Consul + iptables = :3

Добавим в цепочку 10 000 адресов iptables. В результате пинг увеличится в 5 раз: iptables работает линейно, обработка каждого адреса занимает время.

Consul + iptables = :3

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

Но если мы поместим 10 000 адресов в ipset пинг даже уменьшится.

Consul + iptables = :3

Смысл в том, что «O» (сложность алгоритма) для ipset всегда равно 1, независимо от количества правил. Правда, есть ограничение — порядка 65535 правил. Пока справляемся: можно комбинировать, расширять и делать два ipset в одном.

Съхранение

Логичное продолжение процесса итераций — хранение информации о клиентах для сервиса в ipset.

Consul + iptables = :3

Теперь у нас есть тот же SSH, и мы не пишем сразу 100 IP-адресов, а задаем имя ipset, с которым надо работать, и следующее правило Изтриване. Можно объединить в одно правило «Кто не здесь, тот DROP», но так понятней.

Теперь у нас есть правила и наборы. Главная задача — создать сет до того, как написать правило, потому что иначе iptables не сохранит правило.

Общата схема

В виде схемы все, что я рассказал, выглядит так.

Consul + iptables = :3

Коммитим в Puppet, все отправляется на хост, сервисы здесь, ipset там, а тех, кто там не прописан, не пускают.

Allow & deny

Чтобы быстро спасать мир или отключать кого-то, в начале всех цепочек мы создали два ipset: rules_allow и rules_deny. Как это работает?

Например, ако някой създаде натоварване на нашия Web с ботове, по-рано трябваше да намерим IP адреса му в логовете, да го предадем на мрежовите инженери, за да намерят източника на трафика и да го блокират. Сега това изглежда по друг начин.

Consul + iptables = :3

Изпращаме в Consul, изчакваме 2,5 секунди и готово. Тъй като Consul бързо разпределя благодарение на P2P, той работи навсякъде, в която и да е част на света.

Веднъж напълно спрях WOT, погрешно конфигурирайки защитната стена. rules_allow — това е нашата застраховка срещу такива случаи. Ако някъде направим грешка с защитната стена и нещо бъде блокирано, винаги можем да изпратим условно 0.0/0, за да възстановим всичко бързо. По-късно можем да поправим всичко ръчно.

Други набори

Може да добавяте всякакви други набори в пространството $IPSETS$.

Consul + iptables = :3

Защо? Понякога на някого му трябват ipset, например, за да емулира изключването на някоя част от кластера. Всеки може да внесе каквито и да е набори, да ги назове и те ще бъдат извлечени от Consul. При това наборите могат както да участват в правилата на iptables, така и да бъдат команда NOOP: консистентността ще бъде поддържана от демона.

Потребители

По-рано беше така: потребителят се свързваше с мрежата и получаваше параметри чрез домейн. До появата на новите поколенчески защитни стени Cisco не умеше да разбира къде е потребителят и къде е IP. Следователно достъпът се предоставяше само чрез име на хост.

Какво направихме? Намесихме се в момента на получаване на адреса. Обикновено това е dot1x, Wi-Fi или VPN — всичко минава през RADIUS. За всеки потребител създаваме група по името му и поставяме в нея IP с TTL, равен на неговия dhcp.lease — щом изтече, правилото изчезва.

Consul + iptables = :3

Сега можем да отваряме достъпа до услугите, както и в другите групи, по username. Освободихме се от болката с hostname, когато те се променят, и свалихме натоварването от мрежовите инженери, защото вече не им трябва Cisco. Сега инженерите сами задават достъпите на своите сървъри.

Изолация

Паралелно започнахме да разглеждаме изолацията. Услугодателите направиха инвентаризация, а ние анализирахме всичките ни мрежи. Разделихме ги на такива групи, а в нужните сървъри добавихме групи, например, в deny. Сега същата изолация на стейджинга попада в rules_deny на продукцията, но не в самата продукция.

Consul + iptables = :3

Схемата работи бързо и лесно: сваляме всичките ACL от сървърите, разтоварваме оборудването, намаляваме броя на изолираните VLAN.

Контрол на целостта

По-рано при нас работеше специален триггер, който уведомяваше, когато някой ръчно промени правилото на защитната стена. Написах огромен линтер за проверка на правилата на защитната стена, беше сложно. Сега цялостността се контролира от BEFW. Той стриктно следи правилата, които задава, да не се променят. Ако някой промени правилата на защитната стена, той ще ги върне обратно. „Бързо настроих прокси, за да работя от вкъщи“ — такива варианти вече няма.

BEFW контролира ipset от услугите и списъка в befw.conf, правилата на услугите в веригата BEFW. Но не следи за други вериги и правила и други ipset.

Защита от аварии

BEFW винаги запазва последното успешно състояние направо в бинарната структура state.bin. Ако нещо се обърка, той винаги се връща назад на това state.bin.

Consul + iptables = :3

Това е застраховка срещу нестабилната работа на Consul, когато той не изпрати данни или някой сгреши и използва правила, които не могат да бъдат приложени. За да не останем без защитна стена, BEFW ще се върне на последното състояние, ако на някакъв етап възникне грешка.

В критични ситуации това е гаранция, че ще останем с функционираща защитна стена. Отваряме всички сиви мрежи в надеждата, че администраторът ще дойде и ще поправи. Някога ще го добавя в конфигурации, но сега просто имаме три сиви мрежи: 10/8, 172/12 и 192.168/16. В контекста на нашия Consul това е важна особеност, която помага за по-нататъшно развитие.

Демо: по време на презентацията Иван показва демо-режим на работа на BEFW. Демонстрацията е по-удобна за гледане на видео. Изходният код на демото е достъпен на GitHub.

Подводни камъни

Ще разкажа за бъговете, с които се сблъскахме.

ipset add set 0.0.0.0/0. Какво ще се случи, ако добавите в ipset 0.0.0.0/0? Ще добави ли всички IP адреси? Ще се отвори ли достъп до интернет?

Не, ще получим бъг, който ни струваше два часа престой. И този бъг не работи от 2016 година, лежи в RedHat Bugzilla под номер #1297092, а го открихме случайно — от отчета на разработчика.

Сега в BEFW има строго правило, че 0.0.0.0/0 се превръща в два адреса: 0.0.0.0/1 и 128.0.0.0/1.

ipset restore set < file. Какво прави ipset, когато му кажете restore? Вы думаете, он работает также, как iptables? Восстановит данные?

Нищо подобно — той прави сливане и старите адреси не изчезват, достъпът не се затваря.

Забелязахме бъга, когато тествахме изолацията. Сега там има доста сложна система — вместо restore се провежда create temp. Но все още не сме отговорили на въпроса: къде да пишем извикването на модула restore flush temp и restore temp. В края на swap: за атомарност, понеже ако първо се извърши flush и в този момент ще дойде някакъв пакет, той ще бъде отхвърлен и нещо ще се обърка. Затова има малко черна магия.

consul kv get -datacenter=other. Както вече казах, мислим, че искане за данни, но ще получим или данни, или грешка. Можем да го правим през Consul локално, но дори и в този случай и двете ще замръзнат.

Локалният Consul клиент е обвивка над HTTP API. Но той просто замръзва и не отговаря на Ctrl+C, Ctrl+Z или на нищо, само на kill -9 в съседния терминал. С това се сблъскахме, когато изграждахме голям кластер. Но все още нямаме решение, подготвяме се да оправим тази грешка в Consul.

Consul лидерът не отговаря. Нашият майстор в дата центъра не отговаря, мислим: „Може би сега алгоритъмът за преизбиране ще сработи?“

Не, няма да сработи, а мониторингът няма да покаже нищо: Consul ще каже, че индексът на ангажимента е наличен, лидерът е намерен, всичко е наред.

Как се борим с това? service consul restart в cron всеки час. Ако имате 50 сървъра — няма проблем. Когато станат 16 000, ще разберете как работи.

Заключение

В крайна сметка получихме следните предимства:

  • 100% покритие на всички Linux машини.
  • Скорост.
  • Автоматизация.
  • Освободихме железото и мрежовите инженери от робство.
  • Появиха се възможности за интеграция, които са практически безгранични: било с Kubernetes, било с Ansible, било с Python.

Минуси: Consul, с който сега трябва да живеем, и много висока цена на грешка. Например, веднъж в 6 следобед (пиков час за Русия) правих нещо в списъците на мрежите. Тогава тъкмо изграждахме изолация на BEFW. Някъде сбърках, изглежда, посочих неправилна маска, но всичко се срина за две секунди. Запалва се мониторингът, бърза служител на поддръжката: „Всичко е паднало!“ Началникът на отдела побелял, когато обяснявал на бизнеса защо се е случило така.

Цената на грешката е толкова висока, че измислихме собствена сложна процедура за профилактика. Ако ще внедрявате това в голямо производство, не давайте майсторски токен над Consul на всички накуп. Това ще завърши зле.

Разходи. Написах код 400 часа сам. За поддръжка моята екип от 4 души прекарва 10 часа на месец общо. В сравнение с цената на всяко ново поколение защитна стена, това е безплатно.

Планове. Дългосрочният план е да намерим алтернативен транспорт вместо или допълнително към Consul. Може би ще бъде Kafka или нещо подобно. Но в близките години ще живеем с Consul.

Ближайши планове: интеграция с Fail2ban, с мониторингом, с nftables, възможно, с други дистрибуции, метрики, разширен мониторинг, оптимизация. Поддръжката на Kubernetes също има място в плановете, tъй като в момента разполагаме с няколко клъстера и желание.

Още от плановете:

  • търсене на аномалии в трафика;
  • управление на картата на мрежата;
  • поддръжка на Kubernetes;
  • сборка на пакети за всички системи;
  • Web-UI.

Постоянно работим върху разширяване на конфигурацията, увеличаване на метриките и оптимизация.

Присъединете се към проекта. Проектът се получи страхотно, но, за съжаление, в момента е проект на един човек. Заповядайте на GitHub и опитайте да направите нещо: да комитнете, да тествате, да предложите нещо, да дадете своята оценка.

Междувременно подготвяме се за Saint HighLoad++, който ще се състои на 6 и 7 април в Санкт Петербург, и каним разработчици на високонапрегнати системи да подадат заявление за доклад. Опитните лектори вече знаят какво да правят, а на новаците в изказванията препоръчваме поне да опитат. Участието в конференцията като лектор предоставя редица предимства. Какви, можете да прочетете, например, в края на тази статия.

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster