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

Как установить Headscale на свой VPS

Разверните собственный сервер управления Tailscale с помощью Headscale. Инструкция по установке .deb пакета, настройке server_url и подключению первого узла к сети.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, July 30, 2026.

Что такое headscale

Headscale — это self-hosted реализация сервера управления Tailscale, поэтому машина, координирующая вашу частную сеть, является VPS, который вы контролируете. Это общественный проект, который не управляется компанией Tailscale Inc. Каждая машина по-прежнему использует официальный клиент tailscale, настроенный на ваш сервер с помощью одного флага — --login-server.

Сервер управления — это компонент, который знает, кто входит в сеть. Он выдает каждому узлу адрес из диапазона 100.64.0.0/10, распространяет открытые ключи и сообщает узлам, где искать друг друга. Туннели остаются WireGuard, устанавливаемыми напрямую между узлами. Трафик между двумя вашими машинами не проходит через сервер headscale, если только прямой путь не может быть построен и узлы не переключаются на ретранслятор (relay). Выполнение этой координационной роли самостоятельно меняет того, кто ею владеет, а не то, на что она способна, поэтому стоит изучить к чему сервер управления может и не может получить доступ в этой модели, прежде чем рассматривать этот переход как самостоятельное повышение безопасности.

Headscale обслуживает одну tailnet (одну сеть Tailscale) на экземпляр, что, по описанию проекта, подходит для личного использования или небольшой организации. При наличии трех или четырех машин обычный WireGuard VPN на собственном VPS требует установки меньшего количества ПО и реже ломается. Headscale становится полезным, когда вы больше не хотите вручную писать блоки [Peer] для каждого нового ноутбука. Часто именно стоимость заставляет людей искать альтернативы, поэтому стоит ознакомиться с тем, что на самом деле покрывает бесплатный тарифный план, прежде чем запускать свой сервер, так как несколько личных устройств обычно в него укладываются. Если вы уже превысили этот лимит, сравните затраты с стоимостью платных тарифов на пользователя и на помеченный ресурс, поскольку количество пользовательских устройств не ограничено, в то время как для помеченных ресурсов действуют отдельные квоты и тарифы. Если вам нужен self-hosted сервер управления, но вы предпочитаете собственный клиент и веб-интерфейс для управления узлами, а не прямую замену Tailscale, NetBird на одном VPS — это альтернатива, которую стоит рассмотреть. Для более широкого сравнения этих двух моделей см. чем отличаются WireGuard и Tailscale.

Что необходимо перед установкой

  • VPS под управлением Ubuntu 24.04 с публичным IPv4-адресом и доступом sudo. Если сервер новый, сначала выполните действия из руководства первые десять минут на новом VPS.
  • DNS-запись типа A, указывающая на этот адрес. В данном руководстве используется headscale.example.com.
  • Второй домен или поддомен для MagicDNS. В данном руководстве используется tailnet.example.net. Он должен отличаться от домена, указанного в server_url.
  • Одно клиентское устройство для подключения под управлением Linux, macOS, Windows, Android или iOS. Для Headscale 0.29.6 требуется клиент Tailscale версии 1.80.0 или новее.

Установка headscale из официального .deb-пакета

Проект публикует .deb-пакеты на странице релизов в GitHub. По состоянию на 27 октября 2026 года последним стабильным релизом является 0.29.6, выпущенный 24 октября 2026 года. Сначала проверьте архитектуру вашей системы, так как она указана в имени файла.

sudo apt update
sudo apt install -y wget
dpkg --print-architecture

Эта команда выводит amd64 на обычном x86 VPS и arm64 на серверах типа Ampere или Graviton. Подставьте полученное значение в переменную ниже.

HEADSCALE_VERSION="0.29.6"
HEADSCALE_ARCH="amd64"
wget --output-document=headscale.deb \\
  "https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_${HEADSCALE_ARCH}.deb"
sudo apt install -y ./headscale.deb
headscale version

Символ ./ перед именем файла обязателен. Без него apt будет искать пакет с именем headscale.deb в ваших репозиториях и завершится ошибкой.

