SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-10-21

Что такое Tailscale и как работает эта VPN-сеть

Узнайте, как Tailscale создает зашифрованные WireGuard туннели между узлами. Разбираем работу координационного сервера, механизмы NAT traversal и модель угроз сети.

Что такое Tailscale?

Tailscale — это VPN, который соединяет ваши устройства напрямую друг с другом, вместо того чтобы направлять весь трафик через один шлюз под вашим управлением. Каждый узел использует WireGuard, поэтому пакеты передаются между серверами в зашифрованном виде, и никто на пути следования не может их прочитать. Хостинговый координационный сервер выполняет функцию посредника. Он хранит и распространяет открытые ключи, а также сообщает каждому узлу, где находятся остальные. Кроме того, он передает правила доступа, которые вы создали.

Это разделение лежит в основе всей архитектуры. Плоскость данных работает по принципу peer-to-peer, а обмен между узлами зашифрован. Плоскость управления — это сервис, который Tailscale предоставляет вам. Любой важный вопрос о Tailscale, включая неудобные вопросы о доверии, вытекает из этих двух фактов. Если вы уже настраивали VPN на базе WireGuard вручную на VPS, то Tailscale — это тот же самый туннель, в котором распределение ключей и обход межсетевых экранов выполнены за вас.

Как работает Tailscale?

Ваша частная сеть узлов называется tailnet. Когда машина присоединяется к ней, происходят четыре вещи.

  1. Запускается демон tailscaled, генерирует пару ключей WireGuard и сохраняет свое состояние в /var/lib/tailscale/tailscaled.state. Приватный ключ остается на этой машине. Формулировка Tailscale предельно ясна: «приватный ключ никогда, ни при каких обстоятельствах не покидает свой узел».
  2. Узел авторизуется на координационном сервере и загружает свой публичный ключ, а также адреса, по которым, как он считает, с ним можно связаться. Tailscale описывает этот сервер как «общий почтовый ящик для публичных ключей».
  3. Координационный сервер отправляет в ответ карту сети: публичный ключ, адрес в tailnet, имя машины и возможные точки доступа каждого узла, к которому данному узлу разрешено подключаться.
  4. Затем каждая пара узлов пытается построить прямой туннель WireGuard между собой. Если это не удается, они передают пакеты через ретранслятор.

Каждый узел получает стабильный адрес из диапазона 100.64.0.0/10 — это диапазон carrier-grade NAT от 100.64.0.0 до 100.127.255.255. Tailscale использует этот диапазон, так как он зарезервирован для инфраструктуры провайдеров и редко конфликтует с частными адресами, которые уже используются на ваших серверах. В Linux туннель отображается как интерфейс с именем tailscale0.

Реализация WireGuard работает внутри tailscaled в пространстве пользователя, а не в модуле ядра. Именно поэтому Tailscale запускается в контейнерной виртуализации, где sudo modprobe wireguard завершается с ошибкой Operation not supported. Это также означает, что предел пропускной способности на конкретном узле ниже, чем у WireGuard в ядре, что является одним из компромиссов, описанных в Tailscale в сравнении с обычным WireGuard.

Две команды позволяют оценить текущее состояние.

tailscale ip -4
tailscale status

tailscale status выводит по одной строке на каждый узел, и последний столбец является наиболее важным.

100.101.102.103  web-1      you@  linux  -
100.101.102.104  db-1       you@  linux  active; direct 198.51.100.24:41641
100.101.102.105  ci-runner  you@  linux  active; relay "fra"

direct с указанием адреса и порта означает, что две машины нашли путь друг к другу и трафик передается напрямую (peer-to-peer). relay "fra" означает, что трафик проходит через ретранслятор Tailscale во Франкфурте. - означает, что в данный момент активная сессия с этим узлом отсутствует, что является нормальным поведением.

Что сервер координации может и чего не может видеть

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

Он не хранит закрытые ключи, поэтому не может расшифровать трафик между двумя узлами. Шифрование осуществляется по принципу end-to-end между узлами WireGuard, а сервер координации не является участником этого обмена.

Что он может делать, так это передавать ключи. Любому серверу координации, будь то облачный или развернутый самостоятельно, доверяется задача сообщать вашим узлам, какие открытые ключи принадлежат данной tailnet. Это ключевой момент модели угроз, описанной ниже, и причина, по которой существует Headscale, сервер координации с открытым исходным кодом для самостоятельного хостинга.

Как два сервера за разными файрволами связываются напрямую

