NetLab Academy

Сетевые лаборатории в браузере

Войти Начать бесплатно

Теория: Site-to-site VPN

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

Две площадки и чужая сеть между ними

У компании офис и склад в разных городах. В обоих — своя частная сеть, 192.168.10.0/24 и 192.168.20.0/24. Между ними интернет, и он про эти сети не знает ничего и знать не должен: частные адреса в интернете не маршрутизируются.

Задача — сделать так, чтобы для сотрудников обе сети выглядели одной. Не «открыть доступ к одному серверу», а связать целиком: чтобы работали принтеры, файловые шары, внутренние сервисы и всё то, что писалось в расчёте на локальную сеть.

Решение называется туннель: пакет частной сети заворачивают в обычный пакет с публичными адресами, довозят до второй площадки и там разворачивают. Провайдер видит только внешнюю обёртку — трафик между двумя публичными адресами — и маршрутизирует её как любую другую.

Пакет внутри пакета

Механика простая. Роутер площадки А получает от компьютера пакет «от 192.168.10.10 к 192.168.20.10», видит, что маршрут в эту сеть ведёт в туннель, и дописывает спереди новый заголовок: «от 203.0.113.1 к 203.0.113.6». Получившееся уезжает в интернет как обычный трафик. Роутер площадки Б снимает внешний заголовок и отправляет исходный пакет своей сети.

Из этого сразу следуют две вещи, о которых спрашивают чаще всего.

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

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

GRE: просто довезти

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

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

Слабая сторона очевидна: всё идёт открытым текстом. Любой на пути видит содержимое. Поэтому в чистом виде GRE применяют там, где канал и так доверенный, а в интернете — вместе с шифрованием.

Ещё одна деталь: у туннеля нет согласования. Интерфейс поднимается независимо от того, есть ли кто-то на другом конце, и состояние UP не значит, что туннель работает.

IPsec: закрыть содержимое

IPsec решает противоположную задачу: не «как довезти», а «как довезти так, чтобы никто не прочитал и не подменил». Он даёт шифрование, проверку целостности и подлинности сторон.

Работает он в двух режимах:
транспортный — шифруется только содержимое, заголовки остаются исходными. Годится, когда связываются два конкретных узла;
туннельный — весь исходный пакет шифруется целиком и получает новый заголовок. Это и есть вариант для связи площадок.

Установление связи идёт в два этапа: сначала стороны договариваются о ключах и алгоритмах, потом гоняют данные. Отсюда типовая картина отладки: первая фаза поднялась, вторая нет — стороны опознали друг друга, но не сошлись в том, какой трафик защищать.

Главное ограничение: чистый IPsec в туннельном режиме не переносит многоадресную рассылку. Значит, протоколы маршрутизации через него не пойдут, и трафик придётся описывать списками сетей вручную.

GRE поверх IPsec: почему так делают

Два предыдущих раздела складываются в стандартную конструкцию: GRE внутри, IPsec снаружи.

GRE даёт нормальный интерфейс, через который ходит что угодно, включая протоколы маршрутизации. IPsec закрывает всё это шифрованием. Получается туннель, который и защищён, и ведёт себя как обычный линк: можно поднять по нему OSPF, добавить площадку — и маршруты разойдутся сами, без переписывания списков сетей на всех роутерах.

Плата — ещё больше накладных расходов: к двадцати четырём байтам GRE добавляются десятки байт IPsec, и внутри остаётся около 1400.

Современная альтернатива — WireGuard: он делает то же самое одним механизмом, настраивается в несколько строк, живёт в ядре и работает поверх UDP. Накладные расходы около шестидесяти байт. Там, где нет требования совместимости со старым оборудованием, обычно берут его.
Четыре способа связать площадки — и что из них видно провайдеру
Сплошная рамка — то, что читается по дороге; штриховая с замком — то, что закрыто шифрованием. Обратите внимание на строку про протоколы маршрутизации: именно она определяет, придётся ли вручную перечислять сети на каждом роутере при добавлении новой площадки.

Маршрутизация через туннель

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

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

Протоколом маршрутизации. Поверх туннеля поднимают OSPF или BGP, и маршруты расходятся сами. Именно ради этого и городят GRE внутри IPsec.

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

MTU: главная боль туннелей

Обычный кадр Ethernet везёт полторы тысячи байт. Заголовок туннеля занимает часть, и внутри остаётся меньше: у GRE — 1476, у GRE поверх IPsec — около 1400.

Дальше всё зависит от того, узнает ли об этом отправитель. Механизм определения MTU пути устроен так: отправитель шлёт полноразмерный пакет с запретом фрагментации, роутер не может его пропустить и возвращает служебное сообщение ICMP «пакет слишком большой, нужно не больше стольки-то». Отправитель уменьшает размер и продолжает.

Держится это целиком на одном типе сообщений ICMP. Стоит закрыть ICMP «на всякий случай» — и механизм ломается молча. Получается картина, которую видел каждый сетевой инженер:

ping ходит, а ничего не работает. Ping — это маленькие пакеты, они пролезают всегда. Соединение TCP тоже устанавливается: приветственные пакеты крошечные. А как только начинается передача данных полноразмерными сегментами — тишина. Такое называют чёрной дырой MTU.

Надёжное лечение не полагается на ICMP: роутер вмешивается в согласование TCP и правит в приветственном пакете поле «какого размера сегменты мне присылать». Стороны договариваются на то, что гарантированно пролезет. Приём называется зажатием MSS, и его ставят на туннелях по умолчанию, не дожидаясь жалоб. Оговорка: он помогает только TCP — UDP придётся чинить настройкой приложения.

