Production и облако · Production and cloud · урок 9 · 14 мин
Сети: WireGuard, Tailscale, NAT и ретрансляторы DERP
Networking: WireGuard, Tailscale, NAT traversal and DERP relays
Зачем
После урока ты объяснишь, как две машины за разными NAT находят друг друга и шифруют трафик: WireGuard, что поверх него делает Tailscale, когда пакеты идут напрямую, а когда через ретранслятор DERP, и кому при этом приходится доверять. Это нужно, когда GPU-машины стоят в разных местах, и на собеседовании в вопросах «how would you connect these boxes securely?» и «why is this link slow?».
Задача: машины за NAT не видят друг друга
У каждой машины дома адрес вида 192.168.1.x. Это private address (частный адрес): таких адресов в мире миллионы, и снаружи до него не дойти. Наружу весь дом выходит под одним public address (публичным адресом) от провайдера. Подмену делает маршрутизатор, это NAT (Network Address Translation, трансляция адресов): он переписывает обратный адрес исходящего пакета на внешний адрес и свой порт и запоминает соответствие, чтобы вернуть ответ нужной машине.
Главное свойство NAT для нас: маршрутизатор впускает пакет снаружи, только если изнутри перед этим ушёл пакет туда же. Незваный пакет он выбрасывает. Поэтому ноутбук дома и GPU-машина в офисе, каждая за своим NAT, сами друг до друга не достучатся: первый пакет каждой упрётся в чужой маршрутизатор. Классический ответ — открыть порт на маршрутизаторе (port forwarding). Он требует доступа к чужому маршрутизатору и оставляет порт открытым всему интернету.
WireGuard: туннель из пары ключей
WireGuard — протокол VPN (зашифрованного соединения), с 2020 года встроенный в ядро Linux 5.6. У каждой машины пара ключей: private key (закрытый) никогда не покидает машину, public key (открытый) можно раздавать кому угодно. Всё идёт по UDP, поэтому зашифрованный пакет для маршрутизатора — обычный UDP-пакет.
Конфигурация WireGuard — список соседей. Для каждого: его public key, endpoint (адрес и порт, где его искать) и AllowedIPs — какие адреса живут за ним. Пакет на адрес из AllowedIPs шифруется ключом этого соседа; пакет от соседа принимается, только если его адрес из того же списка. Шифры фиксированы: Curve25519 для обмена ключами, ChaCha20-Poly1305 для трафика, BLAKE2s для хеша, рукопожатие по схеме Noise. Выбирать нечего, поэтому и ошибиться в настройке негде.
Чего WireGuard не делает сам: не раздаёт ключи (их переписывают на каждую машину вручную), не знает, где сосед сейчас, и не проходит NAT. Для двух серверов с постоянными публичными адресами это не проблема. Для дюжины устройств за NAT, которые меняют сети, это работа на полный день.
Tailscale: control plane и data plane
Tailscale берёт WireGuard для самих пакетов и делит работу на две части.
- Control plane (управление) — сервер координации. Он как ящик для ключей: каждая машина кладёт туда свой public key и забирает ключи, адреса и правила остальных. Private key остаётся на машине. Трафика здесь почти нет.
- Data plane (данные) — сами пакеты. Они идут напрямую, каждый с каждым (mesh), а не через центр, как в классическом VPN «hub-and-spoke».
Сверху Tailscale даёт постоянные адреса из диапазона 100.64/10 (RFC 6598, он почти никогда не пересекается с домашними сетями), имена через MagicDNS (<машина>.<сеть>.ts.net) и правила доступа (ACL). Правила пишутся в одном месте, а проверяет их каждая машина сама, когда расшифровывает входящий пакет.
Hole punching и DERP: напрямую или через ретранслятор
Как пройти NAT без открытых портов? Через правило «впускаю ответ на свой пакет».
- Каждая машина спрашивает сервер STUN: «с какого адреса и порта ты меня видишь?».
- Машины обмениваются этими адресами через координацию.
- Обе одновременно шлют пакеты друг другу. Пакет ноутбука открывает «дырку» в домашнем NAT, пакет GPU-машины — в офисном. Следующие пакеты каждый NAT принимает как ответ. Это hole punching (пробивка NAT).
Работает это, если NAT даёт машине один и тот же внешний порт для всех адресатов — endpoint-independent mapping, «простой» NAT. «Трудный» NAT выдаёт новый порт на каждого адресата, и адрес из STUN другому соседу не подходит. Против одного трудного NAT есть перебор портов; против двух трудных сразу пробивка почти безнадёжна.
На этот случай есть DERP (Designated Encrypted Relay for Packets) — ретрансляторы Tailscale в разных городах. Через DERP устройства обмениваются служебными пакетами для пробивки, а когда прямой путь не нашёлся, DERP пересылает уже зашифрованные пакеты WireGuard. Прочитать их он не может: ключей у него нет. Соединение обычно начинается через DERP и, если пробивка удалась, переходит на прямой путь.
Пример с числами, Алматы. Ближайшие ретрансляторы в Европе: до Франкфурта 94 мс, до Варшавы 120 мс. Ноутбук дома и GPU-машина в другом здании того же города: первые ответы tailscale ping идут через DERP в Варшаве за 180–240 мс, после пробивки — напрямую за 3–5 мс. Это в 40–80 раз быстрее. Для SSH разница заметна, а для копирования весов модели на 15 ГБ решающая. Поэтому вопрос «напрямую или через relay» — первый, когда связь между своими машинами медленная: tailscale status пишет direct или relay "waw" у каждого соседа.
Кому мы доверяем: Tailnet Lock и Headscale
Ключи раздаёт сервер координации, и машины ему верят. Если его взломают, он может подсунуть public key чужой машины, и наши машины примут её как свою.
Tailnet Lock закрывает эту дыру: новая машина входит в сеть, только если её ключ подписан одной из доверенных машин сети, и подпись проверяет каждая машина сама. Цена (документация Tailscale, 12.10.2026): нужно минимум две подписывающие машины, Android подписывать не может; при включении выдают 10 секретов отключения, и если потерять все, сеть не восстановить; Lock несовместим с device approval.
Headscale — открытый сервер координации, который ставят у себя вместо сервера Tailscale. Клиенты те же, меняется только адрес управления. По списку возможностей на 12.10.2026 есть MagicDNS, ACL, tags, exit nodes, subnet routers, Taildrop, Tailscale SSH и встроенный DERP. Funnel и Serve пока открытые задачи, Tailnet Lock в списке нет. Одна сеть, для себя или маленькой команды.
Решение инженера здесь — про доверие и эксплуатацию, а не про скорость: данные в обоих случаях идут напрямую. С Tailscale ты доверяешь компании и можешь закрыть риск через Tailnet Lock. С Headscale доверяешь своему серверу, а его обновления, резервные копии и доступность становятся твоей работой.
Схема
Термины · Key terms
- WireGuard
- протокол VPN: пара ключей у каждой машины, UDP, фиксированные шифры
- NAT
- подмена внутреннего адреса на внешний адрес маршрутизатора
- endpoint-independent mapping
- «простой» NAT: один внешний порт для всех адресатов
- STUN
- сервер, который говорит машине её внешний адрес и порт
- hole punching
- одновременная отправка пакетов, чтобы оба NAT приняли их как ответ
- control plane / data plane
- управление (ключи, правила) / сами пакеты
- coordination server
- сервер Tailscale, который раздаёт public keys и правила
- DERP
- ретранслятор Tailscale; помогает пробивке и возит шифр, если прямого пути нет
- MagicDNS
- имена машин внутри сети вида
<машина>.<сеть>.ts.net - subnet router
- машина, которая открывает в сеть всю свою локальную подсеть
- Tailnet Lock
- вход новой машины только по подписи доверенной машины сети
- Headscale
- свой открытый сервер координации вместо сервера Tailscale
Сделай сам
На Mac в терминале выполни tailscale status, потом tailscale ping к трём машинам (только чтение, настройки не меняются) и tailscale netcheck. Запиши таблицу из трёх строк: машина → первый ответ (через DERP или напрямую, мс) → итоговый путь и мс. Ниже добавь две строки из netcheck: MappingVariesByDestIP (простой ли у тебя NAT) и ближайший DERP с задержкой.
Обсуди с тьютором: покажи таблицу и спроси, что изменилось бы для каждой машины, если бы офисный NAT стал «трудным», и что тогда проверять первым.
Проверь себя · ответ под вопросом
1Сервер координации Tailscale видит наш трафик? А DERP?
2Первые ответы от машины пришли за 200 мс, следующие за 3 мс. Что произошло между ними?
3От какой угрозы защищает Tailnet Lock и чем это решение отличается от перехода на Headscale?
Interview questions · US / UK
1You have GPU boxes in two offices, both behind NAT, and no open inbound ports. How would you connect them securely, and what happens on the wire?
2In a Tailscale-style mesh, what can a compromised coordination server do, and how do you limit it?
3Two nodes in the same city see 200 ms latency over the VPN. How do you debug it?
tailscale status and tailscale ping for relay versus direct; tailscale netcheck for UDP, NAT type and nearest DERP; suspect a hard NAT on both sides, blocked UDP or a firewall; fixes: allow UDP out, port mapping (UPnP, NAT-PMP, PCP) or one open port, a peer relay close by; confirm the path flips to direct.Ключевые фразы · Say it aloud
- The control plane only exchanges public keys; data goes peer to peerуправление обменивается только открытыми ключами, данные идут напрямую
- Private keys never leave the nodeзакрытые ключи никогда не покидают машину
- It starts on a relay and upgrades to a direct pathначинается через ретранслятор и переходит на прямой путь
- Two hard NATs usually mean we stay on the relayдва «трудных» NAT обычно означают, что останемся на ретрансляторе
- The relay forwards ciphertext it can't decryptретранслятор пересылает шифр, который не может прочитать
- Tailnet Lock removes the coordination server from the trust path for new nodesTailnet Lock убирает сервер координации из доверия для новых машин
Материалы
- Tailscale — How NAT traversal works — firewall, STUN, простой и трудный NAT, перебор портов, DERP (длинная статья, около 40 минут; для урока хватит разделов до DERP)
- Tailscale — How Tailscale works — control plane и data plane, mesh против hub-and-spoke (15 минут)
- Tailscale — DERP servers — домашний DERP, переход с ретранслятора на прямой путь (8 минут)
- Tailscale — Tailnet Lock — подписи, секреты отключения, ограничения (20 минут)
- Headscale — Features — что есть и чего нет в своём сервере координации (3 минуты)