NAT (network address translation) позволяет многим машинам использовать один публичный адрес. Ваш VPS обычно имеет собственный публичный адрес, но другие машины, которые вы хотите включить в tailnet, часто его не имеют: домашний сервер, сборочный узел в офисной сети или устройство за файрволом провайдера, который вы не можете настроить.

Tailscale находит путь с помощью механизмов, основанных на стандартах STUN (session traversal utilities for NAT) и ICE. Каждый узел отправляет небольшой UDP-пакет на STUN-сервер и узнаёт публичный адрес и порт, которые маршрутизатор назначил этому сокету. Оба узла передают эти кандидаты серверу координации, который отправляет их другой стороне. Затем оба узла одновременно начинают отправлять пакеты друг другу. Каждый маршрутизатор сначала видит исходящий пакет, поэтому создаёт отображение и принимает ответ, поступающий с того же адреса. Правило для входящих подключений на межсетевом экране ни на одной стороне не требуется. Поэтому NAS или Pi дома может оставаться доступным без настроенной переадресации портов на маршрутизаторе, а использование Tailscale вместо переадресации портов описывает такую настройку, включая ограничения этого подхода.

Используются конкретные порты. Прямые туннели WireGuard используют UDP с исходным портом, который по умолчанию равен 41641. STUN работает через UDP 3478 с ретрансляционными серверами Tailscale. Управляющее соединение предпочитает обычный HTTP на TCP 80, обернутый в собственный зашифрованный транспорт Tailscale, и переключается на HTTPS на TCP 443, если порт 80 не отвечает. Данные, передаваемые через DERP-серверы Tailscale, используют HTTPS на TCP 443, в то время как пиринговый ретранслятор, запущенный внутри вашего собственного tailnet, передает их по UDP. В большинстве случаев вам не нужно открывать входящие порты, хотя в сети со сложным NAT разрешение входящего UDP 41641 повышает вероятность прямого соединения.

tailscale netcheck

Прочитайте две строки этого отчета. UDP: true означает, что эта машина может отправлять UDP-трафик в интернет, а UDP: false означает, что не может, поэтому каждое соединение с этого узла будет проходить через ретранслятор. MappingVariesByDestIP: true означает, что маршрутизатор назначает разный публичный порт для каждого пункта назначения, поэтому предсказание адреса, описанное выше, не сработает, и такие узлы обычно остаются в режиме ретрансляции.

Когда Tailscale использует ретранслятор DERP

DERP (designated encrypted relay for packets) — это резервный механизм. Tailscale поддерживает ретрансляторы во многих регионах, доступные по TCP 443, и узел, который не может установить прямой путь, передает свои пакеты WireGuard через один из них. Исключение составляют tailnet, где настроены выделенные одноранговые ретрансляторы (peer relays) — это ваши собственные устройства, пересылающие трафик по UDP. Tailscale сначала пытается использовать их и переходит на DERP только тогда, когда ни один из них недоступен, и tailscale status затем отображает соединение как peer-relay.

Пакеты остаются зашифрованными. Tailscale заявляет об этом прямо: «у сервера DERP нет никакой возможности расшифровать ваш трафик. Он просто слепо пересылает уже зашифрованные пакеты от одного узла к другому». Ретранслятор видит только зашифрованный текст и информацию о том, какой узел с каким общается.

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

tailscale ping db-1

Первые ответы приходят как via DERP(fra), затем в следующей строке появляется сообщение вида via 198.51.100.24:41641. Это изменение означает переход на прямой туннель. Если состояние не меняется, запустите tailscale netcheck на обоих концах. Ретранслируемый путь продолжает работать. Это увеличивает задержку, так как каждый пакет делает крюк через третью машину. Если вы заметили медленную передачу данных, а не разрыв соединения, почему ретранслируемое соединение Tailscale работает значительно медленнее прямого поможет оценить разницу и покажет, как перевести VPS на прямой путь.

Подключение VPS к вашей tailnet

Скрипт установки поддерживает Ubuntu и Debian.

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

sudo tailscale up выводит URL. Откройте его, пройдите аутентификацию, и узел появится в вашей консоли администратора. Затем убедитесь, что демон запускается после перезагрузки: это шаг, который часто пропускают.

sudo systemctl is-enabled tailscaled
tailscale status

is-enabled должен вывести enabled, а tailscale status должен показать новый узел с его адресом 100.x. Для сервера, развернутого с помощью скрипта, интерактивный URL не подходит. Создайте ключ аутентификации (auth key) в консоли администратора и передайте его вместе с тегом, который определяет тип этой машины.

