Сервера всех филиалов — соединяйтесь

Жили-были несколько серверов, в разных локациях. Сколько именно — это непринципиально, поэтому упростим, пусть будет два: A и B.

Каждый занимался своими задачами, а между собой они были соединены виртуальной приватной сетью (ну, то, что теперь нельзя называть).
Причем сеть эта использовалась по своему прямому назначению — просто обеспечить передачу локального трафика через публичные сети, дабы посторонние не совали в него свой любопытный клюв.

Однако, с некоторых пор начались проблемы: одна известная организация начала ломать рунет, блокируя соединения то там, то тут.
Сначала заблокировали один протокол — пришлось переходить на другой. Потом заблокировали другой — пришлось переходить на третий.
Третий периодически рвался, потому что начали портить уже соединения между сетями: через одного провайдера канал есть, через другого нет, потом меняются.

Как вы понимаете, нормальной работе это отнюдь не способствовало, пришлось искать какое‑то решение. А ведь оно давно известно — динамическая маршрутизация!
Просто до поры она, казалось бы, совсем тут не нужна — не те масштабы, да и работало всё прекрасно...

Смысл простой: если основной канал внезапно падает — используем резервный.
Портится резервный — меняем провайдера или ищем обходные маршруты.
Но для этого надо оперативно перенастраивать маршруты на роутерах, причем на всех сторонах всех участников процесса.

Каналы связи в данном случае — различные виды того‑что‑нельзя‑называть в различных сочетаниях.
Тут вполне подходит протокол OSPF: он как раз и предназначен для решения подобных задач.
Не буду пытаться обьяснять тонкости работы лучше, чем это делают профессионалы‑сетевики, просто остановлюсь на некоторых практических нюансах реализации.

А роутеры будут программные — для этого можно использовать пакет FRR.
Он стандартно присутствует в репозитарии Debian (apt search frr), но как показалось — лучше сделать немного по‑другому: запустить его через docker — тогда на всех узлах он будет одной версии, и не будет ни с чем конфликтовать.
Есть даже готовый образ — но, по обычаю, можно сделать и самостоятельно:

mkdir -p /etc/frr
docker run -ti --name frr -v /etc/frr:/etc/frr --privileged --network host debian:latest

Это запускает контейнер с правами, близкими к хост-системе - но при этом сохраняется некоторая изоляция от системных библиотек и установленных версий ОС.
Попадаем внутрь контейнера - устанавливаем:

apt update
apt upgrade
apt install frr
exit

Теперь в контейнере живет frr, а его настроечные файлы - в /etc/frr host-системы.
То есть, их можно редактировать вручную в привычном редакторе.

vim /etc/frr/daemons
ospfd=yes

Теперь немного сетевых настроек.
Разрешаем форвардинг, если еще не:

sysctl net.ipv4.ip_forward=1

Назначаем фиксированные, независимые от интерфейсов адреса для серверов, присваивая их локальному интерфейсу, ну например, адрес сервера A - 192.168.10.1
Таким образом, их наличие никак не будет связано с работоспособностью тех или иных сетевых интерфейсов:

ip addr add 192.168.10.1/32 dev lo

Разбираемся с каналами: это у нас различные типы того-что-нельзя-называть, причем нам от них по сути нужна связь "точка-точка": соединяются сервера A, B, а также несколько дополнительных, размещенных в других локациях - для организации подобия mesh-сети.

По сути для каждого из них нужны всего 2 адреса + широковещательный и адрес подсети, итого 4.
Для этого можно выделить специальную отдельную подсеть, например, 192.168.5.0, и нарезать ее на подсети /30.
Кто забыл: маска подсети - количество неизменяемых битов подсети, т.е. /24 - первые три октета фиксированы(192.168.5.), и еще 6 бит - тоже.
В двоичном виде последний октет будет выглядеть так:

(0000 00)00 - в скобках фиксированная часть подсети, без скобок - 00, 01, 10, 11 - адреса сети, узлов и широковещательный соответственно.
А номера сетей меняются от 0000 00 до 1111 11.

Поскольку всё это принято записывать в десятичном виде - можно для удобства использовать встроенную в шелл возможность расчёта:

