SSD Nodes Learn 🎉 VPS от $4.99/мес
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-08-08

Как развернуть свой сервер NetBird VPN на VPS

Пошаговое руководство по установке NetBird на собственный VPS. Настройка DNS, TLS, ключей для автоматического подключения узлов и сравнение архитектуры с Headscale.

Что дает self-hosting сервера NetBird VPN

Self-hosting сервера NetBird VPN переносит плоскость управления (control plane) на ваш собственный VPS: это компонент, который хранит список узлов, определяет правила доступа между ними и помогает двум узлам обнаружить друг друга за NAT (network address translation). Сами туннели по-прежнему работают на базе WireGuard и шифруются напрямую между вашими устройствами. Изменяется лишь то, что никакая сторонняя компания не хранит реестр ваших устройств и данные о процессе входа.

NetBird занимает нишу между двумя уже известными вам решениями. Это mesh-оверлей, поэтому узлы соединяются друг с другом напрямую, а не направляют весь трафик через один шлюз. Также это решение полностью поддерживает self-hosting, что ставит его в один ряд с Headscale, self-hosted сервером управления для Tailscale. Если вы до этого использовали только туннели с одним шлюзом, сначала прочитайте разницу между обычным WireGuard и mesh-оверлеем, так как эта концептуальная модель необходима для понимания остальной части страницы.

Если вам на самом деле нужен один сервер, через который будет выходить весь ваш трафик, то mesh — это избыточное решение для такой задачи. Обычный WireGuard VPN на одном VPS или exit node в Tailscale справятся с этим при гораздо меньших затратах ресурсов.

Что именно запускается в стеке

Структура недавно изменилась, и большинство старых руководств описывают устаревший вариант. По состоянию на август 2026 года, в релизе v0.76.2, скрипт быстрого запуска по умолчанию создает файл Compose с тремя сервисами.

  • netbird-server содержит API управления, сигнальный сервис, ретранслятор со встроенным STUN-слушателем и встроенный провайдер идентификации. В старых релизах это были отдельные контейнеры, а провайдер идентификации представлял собой отдельную инсталляцию Zitadel, которую нужно было предварительно собрать.
  • dashboard — это веб-консоль администратора.
  • traefik выполняет TLS termination (завершение TLS) и запрашивает сертификат у Let's Encrypt при первом запуске.

Существуют еще два сервиса, которые остаются выключенными, если вы не подтвердите их запуск в ответ на запрос. Сервис NetBird Proxy публикует внутренние сервисы на публичных именах хостов. CrowdSec фильтрует вредоносный трафик. Ни один из них не требуется для создания работающей mesh-сети, и оба потребляют оперативную память на небольшом сервере.

Если вы переходите с wg-easy в одном Docker-контейнере, это заметное увеличение количества компонентов. Вы получаете взамен политики доступа, учетные записи для каждого пользователя и пиры, которые соединяются напрямую друг с другом, а не через один шлюз.

Что необходимо перед началом работы

Публичное доменное имя обязательно. Панель управления, API и ретранслятор работают по протоколу HTTPS на порту 443, а Traefik получает сертификат от Let's Encrypt с помощью HTTP-задачи (HTTP challenge). Для этого требуется имя, которое разрешается в IP-адрес вашего VPS из публичного интернета. Использование только IP-адреса в этой схеме не сработает.

Создайте одну A-запись, netbird.example.com, указывающую на публичный IPv4-адрес вашего VPS, и дождитесь её обновления перед запуском любых операций.

dig +short netbird.example.com

Эта команда должна вывести адрес вашего сервера. Если запустить установщик до распространения DNS-записей, запрос сертификата при первом запуске завершится ошибкой. Повторные неудачные попытки проверки приведут к срабатыванию лимитов Let's Encrypt, из-за чего вам придётся ждать час перед следующей попыткой.

Три порта должны быть доступны из интернета: TCP 80 для проверки сертификата и перенаправления на HTTPS, TCP 443 для панели управления, API, сигнального трафика и ретранслятора, а также UDP 3478 для STUN.

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 3478/udp
sudo ufw reload
sudo ufw status

Откройте их также в сетевом межсетевом экране (firewall) вашего провайдера. В большинстве панелей управления VPS это отдельная настройка, и именно из-за неё сервер, на котором ufw status настроен корректно, может отклонять соединения.