Пакет создает системного пользователя headscale, записывает конфигурацию по умолчанию в /etc/headscale/config.yaml, устанавливает systemd-юнит и запускает службу. Таким образом, headscale уже работает, когда команда apt завершает выполнение, а sudo systemctl is-active headscale выводит active. Однако при чистой установке пакет не добавляет юнит в автозагрузку, поэтому служба не запустится после перезагрузки, пока вы её не включите, что будет сделано на этапе перезапуска ниже. Служба также запускается с конфигурацией по умолчанию, в которой server_url указывает на http://127.0.0.1:8080 — этот адрес недоступен для ваших клиентов. Пока ничего не открыто вовне, так как стандартный listen_addr также привязан к loopback, но не подключайте клиентов, пока не настроите server_url и не перезапустите службу, что и будет сделано в следующих двух шагах.

Настройка server_url перед подключением клиентов

Отредактируйте /etc/headscale/config.yaml с помощью sudo nano /etc/headscale/config.yaml или внесите те же три изменения через sed. Сохраните копию исходного файла: он содержит подробные комментарии и является лучшим справочником по остальным настройкам.

sudo cp /etc/headscale/config.yaml /etc/headscale/config.yaml.orig
sudo sed -i 's|^server_url:.*|server_url: https://headscale.example.com|' /etc/headscale/config.yaml
sudo sed -i 's|^listen_addr:.*|listen_addr: 127.0.0.1:8080|' /etc/headscale/config.yaml
sudo sed -i 's|^  base_domain:.*|  base_domain: tailnet.example.net|' /etc/headscale/config.yaml
sudo grep -E '^(server_url|listen_addr):|^  base_domain:' /etc/headscale/config.yaml

server_url — это публичный адрес, который headscale использует при формировании URL для регистрации. Клиенты используют адрес управления, настроенный в --login-server, поэтому используйте одно и то же публичное имя в https:// в обоих полях, никогда не используйте 127.0.0.1. Документация headscale допускает использование обычного HTTP или HTTPS на порту, отличном от 443, но для промышленной эксплуатации настоятельно рекомендуется HTTPS на порту 443; в остальной части руководства подразумевается именно этот вариант.

listen_addr — это адрес, на котором процесс ожидает соединений. Оставьте его на loopback. Обратный прокси-сервер на том же узле выполняет TLS (transport layer security) termination и перенаправляет запросы, поэтому внешним клиентам не требуется прямой доступ к порту 8080.

base_domain — это суффикс MagicDNS, домен, в зоне которого узлы получают имена. Это должно быть полное доменное имя (FQDN) без точки в конце, и оно должно отличаться от домена в server_url, иначе пространства имен будут конфликтовать.

Раздел базы данных оставьте без изменений. По умолчанию используется SQLite в /var/lib/headscale/db.sqlite, в директории, созданной и обслуживаемой пакетом; для tailnet такого размера SQLite достаточно.

Перезапустите headscale и убедитесь, что он работает

sudo systemctl restart headscale
sudo systemctl enable headscale
sudo systemctl is-active headscale
sudo systemctl is-enabled headscale
curl -sS -o /dev/null -w '%{http_code}\\n' http://127.0.0.1:8080/health

is-active выводит active, is-enabled выводит enabled, а curl выводит 200. Перезапуск — это этап, на котором загружаются ваши правки. Headscale считывает конфигурацию один раз, при запуске, поэтому процесс, запущенный пакетом, продолжает использовать установленный по умолчанию server_url, пока вы его не перезапустите. sudo systemctl enable --now headscale не выполняет эту задачу: сервис уже запущен, поэтому --now start ничего не меняет, и старое значение остается активным. Запуск при загрузке — это задача enable, и она не выполняется автоматически: при чистой установке пакет запускает сервис, не включая его автозагрузку, поэтому выполните sudo systemctl enable headscale один раз, как указано выше.

Если is-active выводит что-либо, кроме active, или curl не выводит 200, изучите журнал с помощью sudo journalctl -u headscale -n 50 --no-pager. Ошибка на этом этапе почти всегда связана с файлом конфигурации, поскольку headscale анализирует весь файл целиком перед тем, как открыть сокет, поэтому неверный отступ или некорректный обязательный параметр останавливают процесс до того, как он начнет прослушивание. Исправьте файл, затем выполните sudo systemctl restart headscale. Любое последующее изменение конфигурации требует такого же перезапуска. Клиенты после этого переподключаются самостоятельно. Если юниты systemd для вас в новинку, запуск собственных сервисов и таймеров с помощью systemd содержит описание используемых здесь команд.

