Туннелирование и виртуальные частные сети
В предыдущих темах сеть рассматривалась как система, в которой каждый пакет доставляется по адресу назначения, указанному в его IP-заголовке: маршрутизаторы сравнивают адрес с таблицей маршрутизации (тема 8), провайдеры обмениваются маршрутами по BGP (тема 10), а частные адреса из диапазонов RFC 1918 за пределы организации не выходят и транслируются на границе (тема 14). У этой модели есть очевидное следствие, которое на практике оказывается серьёзным ограничением. Если у компании «Северный узел» есть офис с сетью 10.1.0.0/24 и филиал с сетью 10.2.0.0/24, то пакет из офиса в филиал не может просто «пойти через Интернет»: ни один маршрутизатор провайдера не знает, где находится сеть 10.2.0.0/24, а если бы и знал, то у тысяч других организаций есть свои сети с теми же адресами. Кроме того, пакет, пересекающий Интернет, видят все промежуточные узлы, и межсетевой экран из темы 18 защищает лишь границу площадки, но не канал между площадками.
Обе проблемы решает один приём — туннелирование (англ. tunneling): исходный пакет целиком помещается внутрь другого пакета, адресованного так, чтобы его мог доставить существующий Интернет, а на противоположной стороне внешний пакет снимается и исходный продолжает путь, как будто между площадками проложен прямой провод. Если к туннелю добавить шифрование и аутентификацию, получается виртуальная частная сеть (англ. Virtual Private Network, VPN) — логическая частная сеть, построенная поверх общей, не заслуживающей доверия инфраструктуры. Систематическое введение в эти вопросы дают и классические учебники 13.
Изложение построено от механизма к его применениям. Сначала рассматривается сама идея инкапсуляции пакета в пакет и её неизбежная цена — накладные расходы и уменьшение максимального размера пакета, из-за которого туннели становятся главным источником загадочных отказов в сетях. Затем разбираются туннели без шифрования — IP-in-IP и GRE — вплоть до отдельных байтов в захвате трафика. После этого формулируются задачи VPN и модели доверия, и на их фоне изучаются два основных семейства защищённых туннелей: IPsec с протоколом управления ключами IKEv2 и WireGuard; TLS-VPN (OpenVPN) рассматривается кратко. Завершает тему обзор провайдерских VPN на основе MPLS. Криптографические примитивы — симметричные шифры с аутентификацией (AEAD), обмен ключами Диффи — Хеллмана, подписи — считаются известными из темы 17; оверлейные сети центров обработки данных (VXLAN, EVPN) лишь упоминаются, подробно они изучаются в теме 21.
Идея туннеля: пакет внутри пакета
Задачи, которые решает инкапсуляция
В теме 2 инкапсуляция была введена как способ взаимодействия уровней: данные приложения становятся полезной нагрузкой сегмента TCP, сегмент — полезной нагрузкой IP-пакета, пакет — полезной нагрузкой кадра Ethernet. Каждый уровень добавляет свой заголовок и ничего не знает о содержимом нагрузки. Туннель нарушает привычный порядок уровней, но не принцип: полезной нагрузкой IP-пакета становится не сегмент транспортного уровня, а другой IP-пакет (или кадр Ethernet). Говорят, что пакет одного протокола инкапсулирован в пакет протокола того же или более низкого уровня. Протокол, пакеты которого переносятся, называют пассажирским (англ. passenger protocol), протокол, в который они упакованы, — протоколом доставки (англ. delivery protocol), а заголовок между ними, если он есть, — заголовком инкапсуляции.
Туннель решает несколько разных задач, и полезно различать их, потому что от задачи зависит выбор технологии.
Первая задача — связать сети, адреса которых не маршрутизируются на пути между ними. Пример с офисом и филиалом «Северного узла» — типичный случай: частные сети маршрутизируются только внутри организации, а путь между площадками проходит через Интернет. Внешний заголовок туннеля несёт публичные адреса маршрутизаторов площадок, которые Интернет доставить умеет.
Вторая задача — перенести протокол, который транзитная сеть не поддерживает. Исторически так переносили IPv6 через IPv4-сети (тема 11), протоколы IPX и AppleTalk через IP-магистрали, а сегодня — кадры Ethernet через IP-сеть центра обработки данных (тема 21).
Третья задача — создать логическую связность, отличную от физической. Протоколы динамической маршрутизации (тема 9) обмениваются сообщениями с непосредственными соседями; туннель делает два маршрутизатора, разделённых десятком транзитных узлов, соседями по одному виртуальному каналу, и OSPF между ними работает так же, как через кабель.
Четвёртая задача — защитить трафик на недоверенном участке. Сама по себе инкапсуляция ничего не скрывает: внутренний пакет лежит в нагрузке внешнего открытым текстом. Но инкапсуляция даёт удобную точку, где пакет можно целиком зашифровать и снабдить кодом аутентификации, — именно так устроены IPsec и WireGuard.
Анатомия туннеля: точки входа и выхода
Туннель имеет две конечные точки (англ. tunnel endpoints). Входная точка (англ. ingress, encapsulator) получает исходный пакет, решает, что его следует отправить в туннель, добавляет внешние заголовки и отправляет результат обычным способом. Выходная точка (англ. egress, decapsulator) получает внешний пакет, адресованный ей самой, распознаёт по номеру протокола или порту, что внутри лежит туннельная нагрузка, снимает внешние заголовки и обрабатывает внутренний пакет так, будто он только что пришёл с некоторого интерфейса. Промежуточные маршрутизаторы видят только внешний заголовок и маршрутизируют по нему; внутренний пакет для них — непрозрачная последовательность байтов.
В Linux и в большинстве маршрутизаторов туннель представлен виртуальным интерфейсом. Это ключевая для понимания абстракция: туннельный интерфейс выглядит для стека IP как ещё одна сетевая карта, у него есть имя (gre1, wg0), адрес и MTU, через него можно проложить маршрут. Решение «отправить пакет в туннель» принимает обычная таблица маршрутизации: если наилучший маршрут к адресу назначения указывает на туннельный интерфейс, ядро передаёт пакет драйверу этого интерфейса, а драйвер выполняет инкапсуляцию и снова передаёт получившийся внешний пакет в стек IP — на этот раз с публичным адресом назначения, который маршрутизируется через физический интерфейс. Таким образом каждый пакет, уходящий в туннель, проходит маршрутизацию дважды: сначала внутренний, затем внешний.
Из двойной маршрутизации следует классическая ошибка конфигурации — рекурсивная маршрутизация. Если маршрут к адресу удалённой конечной точки туннеля сам указывает в туннель (например, туннель настроен как маршрут по умолчанию, а отдельного маршрута к удалённой точке через физический интерфейс нет), внешний пакет нужно снова инкапсулировать, и так без конца. Реализации обнаруживают такую петлю и отбрасывают пакеты, а маршрутизаторы Cisco переводят туннель в состояние «down» с диагностикой «recursive routing». Правило простое: адрес удалённой конечной точки всегда должен быть доступен в обход самого туннеля.
Накладные расходы и уменьшение MTU
Внешние заголовки занимают место. Канал Ethernet переносит IP-пакеты размером не более 1500 байт (MTU, тема 4), и это ограничение относится к внешнему пакету. Следовательно, внутренний пакет может быть не больше 1500 байт минус размер добавленных заголовков. Для IP-in-IP это 1480 байт, для GRE — 1476, для WireGuard — 1440 при внешнем IPv4 и 1420 при внешнем IPv6. Рисунок ниже сравнивает накладные расходы основных видов туннелей на одном и том же исходном пакете.
Сама по себе потеря нескольких десятков байт на пакет невелика: при пакетах 1500 байт GRE снижает полезную долю на 24 / 1500 = 1,6 %. Опасно другое — несоответствие размеров. Хосты площадки по-прежнему подключены к Ethernet с MTU 1500 и формируют пакеты по 1500 байт, а в туннель помещается только 1476. Что произойдёт с «лишним» пакетом, определяет флаг DF (англ. Don't Fragment) в его IP-заголовке (тема 7). Если флаг сброшен, входная точка фрагментирует внутренний пакет на два и инкапсулирует каждый фрагмент отдельно; выходная точка передаст оба фрагмента дальше, и собирать их будет хост назначения. Если флаг установлен — а современные TCP-стеки устанавливают его во всех сегментах, — входная точка отбрасывает пакет и возвращает отправителю ICMP-сообщение «Destination Unreachable, Fragmentation Needed» (тип 3, код 4) с указанием MTU следующего участка. Получив его, хост уменьшает размер пакетов для этого адресата. Механизм называется обнаружением MTU пути (англ. Path MTU Discovery, PMTUD) и описан в RFC 1191 4.
PMTUD работает, только если ICMP-сообщение дошло до отправителя. Межсетевые экраны, настроенные по принципу «запретить весь ICMP», уничтожают эти сообщения, и возникает «чёрная дыра» PMTUD (англ. PMTUD black hole). Её симптомы узнаваемы: ping с маленькими пакетами проходит, TCP-соединение устанавливается (сегменты SYN малы), веб-страница начинает загружаться и зависает на первом же полноразмерном сегменте; SSH подключается, но зависает при выводе длинного листинга. Отправитель повторяет большой сегмент, не узнавая причины, а получатель ничего не получает. Проблемы фрагментации и MTU в туннелях, создаваемых внутри сети, систематизированы в RFC 4459 3.
Практическое средство против чёрных дыр — ограничение MSS (англ. MSS clamping). Максимальный размер сегмента (англ. Maximum Segment Size, MSS) — параметр, который каждая сторона TCP-соединения объявляет в сегменте SYN (тема 12): «присылай мне сегменты с данными не длиннее MSS байт». Маршрутизатор, через который проходит рукопожатие, может переписать это значение в меньшую сторону. Если входная точка GRE-туннеля уменьшит MSS в проходящих SYN до 1476 − 20 − 20 = 1436 байт, обе стороны будут сразу формировать пакеты, которые помещаются в туннель, и PMTUD не понадобится. Приём работает только для TCP, причём только для соединений, проходящих через данный маршрутизатор; для UDP (в частности, для QUIC) единственными средствами остаются PMTUD, уменьшение MTU на хостах и механизм поиска MTU на уровне протокола (англ. Packetization Layer PMTUD), описанный в RFC 4821.
Рассмотрим числовой пример. Филиал «Северного узла» подключён к провайдеру по PPPoE, что уменьшает MTU канала до 1492 байт (8 байт занимает заголовок PPPoE и PPP). Поверх него настроен WireGuard с внешним IPv6. Накладные расходы WireGuard при внешнем IPv6 составляют 40 байт IPv6 + 8 байт UDP + 16 байт заголовка сообщения + 16 байт тега аутентификации = 80 байт, значит MTU интерфейса wg0 не должен превышать 1492 − 80 = 1412 байт. Значение по умолчанию 1420 на этом канале приведёт к тому, что полноразмерные пакеты придётся либо фрагментировать на внешнем уровне, либо отбрасывать; MSS для TCP внутри туннеля должен быть не больше 1412 − 20 − 20 = 1372 байт. Доля полезных данных в полноразмерном пакете на проводе — 1372 / 1492 ≈ 92 % против 1460 / 1500 ≈ 97 % без туннеля и PPPoE.
Туннели без шифрования: IP-in-IP и GRE
IP-in-IP: минимальная инкапсуляция
Простейший туннель — инкапсуляция IP в IP, описанная в RFC 2003 1. Внешний IPv4-заголовок имеет в поле Protocol значение 4, а его полезная нагрузка — исходный IPv4-пакет без изменений, если не считать уменьшения TTL на входной точке. Никаких дополнительных полей нет, накладные расходы — 20 байт. Стандарт оговаривает, как обращаться с полями внешнего заголовка: адреса источника и назначения — адреса конечных точек туннеля, TTL выбирается входной точкой, флаг DF может копироваться из внутреннего заголовка, а ICMP-сообщения об ошибках, пришедшие на входную точку из-за внешнего пакета, по возможности транслируются в ICMP-сообщения исходному отправителю.
Минимализм IP-in-IP оборачивается ограничениями. Пассажиром может быть только IPv4 (для IPv6 внутри IPv4 используется отдельный номер протокола 41, тема 11), у туннеля нет никаких служебных полей — ни идентификатора, позволяющего различить несколько туннелей между одной парой адресов, ни признака типа нагрузки. В Linux такой туннель создаётся типом интерфейса ipip, и его MTU по умолчанию — 1480 байт.
Формат GRE и его разбор по захвату
Протокол общей инкапсуляции маршрутизации (англ. Generic Routing Encapsulation, GRE) появился в начале 1990-х годов в Cisco как универсальный способ переносить пакеты любого протокола сетевого уровня поверх другого; его современная спецификация — RFC 2784 2. «Универсальность» обеспечивает одно поле — тип протокола пассажира, в котором используются те же значения EtherType, что и в кадрах Ethernet (тема 4): 0x0800 для IPv4, 0x86DD для IPv6, 0x6558 для кадров Ethernet целиком (так называемый режим TEB, англ. Transparent Ethernet Bridging). Внешний IP-заголовок содержит в поле Protocol значение 47.
Базовый заголовок GRE занимает 4 байта:
- бит C (1 бит) — присутствует ли необязательное поле контрольной суммы;
- Reserved0 (12 бит) — зарезервировано, должно быть нулевым;
- Ver (3 бита) — версия, для GRE равна 0;
- Protocol Type (16 бит) — EtherType пассажирского протокола;
- Checksum и Reserved1 (по 16 бит) — только если C = 1.
Расширение RFC 2890 добавляет необязательные поля Key (32 бита, позволяет различать несколько туннелей между одной парой адресов) и Sequence Number. Схема на рисунке ниже показывает учебную топологию, используемую в лабораторной работе, и пакет на участке между маршрутизатором офиса и Интернетом.
Посмотрим, как выглядит такой пакет на проводе. В учебной топологии хост h1 отправил эхо-запрос хосту h2, а захват выполнен на канале между r1 и маршрутизатором провайдера:
IP (tos 0x0, ttl 64, id 55499, offset 0, flags [DF], proto GRE (47), length 60)
198.51.100.2 > 203.0.113.2: GREv0, Flags [none], length 40
IP (tos 0x0, ttl 63, id 55472, offset 0, flags [DF], proto ICMP (1), length 36)
10.1.0.10 > 10.2.0.10: ICMP echo request, id 65089, seq 1, length 16
Утилита tcpdump распознала оба уровня: внешний пакет длиной 60 байт с протоколом 47 и внутренний длиной 36 байт. Заметим, что TTL внутреннего пакета равен 63, а не 64: r1 выполнил обычную маршрутизацию внутреннего пакета (уменьшив TTL) и только потом инкапсулировал его. Шестнадцатеричный дамп того же кадра:
0x0000: 22eb e150 313d 7e45 0a55 78f6 0800 4500
0x0010: 003c d8cb 4000 402f fb8e c633 6402 cb00
0x0020: 7102 0000 0800 4500 0024 d8b0 4000 3f01
0x0030: 4f12 0a01 000a 0a02 000a 0800 edac fe41
0x0040: 0001 0001 0203 0405 0607
Разберём его по байтам. Первые 14 байт — заголовок Ethernet: MAC-адрес назначения 22:eb:e1:50:31:3d, источника 7e:45:0a:55:78:f6 и EtherType 0x0800 (IPv4). Далее начинается внешний IPv4-заголовок: 45 — версия 4 и длина заголовка 5 × 4 = 20 байт; 00 — тип обслуживания; 003c — общая длина 60 байт; d8cb — идентификатор; 4000 — флаг DF без смещения; 40 — TTL 64; 2f — протокол 47, то есть GRE; fb8e — контрольная сумма; c633 6402 — адрес 198.51.100.2; cb00 7102 — адрес 203.0.113.2. Следующие 4 байта 0000 0800 — заголовок GRE: все флаги и версия нулевые, тип протокола 0x0800, внутри IPv4. И наконец с 4500 0024 начинается внутренний пакет: 20 байт IP-заголовка с TTL 3f = 63, протоколом 01 (ICMP), адресами 0a01 000a = 10.1.0.10 и 0a02 000a = 10.2.0.10, а за ним 16 байт ICMP-сообщения (тип 8 — эхо-запрос). Итог: 14 + 20 + 4 + 20 + 16 = 74 байта кадра, из которых туннелю принадлежат ровно 24.
Этот разбор демонстрирует главное свойство туннеля без шифрования: любой промежуточный узел видит внутренние адреса, номера портов и данные. GRE обеспечивает связность, но не конфиденциальность.
Туннели в Linux: создание, маршрутизация и проверка MTU
В Linux GRE-туннель — интерфейс типа gre, создаваемый командой ip link add. Параметр local задаёт собственный внешний адрес, remote — адрес удалённой конечной точки, ttl — TTL внешнего заголовка (без него TTL наследуется от внутреннего пакета):
# на маршрутизаторе офиса r1
ip link add gre1 type gre local 198.51.100.2 remote 203.0.113.2 ttl 64
ip addr add 172.16.0.1/30 dev gre1
ip link set gre1 up
ip route add 10.2.0.0/24 via 172.16.0.2 dev gre1
На r2 выполняются симметричные команды. Адреса 172.16.0.0/30 на туннельных интерфейсах не обязательны для пересылки, но удобны: туннель становится обычной двухточечной подсетью, через которую можно, например, установить соседство OSPF. Подробный вывод ip -d link show показывает параметры туннеля и вычисленный ядром MTU:
8: gre1@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1476 qdisc noqueue state UNKNOWN
link/gre 198.51.100.2 peer 203.0.113.2
gre remote 203.0.113.2 local 198.51.100.2 ttl 64 ...
Ядро само установило MTU 1476 = 1500 − 20 − 4, исходя из MTU физического интерфейса, через который маршрутизируется адрес удалённой точки. Флаг NOARP напоминает, что на туннеле нет канального уровня и разрешения адресов: «сосед» у двухточечного туннеля один.
Теперь проверим поведение при большом пакете. Хост h1 по-прежнему считает свой MTU равным 1500 и отправляет эхо-запрос с 1472 байтами данных и запретом фрагментации (1472 + 8 байт ICMP + 20 байт IP = 1500):
ip netns exec h1 ping -c2 -M do -s 1472 10.2.0.10
PING 10.2.0.10 (10.2.0.10) 1472(1500) bytes of data.
From 10.1.0.1 icmp_seq=1 Frag needed and DF set (mtu = 1476)
ping: local error: message too long, mtu=1476
Первый пакет дошёл до r1, не поместился в gre1, и r1 вернул ICMP «Fragmentation Needed» с MTU 1476. Ядро h1 запомнило это значение в кэше маршрутов, и второй пакет уже не был отправлен: ошибку выдал локальный стек. Запомненное значение видно в выводе ip route get 10.2.0.10 как cache expires 597sec mtu 1476 — PMTU хранится ограниченное время (по умолчанию 10 минут), после чего снова проверяется. Если же флаг DF не установлен (ping -M dont), r1 фрагментирует внутренний пакет до инкапсуляции, и в захвате на внешнем канале видны два GRE-пакета с фрагментами одного внутреннего пакета: первый длиной 1500 байт (внутри — фрагмент 1476 байт с флагом MF), второй длиной 68 байт (внутри — хвост из 24 байт с данными, смещение 1456). Фрагментацию внутреннего, а не внешнего пакета Linux выбирает потому, что внешний заголовок GRE-туннеля по умолчанию имеет флаг DF (параметр pmtudisc): фрагменты внешнего пакета пришлось бы собирать на выходной точке туннеля, что дороже и уязвимее.
GRE в Linux имеет «двойника» — интерфейс типа gretap, который переносит не IP-пакеты, а целые кадры Ethernet (тип протокола 0x6558). Такой интерфейс можно включить в программный мост (тема 4) и получить единую L2-сеть на двух площадках. Тот же принцип, но с инкапсуляцией в UDP и 24-битным идентификатором сегмента, лежит в основе VXLAN; он подробно рассматривается в теме 21.
Виртуальные частные сети: задачи и модели доверия
Соединение площадок и удалённый доступ
Под виртуальной частной сетью понимают совокупность туннелей и политик, которая создаёт у участников иллюзию отдельной частной сети, хотя трафик идёт через общую инфраструктуру. Термин употребляется в двух смыслах. В широком смысле VPN — это любая логическая изоляция трафика: провайдерские MPLS VPN, о которых пойдёт речь в конце темы, изолируют трафик клиентов друг от друга, но не шифруют его. В узком смысле, привычном пользователю, VPN — это защищённый туннель через Интернет, обеспечивающий конфиденциальность, целостность и аутентификацию сторон.
По топологии различают два основных сценария. Соединение площадок (англ. site-to-site VPN) связывает сети целиком: туннель устанавливают маршрутизаторы или межсетевые экраны площадок, а хосты о нём не знают — для них маршрутизатор площадки просто знает путь к сети филиала. Туннель существует постоянно, конечные точки имеют известные (обычно статические) адреса, аутентификация выполняется сертификатами или заранее распределёнными ключами. Удалённый доступ (англ. remote access VPN) подключает отдельное устройство — ноутбук сотрудника, телефон — к сети организации. Клиент находится за NAT домашнего маршрутизатора или в сети оператора связи, его внешний адрес заранее неизвестен и меняется, туннель устанавливается по требованию, а аутентифицировать необходимо пользователя, часто с привязкой к корпоративному каталогу и второму фактору. Отдельно стоят сетевые топологии «каждый с каждым» (англ. full mesh), в которых число туннелей растёт как n(n − 1) / 2: для 20 филиалов это 190 туннелей, поэтому на практике выбирают топологию «звезда» с центральной площадкой или средства автоматического построения туннелей.
Что защищает VPN и кому приходится доверять
Защищённый туннель гарантирует, что данные на участке между его конечными точками нельзя прочитать и незаметно изменить. Важно понимать границы этой гарантии. Во-первых, защищён только участок туннеля: от выходной точки до сервера трафик идёт так же, как шёл бы без VPN. Во-вторых, внешний заголовок остаётся открытым: наблюдатель на пути видит адреса конечных точек, время и объём трафика, а часто и сам факт использования VPN — по номеру протокола (ESP — 50), порту (IKE — UDP 500 и 4500, WireGuard — по умолчанию UDP 51820, OpenVPN — UDP 1194) или характерным размерам сообщений рукопожатия. Защита содержимого не равна сокрытию факта связи.
В-третьих, VPN переносит доверие, а не устраняет его. Корпоративный VPN защищает трафик сотрудника от владельца гостиничного Wi-Fi, но весь этот трафик видит организация, управляющая выходной точкой. Коммерческий «VPN-сервис» для частных лиц скрывает трафик от провайдера доступа, но лишь потому, что всё доверие передаётся оператору сервиса, который видит те же метаданные, что видел провайдер. Корпоративный доступ и обход сетевых ограничений технически используют одни и те же протоколы, но решают разные задачи: в первом случае цель — доступ к внутренним ресурсам с проверкой пользователя и устройства, во втором — смена точки выхода в Интернет и маскировка самого туннеля. Последняя задача породила протоколы, имитирующие обычный HTTPS-трафик, однако их устройство выходит за рамки курса.
Наконец, модель «периметр плюс VPN» — сотрудник, подключившийся к VPN, получает доступ ко всей внутренней сети — противоречит принципу минимальных привилегий (тема 18). Скомпрометированный ноутбук становится плацдармом внутри периметра. Поэтому современные архитектуры нулевого доверия (англ. zero trust) проверяют каждое обращение к каждому приложению, а VPN в них — лишь одно из средств защиты канала.
Практические проблемы: MTU, раздельное туннелирование, утечки DNS
Помимо уже рассмотренной проблемы MTU, у VPN удалённого доступа есть две характерные проблемы маршрутизации.
Первая — выбор, какой трафик направлять в туннель. При полном туннелировании (англ. full tunnel) клиент получает маршрут по умолчанию через туннель, и весь его трафик, включая обращения к внешним сайтам, проходит через организацию — это позволяет применить корпоративные политики, но нагружает канал организации и увеличивает задержку. При раздельном туннелировании (англ. split tunneling) в туннель направляются только префиксы внутренних сетей, а остальной трафик идёт напрямую. Решение принимает таблица маршрутизации клиента, и типичная ошибка — пересечение адресов: если домашняя сеть сотрудника использует тот же диапазон 10.1.0.0/24, что и офис, маршрут к непосредственно подключённой домашней сети окажется предпочтительнее, и офис станет недоступен. Выбор неочевидных внутренних диапазонов при проектировании адресного плана (тема 6) избавляет от многих таких обращений в службу поддержки.
Вторая — утечки DNS (англ. DNS leak). Даже если весь IP-трафик идёт в туннель, операционная система может продолжать отправлять DNS-запросы серверу, полученному от DHCP локальной сети (тема 14), — и тогда наблюдатель в локальной сети видит, какие имена разрешает пользователь. Обратный случай для раздельного туннелирования: внутренние имена вида intranet.nsu.example должны разрешаться корпоративным DNS-сервером через туннель, а внешние — как обычно. Клиенты VPN решают это настройкой локального резолвера (в Linux — systemd-resolved с маршрутизацией запросов по доменам), но при неправильной настройке запросы утекают. Родственная проблема — утечка трафика в моменты, когда туннель ещё не поднят или упал; функцию «аварийного выключателя» (англ. kill switch) реализуют правилами межсетевого экрана, разрешающими выход только через туннельный интерфейс.
IPsec: защита на сетевом уровне
Архитектура: ассоциации безопасности и базы политик
IPsec (англ. IP Security) — семейство протоколов IETF, обеспечивающее защиту IP-пакетов на сетевом уровне. Он разрабатывался в 1990-х годах одновременно с IPv6, и его текущая архитектура описана в RFC 4301 5. В отличие от TLS (тема 17), который защищает одно соединение транспортного уровня и встроен в приложение, IPsec работает в ядре операционной системы или в маршрутизаторе и прозрачен для приложений: защищён может быть любой IP-трафик, включая UDP, ICMP и протоколы маршрутизации.
Центральное понятие IPsec — ассоциация безопасности (англ. Security Association, SA): однонаправленное соглашение двух узлов о том, как защищать пакеты — каким протоколом (AH или ESP), каким алгоритмом, с какими ключами, в каком режиме, с какими счётчиками. Поскольку SA однонаправлена, для двустороннего обмена нужна пара SA. Каждая SA идентифицируется 32-битным индексом параметров безопасности (англ. Security Parameters Index, SPI), который получатель выбирает сам и который передаётся в каждом защищённом пакете: по SPI получатель находит нужную SA и ключи, не расшифровывая пакет.
Архитектура вводит две базы данных. База политик безопасности (англ. Security Policy Database, SPD) отвечает на вопрос «что делать с этим пакетом?» по его селекторам — адресам, протоколу, портам. Возможных решений три: защитить (PROTECT — направить через определённую SA), пропустить без защиты (BYPASS) или отбросить (DISCARD). База ассоциаций безопасности (англ. Security Association Database, SAD) хранит параметры действующих SA. Обработка исходящего пакета сводится к поиску в SPD; если политика требует защиты, а подходящей SA ещё нет, ядро запрашивает её у демона управления ключами, и тот устанавливает SA по протоколу IKE. В Linux обе базы реализует подсистема XFRM, их содержимое показывают команды ip xfrm policy и ip xfrm state, а протокол IKE реализуют пользовательские демоны, например strongSwan или Libreswan.
Заметим принципиальное отличие от GRE: в «классическом» IPsec решение о защите принимает политика по селекторам, а не таблица маршрутизации, и отдельного интерфейса может не быть. Это делает IPsec гибким, но плохо сочетается с динамической маршрутизацией, поэтому на практике часто используют маршрутный вариант (англ. route-based VPN): создаётся виртуальный интерфейс (в Linux — xfrm или vti), всё, что маршрутизируется в него, защищается одной парой SA, а выбор трафика снова выполняет таблица маршрутизации. Распространена и комбинация «GRE поверх IPsec»: GRE создаёт интерфейс, по которому ходят OSPF и мультикаст, а IPsec в транспортном режиме защищает GRE-пакеты между двумя маршрутизаторами.
Протоколы AH и ESP, транспортный и туннельный режимы
IPsec определяет два протокола защиты пакетов. Заголовок аутентификации (англ. Authentication Header, AH, протокол 51, RFC 4302 6) обеспечивает целостность и аутентификацию источника, причём защищает и неизменяемые поля внешнего IP-заголовка — адреса, протокол, длину. Шифрования AH не обеспечивает. Инкапсуляция защищённой нагрузки (англ. Encapsulating Security Payload, ESP, протокол 50, RFC 4303 7) обеспечивает конфиденциальность, целостность, аутентификацию и защиту от повторов, но защищает только то, что находится после её заголовка. Из-за защиты адресов AH несовместим с NAT (трансляция меняет адрес, и проверка целостности перестаёт сходиться), а ESP с алгоритмами AEAD перекрывает его возможности. Поэтому на практике используется почти исключительно ESP, а AH реализуется для совместимости.
Пакет ESP состоит из заголовка, зашифрованной части и кода целостности. Заголовок ESP — 8 байт: SPI (32 бита) и порядковый номер (англ. Sequence Number, 32 бита, с расширением до 64 бит, которое не передаётся). Зашифрованная часть включает защищаемые данные, выравнивание (англ. padding), однобайтовую длину выравнивания и однобайтовое поле Next Header, указывающее, что лежит внутри: 6 — TCP, 17 — UDP, 4 — IPv4-пакет целиком. Завершает пакет значение проверки целостности (англ. Integrity Check Value, ICV). Порядковый номер растёт с каждым пакетом, и получатель поддерживает скользящее окно принятых номеров (типично 64 пакета и более): пакет с номером, уже встречавшимся или оставшимся левее окна, отбрасывается. Так реализуется защита от повторов (англ. anti-replay) — злоумышленник не может записать защищённый пакет и отправить его повторно.
Каждый из протоколов может работать в одном из двух режимов, показанных на рисунке ниже. В транспортном режиме (англ. transport mode) заголовок ESP вставляется между исходным IP-заголовком и заголовком транспортного уровня; адреса пакета остаются исходными, накладные расходы минимальны. Этот режим применяется, когда конечные точки IPsec совпадают с конечными точками связи — например, для защиты обмена между двумя серверами или для защиты GRE-туннеля. В туннельном режиме (англ. tunnel mode) исходный пакет целиком, вместе с IP-заголовком, становится защищаемыми данными, а снаружи добавляется новый IP-заголовок с адресами шлюзов. Это и есть IPsec VPN между площадками: внутренние адреса зашифрованы, наблюдатель видит только адреса шлюзов и номер протокола 50.
Подсчитаем накладные расходы туннельного ESP с алгоритмом AES-GCM с 16-байтовым ICV (RFC 4106). Добавляются новый IP-заголовок (20 байт), заголовок ESP (8), вектор инициализации GCM (8), минимум 2 байта трейлера и ICV (16), итого 54 байта плюс от 0 до 3 байт выравнивания: длина зашифрованной части (данные, выравнивание и два байта трейлера) должна быть кратна 4. При внешнем MTU 1500 на данные остаётся 1500 − 20 − 8 − 8 − 16 = 1448 байт, из них 2 байта занимает трейлер, поэтому максимальный внутренний пакет — 1446 байт. С блочным шифром в режиме CBC выравнивание идёт до границы 16-байтового блока, вектор инициализации занимает 16 байт, и накладные расходы оказываются ещё больше. Поэтому MTU IPsec-туннеля нельзя вывести из одной формулы: он зависит от выбранных алгоритмов.
IKEv2: согласование ключей и установление ассоциаций
Ассоциации безопасности можно задать вручную, прописав ключи и SPI на обеих сторонах, но такая схема не масштабируется и не даёт прямой секретности: ключи годами не меняются. Поэтому SA устанавливаются автоматически протоколом обмена ключами в Интернете (англ. Internet Key Exchange, IKE), текущая версия которого, IKEv2, описана в RFC 7296 8. IKE работает поверх UDP, порт 500, и сам по себе устанавливает защищённый управляющий канал — IKE SA, внутри которого затем согласуются ассоциации для данных, называемые дочерними (англ. Child SA).
Базовый обмен IKEv2 состоит из двух пар сообщений, то есть занимает два периода кругового обхода:
IKE_SA_INIT(запрос и ответ). Стороны предлагают и выбирают криптографические алгоритмы, обмениваются открытыми значениями Диффи — Хеллмана (тема 17) и случайными числами (англ. nonce). После этого обмена обе стороны вычисляют общий секрет и выводят из него ключи IKE SA, но ещё не знают, с кем говорят.IKE_AUTH(запрос и ответ, уже зашифрованные). Стороны предъявляют идентификаторы и доказывают, что они те, за кого себя выдают: подписью сертифицированным ключом, заранее распределённым ключом (англ. pre-shared key, PSK) или через протокол EAP с внешним сервером аутентификации. В этом же обмене согласуются селекторы трафика (какие адреса защищать) и создаётся первая Child SA.
Дополнительные Child SA и плановая смена ключей (англ. rekeying) выполняются обменом CREATE_CHILD_SA, а служебные уведомления — обменом INFORMATIONAL. Рукопожатие защищено от простейшего DoS механизмом «cookie»: перегруженный ответчик может не создавать состояние до тех пор, пока инициатор не подтвердит, что действительно владеет своим адресом. Сравнительно с первой версией IKE (RFC 2409), в которой было восемь вариантов обмена и множество необязательных режимов, IKEv2 существенно проще, однако IPsec в целом остаётся сложной системой: количество параметров, которые должны совпасть на двух сторонах, — главная причина неудачных попыток «поднять туннель» между оборудованием разных производителей.
NAT-T: IPsec через трансляцию адресов
ESP — самостоятельный протокол сетевого уровня с номером 50, и у него нет портов. Трансляция адресов и портов (тема 14) различает сеансы по портам TCP и UDP, поэтому ESP-пакеты нескольких клиентов за одним NAT-устройством оно различить не может, и многие домашние маршрутизаторы просто не пропускают ESP. Решение, называемое обходом NAT (англ. NAT Traversal, NAT-T), стандартизовано в RFC 3948 9: ESP-пакеты помещаются в UDP-датаграммы с портом 4500 — ещё одна инкапсуляция, добавляющая 8 байт. Чтобы на одном порту различать IKE и ESP, сообщения IKE на порту 4500 предваряются четырьмя нулевыми байтами (англ. non-ESP marker), а пакеты ESP начинаются с SPI, который не может быть нулевым.
Узнают о наличии NAT сами участники IKE: в обмене IKE_SA_INIT каждая сторона отправляет уведомления NAT_DETECTION_SOURCE_IP и NAT_DETECTION_DESTINATION_IP, содержащие хеш адресов и портов, какими их видит отправитель. Если получатель, вычислив хеш по фактическим адресам пакета, получает другое значение, значит, по дороге адреса были изменены, и стороны переходят на порт 4500. Поскольку запись в таблице NAT удаляется после периода неактивности, сторона за NAT периодически отправляет однобайтовые пакеты поддержания (англ. NAT-keepalive, байт 0xFF), по умолчанию раз в 20 секунд.
WireGuard и TLS-VPN
Криптомаршрутизация: ключи и AllowedIPs
WireGuard — протокол защищённого туннеля, предложенный Дж. Доненфельдом и представленный на симпозиуме NDSS в 2017 году 10; в 2020 году его реализация вошла в основное ядро Linux (версия 5.6). Его проектирование было реакцией на сложность IPsec: вместо согласования алгоритмов — один фиксированный набор современных примитивов, вместо базы политик и демона управления ключами — один сетевой интерфейс, вместо сертификатов и идентификаторов — открытые ключи. Реализация в ядре Linux занимает около 4 тысяч строк, что делает её доступной для полного аудита.
Каждый участник WireGuard идентифицируется парой ключей Curve25519: закрытым ключом (32 случайных байта) и открытым, вычисленным из закрытого. Ключи записываются в кодировке Base64 и занимают 44 символа. Интерфейс WireGuard (wg0) имеет собственный закрытый ключ и UDP-порт, на котором принимает пакеты, и список пиров (англ. peers). Для каждого пира задаются его открытый ключ, необязательный адрес назначения (англ. endpoint: IP-адрес и порт) и список разрешённых адресов (AllowedIPs). Понятия «сервер» и «клиент» в протоколе отсутствуют — есть только пиры; разница лишь в том, у кого из них известен заранее endpoint.
Список AllowedIPs — ядро идеи, которую автор называет криптомаршрутизацией (англ. cryptokey routing): это одновременно таблица маршрутизации внутри интерфейса и список контроля доступа. Механизм показан на рисунке ниже. При отправке пакета через wg0 его адрес назначения ищется среди AllowedIPs всех пиров по правилу наибольшего совпадающего префикса (тема 8); найденный пир определяет ключи шифрования и endpoint. Если совпадения нет, пакет отбрасывается, а отправитель получает ICMP-сообщение о недостижимости. При приёме пакет сначала расшифровывается, причём сам успешный результат расшифровки доказывает, от какого пира он пришёл, а затем адрес источника внутреннего пакета проверяется по AllowedIPs этого пира. Пакет, пришедший от пира c1 с внутренним адресом, принадлежащим r2, будет отброшен. Таким образом, связь «открытый ключ — внутренние адреса» аутентифицирована криптографически, и подмена внутреннего адреса источника невозможна.
Важно не путать AllowedIPs с таблицей маршрутизации ядра. Чтобы пакет попал в wg0, в таблице маршрутизации должен быть маршрут через этот интерфейс; AllowedIPs решают лишь, какому из пиров интерфейса пакет отправить. Утилита wg-quick автоматически добавляет маршруты ко всем префиксам из AllowedIPs, что создаёт впечатление, будто это одно и то же, но при ручной настройке через ip и wg маршруты нужно добавить явно. Вывод команды wg show на маршрутизаторе офиса из лабораторной работы показывает обе стороны конфигурации:
interface: wg0
public key: 2PfZdWCZFEhYInMEFdcZkHEgtFl60cdbDz+VV5Ov82w=
private key: (hidden)
listening port: 51820
peer: Qw+XhLa6LHuqPxjkBIJMYAA2XDpgiQU9+7B1MnQ0NUE=
endpoint: 203.0.113.2:51820
allowed ips: 10.255.0.2/32, 10.2.0.0/24
latest handshake: 4 seconds ago
transfer: 348 B received, 404 B sent
Рукопожатие Noise и формат сообщений
WireGuard использует единый набор алгоритмов: обмен ключами Диффи — Хеллмана на кривой Curve25519, шифрование с аутентификацией ChaCha20-Poly1305, хеш-функцию BLAKE2s и функцию вывода ключей HKDF. Рукопожатие построено по шаблону IKpsk2 из каркаса протоколов Noise: инициатор заранее знает статический открытый ключ ответчика (буква K), а свой статический ключ передаёт в первом же сообщении в зашифрованном виде (буква I); необязательный общий симметричный ключ (англ. preshared key, psk2) добавляет к асимметричной защите ещё один слой — на случай появления квантовых компьютеров, способных взломать Curve25519.
Обмен состоит из двух сообщений, то есть занимает один период кругового обхода, и после него стороны получают пару симметричных сеансовых ключей — по одному на каждое направление. В каждом рукопожатии генерируются новые эфемерные ключи, поэтому компрометация статического ключа в будущем не позволит расшифровать записанный ранее трафик — это свойство прямой секретности (тема 17). Сеансовые ключи меняются новым рукопожатием каждые две минуты (константа REKEY_AFTER_TIME = 120 с), а пакеты на ключах старше трёх минут не принимаются (REJECT_AFTER_TIME = 180 с) 11.
WireGuard определяет четыре типа сообщений, каждое начинается с однобайтового типа и трёх нулевых байтов 11. Захват на внешнем канале учебной топологии при первом эхо-запросе через туннель:
198.51.100.2.51820 > 203.0.113.2.51820: UDP, length 148
203.0.113.2.51820 > 198.51.100.2.51820: UDP, length 92
198.51.100.2.51820 > 203.0.113.2.51820: UDP, length 128
203.0.113.2.51820 > 198.51.100.2.51820: UDP, length 128
Первое сообщение длиной 148 байт — инициация рукопожатия (тип 1): индекс отправителя (4 байта), эфемерный открытый ключ (32), зашифрованный статический ключ инициатора (32 + 16 байт тега), зашифрованная метка времени TAI64N (12 + 16) и два поля MAC по 16 байт. Метка времени защищает от повтора записанной инициации: ответчик запоминает наибольшую метку от каждого пира и отвергает не превосходящие её. Второе сообщение длиной 92 байта — ответ (тип 2): индексы обеих сторон, эфемерный ключ ответчика, пустая зашифрованная нагрузка (только тег 16 байт) и два MAC. Третий тип (64 байта, cookie reply) используется только при перегрузке. Далее идут транспортные сообщения (тип 4): заголовок из 16 байт — тип, индекс получателя и 64-битный счётчик, служащий одновременно одноразовым числом шифра и номером для защиты от повторов, — затем зашифрованный внутренний пакет, дополненный нулями до длины, кратной 16, и 16-байтовый тег Poly1305. Проверим длину: внутренний ICMP-пакет из ping занимает 84 байта, выравнивание до 96, плюс 16 байт заголовка и 16 байт тега дают ровно 128 байт, что и показывает захват. В отличие от GRE, в нагрузке не видно ни внутренних адресов, ни протокола: наблюдатель знает только адреса конечных точек и длины пакетов.
Роуминг, «молчание» и поддержание связи
Несколько свойств WireGuard непосредственно вытекают из того, что пир идентифицируется ключом, а не адресом. Первое — роуминг (англ. roaming). Получив аутентифицированный пакет от пира с нового внешнего адреса или порта, WireGuard просто обновляет его endpoint и отвечает уже туда. Ноутбук, перешедший из офисного Wi-Fi в сеть мобильного оператора, продолжает работать в туннеле без повторного подключения; так же туннель переживает смену внешнего порта на NAT-устройстве. По той же причине endpoint клиента на сервере удалённого доступа указывать не нужно: сервер узнает его из первого пакета.
Второе — «молчание» (англ. stealth). WireGuard не отвечает на пакеты, которые не удалось аутентифицировать: при сканировании портов он не отвечает и не порождает даже ICMP «порт недостижим», как закрытый порт UDP, поэтому выглядит фильтруемым (у nmap — open|filtered), а постороннему невозможно даже узнать, что на узле работает WireGuard. Протокол не поддерживает соединение в фоне: если данных нет, по проводу ничего не передаётся. Это хорошо для мобильных устройств, но плохо для клиента за NAT: запись в таблице трансляции истекает, и сервер теряет возможность послать клиенту пакет первым. Параметр PersistentKeepalive (обычно 25 секунд) заставляет пира периодически отправлять пустое аутентифицированное сообщение, чтобы запись не истекала.
Третье — защита от DoS. Проверка инициации требует операции на эллиптической кривой, и поток поддельных инициаций мог бы загрузить процессор. Поле mac1 в каждой инициации вычисляется от открытого ключа получателя, поэтому сообщения от тех, кто этот ключ не знает, отбрасываются дешёвой проверкой хеша. Под нагрузкой ответчик требует ещё и поле mac2, вычисленное с помощью «cookie» — значения, зависящего от IP-адреса инициатора, которое ответчик высылает в сообщении типа 3. Тем самым инициатор должен доказать, что действительно получает пакеты на свой адрес.
У простоты есть цена. В WireGuard нет встроенных средств раздачи адресов, учётных записей и проверки пользователей: распределение ключей и конфигураций остаётся задачей администратора или внешних систем. Нет и согласования алгоритмов: если в одном из примитивов найдут уязвимость, потребуется новая версия протокола. Наконец, WireGuard работает только поверх UDP, что затрудняет его использование в сетях, где разрешён лишь HTTPS.
TLS-VPN и сравнение технологий
Третье широко распространённое семейство — VPN на основе TLS. Самый известный представитель — OpenVPN: пользовательская программа, которая создаёт виртуальный интерфейс (tun для IP-пакетов или tap для кадров Ethernet), устанавливает управляющий канал по протоколу TLS (тема 17) с проверкой сертификатов и затем передаёт туннельные пакеты поверх UDP (порт 1194 по умолчанию) или TCP. Преимущества — богатые средства аутентификации и раздачи конфигурации клиентам и возможность работать через TCP-порт 443, где пропускается почти всё. Недостатки — производительность пользовательской реализации ниже, чем у ядерных IPsec и WireGuard, а режим поверх TCP подвержен эффекту «TCP поверх TCP»: при потере пакета повторную передачу одновременно запускают внешний и внутренний TCP, их таймеры взаимодействуют, и пропускная способность резко падает. Близкий подход используют коммерческие SSL-VPN, а также современные протоколы на базе QUIC и HTTP/3, позволяющие переносить IP-пакеты внутри соединения HTTP.
Таблица сводит характеристики рассмотренных технологий.
| Свойство | GRE | IPsec (ESP + IKEv2) | WireGuard | OpenVPN |
|---|---|---|---|---|
| Уровень и транспорт | IP, протокол 47 | IP, протокол 50; UDP 500/4500 | UDP, порт задаётся (обычно 51820) | UDP или TCP (обычно 1194) |
| Шифрование | нет | да, согласуемые алгоритмы | да, фиксированный набор | да, TLS + согласуемые шифры |
| Аутентификация сторон | нет | PSK, сертификаты, EAP | открытые ключи | сертификаты, логин и пароль |
| Выбор трафика | маршрутизация | политики SPD или маршрутизация (VTI) | маршрутизация + AllowedIPs | маршрутизация |
| Работа через NAT | плохо | с NAT-T | да | да |
| Накладные расходы, IPv4 | 24 байта | 54–73 байта, с NAT-T ещё 8 | 60 байт | зависит от режима, обычно 50–70 байт |
| Сложность настройки | минимальная | высокая | низкая | средняя |
| Типичное применение | связность, оверлеи | соединение площадок, оборудование разных производителей | площадки, удалённый доступ | удалённый доступ |
Выбор технологии определяется задачей. Для связи с оборудованием провайдера или облачного оператора стандартом де-факто остаётся IPsec с IKEv2: его поддерживает всё сетевое оборудование. Для собственной инфраструктуры на Linux простота и производительность делают естественным выбором WireGuard. GRE без шифрования уместен внутри доверенной сети или как интерфейс поверх IPsec. TLS-VPN выбирают, когда важно прохождение через строгие межсетевые экраны или интеграция с корпоративной аутентификацией.
Провайдерские VPN на основе MPLS
Коммутация по меткам
Все рассмотренные VPN строит сама организация поверх Интернета. Исторически же корпоративные сети связывались услугами операторов — выделенными каналами, а затем виртуальными каналами Frame Relay и ATM. Их современный наследник — VPN на основе многопротокольной коммутации по меткам (англ. Multiprotocol Label Switching, MPLS), архитектура которой описана в RFC 3031 14. Идея MPLS — заменить на транзитных маршрутизаторах поиск наибольшего совпадающего префикса по IP-адресу на поиск по короткой метке фиксированной длины. На входе в сеть оператора пограничный маршрутизатор (англ. Label Edge Router, LER) классифицирует пакет и добавляет к нему метку; транзитные маршрутизаторы (англ. Label Switching Router, LSR) по входной метке находят в таблице выходной интерфейс и новую метку, заменяют метку и пересылают пакет; на выходе метка снимается. Последовательность меток задаёт путь с коммутацией по меткам (англ. Label Switched Path, LSP).
Запись метки (англ. label stack entry) занимает 32 бита и помещается между заголовками канального и сетевого уровней: 20 бит — значение метки, 3 бита — класс трафика, 1 бит S — признак дна стека, 8 бит — TTL. Метки можно складывать в стек, и это делает MPLS разновидностью туннелирования: внешняя метка доставляет пакет до нужного пограничного маршрутизатора, а внутренняя указывает, что с ним делать там. Исходное назначение MPLS — ускорение коммутации — давно потеряло актуальность, поскольку маршрутизаторы научились выполнять поиск по префиксу аппаратно с той же скоростью; сохранились и развились другие его возможности — управление путями трафика (англ. traffic engineering) и VPN.
BGP/MPLS L3VPN
Наиболее массовая услуга операторов для корпоративных клиентов — VPN третьего уровня по RFC 4364 12. Каждый клиентский маршрутизатор (англ. Customer Edge, CE) подключён к пограничному маршрутизатору оператора (англ. Provider Edge, PE). На PE для каждого клиента создаётся отдельный экземпляр таблицы маршрутизации — VRF (англ. Virtual Routing and Forwarding), так что пересекающиеся частные адреса разных клиентов друг другу не мешают. Маршруты клиентов передаются между PE по протоколу MP-BGP (тема 10) в расширенном виде: к префиксу добавляется 64-битный различитель маршрутов (англ. Route Distinguisher, RD), делающий адреса разных клиентов уникальными, а атрибуты «цель маршрута» (англ. Route Target, RT) определяют, в какие VRF маршрут импортируется. Пересылка выполняется двумя метками: внешняя доставляет пакет до нужного PE через ядро оператора, внутренняя указывает VRF на этом PE. Транзитные маршрутизаторы ядра (англ. Provider, P) о клиентских маршрутах ничего не знают.
Такая VPN изолирует трафик клиентов логически, но не шифрует его: клиент доверяет оператору. Её достоинства — гарантированное качество обслуживания и отсутствие у клиента необходимости настраивать туннели; недостатки — стоимость и зависимость от одного оператора. Последнее десятилетие эту нишу активно занимают программно-определяемые глобальные сети (англ. SD-WAN): устройства на площадках автоматически строят IPsec-туннели через несколько доступных каналов, в том числе обычный Интернет и мобильную связь, и распределяют трафик приложений между ними по измеренным задержкам и потерям. Технически SD-WAN — это управляемая централизованно совокупность тех же механизмов, что изучены в этой теме: туннелей, IPsec, маршрутизации и политик. Ещё одно направление — идеи VRF и стековой инкапсуляции в центрах обработки данных, где роль MPLS играет VXLAN с плоскостью управления EVPN; эти вопросы рассматриваются в теме 21.
Анонимизирующие оверлейные сети: луковая и чесночная маршрутизация
Все рассмотренные выше технологии — IPsec, WireGuard, OpenVPN — решают задачу объединения доверенных площадок или защищённого выхода в Интернет через посредника (VPN-провайдера). Однако модель доверия коммерческого или корпоративного VPN имеет фундаментальное ограничение: концентрация доверия в одной точке. Оператор VPN-шлюза видит исходный IP-адрес клиента и одновременно видит все исходящие подключения, посещаемые домены и время активности. Если оператор скомпрометирован, ведёт журналы или подвергается давлению со стороны регулятора, связь между клиентом и его действиями в сети восстанавливается тривиально.
Для противодействия анализу сетевого трафика и устранения единой точки доверия были разработаны распределённые анонимизирующие оверлейные сети. Вместо одного посредника они пропускают трафик через цепочку независимых промежуточных узлов, распределяя доверие так, чтобы ни один узел в сети не обладал полной информацией о соединении.
Tor и луковая маршрутизация (Onion Routing)
Протокол Tor (The Onion Router) реализует концепцию луковой маршрутизации, разработанную в Исследовательской лаборатории ВМС США (NRL) 15. Принцип работы Tor основан на трёх ключевых механизмах:
- Цепочка из трёх релеев (Circuit): клиентское ПО (Tor Onion Proxy) строит виртуальный канал через три случайно выбранных узла из публичного списка:
- Входной узел (Guard Relay): знает реальный IP-адрес клиента, но не знает адрес назначения и видит только зашифрованный трафик до промежуточного узла. Для защиты от атак профилирования клиент использует фиксированные доверенные Guard-узлы в течение нескольких месяцев.
- Промежуточный узел (Middle Relay): знает только предыдущий (Guard) и последующий (Exit) узлы. Он изолирует вход от выхода: ни входной, ни выходной узел не видят друг друга напрямую.
- Выходной узел (Exit Relay): снимает последний слой шифрования и отправляет открытый (или защищённый TLS) трафик на целевой сервер Интернета. Выходной узел видит адрес назначения, но не имеет возможности узнать реальный IP-адрес отправителя.
- Многослойное шифрование («луковица»): клиент последовательно согласовывает сеансовые симметричные ключи (по протоколу ntor на базе Curve25519) с каждым узлом цепочки. При отправке пакета полезная нагрузка шифруется сначала ключом Exit, затем Middle, затем Guard. Проходя через узлы, пакет послойно расшифровывается (каждый узел снимает свой слой «кожуры»), причём размер ячеек Tor строго фиксирован (514 байт), что предотвращает анализ объёмов пересылаемых данных.
- Скрытые сервисы (Onion Services): Tor позволяет размещать серверы, IP-адрес которых скрыт даже от клиентов. Адрес скрытого сервиса в версии v3 имеет вид
56_символов.onionи представляет собой закодированный в Base32 открытый ключ Ed25519 сервера 16. Связь между клиентом и скрытым сервисом устанавливается вслепую через промежуточную точку встречи (Rendezvous Point) и сеть узлов интродукции (Introduction Points), обеспечивая сквозную взаимную анонимность: клиент не знает, где физически находится сервер, а сервер не знает, кто к нему обращается.
Каталог всех активных узлов формируется консенсусом девяти доверенных серверов авторитетов каталога (Directory Authorities) раз в час, публикующих подписанный сетевой статус.
I2P и чесночная маршрутизация (Garlic Routing)
Проект I2P (Invisible Internet Project) разрабатывался с иной философией 17. Если Tor проектировался преимущественно для анонимного доступа к внешнему Интернету («outproxy»), то I2P — это закрытая автономная оверлейная сеть (Darknet), оптимизированная для внутрисетевого взаимодействия (внутренние сайты eepsites с доменами .i2p, защищённая почта I2P-Bote, торренты I2PSnark).
Принципиальные отличия I2P от Tor:
- Чесночная маршрутизация (Garlic Routing): развитие луковой маршрутизации. Клиент объединяет несколько независимых сообщений (называемых «зубчиками чеснока», cloves), каждое со своими инструкциями доставки и отдельным слоем сквозного шифрования (ElGamal / ECIES + AES-256), в один общий зашифрованный пакет («головку чеснока»). Промежуточный узел, расшифровав внешний контейнер, рассылает отдельные зубчики по разным адресатам, что резко затрудняет сопоставление трафика.
- Однонаправленные туннели (Unidirectional Tunnels): в Tor входящие и исходящие пакеты сессии идут по одной и той же цепочке из трёх узлов. В I2P входящий трафик идёт по одному туннелю (Inbound Tunnel), а исходящий — по совершенно другому (Outbound Tunnel), сформированному из других маршрутизаторов. Атакующему, контролирующему один из туннелей, намного труднее наблюдать корреляцию запроса и ответа.
- Полная децентрализация (NetDB и Kademlia): в I2P нет серверов каталогов или централизованных авторитетов. Информация о топологии сети, маршрутизаторах и криптографических адресах (LeaseSets) распределена по распределённой хеш-таблице (DHT Kademlia), поддерживаемой высокопроизводительными узлами (Floodfill routers).
- Сетевая модель «каждый клиент — маршрутизатор»: по умолчанию каждый запущенный узел I2P участвует в транзитной пересылке чужого зашифрованного трафика, смешивая собственный поток с транзитным.
Микснеты и пределы стойкости оверлеев
Ни Tor, ни I2P не защищают от глобального пассивного наблюдателя (Global Passive Adversary) — противника (например, коалиции магистральных провайдеров Tier-1 или спецслужб), способного одновременно отслеживать входной и выходной трафик сети. Поскольку Tor и I2P являются сетями с малой задержкой (англ. low-latency networks), пакет проходит через цепочку за десятки миллисекунд. Анализируя временные метки пакетов и флуктуации скорости (англ. traffic confirmation / statistical timing analysis), наблюдатель сопоставляет всплески трафика на входе в Guard-узел и выходе из Exit-узла с математической достоверностью свыше 95 % 18.
Для защиты от глобального наблюдателя применяются микснеты с большой задержкой (High-Latency Mixnets: Loopix, Nym) 19:
- узлы-миксеры накапливают пакеты в буфере и задерживают их на случайный интервал времени, распределённый по закону Пуассона;
- порядок отправки пакетов перемешивается;
- сеть непрерывно генерирует фиктивный шумовой трафик (англ. cover / chaff traffic), неотличимый по криптографическим свойствам от полезных данных (сфинкс-пакеты, Sphinx format).
Микснеты обеспечивают наивысшую математическую защиту от анализа трафика, однако ценой задержки сообщений от сотен миллисекунд до десятков секунд, что делает их пригодными для обмена сообщениями, голосований и транзакций, но непригодными для интерактивного веб-сёрфинга и потокового аудио.
Итоги темы
Туннель — это инкапсуляция пакета в пакет, позволяющая доставить трафик через сеть, которая не умеет или не должна его маршрутизировать. Конечные точки туннеля добавляют и снимают внешний заголовок, промежуточные узлы видят только его, а сам туннель в операционной системе выглядит как виртуальный интерфейс, решение о передаче в который принимает обычная таблица маршрутизации. Из этого следуют две практически важные закономерности: каждый пакет маршрутизируется дважды, поэтому адрес удалённой точки должен быть доступен в обход туннеля, и каждый туннель уменьшает MTU на размер своих заголовков, поэтому без работающего PMTUD или ограничения MSS туннели порождают «чёрные дыры», в которых маленькие пакеты проходят, а большие исчезают.
Туннели без шифрования — IP-in-IP и GRE — дают связность и только её: в захвате GRE-трафика внутренние адреса и данные видны полностью. Виртуальная частная сеть добавляет к туннелю конфиденциальность, целостность и аутентификацию сторон, но не устраняет необходимость доверия: защищён лишь участок между конечными точками, метаданные внешнего заголовка видны, а выходная точка видит весь трафик. Проектирование VPN включает решения о раздельном туннелировании, разрешении имён и поведении при обрыве туннеля.
IPsec защищает пакеты на сетевом уровне с помощью однонаправленных ассоциаций безопасности, протокола ESP в транспортном или туннельном режиме и протокола IKEv2, который согласует алгоритмы, аутентифицирует стороны и выводит ключи; для работы через NAT ESP помещается в UDP с портом 4500. WireGuard решает ту же задачу иначе: фиксированный набор современных алгоритмов, однократное рукопожатие Noise, идентификация пиров открытыми ключами и криптомаршрутизация, в которой список AllowedIPs одновременно выбирает пира при отправке и проверяет источник при приёме. TLS-VPN, такие как OpenVPN, обменивают производительность на гибкость аутентификации и проходимость через межсетевые экраны. Провайдерские MPLS L3VPN строят изоляцию на стороне оператора с помощью VRF и стека меток, не шифруя трафик.
Идеи этой темы — инкапсуляция, виртуальный интерфейс, раздельные таблицы маршрутизации, учёт MTU — непосредственно используются в следующих. В теме 20 будет показано, как защищается беспроводной канал на канальном уровне, где задача шифрования решается не туннелем, а протоколами WPA2 и WPA3. В теме 21 те же механизмы инкапсуляции становятся основой сетей центров обработки данных: VXLAN переносит кадры Ethernet арендаторов через IP-фабрику, а VRF разделяет их таблицы маршрутизации.
Литература
- Perkins C. IP Encapsulation within IP. — RFC 2003, IETF, 1996. https://www.rfc-editor.org/rfc/rfc2003
- Farinacci D., Li T., Hanks S., Meyer D., Traina P. Generic Routing Encapsulation (GRE). — RFC 2784, IETF, 2000. https://www.rfc-editor.org/rfc/rfc2784
- Savola P. MTU and Fragmentation Issues with In-the-Network Tunneling. — RFC 4459, IETF, 2006. https://www.rfc-editor.org/rfc/rfc4459
- Mogul J., Deering S. Path MTU Discovery. — RFC 1191, IETF, 1990. https://www.rfc-editor.org/rfc/rfc1191
- Kent S., Seo K. Security Architecture for the Internet Protocol. — RFC 4301, IETF, 2005. https://www.rfc-editor.org/rfc/rfc4301
- Kent S. IP Authentication Header. — RFC 4302, IETF, 2005. https://www.rfc-editor.org/rfc/rfc4302
- Kent S. IP Encapsulating Security Payload (ESP). — RFC 4303, IETF, 2005. https://www.rfc-editor.org/rfc/rfc4303
- Kaufman C., Hoffman P., Nir Y., Eronen P., Kivinen T. Internet Key Exchange Protocol Version 2 (IKEv2). — RFC 7296, IETF, 2014. https://www.rfc-editor.org/rfc/rfc7296
- Huttunen A., Swander B., Volpe V., DiBurro L., Stenberg M. UDP Encapsulation of IPsec ESP Packets. — RFC 3948, IETF, 2005. https://www.rfc-editor.org/rfc/rfc3948
- Donenfeld J. A. WireGuard: Next Generation Kernel Network Tunnel. — Proceedings of the Network and Distributed System Security Symposium (NDSS), 2017, DOI: 10.14722/ndss.2017.23160.
- WireGuard. Protocol & Cryptography. — 2025. https://www.wireguard.com/protocol/
- Rosen E., Rekhter Y. BGP/MPLS IP Virtual Private Networks (VPNs). — RFC 4364, IETF, 2006. https://www.rfc-editor.org/rfc/rfc4364
- Kurose J. F., Ross K. W. Computer Networking: A Top-Down Approach. 8th ed. — Pearson, 2021.
- Rosen E., Viswanathan A., Callon R. Multiprotocol Label Switching Architecture. — RFC 3031, IETF, 2001. https://www.rfc-editor.org/rfc/rfc3031
- Dingledine R., Mathewson N., Syverson P. Tor: The Second-Generation Onion Router. — Proceedings of the 13th USENIX Security Symposium, 2004, С. 303–320.
- The Tor Project. Tor Rendezvous Specification — Version 3. — 2024. https://spec.torproject.org/rend-spec-v3/
- Zantig J., et al. The Invisible Internet Project (I2P) Architecture and Specifications. — I2P Project, 2025. https://geti2p.net/en/docs/how/garlic-routing
- Murdoch S. J., Danezis G. Low-Cost Traffic Analysis of Tor. — 2005 IEEE Symposium on Security and Privacy (S&P), 2005, С. 183–195. DOI: 10.1109/SP.2005.12
- Piotrowska A., Hayes J., Elahi T., Danezis G. The Loopix Anonymity System. — 26th USENIX Security Symposium, 2017, С. 1199–1216.