STUN (Session Traversal Utilities for NAT) позволяет узлу узнать публичный адрес и порт, назначенные его NAT, чтобы два узла могли попытаться установить прямое соединение. Если заблокировать UDP 3478, узлы всё равно соединятся через ретранслятор по протоколу TCP 443, поэтому внешне всё будет выглядеть исправно. Однако вместо прямого соединения вы получите Connection type: Relayed на каждом узле, и весь трафик будет проходить через ваш VPS, а не напрямую между участниками.

На стороне программного обеспечения вам потребуются Docker с плагином Compose v2, а также jq и curl. Скрипт проверяет наличие всех этих компонентов и останавливается, если какой-либо из них отсутствует. Если Docker на сервере установлен недавно, сначала настройте Docker Compose на VPS.

Порты, если вы не используете встроенный обратный прокси

Работа без Traefik означает, что отдельные сервисы будут доступны напрямую, и список портов увеличится:

  • TCP 80, HTTP-редиректы
  • TCP 443, HTTPS
  • TCP 33073, управление gRPC
  • TCP 10000, сигнальный gRPC
  • TCP 33080, ретранслятор через WebSocket или QUIC
  • UDP 3478, STUN

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

Установка сервера NetBird с помощью скрипта быстрого запуска

Документированная команда в одну строку передает новейший релиз напрямую в оболочку:

curl -fsSL https://github.com/netbirdio/netbird/releases/latest/download/getting-started.sh | bash

Вместо этого зафиксируйте версию. latest перемещается, поэтому одна и та же команда, запущенная с интервалом в две недели, приводит к двум разным установкам, и на диске не остается записей о том, какая именно версия создала вашу конфигурацию. Скачайте помеченный релиз, изучите его, а затем запустите.

mkdir -p ~/netbird
cd ~/netbird
curl -fsSL -o getting-started.sh \
  https://github.com/netbirdio/netbird/releases/download/v0.76.2/getting-started.sh
less getting-started.sh
bash getting-started.sh

Скрипт сначала запрашивает домен:

Enter the domain you want to use for NetBird (e.g. netbird.my-domain.com):

Затем он спрашивает, как будет обрабатываться TLS:

Which reverse proxy will you use?
  [0] Traefik (recommended - automatic TLS, included in Docker Compose)
  [1] Existing Traefik (labels for external Traefik instance)
  [2] Nginx (generates config template)
  [3] Nginx Proxy Manager (generates config + instructions)
  [4] External Caddy (generates Caddyfile snippet)
  [5] Other/Manual (displays setup documentation)
Enter choice [0-5] (default: 0):

Выберите [0]. Варианты со 2 по 5 записывают фрагмент конфигурации и оставляют настройку связей вам, что правильно для сервера, где уже работает прокси, но не подходит для «чистой» системы. Вариант 0 затем запрашивает адрес электронной почты для Let's Encrypt, который используется для уведомлений об истечении срока действия сертификатов.

При первой установке откажитесь от использования сервиса NetBird Proxy. Ему требуются две дополнительные DNS-записи: proxy.netbird.example.com и wildcard-запись *.proxy.netbird.example.com, при этом для обычной mesh-сети он не дает преимуществ. Также откажитесь от CrowdSec. Оба компонента можно добавить позже.

Скрипт записывает файлы в текущую директорию: docker-compose.yml, config.yaml с правами доступа 600, dashboard.env и traefik-dynamic.yaml (если вы выбрали встроенный Traefik). Относитесь к этой директории как к состоянию, которое необходимо хранить, так как config.yaml содержит ключ, шифрующий данные в хранилище. Потеря этого файла не исправляется переустановкой.

docker compose ps
docker compose logs -f netbird-server

Каждый сервис должен прочитать running, а лог сервера должен стабилизироваться, а не перезапускаться в цикле. Отслеживайте состояние сертификата отдельно:

docker compose logs traefik | grep -i acme

ACME (automatic certificate management environment) — это протокол, который Traefik использует для получения сертификата. Ошибки на этом этапе почти всегда связаны с DNS или закрытым 80 портом.

Создание первой учетной записи администратора

Откройте https://netbird.example.com. При чистой установке вместо формы входа отображается страница настройки. Введите адрес электронной почты, имя и пароль, затем нажмите Create Account. Эта учетная запись станет первой административной, после чего произойдет перенаправление на форму входа.

Данная учетная запись хранится во внутреннем хранилище пользователей NetBird, которое обслуживается провайдером идентификации, встроенным в контейнер netbird-server. Внешние компоненты не используются. Это главное отличие от self-hosted версии NetBird годовой давности, когда для работы требовалось сначала развернуть Zitadel или Keycloak и скопировать четыре значения OIDC (OpenID Connect) в setup.env до запуска системы.

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