sudo tailscale up --auth-key=tskey-auth-REPLACE-ME --advertise-tags=tag:server

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

Для управления парком серверов важны две настройки. Ключи узлов по умолчанию истекают через 180 дней (по состоянию на октябрь 2026 года), и после истечения срока действия ключа «соединения с данным узлом и от него перестанут работать» до тех пор, пока устройство не пройдет повторную аутентификацию. Администратор может выбрать «Temporarily extend key» (Временно продлить ключ) для истекшего узла в консоли администратора, что даст 30 минут на повторный вход или отключение срока действия. Узел, аутентифицированный с помощью тега, как в примере выше, имеет отключенное по умолчанию истечение срока действия ключа. Для любого другого сервера, работающего без присмотра, откройте строку с машиной в консоли администратора и выберите «Disable Key Expiry» (Отключить истечение срока действия ключа). MagicDNS, включенный по умолчанию для tailnet, созданных 20 октября 2022 года или позже, присваивает каждому узлу имя, например db-1.yak-bebop.ts.net, которое разрешается через stub resolver по адресу 100.100.100.100. Используйте имена вместо IP-адресов, так как пересобранный узел получает новый адрес, но сохраняет свое имя.

Если установка завершается ошибкой при работе с apt или репозиторием, в разделе распространенные ошибки установки Tailscale в Ubuntu описаны способы их устранения.

Доступ к сервису, привязанному к localhost

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

ss -tlnp | grep 3000

Если эта команда выводит 127.0.0.1:3000, значит сокет принимает только пакеты, адресованные на 127.0.0.1. Запрос от другого узла приходит на адрес 100.x этого узла, поэтому ядро не находит слушающего процесса и отвечает TCP-сбросом. Клиент сообщает об ошибке Connection refused. Туннель исправен. Проблема заключается в настройках слушающего процесса.

Существует два корректных решения. Привяжите сервис к адресу tailnet вашего узла: это исключит его из публичного интерфейса без использования прокси. Передайте --bind 100.101.102.104 или эквивалентную опцию в конфигурации, а для контейнера опубликуйте порт как -p 100.101.102.104:3000:3000. Либо оставьте сервис на loopback и установите перед ним Tailscale.

tailscale serve 3000

Это проксирует запросы на http://127.0.0.1:3000 и обслуживает их внутри вашего tailnet по имени ts.net через HTTPS, если для tailnet включены HTTPS-сертификаты. Сервис останется доступным только для ваших узлов. Публичная версия этого решения называется Funnel, а в Tailscale serve и funnel описано, какой вариант выбрать.

Две связанные задачи вынесены на отдельные страницы. Для доступа к целой частной сети, где не установлен Tailscale, требуется subnet router на VPS, а для перенаправления исходящего интернет-трафика узла через другой узел требуется exit node.

Закрытие портов, которые больше не нужны

Как только администратор получает доступ к серверу через tailnet, публичный порт 22 становится не нужен. В этом заключается практическая польза: закрытый порт невозможно подвергнуть брутфорсу, а логи перестают заполняться попытками взлома.

Порядок действий имеет значение. Сначала настройте доступ через tailnet, убедитесь, что можете войти через него в рамках второй сессии, и только после этого удаляйте публичное правило. Если вы хотите пройти эту последовательность по шагам на чистом Ubuntu VPS, включая Tailscale SSH и закрытие порта 22 в ufw, воспользуйтесь руководством по настройке Tailscale на VPS.

sudo ufw allow in on tailscale0
sudo ufw status verbose

После этого удалите публичное правило SSH и переподключитесь, используя имя MagicDNS. Учтите, что именно делает ufw allow in on tailscale0: этот инструмент доверяет всему трафику, поступающему через туннель, поэтому файл политик Tailscale становится основным средством контроля доступа вместо ufw. Составляйте политики с учетом этого факта.

Предупреждение для тех, кто использует контейнеры. Опубликованный порт Docker создает собственные правила NAT и обходит ufw, поэтому ufw deny не закрывает его. В опубликованных портах Docker, обходящих ufw объясняется этот механизм. Публикация на адрес tailnet, как описано выше, позволяет избежать этой проблемы. Если приложение работает через Docker Compose, sidecar-контейнер Tailscale в стеке Compose идет еще дальше и полностью убирает опубликованный порт, оставляя контейнер доступным только по его имени в tailnet.

Что защищает Tailscale, а что нет

Это стоит прояснить, так как маркетинговые материалы часто размывают границы.

