Headscale на VPS: как объединить серверы и устройства в собственную mesh-сеть
Когда в частной сети несколько серверов, рабочих компьютеров и мобильных устройств, ручное управление отдельными конфигурациями WireGuard быстро усложняется. Администратору приходится самостоятельно распределять ключи, учитывать адреса узлов, обновлять конфигурации и следить за тем, какие устройства могут обращаться друг к другу.
Headscale позволяет разместить на собственном VPS сервер управления для клиентов Tailscale. Через него устройства регистрируются в частной сети, получают адреса, правила доступа, DNS-настройки и разрешённые маршруты. При этом трафик между узлами по возможности передаётся напрямую по защищённым соединениям WireGuard.
В этой инструкции разберём установку Headscale на VPS, подключение серверов и пользовательских устройств, настройку правил доступа, публикацию внутренней подсети и резервное копирование конфигурации. Сценарии с выходными узлами, перенаправлением всего интернет-трафика и маршрутами 0.0.0.0/0 или ::/0 здесь не рассматриваются.
Как работает Headscale и когда он нужен
Headscale — открытая реализация управляющего сервера для клиентов Tailscale. Он отвечает за регистрацию устройств, распределение сетевых адресов, сведения об узлах, маршруты, DNS и политики доступа.
Сам Headscale не заменяет WireGuard и обычно не передаёт через себя пользовательский трафик. После получения необходимых параметров клиенты Tailscale стараются установить прямое защищённое соединение между устройствами.
Headscale на VPS
регистрация, узлы, политики, DNS
/ | \
/ | \
ноутбук сервер офисный шлюз
\ | /
\___ WireGuard _____/
трафик данныхКогда Headscale полезен
Собственный управляющий сервер оправдан, если необходимо:
- объединить несколько VPS, физических серверов, рабочих станций и мобильных устройств;
- централизованно добавлять и отзывать узлы;
- разделять доступ сотрудников и администраторов;
- назначать серверным узлам постоянные теги;
- предоставлять доступ к отдельной офисной или домашней подсети;
- использовать собственный домен, DNS и правила доступа;
- хранить данные управляющего сервера в своей инфраструктуре.
Если требуется подключить только несколько сотрудников к одному серверу или внутреннему сервису, отдельный Headscale может оказаться избыточным. Для такого сценария подойдет обычная настройка из статьи «WireGuard на Linux VPS для сотрудников».
Какие компоненты участвуют в работе
- Headscale — управляющий сервер, размещённый на VPS.
- Tailscale — клиент на компьютерах, серверах и мобильных устройствах.
- WireGuard — протокол, который защищает соединения между узлами.
- Nginx — reverse proxy, принимающий HTTPS-соединения на публичном домене.
- Grants — правила, определяющие, каким узлам и сервисам разрешено взаимодействовать.
- Subnet router — узел, публикующий в mesh-сети отдельную локальную подсеть.
У Headscale нет обязательной встроенной графической панели администрирования. Основные операции выполняются через командную строку и конфигурационные файлы. Сторонние панели следует устанавливать только после отдельной проверки их происхождения, поддержки и модели доступа.
Правовые и эксплуатационные границы
Headscale следует использовать для защищённого подключения к собственной инфраструктуре или к ресурсам, доступ к которым разрешён их владельцем: корпоративным серверам, офисным подсетям, тестовым средам и административным интерфейсам.
В этой статье Headscale не рассматривается как средство изменения геолокации, анонимизации, обхода ограничений или перенаправления всего пользовательского интернет-трафика. Настраивайте только необходимые адреса, подсети и порты.
Как подготовить VPS, домен и TLS
Для управляющего сервера лучше использовать отдельный Linux VPS с постоянным публичным IP-адресом. Headscale поддерживает установку из DEB-пакета на актуальные версии Ubuntu и Debian. В примерах используется сервер с Ubuntu 22.04 или новее.
Перед установкой обновите систему, настройте SSH-доступ и firewall. Базовый порядок действий приведён в материале «Первичная настройка Ubuntu VPS после заказа».
Требования к серверу
Для небольшой сети Headscale не требуется мощная конфигурация. Важнее стабильность сервера, резервное копирование и доступность домена.
| Компонент | Начальная конфигурация | Комментарий |
|---|---|---|
| CPU | 1 vCPU | Обычно достаточно для небольшой сети |
| Оперативная память | 1 ГБ | Учитывайте также Nginx и системные службы |
| Диск | 10–20 ГБ SSD | База Headscale небольшая, но нужен запас для журналов и копий |
| IP-адрес | Постоянный публичный IPv4 | Упрощает DNS и стабильное подключение клиентов |
| Домен | Отдельный поддомен | Например, headscale.example.ru |
Домен и DNS
Создайте A-запись отдельного поддомена, направленную на публичный IP-адрес VPS:
headscale.example.ru. A 203.0.113.10После обновления DNS проверьте, что домен возвращает адрес нужного сервера:
dig +short headscale.example.ruДля внутренних имён выберите другой домен, например mesh.example.ru. Публичный адрес Headscale и внутренний DNS-домен не должны совпадать.
Сетевые порты
На сервере должны быть доступны:
22/tcp— для SSH, желательно только с доверенных адресов;80/tcp— для выпуска сертификата и перенаправления на HTTPS;443/tcp— для подключения клиентов к Headscale.
Если используется UFW, добавьте правила:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status verboseЛокальные порты Headscale 8080 и метрик 9090 не нужно открывать в интернет. Далее служба будет слушать их только на 127.0.0.1.
Установка и базовая настройка Headscale
Установка DEB-пакета
Проверьте архитектуру операционной системы:
dpkg --print-architectureНа странице релизов Headscale выберите актуальную стабильную версию и пакет для своей архитектуры. В командах ниже замените X.Y.Z на номер выбранного релиза, а при необходимости измените amd64 на другую архитектуру.
HEADSCALE_VERSION="X.Y.Z"
HEADSCALE_ARCH="amd64"
wget "https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_${HEADSCALE_ARCH}.deb"
sudo apt install "./headscale_${HEADSCALE_VERSION}_linux_${HEADSCALE_ARCH}.deb"
headscale versionНе фиксируйте в рабочих инструкциях случайную устаревшую версию. Перед установкой проверяйте примечания к стабильному релизу и изменения формата конфигурации.
Резервная копия исходной конфигурации
Перед редактированием сохраните конфигурацию, установленную вместе с пакетом:
sudo cp /etc/headscale/config.yaml /etc/headscale/config.yaml.before-edit
sudo nano /etc/headscale/config.yamlНе заменяйте файл целиком без проверки. В новых версиях Headscale могут появляться обязательные параметры. Сопоставьте приведённые ниже значения с конфигурацией вашего релиза.
Основные параметры Headscale
Проверьте или измените следующие параметры:
server_url: https://headscale.example.ru
listen_addr: 127.0.0.1:8080
metrics_listen_addr: 127.0.0.1:9090
trusted_proxies:
- 127.0.0.1/32
- ::1/128
noise:
private_key_path: /var/lib/headscale/noise_private.key
prefixes:
v4: 100.64.0.0/10
v6: fd7a:115c:a1e0::/48
database:
type: sqlite
sqlite:
path: /var/lib/headscale/db.sqlite
write_ahead_log: true
policy:
mode: file
path: /etc/headscale/policy.hujson
dns:
magic_dns: true
base_domain: mesh.example.ru
override_local_dns: false
nameservers:
global: []
search_domains: []
extra_records: []
tls_cert_path: ""
tls_key_path: ""server_url— публичный HTTPS-адрес управляющего сервера.listen_addr— локальный адрес Headscale за Nginx.trusted_proxies— доверенные reverse proxy на этом сервере.prefixes— диапазоны адресов для узлов mesh-сети.database— локальная база данных Headscale.policy— файл правил доступа.base_domain— внутренний DNS-суффикс узлов.
Начальный файл политик
Создайте отдельный файл политик:
sudo nano /etc/headscale/policy.hujsonНа первом этапе можно создать пустой набор Grants:
{
"grants": []
}Проверьте конфигурацию и запустите службу:
sudo headscale configtest
sudo systemctl enable --now headscale
sudo systemctl status headscale --no-pager
curl -fsS http://127.0.0.1:8080/healthКоманда configtest должна завершиться без ошибок, служба — перейти в состояние active, а локальная проверка здоровья — вернуть успешный ответ.
Nginx и HTTPS
Установите Nginx и Certbot:
sudo apt update
sudo apt install nginx certbot python3-certbot-nginxСоздайте файл /etc/nginx/conf.d/headscale-map.conf:
map $http_upgrade $connection_upgrade {
default keep-alive;
'' close;
}Затем создайте виртуальный хост /etc/nginx/sites-available/headscale:
upstream headscale_backend {
zone headscale_backend 64k;
server 127.0.0.1:8080;
keepalive 2;
}
server {
listen 80;
listen [::]:80;
server_name headscale.example.ru;
location = /generate_204 {
return 204;
}
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 True-Client-IP $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_pass http://headscale_backend;
}
}Активируйте конфигурацию, проверьте её и получите TLS-сертификат:
sudo ln -s /etc/nginx/sites-available/headscale /etc/nginx/sites-enabled/headscale
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d headscale.example.ru
curl -I https://headscale.example.ru/healthКак зарегистрировать пользователей и узлы
В актуальных версиях Headscale для группировки узлов используются пользователи. Персональные устройства можно связывать с конкретным пользователем, а серверные узлы дополнительно помечать тегами.
Создание пользователей
Создадим отдельные учётные записи администратора и сотрудника:
sudo headscale users create admin
sudo headscale users create employee
sudo headscale users listВ командах имена указываются без символа @. В файле политик пользователь обозначается как admin@ или employee@.
Интерактивная регистрация устройства
Установите официальный клиент Tailscale на подключаемое устройство, а затем укажите собственный управляющий сервер:
sudo tailscale up --login-server https://headscale.example.ruКлиент покажет адрес регистрации с ключом узла. На сервере Headscale выполните команду, подставив полученный ключ:
sudo headscale nodes register --user employee --key <REGISTRATION_KEY>
sudo headscale nodes listПосле регистрации устройство должно появиться в списке узлов и получить адрес из диапазона mesh-сети.
Подключение с одноразовым ключом
Для автоматизированной регистрации сервера сначала определите идентификатор пользователя:
sudo headscale users list
sudo headscale preauthkeys create --user <USER_ID>На подключаемом сервере используйте выданный ключ:
sudo tailscale up \
--login-server https://headscale.example.ru \
--auth-key <PREAUTH_KEY>Теги для серверных узлов
Персональные ноутбуки и телефоны обычно остаются привязанными к пользователю. Серверы и сетевые шлюзы удобнее отмечать тегами, чтобы правила не зависели от имени конкретного устройства.
sudo headscale nodes list
sudo headscale nodes tag -i <SERVER_NODE_ID> --tags tag:server
sudo headscale nodes tag -i <ROUTER_NODE_ID> --tags tag:routerПраво назначать такие теги далее будет ограничено группой администраторов.
Отзыв доступа
Перед удалением узла посмотрите его идентификатор и доступные команды вашей версии Headscale:
sudo headscale nodes list
sudo headscale nodes --helpУдаляйте устройство только после сверки имени, пользователя, адреса и идентификатора. Если узел публикует офисную подсеть, его удаление одновременно прекратит доступ к этой сети.
Правила доступа, маршруты и DNS
В новых конфигурациях Headscale предпочтительно использовать Grants. Старый формат ACL может поддерживаться для совместимости, но новую политику лучше строить на Grants и сверять с документацией установленной версии.
Базовая политика доступа
Следующий пример разрешает администраторам обращаться к серверам и сетевым шлюзам по любым портам, а сотрудникам — только к HTTPS-сервисам на узлах с тегом tag:server:
{
"groups": {
"group:admins": ["admin@"],
"group:employees": ["employee@"]
},
"tagOwners": {
"tag:server": ["group:admins"],
"tag:router": ["group:admins"]
},
"grants": [
{
"src": ["group:admins"],
"dst": ["tag:server", "tag:router"],
"ip": ["*"]
},
{
"src": ["group:employees"],
"dst": ["tag:server"],
"ip": ["443"]
}
]
}После сохранения проверьте конфигурацию и перезапустите Headscale:
sudo headscale configtest
sudo systemctl restart headscale
sudo systemctl status headscale --no-pager
sudo journalctl -u headscale -n 50 --no-pagerПроверяйте не только разрешённое подключение, но и запрет: сотрудник не должен получать доступ к административным портам только потому, что сервер присутствует в mesh-сети.
Публикация офисной подсети
Предположим, что офисный шлюз подключён к сети 192.168.50.0/24. Включите на нём пересылку IPv4-пакетов, создав файл /etc/sysctl.d/99-headscale-router.conf:
net.ipv4.ip_forward = 1Примените настройку:
sudo sysctl --systemПереподключите клиент Tailscale на шлюзе с публикацией только нужной подсети:
sudo tailscale up \
--login-server https://headscale.example.ru \
--advertise-routes=192.168.50.0/24На сервере Headscale найдите узел и подтвердите маршрут:
sudo headscale nodes list-routes
sudo headscale nodes approve-routes \
--identifier <ROUTER_NODE_ID> \
--routes 192.168.50.0/24На Linux-устройствах, которым требуется доступ к опубликованной сети, разрешите приём маршрутов:
sudo tailscale set --accept-routes=trueОграничение доступа к подсети
Публикация маршрута ещё не означает, что всем пользователям нужно разрешать доступ ко всей подсети. Например, сотрудникам можно открыть только HTTPS на внутреннем приложении 192.168.50.20:
{
"hosts": {
"office-app": "192.168.50.20/32"
},
"grants": [
{
"src": ["group:employees"],
"dst": ["office-app"],
"ip": ["443"]
}
]
}Этот фрагмент нужно объединить с существующим корневым объектом policy.hujson, а не добавлять в файл вторым независимым объектом. После применения политики проверьте:
- доступ сотрудника к
192.168.50.20:443; - отсутствие доступа к SSH и другим административным портам;
- отсутствие доступа к остальным адресам подсети;
- полный административный доступ только у назначенной группы.
Внутренние DNS-имена
MagicDNS позволяет обращаться к узлам по именам внутри выбранного домена. Для отдельного внутреннего ресурса можно добавить A-запись:
dns:
magic_dns: true
base_domain: mesh.example.ru
override_local_dns: false
nameservers:
global: []
search_domains: []
extra_records:
- name: app.mesh.example.ru
type: A
value: 100.64.0.10Примените настройки и разрешите клиенту использовать DNS-параметры mesh-сети:
sudo headscale configtest
sudo systemctl restart headscale
sudo tailscale set --accept-dns=true
dig app.mesh.example.ruДополнительные записи Headscale предназначены прежде всего для простых сопоставлений имён и IP-адресов. Для сложной внутренней DNS-зоны используйте отдельный DNS-сервер и передавайте его адрес клиентам через настройки Headscale.
Проверка, обновление и резервное копирование
Проверка соединений
После подключения узлов проверьте их состояние с обеих сторон:
sudo headscale nodes list
tailscale status
tailscale ping app01
curl -I https://app.mesh.example.ruПроверка должна подтверждать:
- регистрацию узла у правильного пользователя;
- наличие ожидаемого mesh-адреса;
- прямое или ретранслируемое соединение между устройствами;
- работу внутреннего DNS;
- доступ только к разрешённым адресам и портам;
- блокировку действий, отсутствующих в Grants.
Диагностика неполадок
Для начальной диагностики проверьте службы и журналы:
sudo systemctl status headscale --no-pager
sudo journalctl -u headscale -n 100 --no-pager
curl -fsS http://127.0.0.1:8080/health
sudo systemctl status nginx --no-pager
sudo nginx -t- Если локальный
/healthнедоступен, проверяйте Headscale иconfig.yaml. - Если локальный ответ есть, но HTTPS не работает, проверяйте DNS, Nginx, сертификат и firewall.
- Если узел зарегистрирован, но соединение отсутствует, проверяйте клиент Tailscale и сетевую доступность.
- Если соединение есть, но сервис недоступен, проверяйте Grants, локальный firewall и прослушиваемый порт приложения.
- Если не работает офисная подсеть, проверяйте публикацию и подтверждение маршрута, IP forwarding и отсутствие пересечения адресных диапазонов.
Что резервировать
В резервную копию Headscale должны входить:
/etc/headscale/
/var/lib/headscale/db.sqlite
/var/lib/headscale/noise_private.key
/etc/nginx/sites-available/headscale
/etc/nginx/conf.d/headscale-map.confДополнительно сохраните сведения о DNS-записях, сертификатах, пользователях, тегах, опубликованных маршрутах и назначении узлов.
Копия перед обновлением
Для согласованной копии SQLite временно остановите Headscale:
BACKUP_DATE="$(date +%F-%H%M)"
sudo mkdir -p "/var/backups/headscale/${BACKUP_DATE}"
sudo systemctl stop headscale
sudo cp -a /etc/headscale "/var/backups/headscale/${BACKUP_DATE}/"
sudo cp -a /var/lib/headscale "/var/backups/headscale/${BACKUP_DATE}/"
sudo systemctl start headscale
sudo systemctl status headscale --no-pagerБезопасное обновление
Перед обновлением:
- прочитайте примечания ко всем промежуточным стабильным версиям;
- проверьте изменения в формате
config.yamlи политик; - сделайте внешнюю резервную копию;
- зафиксируйте текущую версию Headscale;
- подготовьте окно обслуживания и способ отката.
После установки новой версии выполните:
headscale version
sudo headscale configtest
sudo systemctl restart headscale
sudo systemctl status headscale --no-pager
sudo headscale nodes listЗатем проверьте регистрацию клиентов, DNS, Grants и маршруты. Не переходите через несколько значимых версий без изучения миграций: формат конфигурации и команды управления могут изменяться.
Заключение
Headscale помогает централизованно управлять частной сетью из серверов, рабочих компьютеров и мобильных устройств. Он отвечает за регистрацию узлов, адреса, политики, DNS и маршруты, а клиенты Tailscale устанавливают между собой защищённые соединения WireGuard.
Надёжность такой сети зависит не только от установки Headscale. Необходимо ограничить доступ с помощью Grants, защищать ключи регистрации, контролировать публикуемые подсети, резервировать базу и проверять восстановление после обновлений.
Используйте конфигурацию только для доступа к собственной инфраструктуре и ресурсам, на подключение к которым у вас есть разрешение. Не публикуйте маршруты и сервисы, не требующиеся для рабочей задачи.
Что почитать дальше
- WireGuard на Linux VPS для сотрудников: защищённый доступ к внутренним сервисам.
- Первичная настройка Ubuntu VPS после заказа: SSH, обновления, firewall и резервное копирование.
Когда стоит обратиться к специалистам
Помощь администратора потребуется, если Headscale должен работать в отказоустойчивой инфраструктуре, сеть включает много пользователей и подсетей, необходимы сложные Grants, централизованный DNS, интеграция с корпоративной системой доступа или безопасная миграция существующих узлов.
Кратко
- Headscale управляет узлами частной сети, но не заменяет WireGuard.
- Устройства подключаются к собственному управляющему серверу через клиенты Tailscale.
- Для Headscale нужен постоянный VPS, отдельный домен и действующий HTTPS-сертификат.
- В новых конфигурациях правила доступа лучше описывать через Grants, а не через устаревающий формат ACL.
- Отсутствие явной политики может привести к разрешению лишних соединений, поэтому доступ нужно проверять отдельно.
- Серверные узлы и сетевые шлюзы удобно отделять от персональных устройств с помощью тегов.
- Маршрут к локальной подсети начинает работать только после публикации шлюзом и подтверждения на Headscale.
- Конфигурацию, базу данных, политики и ключи Headscale необходимо регулярно копировать во внешнее хранилище.