Подключение первого узла

Установите клиент на любой Linux-машине, включая сам VPS, если вы хотите включить его в mesh-сеть:

curl -fsSL https://pkgs.netbird.io/install.sh | sh

В Debian и Ubuntu этот скрипт настраивает репозиторий пакетов NetBird, а затем устанавливает клиент через apt, поэтому управление пакетом в любом случае переходит к менеджеру пакетов. Если вас беспокоит передача скрипта напрямую в оболочку, сначала сохраните его с помощью curl -fsSL -o install.sh https://pkgs.netbird.io/install.sh и изучите содержимое перед запуском sh install.sh. В любом случае проверьте результат установки:

apt-cache policy netbird

netbird — это клиент командной строки и демон. netbird-ui — это приложение для системного трея, которое не требуется на headless-серверах.

Теперь укажите клиенту адрес вашего сервера:

sudo netbird up --management-url https://netbird.example.com

Если пропустить --management-url, клиент зарегистрируется в облачном сервисе NetBird, так как это значение задано по умолчанию при компиляции. Команда выполнится успешно, машина получит адрес, но ваша панель управления на собственном сервере останется пустой. На этом этапе ошибаются почти все.

Команда выведет URL, который нужно открыть в браузере для завершения входа. После этого выполните:

netbird status
ip addr show wt0

Прочитайте четыре строки из netbird status: Management: Connected, Signal: Connected, строку Relays: с отчетом о всех доступных реле и NetBird IP: в диапазоне оверлейной сети. wt0 — это интерфейс WireGuard, который создает NetBird, и он должен иметь тот же адрес.

Автоматическое подключение второй машины с помощью setup key

Вход через браузер невозможен на машине без графического интерфейса, если рядом нет пользователя. Setup key — это токен предварительной аутентификации, который регистрирует машину без интерактивного этапа. Создайте его в панели управления в разделе Setup Keys.

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

sudo netbird up --setup-key <SETUP-KEY> \
  --management-url https://netbird.example.com \
  --hostname build-runner-01

--hostname задает имя, отображаемое в панели управления. Без этого параметра узел будет использовать имя, которое машина присвоила себе сама, а список из множества записей с именем ubuntu не несет никакой пользы.

Для контейнеров и кратковременных агентов сборки при создании ключа установите флаг ephemeral. Узлы, зарегистрированные с помощью ephemeral ключа, автоматически удаляются после того, как они остаются офлайн более 10 минут, что позволяет избежать появления «мертвых» записей в списке узлов.

Перед планированием использования setup key важно учитывать одно ограничение: истечение срока действия или удаление ключа останавливает регистрацию новых машин, но не отключает те, что уже были зарегистрированы с его помощью. Чтобы отозвать доступ у машины, необходимо удалить соответствующий узел.

Нужен ли вам отдельный провайдер идентификации?

Для небольшой инсталляции — нет. Встроенное хранилище пользователей позволяет создавать учетные записи через панель управления, и этого достаточно для нескольких человек.

Внешний провайдер идентификации необходим, если он у вас уже есть и вы не хотите поддерживать второй список пользователей. NetBird поддерживает любого провайдера, работающего по протоколу OIDC. Зарегистрируйте конфиденциальный OIDC-клиент в вашем провайдере, а затем добавьте его в панели управления NetBird, указав четыре значения: имя, client ID, client secret и issuer. NetBird предоставит вам URL для перенаправления (redirect URL), который нужно вставить в настройки провайдера. Существуют готовые интеграции для Google, Microsoft Entra ID, Okta, Zitadel, Keycloak, Authentik и Pocket ID, а любые другие можно подключить как универсальный OIDC. Если вы уже используете Authentik в качестве self-hosted решения для единого входа, этот путь позволит сохранить единый список учетных записей вместо двух.

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

NetBird или Headscale: какой control plane выбрать?

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

Headscale — это реализация сервера управления Tailscale, при которой вы продолжаете использовать официальные клиенты Tailscale. Официальная веб-консоль отсутствует. Управление пользователями и ключами предварительной аутентификации осуществляется через команду headscale при работе с конфигурационным файлом. Существуют сторонние веб-интерфейсы, созданные сообществом, но они не являются частью проекта. Это подходит тем, кто предпочитает хранить состояние в файлах, а изменения — в системе контроля версий.