Проверьте файлы состояния, пока находитесь в оболочке:

stat -c '%U %n' /var/lib/headscale/db.sqlite /var/lib/headscale/noise_private.key

Обе строки начинаются с headscale — непривилегированного пользователя, созданного пакетом. noise_private.key — это идентификатор сервера для его клиентов. Сохраните его. Если вы удалите его, headscale сгенерирует новый, и клиентам придется получить новый ключ сервера перед повторным подключением; существующие регистрации останутся в базе данных.

Настройка TLS перед headscale

Клиенты должны обращаться к server_url по протоколу HTTPS. Caddy — самый быстрый путь, так как он самостоятельно запрашивает и обновляет сертификаты.

sudo apt install -y caddy

Замените /etc/caddy/Caddyfile блоком из документации headscale:

headscale.example.com {
    reverse_proxy 127.0.0.1:8080 {
        header_up True-Client-IP {remote_host}
        header_up X-Real-IP {remote_host}
    }
}
sudo caddy validate --adapter caddyfile --config /etc/caddy/Caddyfile
sudo systemctl restart caddy
sudo systemctl is-active caddy

validate выводит adapted config to JSON при успешном разборе файла. Предупреждение о том, что файл не отформатирован, носит косметический характер. С вашего ноутбука команда curl -sS -o /dev/null -w '%{http_code}\\n' https://headscale.example.com/health также должна выводить 200. Эта единственная проверка подтверждает, что DNS, межсетевой экран, сертификат и прокси работают корректно.

Ниже приведена деталь настройки прокси, на которой многие теряют вечер. Управляющее соединение Tailscale представляет собой HTTP upgrade, оно инициируется методом POST, а не GET, а значение заголовка Upgrade равно tailscale-control-protocol. Caddy передает его без дополнительной настройки. nginx этого не делает, поэтому фронтенд на базе nginx должен явно передавать заголовки Upgrade и Connection. В документации headscale это реализовано через карту upgrade:

map $http_upgrade $connection_upgrade {
    default keep-alive;
    ''      close;
}

server {
    listen 443 ssl;
    server_name headscale.example.com;
    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_buffering off;
        proxy_pass http://127.0.0.1:8080;
    }
}

Если пропустить эти строки, обычные запросы будут проходить успешно — именно поэтому /health возвращает 200 и всё выглядит исправно, хотя управляющее соединение не устанавливается: новые узлы не могут зарегистрироваться, а существующие не могут переподключиться и сообщить о своем статусе онлайн. Если вы выбрали путь с nginx, в Certbot в Ubuntu 24.04 с nginx описана часть, касающаяся сертификатов.

Какие порты открыть в UFW

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Порт 443 обеспечивает каждое управляющее соединение клиента с headscale. Если вы позже включите встроенный ретранслятор DERP, ему также потребуется порт 3478/udp, о котором сказано ниже. Порт 80 необходим для HTTP-вызова ACME (автоматизированная среда управления сертификатами) и перенаправления на HTTPS. Caddy может получить сертификат и при закрытом 80 порте, используя TLS-ALPN challenge на 443 порту, но при открытом 80 порте доступны оба метода проверки, а обычные запросы http:// перенаправляются.

Порт 8080 должен оставаться закрытым. listen_addr — это 127.0.0.1:8080, поэтому прокси обращается к headscale через интерфейс loopback, и правила межсетевого экрана здесь не задействованы. Открытие порта 8080 в UFW ничего не даст, так как снаружи на нем никто не слушает, и это не приносит никакой пользы. Учтите, что большинство провайдеров используют второй межсетевой экран в своей панели управления, отдельный от UFW, поэтому порт может быть открыт на сервере, но закрыт на границе сети. В основах работы с UFW на VPS подробно описан синтаксис правил.

Создание пользователя и ключа предварительной авторизации

sudo headscale users create alice
sudo headscale users list

Команда headscale является клиентом. Она взаимодействует с запущенным демоном через unix-сокет по пути /var/run/headscale/headscale.sock, который имеет права доступа 0770 и принадлежит группе headscale. Из этого следуют два вывода. Команда завершается ошибкой, если служба остановлена (поэтому порядок действий в этом руководстве имеет значение), и для её выполнения требуются права sudo, если вы не добавили свою учётную запись в группу headscale.