Защищено: трафик между двумя узлами шифруется сквозным образом с помощью WireGuard, и ни один промежуточный ретранслятор не может его прочитать. Приватные ключи никогда не покидают машину, на которой были созданы. Узлам не требуются открытые входящие порты, поэтому в Интернете нечего сканировать на наличие портов 22 или 5432. Доступ между узлами определяется файлом политик, а не тем, кто знает IP-адрес.

Не защищено: сервер координации видит граф ваших устройств. Эти метаданные сами по себе чувствительны, так как имена машин, владельцы, адреса и время нахождения в сети описывают вашу инфраструктуру. Сервер также распределяет ключи, что является более серьезным риском. Tailscale заявляет об этом прямо: «Если бы Tailscale действовал злонамеренно и скрытно добавил новые узлы в вашу сеть, он мог бы отправлять или принимать трафик от ваших существующих узлов в открытом виде». Ваш провайдер единого входа (SSO) находится на том же пути доверия, так как любой, кто может создать там учетную запись, может добавить узел. А скомпрометированный узел становится полноценным участником tailnet, поэтому он получает доступ ко всему, что разрешено вашими политиками. Является ли это приемлемым риском, зависит от того, против кого вы защищаетесь, а полная модель доверия подробно описывает каждый из этих случаев, включая то, что на самом деле может сделать злоумышленник с украденной учетной записью.

Существует два ответа на риск при распределении ключей. Первый — это tailnet lock, который требует, чтобы существующие доверенные узлы криптографически подписали новый узел, прежде чем остальные узлы примут его. Control plane, добавляющий узел без действительной подписи, игнорируется. Консоль администратора генерирует точную строку tailscale lock init для ваших подписывающих узлов, и каждый узел может подтвердить то, что он видит.

tailscale lock status

Все узлы должны сообщать об одном и том же наборе доверенных ключей подписи. Второй ответ — запустить control plane самостоятельно. Самохостируемый сервер координации Headscale использует тот же протокол для тех же клиентов, что переносит граф устройств и распределение ключей на оборудование, которым владеете вы. Вы также берете на себя ответственность за время безотказной работы этого сервера. Если вы все еще сравниваете варианты самохостируемых control plane, а не остановились на этом, NetBird — это отдельный mesh VPN, сервер которого вы запускаете целиком на одном VPS.

Один параметр по умолчанию, который нужно исправить в первый же день. Новая tailnet поставляется с разрешительными настройками: «политика tailnet по умолчанию разрешает обмен данными между всеми устройствами внутри tailnet». Как только вы добавляете секцию acls, модель меняется на «запрещено по умолчанию», и пропускаются только ваши правила.

{
  "tagOwners": {
    "tag:server": ["autogroup:admin"]
  },
  "acls": [
    {"action": "accept", "src": ["autogroup:member"], "dst": ["tag:server:22"]}
  ]
}

Эта политика позволяет участникам tailnet подключаться по SSH к помеченным серверам и больше ни к чему. Добавляйте правила для каждого сервиса отдельно, вместо того чтобы оставлять подстановочный знак (wildcard), так как подстановочный знак означает, что с помощью одного украденного ключа от ноутбука можно получить доступ к вашей базе данных.

Типичные сбои и сообщения об ошибках

tailscale status всегда выдает relay. Узлы не смогли установить прямой путь соединения. Запустите tailscale netcheck на обоих концах. UDP: false означает, что исходящий UDP-трафик заблокирован, поэтому работать будет только ретранслятор (relay). MappingVariesByDestIP: true означает наличие жесткого NAT; часто проблему решает открытие входящего UDP-порта 41641 на стороне, которую вы контролируете.

Узел, работавший месяцами, исчез. Распространенная причина — истечение срока действия ключа узла, который по умолчанию составляет 180 дней. Сначала проверьте состояние машины в панели администратора. Если статус «истек» (expired), команда sudo tailscale up на самом устройстве восстановит доступ. Чтобы ситуация не повторилась, отключите истечение срока действия ключей для серверов. Если срок не истек, проверьте файл политик: Tailscale рекомендует при исчезновении устройства из tailscale status искать правила доступа, блокирующие соединение.

Пиры отображаются в списке, но соединения завершаются по тайм-ауту. Если tailscale ping получает ответы, значит, сетевое взаимодействие работает, а вероятная причина — политика, запрещающая данный трафик. Проверьте раздел acls на наличие правила, охватывающего данный источник, назначение и порт. Запрещенный пакет отбрасывается без ответа, поэтому вместо Connection refused вы получаете тайм-аут.