NetBird поставляется как полноценный продукт: собственный клиент, собственная панель управления, встроенный провайдер идентификации и политики доступа, редактируемые в браузере. Это означает больше компонентов на вашем VPS, но такой вариант гораздо проще передать коллеге, который не планирует работать с терминалом.

Используйте Headscale, если вы уже используете клиенты Tailscale или вам нужен максимально компактный control plane. Используйте NetBird, если управлять узлами должны несколько человек и вам необходима консоль управления и SSO без самостоятельной сборки системы.

Насколько маленьким может быть VPS для запуска?

Документированный минимум составляет 1 CPU и 2 GB оперативной памяти. Согласно собственным заметкам NetBird, текущий порог составляет около 1 GB RAM, так как управление пользователями теперь локальное, в отличие от 2–4 GB, требовавшихся ранее, когда в состав стека входило полноценное развертывание Zitadel. Приобретайте 2 GB. Дополнительный запас ресурсов позволит выполнять обновление, загружая новые образы, пока старые еще находятся на диске.

Три компонента можно безопасно исключить на маломощном сервере. Откажитесь от сервиса NetBird Proxy, который предназначен для публикации внутренних сервисов по публичным именам хостов и не влияет на соединение узлов (peers) между собой. Откажитесь от CrowdSec; его стоит добавить на открытый в сеть сервер позже, а не в первый день. Оставьте хранилище SQLite по умолчанию в томе netbird_data и переходите на PostgreSQL только тогда, когда начнете распределять развертывание по разным машинам или столкнетесь с реальной конкурентностью; миграция на него описана как задача, которую можно выполнить позже.

Relay — это единственный компонент, от которого нельзя отказаться. Два узла, чьи NAT назначают разные порты для каждого направления, никогда не установят прямой туннель, поэтому relay остается единственным путем, обеспечивающим их работу. Его отключение экономит крайне мало памяти, но разрывает соединения способом, который трудно диагностировать.

Когда одного сервера перестает хватать, relay — это первое, что нужно вынести на отдельную машину. Автономный relay запускается с помощью NB_LISTEN_ADDRESS, NB_EXPOSED_ADDRESS, NB_AUTH_SECRET и NB_ENABLE_STUN. Общий секрет (shared secret) должен быть идентичным на relay и на основном сервере, иначе клиенты не смогут пройти аутентификацию.

Типовые сбои и их признаки

В панели управления отображается предупреждение о сертификате. Traefik не смог получить сертификат. Выполните docker compose logs traefik | grep -i acme. Существует две причины. Либо dig +short netbird.example.com еще не указывает на этот VPS, либо порт TCP 80 закрыт где-то между Let's Encrypt и контейнером — обычно это сетевой файрвол провайдера, а не ufw. Устраните причину перед повторными попытками, так как количество неудачных проверок ограничено, и вы можете заблокировать себе возможность повторного запроса на час.

Клиент сообщает об успешном подключении, но панель управления пуста. Клиент зарегистрировался в облачном сервисе NetBird, так как отсутствовал параметр --management-url. Выполните netbird status --detail и изучите строку Management:, в которой указан сервер, с которым фактически идет обмен данными. Если вы видите Management: Connected to https://api.netbird.io:443, значит, клиент обращается к облаку. Выполните sudo netbird down, а затем снова sudo netbird up --management-url https://netbird.example.com.

Для всех узлов отображается Connection type: Relayed. Прямые туннели не устанавливаются, поэтому весь трафик проходит через ваш VPS, что увеличивает задержку. Проверьте порт UDP 3478 на файрволе VPS и на файрволе провайдера, так как протокол STUN позволяет узлу определить свой публичный адрес и порт. Команда netbird status --detail также выводит Direct: false и типы кандидатов ICE (interactive connectivity establishment) для каждого узла, что позволяет понять, на каком этапе произошел сбой. В некоторых сетях состояние relayed является единственно возможным, и это не считается ошибкой.

Узел подключился, но не имеет доступа к ресурсам. Нахождение в сети mesh не означает, что узлы могут обмениваться данными. Доступ определяется политиками, и группа без назначенной политики не имеет доступа ни к чему. Проверьте политику в панели управления, прежде чем приступать к отладке маршрутов и файрволов.