users list выводит ID рядом с каждым именем. Вам понадобится это число, так как команда для работы с ключами принимает числовой ID пользователя, а не его имя.

sudo headscale preauthkeys create --user 1 --expiration 24h

Ключ выводится только один раз. Скопируйте его сейчас. Ключ предварительной авторизации является одноразовым и действует один час, если не указано иное, поэтому параметр --expiration 24h стоит настроить на этапе тестирования. Добавьте --reusable для ключа, который позволяет зарегистрировать несколько машин, и обращайтесь с ним как с паролем, так как любой, у кого он есть, сможет подключиться к вашей сети.

Подключение первого клиента с помощью --login-server

На машине, которую вы хотите добавить в сеть:

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --login-server https://headscale.example.com --auth-key 'hskey-auth-PASTE-YOUR-KEY-HERE'
tailscale status
tailscale ip -4

Скрипт установки берёт пакеты из репозитория pkgs.tailscale.com; если этот адрес или Google Play у вас не открываются, посмотрите, где взять официальный клиент Tailscale в виде APK, MSI или сборки для Linux и как проверить его подпись перед установкой.

tailscale ip -4 выводит адрес, назначенный headscale, например 100.64.0.1. Вернувшись на сервер, выполните sudo headscale nodes list, чтобы увидеть узел с его ID, пользователем и статусом подключения.

Используйте публичный HTTPS-адрес из server_url для --login-server. Клиент автоматически удаляет завершающие слэши из URL управления; строгое соответствие строки не требуется, поэтому наличие или отсутствие слэша не критично.

Если машина ранее была подключена к облачному сервису Tailscale, она сохранит данные авторизации. Сначала выполните на ней sudo tailscale logout, а затем запустите tailscale up с флагом --login-server.

Если не указывать --auth-key, клиент выведет URL в консоль. Откройте его в браузере: на странице отобразится идентификатор попытки регистрации, который нужно подтвердить на сервере:

sudo headscale auth register --user alice --auth-id PASTE-THE-ID-FROM-THE-PAGE

Этот способ удобен для личного ноутбука. Для автоматизированных сценариев лучше использовать preauth keys, так как они не требуют участия человека. Как только VPS станет узлом сети, он сможет перенаправлять интернет-трафик других ваших машин. Это называется настройка exit node, с той лишь разницей, что подтверждение анонсированного маршрута выполняется на сервере командой headscale, а не через веб-консоль облачного сервиса. Если вам нужен доступ к частной сети за этим VPS, а не выход в интернет, тот же этап подтверждения используется для анонсирования подсети в вашей tailnet. Публикация отдельного приложения с узла — это другая задача, и для неё существуют serve и funnel. Оба этих механизма опираются на собственные сертификаты и механизмы ingress от Tailscale, поэтому их следует рассматривать как функции облачной tailnet, а не как инструменты, предоставляемые headscale.

DERP и ретрансляция трафика при невозможности прямого соединения

DERP (designated encrypted relay for packets) — это резервный путь передачи данных. Если два узла не могут установить прямое соединение WireGuard (обычно из-за того, что оба находятся за строгим NAT), они отправляют пакеты через ретранслятор. Ретранслятор не обладает ключами, поэтому он не может прочитать ваш трафик. Он видит только то, какие узлы обмениваются данными и какой объем трафика передается.

Важно понимать, как работает конфигурация по умолчанию. Headscale поставляется с настройками, указывающими на https://controlplane.tailscale.com/derpmap/default с auto_update_enabled: true и update_frequency: 3h, поэтому ваш control plane остается под вашим контролем, а ретрансляторы используются от Tailscale. Для большинства пользователей это приемлемый компромисс. Если это не так, разверните собственный ретранслятор.