Имена MagicDNS не разрешаются. ping db-1 завершается ошибкой, в то время как ping 100.101.102.104 работает. Сначала убедитесь, что клиент принимает настройки DNS от Tailscale: узел, запущенный с флагом --accept-dns=false, не отправляет запросы на stub-резолвер 100.100.100.100. Затем проверьте cat /etc/resolv.conf и другие процессы на устройстве, которые могут изменять этот файл. В системах с systemd-resolved этот файл обычно является символической ссылкой на /run/systemd/resolve/stub-resolv.conf, и отсутствие в нем 100.100.100.100 является нормальным поведением. Если tailscaled записывает файл напрямую, его может перезаписывать DHCP-клиент или другая утилита, что нарушает работу MagicDNS. Если это не объясняет проблему, ошибка может быть в локальной конфигурации DNS или настройках сети. Это тот же класс проблем, что и нарушение работы DNS внутри туннеля WireGuard.

tailscale up отклоняет ваш тег. Тег не объявлен в разделе tagOwners файла политик. Добавьте его туда и повторно выполните команду.

FAQ

Является ли Tailscale VPN или mesh-сетью?

Оба термина точны и описывают разные уровни. Туннели работают на основе WireGuard, поэтому это VPN. Топология является mesh, поскольку каждый узел устанавливает туннель непосредственно с каждым узлом, с которым он обменивается трафиком, вместо отправки каждого пакета через один центральный сервер. Сервер координации находится в плоскости управления, а не в плоскости передачи данных. Поэтому при потере доступа к нему уже установленные туннели продолжают передавать трафик. Во время сбоя прекращается подключение новых узлов и применение изменений ключей или политик. Однако по умолчанию это не VPN для обеспечения конфиденциальности: веб-сайты по-прежнему видят ваш собственный публичный адрес, пока вы не направите трафик через exit node. Подробнее о том, что Tailscale скрывает от веб-сайтов и вашего интернет-провайдера, рассказывается для каждого варианта настройки.

Может ли Tailscale читать мой трафик?

Содержимое — нет. Трафик шифруется сквозным образом между узлами с помощью WireGuard, закрытые ключи никогда не покидают узлы, а ретранслятор DERP пересылает пакеты, которые не может расшифровать. Tailscale видит метаданные: имена машин, владельцев, открытые ключи, адреса конечных точек и время нахождения узла в сети. Также компания занимается распределением ключей, поэтому скомпрометированный сервер координации теоретически может попытаться добавить узел, которому ваша сеть начнет доверять. Функция tailnet lock предотвращает это, требуя подписи от ваших собственных доверенных узлов, а использование Headscale полностью исключает сторонний сервер управления из схемы.

Нужно ли открывать порты на брандмауэре для Tailscale?

Входящие — почти никогда. Согласно рекомендациям Tailscale, «в большинстве случаев открывать порты на брандмауэре не требуется». Для исходящих соединений узлу нужен TCP 443 для связи с сервером координации и ретрансляторами, а также UDP 3478 для STUN. Прямые туннели используют UDP с портом источника, который по умолчанию равен 41641. Разрешение входящего UDP 41641 является опциональным и помогает устанавливать прямые соединения в сетях со сложной конфигурацией.

Почему другие узлы не могут подключиться к моему сервису на порту 3000?

Сначала проверьте адрес привязки (bind address) с помощью ss -tlnp. Слушатель на 127.0.0.1:3000 отклоняет соединения, которые приходят на адрес 100.x в tailnet, так как этот сокет принимает запросы только с интерфейса loopback, и клиент получает Connection refused. Привяжите сервис к адресу tailnet или используйте tailscale serve 3000 для проксирования. Если слушатель уже настроен на 0.0.0.0, а соединение завершается по таймауту, а не отказом, проблема не в адресе привязки. В первую очередь проверьте правила политик и локальные брандмауэры, затем сетевые экраны и статус аутентификации на обоих устройствах.

Стоит ли использовать Headscale вместо сервера координации Tailscale?

Используйте Headscale, если граф устройств или распределение ключей должны находиться на инфраструктуре под вашим контролем, или если tailnet должна работать без зависимости от внешнего сервиса. Клиенты и протокол при этом остаются прежними. Обратной стороной является необходимость самостоятельно обслуживать сервер координации: его отказ приведет к невозможности подключения новых узлов и применения новых политик. Для небольших сетей использование облачного сервера управления с включенным tailnet lock обычно является более рациональным выбором.