netbird status сообщает о проблеме с демоном. Сервис не запущен. Используйте sudo netbird service status и sudo netbird service start. Логи клиента находятся в /var/log/netbird/client.log. Если вы не можете определить причину, netbird debug bundle --anonymize --system-info соберет логи, статус, маршруты, настройки DNS и состояние файрвола в один архив.

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

Всю установку определяют два компонента: каталог, содержащий docker-compose.yml и config.yaml, а также Docker volume, в котором хранятся база данных и ключи шифрования. Выполняйте их резервное копирование совместно. В config.yaml находится ключ, шифрующий данные в хранилище, поэтому копия базы данных без него не позволит восстановить читаемую информацию.

docker volume ls
docker compose down
sudo tar czf netbird-config.tgz -C ~ netbird
docker run --rm -v netbird_netbird_data:/data -v "$PWD":/backup \
  alpine tar czf /backup/netbird-data.tgz -C /data .
docker compose up -d

Compose добавляет префикс имени проекта к именам томов, поэтому том, указанный как netbird_data, обычно отображается как netbird_netbird_data. Сначала выполните docker volume ls и используйте имя, которое он выведет, иначе команда docker run выше завершится неудачей: она молча создаст пустой том и не заархивирует ничего. Храните архивы вне VPS. Если у вас уже есть инструмент резервного копирования, restic или BorgBackup справится с задачей переноса данных на внешний узел.

Обновление сервера выполняется через pull и пересоздание:

docker compose pull
docker compose up -d
docker compose ps

Прежде чем полагаться на этот процесс, выполните docker compose config | grep image:. Любой тег со значением latest следует зафиксировать на конкретной версии по той же причине, по которой вы зафиксировали версию скрипта установки: вы должны знать, что именно запущено, и иметь версию для отката, если обновление приведет к сбоям. Клиенты обновляются через тот менеджер пакетов, с помощью которого они были установлены.

FAQ

Нужен ли мне собственный провайдер идентификации для самостоятельного размещения NetBird?

Нет. Текущие релизы включают встроенное хранилище пользователей, поэтому вы создаете первую учетную запись администратора в браузере по адресу https://netbird.example.com, а затем добавляете пользователей через панель управления. Внешний OIDC-провайдер является опциональным и может быть добавлен позже с помощью четырех параметров: имя, client ID, client secret и issuer. Руководства, рекомендующие развертывать Zitadel или Keycloak перед NetBird, описывают настройку, которая больше не требуется, а их выполнение вынуждает вас запускать лишний сервис.

Почему все мои узлы отображаются как Connection type: Relayed?

Прямые соединения не устанавливаются, поэтому трафик идет через ретранслятор (relay) на вашем VPS. Обычная причина — блокировка порта UDP 3478, который является STUN-портом, используемым узлами для определения собственного публичного адреса и порта. Откройте его в брандмауэре VPS и в сетевом экране вашего провайдера, затем снова выполните netbird status --detail и прочитайте строку Direct:. В сети, где NAT назначает разные порты для разных направлений, состояние relayed является единственно возможным, и это не означает ошибку конфигурации.

Клиент подключился, но в панели управления нет узлов. Что произошло?

Клиент зарегистрировался в облачном сервисе NetBird вместо вашего сервера, что происходит, если пропущен параметр --management-url. Команда netbird status --detail выводит адрес сервера, с которым идет взаимодействие, в строке Management:, поэтому значение вроде https://api.netbird.io:443 подтверждает проблему. Выполните sudo netbird down, затем sudo netbird up --management-url https://netbird.example.com, и узел появится в вашей панели управления.

Чем самостоятельный NetBird отличается от Headscale?

Оба решения заменяют облачный сервер управления на ваш собственный. Headscale — это только плоскость управления: вы управляете им через команду headscale и файл конфигурации, официальной веб-консоли нет, и он работает с официальными клиентами Tailscale. NetBird поставляет собственный клиент, панель администратора и интеграцию с провайдерами идентификации в одном стеке. Headscale требует меньше ресурсов и хранит состояние в файлах. NetBird проще передать пользователям, которые не работают с терминалом.

Какой размер VPS нужен для сервера NetBird?

Документированный минимум составляет 1 CPU и 2 GB оперативной памяти, и 2 GB — это объем, который стоит приобрести. Практический порог снизился примерно до 1 GB в последних релизах, так как провайдер идентификации теперь встроен, а не является отдельным развертыванием. Откажитесь от опциональных сервисов прокси и CrowdSec во время установки и используйте стандартное хранилище SQLite, пока вам действительно не потребуется PostgreSQL.