Что здесь ломается

Перепутаны local и remote. Ошибка в одну цифру, и интерфейс всё равно поднимается: согласования у туннеля нет. Состояние UP ничего не доказывает.

Маршрут прописан с одной стороны. Запрос уходит, ответ возвращаться не по чему. Классическая картина: на дальнем роутере в туннеле виден пришедший запрос без ответа.

Не учтён MTU. Ping ходит, работа стоит. Самая частая авария туннелей и самая долгая в поиске, потому что первые же проверки показывают, что «связь есть».

Закрыт ICMP. Он же и есть причина предыдущего пункта. Полностью закрывать ICMP нельзя, но полагаться на то, что его не закроют у соседа, тоже нельзя — отсюда и зажатие MSS.

Рекурсивная маршрутизация. Туннель флапает с ровным периодом, и в журнале это выглядит как проблема с каналом.

Наружу выпущено больше, чем нужно. Туннель связывает площадки целиком, и сеть партнёра или подрядчика получает доступ ко всему. Список того, что уходит в туннель, ограничивают так же осознанно, как правила на межсетевом экране.

Как проверять

Порядок разбора у туннелей всегда один и тот же — снаружи внутрь.

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

Потом параметры туннеля с обеих сторон: ip tunnel show. Local одной стороны обязан быть remote другой. Здесь находится половина проблем.

Потом адреса внутри туннеля: пингуются ли его концы. Это проверка самого туннеля без маршрутизации.

Потом маршруты, и обязательно с обеих сторон. tcpdump -i gre1 -nn на дальнем роутере сразу показывает, доходят ли запросы и уходят ли ответы.

И только в конце — размер пакета. Если ping проходит, а передача нет, проверяйте прямо: ping -M do -s 1472 и любая TCP-передача. Одно проходит, другое нет — это MTU, и никакая другая проверка вам этого не покажет.

Команды — шпаргалка

# туннель GRE между площадками (Linux)
ip tunnel add gre1 mode gre local 203.0.113.1 remote 203.0.113.6 ttl 255
                                 # gre1 — имя туннеля; mode — тип инкапсуляции;
                                 #   local и remote — ВНЕШНИЕ адреса площадок, между
                                 #   которыми строится труба; ttl 255 — чтобы пакет
                                 #   не умер по дороге
ip addr add 10.255.255.1/30 dev gre1     # адрес внутри туннеля: /30 — ровно два
                                 #   адреса, по одному на конец
ip link set gre1 up              # поднять интерфейс
ip route replace 192.168.20.0/24 dev gre1
                                 # сеть на той стороне отправлять в туннель.
                                 #   replace — создать или переписать существующий

# зажать MSS: не полагаемся на то, что ICMP дойдёт
iptables -t mangle -A FORWARD -o gre1 -p tcp --tcp-flags SYN,RST SYN \
         -j TCPMSS --clamp-mss-to-pmtu
                                 # -t mangle — таблица правки заголовков;
                                 #   -A FORWARD — добавить в цепочку транзита;
                                 #   -o gre1 — только то, что уходит в туннель;
                                 #   --tcp-flags SYN,RST SYN — смотреть на эти два
                                 #   флага и брать пакеты, где взведён только SYN,
                                 #   то есть начала соединений;
                                 #   --clamp-mss-to-pmtu — урезать заявленный размер
                                 #   сегмента под реальный MTU пути

# или задать MTU туннеля руками
ip link set gre1 mtu 1476        # 1500 минус 24 байта заголовков GRE и IP

# WireGuard: то же самое, но со стойким шифрованием
ip link add wg0 type wireguard   # имя и тип интерфейса
wg set wg0 private-key /etc/wireguard/priv listen-port 51820 \
       peer <открытый ключ соседа> endpoint 203.0.113.6:51820 \
       allowed-ips 192.168.20.0/24
                                 # private-key — файл со своим секретом;
                                 #   listen-port — на каком порту принимать;
                                 #   peer — открытый ключ соседа, он же его имя;
                                 #   endpoint — где сосед находится сейчас;
                                 #   allowed-ips — какие сети через него ходят.
                                 #   Это одновременно и маршрут, и право доступа
ip addr add 10.255.255.1/30 dev wg0 && ip link set wg0 up

# проверка — снаружи внутрь
ping 203.0.113.6                 # видят ли друг друга внешние адреса
ip tunnel show                   # local и remote с обеих сторон совпадают крест-накрест?
ping 10.255.255.2                # сам туннель
ip route show | grep gre1        # маршруты в чужие сети через туннель
tcpdump -i gre1 -nn icmp         # слушаем ВНУТРИ туннеля: -nn не резолвит ни
                                 #   адреса, ни порты. Видно, доходят ли запросы
                                 #   и уходят ли ответы
ping -M do -s 1472 <хост>        # -M do запрещает фрагментацию, -s задаёт размер:
                                 #   проходит ли полноразмерный пакет
Контрольные вопросы

Дальше — лабораторная работа «Туннель между площадками»

Для неё нужен аккаунт: стенд поднимается персонально под вас — свои роутеры, свои конфиги, никто в них не мешает. Регистрация — почта и пароль.

Теория прочитана. Дальше — руками.

Личный стенд из настоящих роутеров разворачивается за секунды. Платформа проверяет не ответы на тесты, а состояние вашей сети: поднялись ли соседства, сошлись ли маршруты, ходит ли ping. Рядом — AI-наставник, который видит ваши конфиги и ведёт к решению, не выдавая готовое.

Начать бесплатно → бета открыта, доступ бесплатный