Теория: 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, счётчики, через него прописывают маршруты и по нему могут работать протоколы маршрутизации.
Пакет стал больше. Внешний заголовок занимает место, и внутри туннеля помещается меньше, чем снаружи. Это источник большинства аварий с туннелями, и ниже про него отдельный раздел.
Из этого сразу следуют две вещи, о которых спрашивают чаще всего.
Туннель — это интерфейс. Он ведёт себя как обычный порт: у него есть адрес, MTU, счётчики, через него прописывают маршруты и по нему могут работать протоколы маршрутизации.
Пакет стал больше. Внешний заголовок занимает место, и внутри туннеля помещается меньше, чем снаружи. Это источник большинства аварий с туннелями, и ниже про него отдельный раздел.
GRE: просто довезти
Самый прямолинейный способ. GRE заворачивает пакет и ничего больше не делает: не шифрует, не проверяет подлинность, не спрашивает пароля. Накладные расходы — 24 байта: двадцать на новый заголовок IP и четыре на сам GRE.
Настройка занимает три строки, и в этом его сила. Ещё одна сильная сторона: GRE переносит что угодно, включая многоадресную рассылку. Поэтому протоколы маршрутизации через GRE ходят нормально — соседство OSPF поднимется через туннель так же, как через кабель.
Слабая сторона очевидна: всё идёт открытым текстом. Любой на пути видит содержимое. Поэтому в чистом виде GRE применяют там, где канал и так доверенный, а в интернете — вместе с шифрованием.
Ещё одна деталь: у туннеля нет согласования. Интерфейс поднимается независимо от того, есть ли кто-то на другом конце, и состояние UP не значит, что туннель работает.
Настройка занимает три строки, и в этом его сила. Ещё одна сильная сторона: GRE переносит что угодно, включая многоадресную рассылку. Поэтому протоколы маршрутизации через GRE ходят нормально — соседство OSPF поднимется через туннель так же, как через кабель.
Слабая сторона очевидна: всё идёт открытым текстом. Любой на пути видит содержимое. Поэтому в чистом виде GRE применяют там, где канал и так доверенный, а в интернете — вместе с шифрованием.
Ещё одна деталь: у туннеля нет согласования. Интерфейс поднимается независимо от того, есть ли кто-то на другом конце, и состояние UP не значит, что туннель работает.
IPsec: закрыть содержимое
IPsec решает противоположную задачу: не «как довезти», а «как довезти так, чтобы никто не прочитал и не подменил». Он даёт шифрование, проверку целостности и подлинности сторон.
Работает он в двух режимах:
• транспортный — шифруется только содержимое, заголовки остаются исходными. Годится, когда связываются два конкретных узла;
• туннельный — весь исходный пакет шифруется целиком и получает новый заголовок. Это и есть вариант для связи площадок.
Установление связи идёт в два этапа: сначала стороны договариваются о ключах и алгоритмах, потом гоняют данные. Отсюда типовая картина отладки: первая фаза поднялась, вторая нет — стороны опознали друг друга, но не сошлись в том, какой трафик защищать.
Главное ограничение: чистый IPsec в туннельном режиме не переносит многоадресную рассылку. Значит, протоколы маршрутизации через него не пойдут, и трафик придётся описывать списками сетей вручную.
Работает он в двух режимах:
• транспортный — шифруется только содержимое, заголовки остаются исходными. Годится, когда связываются два конкретных узла;
• туннельный — весь исходный пакет шифруется целиком и получает новый заголовок. Это и есть вариант для связи площадок.
Установление связи идёт в два этапа: сначала стороны договариваются о ключах и алгоритмах, потом гоняют данные. Отсюда типовая картина отладки: первая фаза поднялась, вторая нет — стороны опознали друг друга, но не сошлись в том, какой трафик защищать.
Главное ограничение: чистый IPsec в туннельном режиме не переносит многоадресную рассылку. Значит, протоколы маршрутизации через него не пойдут, и трафик придётся описывать списками сетей вручную.
GRE поверх IPsec: почему так делают
Два предыдущих раздела складываются в стандартную конструкцию: GRE внутри, IPsec снаружи.
GRE даёт нормальный интерфейс, через который ходит что угодно, включая протоколы маршрутизации. IPsec закрывает всё это шифрованием. Получается туннель, который и защищён, и ведёт себя как обычный линк: можно поднять по нему OSPF, добавить площадку — и маршруты разойдутся сами, без переписывания списков сетей на всех роутерах.
Плата — ещё больше накладных расходов: к двадцати четырём байтам GRE добавляются десятки байт IPsec, и внутри остаётся около 1400.
Современная альтернатива — WireGuard: он делает то же самое одним механизмом, настраивается в несколько строк, живёт в ядре и работает поверх UDP. Накладные расходы около шестидесяти байт. Там, где нет требования совместимости со старым оборудованием, обычно берут его.
GRE даёт нормальный интерфейс, через который ходит что угодно, включая протоколы маршрутизации. IPsec закрывает всё это шифрованием. Получается туннель, который и защищён, и ведёт себя как обычный линк: можно поднять по нему OSPF, добавить площадку — и маршруты разойдутся сами, без переписывания списков сетей на всех роутерах.
Плата — ещё больше накладных расходов: к двадцати четырём байтам GRE добавляются десятки байт IPsec, и внутри остаётся около 1400.
Современная альтернатива — WireGuard: он делает то же самое одним механизмом, настраивается в несколько строк, живёт в ядре и работает поверх UDP. Накладные расходы около шестидесяти байт. Там, где нет требования совместимости со старым оборудованием, обычно берут его.
Сплошная рамка — то, что читается по дороге; штриховая с замком —
то, что закрыто шифрованием. Обратите внимание на строку про протоколы маршрутизации:
именно она определяет, придётся ли вручную перечислять сети на каждом роутере
при добавлении новой площадки.
Маршрутизация через туннель
Туннель сам по себе ничего не связывает — он только даёт путь. Роутер должен ещё узнать, что чужая сеть находится за ним.
Статикой. На каждой площадке прописывают маршрут в чужие сети через интерфейс туннеля. Просто и предсказуемо, пока площадок две. На пяти площадках это уже двадцать маршрутов, и каждая новая сеть требует правки на всех.
Протоколом маршрутизации. Поверх туннеля поднимают OSPF или BGP, и маршруты расходятся сами. Именно ради этого и городят GRE внутри IPsec.
И отдельная ловушка, которая ловит всех по одному разу — рекурсивная маршрутизация. Если маршрут до внешнего адреса второй площадки вдруг начинает вести через сам туннель, туннель пытается упаковать пакет в самого себя. Он падает, маршрут пропадает, туннель поднимается, маршрут возвращается — и так по кругу. Лечится тем, что адреса концов туннеля в него никогда не заворачивают: маршрут до них держат отдельно и не отдают протоколу, работающему внутри.
Статикой. На каждой площадке прописывают маршрут в чужие сети через интерфейс туннеля. Просто и предсказуемо, пока площадок две. На пяти площадках это уже двадцать маршрутов, и каждая новая сеть требует правки на всех.
Протоколом маршрутизации. Поверх туннеля поднимают OSPF или BGP, и маршруты расходятся сами. Именно ради этого и городят GRE внутри IPsec.
И отдельная ловушка, которая ловит всех по одному разу — рекурсивная маршрутизация. Если маршрут до внешнего адреса второй площадки вдруг начинает вести через сам туннель, туннель пытается упаковать пакет в самого себя. Он падает, маршрут пропадает, туннель поднимается, маршрут возвращается — и так по кругу. Лечится тем, что адреса концов туннеля в него никогда не заворачивают: маршрут до них держат отдельно и не отдают протоколу, работающему внутри.
MTU: главная боль туннелей
Обычный кадр Ethernet везёт полторы тысячи байт. Заголовок туннеля занимает часть, и внутри остаётся меньше: у GRE — 1476, у GRE поверх IPsec — около 1400.
Дальше всё зависит от того, узнает ли об этом отправитель. Механизм определения MTU пути устроен так: отправитель шлёт полноразмерный пакет с запретом фрагментации, роутер не может его пропустить и возвращает служебное сообщение ICMP «пакет слишком большой, нужно не больше стольки-то». Отправитель уменьшает размер и продолжает.
Держится это целиком на одном типе сообщений ICMP. Стоит закрыть ICMP «на всякий случай» — и механизм ломается молча. Получается картина, которую видел каждый сетевой инженер:
ping ходит, а ничего не работает. Ping — это маленькие пакеты, они пролезают всегда. Соединение TCP тоже устанавливается: приветственные пакеты крошечные. А как только начинается передача данных полноразмерными сегментами — тишина. Такое называют чёрной дырой MTU.
Надёжное лечение не полагается на ICMP: роутер вмешивается в согласование TCP и правит в приветственном пакете поле «какого размера сегменты мне присылать». Стороны договариваются на то, что гарантированно пролезет. Приём называется зажатием MSS, и его ставят на туннелях по умолчанию, не дожидаясь жалоб. Оговорка: он помогает только TCP — UDP придётся чинить настройкой приложения.
Дальше всё зависит от того, узнает ли об этом отправитель. Механизм определения MTU пути устроен так: отправитель шлёт полноразмерный пакет с запретом фрагментации, роутер не может его пропустить и возвращает служебное сообщение ICMP «пакет слишком большой, нужно не больше стольки-то». Отправитель уменьшает размер и продолжает.
Держится это целиком на одном типе сообщений ICMP. Стоит закрыть ICMP «на всякий случай» — и механизм ломается молча. Получается картина, которую видел каждый сетевой инженер:
ping ходит, а ничего не работает. Ping — это маленькие пакеты, они пролезают всегда. Соединение TCP тоже устанавливается: приветственные пакеты крошечные. А как только начинается передача данных полноразмерными сегментами — тишина. Такое называют чёрной дырой MTU.
Надёжное лечение не полагается на ICMP: роутер вмешивается в согласование TCP и правит в приветственном пакете поле «какого размера сегменты мне присылать». Стороны договариваются на то, что гарантированно пролезет. Приём называется зажатием MSS, и его ставят на туннелях по умолчанию, не дожидаясь жалоб. Оговорка: он помогает только TCP — UDP придётся чинить настройкой приложения.
Что здесь ломается
Перепутаны local и remote. Ошибка в одну цифру, и интерфейс всё равно поднимается: согласования у туннеля нет. Состояние UP ничего не доказывает.
Маршрут прописан с одной стороны. Запрос уходит, ответ возвращаться не по чему. Классическая картина: на дальнем роутере в туннеле виден пришедший запрос без ответа.
Не учтён MTU. Ping ходит, работа стоит. Самая частая авария туннелей и самая долгая в поиске, потому что первые же проверки показывают, что «связь есть».
Закрыт ICMP. Он же и есть причина предыдущего пункта. Полностью закрывать ICMP нельзя, но полагаться на то, что его не закроют у соседа, тоже нельзя — отсюда и зажатие MSS.
Рекурсивная маршрутизация. Туннель флапает с ровным периодом, и в журнале это выглядит как проблема с каналом.
Наружу выпущено больше, чем нужно. Туннель связывает площадки целиком, и сеть партнёра или подрядчика получает доступ ко всему. Список того, что уходит в туннель, ограничивают так же осознанно, как правила на межсетевом экране.
Маршрут прописан с одной стороны. Запрос уходит, ответ возвращаться не по чему. Классическая картина: на дальнем роутере в туннеле виден пришедший запрос без ответа.
Не учтён MTU. Ping ходит, работа стоит. Самая частая авария туннелей и самая долгая в поиске, потому что первые же проверки показывают, что «связь есть».
Закрыт ICMP. Он же и есть причина предыдущего пункта. Полностью закрывать ICMP нельзя, но полагаться на то, что его не закроют у соседа, тоже нельзя — отсюда и зажатие MSS.
Рекурсивная маршрутизация. Туннель флапает с ровным периодом, и в журнале это выглядит как проблема с каналом.
Наружу выпущено больше, чем нужно. Туннель связывает площадки целиком, и сеть партнёра или подрядчика получает доступ ко всему. Список того, что уходит в туннель, ограничивают так же осознанно, как правила на межсетевом экране.
Как проверять
Порядок разбора у туннелей всегда один и тот же — снаружи внутрь.
Сначала внешние адреса: видят ли концы друг друга без всякого туннеля. Не видят — искать надо в интернете, а не в настройке.
Потом параметры туннеля с обеих сторон:
Потом адреса внутри туннеля: пингуются ли его концы. Это проверка самого туннеля без маршрутизации.
Потом маршруты, и обязательно с обеих сторон.
И только в конце — размер пакета. Если ping проходит, а передача нет, проверяйте прямо:
Сначала внешние адреса: видят ли концы друг друга без всякого туннеля. Не видят — искать надо в интернете, а не в настройке.
Потом параметры туннеля с обеих сторон:
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-наставник, который видит ваши конфиги и ведёт к решению, не выдавая готовое.
Начать бесплатно →
бета открыта, доступ бесплатный