Чтобы запустить свой ретранслятор, укажите enabled: true в разделе derp.server файла config.yaml, замените стандартные ipv4: 198.51.100.1 и ipv6: 2001:db8::1 на публичные адреса вашего ретранслятора или удалите оба параметра, чтобы использовать DNS. После этого перезапустите headscale и откройте порт STUN (session traversal utilities for NAT) с помощью sudo ufw allow 3478/udp. Эти настройки адресов имеют приоритет над DNS, поэтому, если оставить любой из плейсхолдеров, клиенты будут направляться на недоступный адрес. В файле конфигурации четко указано требование: server_url должен использовать https, так как DERP требует TLS. Очистка списка derp.urls удаляет ретрансляторы Tailscale из карты; перед этим убедитесь, что у вас настроен рабочий встроенный или пользовательский ретранслятор. Headscale не запустится с пустой картой ретрансляторов, а карта, содержащая только недоступный ретранслятор, приведет к тому, что узлы, не способные соединиться напрямую, не смогут обмениваться данными.

На клиенте команда tailscale netcheck выводит задержку до каждого известного региона ретрансляции, а tailscale status отображает direct с адресом или relay с кодом региона для активных соединений с узлами. Если узел «застрял» на relay, необходимо проверить его прямой путь, включая правила NAT и межсетевого экрана. Если узел находится в состоянии direct, но соединение все равно медленное, это отдельная проблема, и обычный ответ в таких случаях связан с MTU, а не с самим туннелем.

Почему узел отображается как offline?

Прокси сбрасывает обновление. Признаком этого является то, что /health возвращает 200, в то время как новые регистрации завершаются ошибкой или существующие узлы не могут переподключиться. Управляющее соединение представляет собой POST-запрос, содержащий Upgrade: tailscale-control-protocol, и прокси, который не пересылает его, блокирует как регистрацию, так и канал, сообщающий о состоянии узла. Сравните свою конфигурацию nginx со строками обновления выше или переключитесь на Caddy, чтобы исключить влияние прокси.

Изменился публичный адрес управления. Узлы продолжают обращаться по адресу, настроенному с помощью --login-server; изменение server_url не обновляет эту настройку на клиенте. Если старый адрес больше не достигает вашего сервера, выполните sudo tailscale up --login-server https://headscale.example.com --force-reauth на каждом узле.

Клиент не запущен. На узле выполните sudo systemctl is-active tailscaled и sudo journalctl -u tailscaled -n 50 --no-pager. Клиент, который не может разрешить или достичь вашего домена, записывает свои попытки повторного подключения в логи.

Истек срок действия ключа. Рассматривается в следующем разделе.

Чтобы наблюдать за серверной частью во время тестирования, выполните sudo journalctl -u headscale -f на VPS и перезапустите tailscaled на клиенте. Проверьте также журнал клиента: запрос, дошедший до headscale, не гарантирует появление записи при стандартном уровне логирования, поэтому отсутствие записей в логах сервера само по себе не доказывает проблему с DNS, брандмауэром или прокси.

Истечение срока действия ключей и узел, который перестает работать через несколько недель

Существует два отдельных срока действия, и их путаница приводит к потере времени.

Preauth-ключи по своей природе имеют короткий срок действия. По умолчанию это один час и одно использование. Если tailscale up отклоняет ключ, создайте новый на сервере, вместо того чтобы редактировать что-либо на клиенте.

Ключи узлов — это долгоживущая часть. Секция node в config.yaml задает expiry: 0, а 0 означает отсутствие срока действия по умолчанию; при этом явный срок действия для клиента или срок действия OIDC все равно могут применяться. Тегированные узлы освобождены от автоматического истечения срока действия, хотя администратор может принудительно завершить их сессию. Установите expiry: 180d, если хотите задать 180-дневный срок по умолчанию для нетегированных регистраций, но срок, запрошенный клиентом, имеет приоритет, а OIDC может переопределить значение по умолчанию. Изменение этой настройки не влияет на уже существующие регистрации задним числом. Узел с ограниченным сроком действия требует повторной аутентификации до наступления этого срока с помощью sudo tailscale up --login-server https://headscale.example.com --force-reauth, и headless-сервер, который никто не переаутентифицирует, будет удален из сети по истечении срока его регистрации.

Выполняйте это вручную, если кто-то потерял ноутбук. sudo headscale nodes list позволяет узнать ID, затем sudo headscale nodes expire -i 3 завершает сессию этого узла, а sudo headscale nodes delete -i 3 полностью удаляет его из сети.

Резервное копирование и обновление

/var/lib/headscale и /etc/headscale вместе составляют весь сервер. Остановите службу перед копированием файлов, так как SQLite может выполнять запись в этот момент, и база данных, скопированная под нагрузкой, может оказаться поврежденной.