echo $(( 2#00000001 ))  # 1 - 1 адрес сети 0
echo $(( 2#00000010 ))  # 2 - 2 адрес сети 0
echo $(( 2#00000101 ))  # 5 - 1 адрес сети 1
echo $(( 2#00000110 ))  # 6 - 2 адрес сети 1
echo $(( 2#00001001 ))  # 9 - 1 адрес сети 2
echo $(( 2#00001010 ))  # 10 - 2 адрес сети 2

Ну и так далее. Несложно.
К примеру, связываем сервера A и B двумя прямыми каналами:

192.168.5.1/30 - 192.168.5.2/30  # то-что-нельзя-называть тип 1
192.168.5.5/30 - 192.168.5.6/30  # то-что-нельзя-называть тип 2

Ну и так далее. Еще раз отмечу, что это чисто "связные подсети", на них не будет работающих сервисов.
Сервисы у нас на 192.168.10.1 и подобных.

Теперь запускаем frr:

docker start frr
docker exec -ti frr /usr/lib/frr/frrinit.sh start

У frr есть Cisco-подобный интерфейс, через который можно делать настройки и смотреть состояние:
(TAB помогает)

docker exec -ti frr vtysh
configure terminal
router ospf
ospf router-id 1.1.1.1
maximum-paths 1
network 192.168.10.1/32 area 0
network 192.168.5.0/24 area 0
exit
exit
write memory
exit

И смотрим, что получилось:

vim /etc/frr/frr.conf

frr version 10.3
frr defaults traditional
hostname alice
log syslog informational
service integrated-vtysh-config
!
router ospf
 ospf router-id 1.1.1.1
 maximum-paths 1
 network 192.168.10.1/32 area 0
 network 192.168.5.0/24 area 0
exit
!

Синтаксис простой, блоки выделяются отступом, символ ! или # - комментарий, в данном случае они вообще не обязательны и служат просто для визуальной отметки конца блока.
(тут, к слову, та самая ситуация, когда один лишний пробел может поломать всё)

Если что-то поменять - потом достаточно перезапустить frr:

docker exec -ti frr /usr/lib/frr/frrinit.sh restart

Ну или воспользоваться vtysh для правки, кому что привычнее.

Что сейчас настроено:

По интерфейсам, подпадающим под маску, будут рассылаться сообщения Hello от OSPF - предполагается, что с другой стороны их будут слушать другие OSPF-роутеры.

По такой же схеме настраиваем FRR на других машинах.
Если там нет своих "сервисных адресов" - достаточно указать только одну сеть, через которую идёт связь, в данном случае 192.168.5.0/24

И в общем-то это всё.
Перезапускаются frr, они обмениваются между собой данными о доступных маршрутах - и теперь на любой машине можно обратиться к 192.168.10.1 - запрос уйдет именно на сервер A, по кратчайшему маршруту, в зависимости от того какие каналы где сейчас работают.

Проверить работу можно так:

docker exec -ti frr vtysh
show running-config
show ip ospf neighbor
show ip ospf route
...

А вот теперь нюансы:

Протокол OSPF - это не TCP и не UDP, это отдельный протокол 89.
Поэтому некоторые, эээ, каналы, его не пропускают.
Решить эту проблему можно примерно следующим образом: сначала поднять просто TCP/IP канал, потом поверх него VXLAN (L2, "езернет", инкапсулированный в UDP), потом поверх него "связную сеть", и вот уже тогда пускать OSPF.
Слоёный пирог, но работает. Альтернатива - использовать BGP, но там настройка несколько сложнее.

Address = 192.168.3.1/30
Table = off
PostUp = ip link add vxlwgA type vxlan id 12 dev %i remote 192.168.3.2 dstport 4789
PostUp = ip link set dev vxlwgA up
PostUp = ip addr add 192.168.5.9/30 dev vxlwgA

Вданном случае сначала устанавливается «транспортная подсеть» 192.168.3.0/30, поверх нее «связная подсеть» 192.168.5.4/30, и вот уже по ней и будет работать OSPF.
А 192.168.3.0 в маршруты не попадёт (хотя можно и ее добавить, еще одной network).

Заметим, что статические маршруты тут не нужны, и даже вредны — оно само всё разрулит лучше.

Теперь включаем ping, и начинаем портить:

Для приложений, работающих с 192.168.10.1, будут лишь кратковременные потери пакетов, может вырасти время пинга, особенно если меняется вообще способ подключения — но в целом всё работает, хоть и идет неведомыми путями.
А значит, цель достигнута.

@JBFW
23.11.2025 15:48 UTC
Первоисточник

Комментарии

@aborouhin
23.11.2025 11:19 UTC
+2

Иногда одна известная организация ломает инет так, что связность вроде бы и есть, но по факту пользоваться невозможно, потери пакетов >30% и latency плавает вплоть до нескольких секунд. И вот тут к OSPF (который у меня уже настроен ровно для той же задачи, что Вы решаете, только что bird, а не frr) неплохо бы добавить BFD. Никак руки не дойдут, так что изредка такие "зомби-каналы" приходится руками отключать, чтобы OSPF их мёртвыми признал.

@JBFW
23.11.2025 11:35 UTC
0

Совершенно верно

И bfd там тоже есть, кстати, надо его с ospf подружить...

@michaelkuz
23.11.2025 13:56 UTC
+1

Не так давно надо было поднимать роутинг где есть и linux, и windows. В Windows server оказалось есть родная поддержка BGP. Был немного удивлен. Сразу и безпроблемно заработало с bird

@K0Jlya9
23.11.2025 14:46 UTC
+2

Настало время героев, кто то должен набраться слабоумия и отваги, пойти на поклон к ИИ что бы навайбкодить такой п2п серверлес впнище который будет пробивать всё насквозь с большим запасом.

@mvv-rus
23.11.2025 23:19 UTC
0

Чисто для себя хочу поинтересоваться: вы, прежде чем эти партизанские тропы торить, штатным способом - уведомить Минцифры об используемых для бизнеса каналах VPN - воспользоваться не пробовали? Интересуюсь, потому что хотелось бы знать, существует ли этот способ в нашей реальности или нет.
Ну, а ещё интересно, жив ли в наше время протокол PPTP (он, вроде как, для всяких там запрещенных дел не годится), не в курсе?
Мне всё это не то, чтобы сильно надо (иначе бы знал), но может внезапно пригодиться. Заранее благодарю.

@JBFW
23.11.2025 23:38 UTC
+3

Государства и так стало слишком много: оно залезло к гражданам в холодильники, в книжки, в фильмы, даже в штаны - можно как-нибудь не уведомлять о том, что его не касается?
Герр комендант чрезмерно любопытен, и добра от этого любопытства пока что-то не видно.

Протокол PPTP технически жив, но его и в лучшие времена не всегда пропускали на маршрутизаторах, а сейчас-то...

24.11.2025 00:18 UTC
-1

Государства и так стало слишком много: оно залезло к гражданам в холодильники, в книжки, в фильмы, даже в штаны - можно как-нибудь не уведомлять о том, что его не касается?

Я правильно понял эти много слов, что использовать этот, предусмотренный установленным в государстве порядком, путь вы не пытались (по идейным или каким ещё причинам - мне не важно) и в силу этого полезной мне информацией вы не обладаете?

Протокол PPTP технически жив, но его и в лучшие времена не всегда пропускали на маршрутизаторах, а сейчас-то...

Не помню, чтобы его когда-то специально блокировали. Но вот через NAT он просто так проходить без поддерживащего его ALG не мог (впрочем, к середине 00-х все производители ПО для шлюзов NAT поддержку его таки добавили). Но меня интересовало не это, а прохождение PPTP в отсутствии NAT, с реального IP на другой реальный IP. Как я понял, этой информацией вы тоже не обладаете.

24.11.2025 00:33 UTC
+2

По первому вопросу Вы можете получить эту информацию самостоятельно, подав прошение в комендатуру.

А по протоколу - просто имейте ввиду, что это GRE. Будет он работать или не будет он работать - зависит в каждом конкретном случае от кривизны ручек сетевиков и наличия умыслов.
Даже при отсутствии умыслов - про кривизну ручек между вашими реальными IP мне ничего неизвестно. Может быть и так и этак.

Проверьте, создайте туннель - заработает - значит, и PPTP будет. Не заработает - значит нет.

24.11.2025 01:14 UTC
-1

Хотел написать ответ и даже поначалу написал, но понял, что отвечать тут не на что.

@drnorfolk
24.11.2025 14:29 UTC
0

Так вот о чем рассказывала преподша по "Сетевым технологиям", вот к чему готовили! Круто и лайк)