sudo systemctl stop headscale
sudo tar czf /root/headscale-state.tgz -C /var/lib headscale
sudo tar czf /root/headscale-config.tgz -C /etc headscale
sudo systemctl start headscale
sudo chmod 600 /root/headscale-*.tgz

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

Обновление повторяет процесс установки: загрузите новые .deb, sudo apt install ./headscale.deb, затем перезапустите службу и повторно выполните проверки is-active и /health. Начиная с версии 0.29 путь обновления стал строгим. Пропуск минорной версии заблокирован, как и откат к более старой минорной версии. Переходите по одной минорной версии за раз, делайте резервную копию перед каждым шагом и сначала читайте примечания к выпуску для этой версии, так как в одном из релизов изменилось поведение политики ACL и были перемещены некоторые ключи конфигурации. Версия 0.29.6 также включает обновления безопасности для проверки сертификатов и зависимостей, поэтому существующие установки 0.29 должны получить это исправление.

FAQ

Запускается ли headscale сразу после установки .deb-пакета?

Да. Пакет запускает службу сразу после установки на /etc/headscale/config.yaml, который слушает только loopback, и устанавливает server_url в значение http://127.0.0.1:8080. При чистой установке служба не добавляется в автозагрузку, поэтому она не запустится при старте системы, пока вы не выполните sudo systemctl enable headscale. Указанный по умолчанию адрес бесполезен для клиентов, поэтому отредактируйте server_url, listen_addr и base_domain, затем выполните sudo systemctl restart headscale и подтвердите результат командой sudo systemctl is-active headscale. Это обязательно должно быть restart: headscale считывает файл только при запуске, а enable --now для уже работающей службы включает её в автозагрузку, но не перезапускает, поэтому старые значения остаются активными. Если после перезапуска возникла ошибка, sudo journalctl -u headscale -n 50 --no-pager укажет на проблему; на данном этапе это почти всегда ошибка в YAML, так как headscale парсит весь файл целиком перед тем, как занять порт.

Нужно ли устанавливать обычный клиент Tailscale на мои устройства?

Да. Headscale заменяет только сервер управления. Каждый узел использует официальный клиент от Tailscale, который вы направляете на свой сервер с помощью sudo tailscale up --login-server https://headscale.example.com. Этот флаг присутствует в стандартном клиенте, поэтому ничего не нужно патчить или пересобирать.

Проходит ли мой трафик через сервер headscale?

Обычно нет. Headscale координирует сеть, распределяет ключи и адреса, в то время как передача данных происходит по протоколу WireGuard напрямую между вашими узлами. Трафик идет в обход только в том случае, если два узла не могут связаться напрямую и переключаются на ретранслятор DERP; в конфигурации по умолчанию используются публичные ретрансляторы Tailscale. Выполните tailscale status на узле, чтобы увидеть, является ли соединение с конкретным узлом direct или проходит через relay.

Почему мой узел остается в статусе offline после регистрации?

Если узел отображается в headscale nodes list, но не переходит в онлайн, необходимо проверить его управляющее соединение, включая работу reverse proxy. Это соединение представляет собой HTTP upgrade, отправляемый методом POST с заголовком Upgrade: tailscale-control-protocol. Nginx сбрасывает его, если вы явно не передадите заголовки Upgrade и Connection с помощью proxy_set_header, что и делает приведенная выше конфигурация через блок map $http_upgrade $connection_upgrade. Отсутствие этих заголовков также препятствует регистрации новых узлов. Caddy передает их без дополнительной настройки, что делает его удобным инструментом для проверки того, является ли прокси причиной проблемы.

Нужны ли мне доменное имя и TLS для headscale?

Для данной настройки — да: используйте доменное имя и HTTPS. Сертификаты могут быть выпущены и для IP-адресов, но в конфигурационном файле указано, что для DERP требуется TLS. Домен вместе с Caddy настраивается примерно за пять минут и предоставляет HTTPS-эндпоинт с автоматическим обновлением сертификатов. Использование обычного HTTP возможно, но документация headscale настоятельно рекомендует HTTPS на 443 порту для продуктовой среды и отмечает, что клиент Tailscale в определенных ситуациях ожидает именно HTTPS на 443 порту.

Была ли эта статья полезной?