wgbutler logo

wgbutler

wgbutler — менеджер кластера для оверлейной сети на базе WireGuard: инициализация кластера, присоединение нод, демон для синхронизации состояния (gossip) и автоматической конфигурации WireGuard.

Возможности

Поддержка ОС

Где хранятся конфиги

По умолчанию wgbutler использует каталог:

Файлы пишутся с правами 0600, директория — 0700.

Быстрый старт

1) Инициализация первого узла

На первом сервере (Linux):

wgbutler init \
  --network-name mynet \
  --network-cidr 10.0.0.0/16 \
  --public-endpoint your.public.host:51820

Команда выведет Join-Token: ....

2) Запуск демона

На первом сервере:

wgbutler daemon

По умолчанию HTTP API слушает :51821.

3) Присоединение нового узла

На новом сервере:

wgbutler join \
  --cluster-ip <ip-or-hostname-of-existing-node> \
  --cluster-token <JOIN_TOKEN> \
  --public-endpoint your.public.host:51820

wgbutler daemon

Администрирование (CLI)

Большинство админ-команд читают admin_token, api_listen и (опционально) api_tls_listen из config.json. Если нужно — можно передавать --api-endpoint/--admin-token явно, либо использовать mTLS (--auth mtls + TLS flags).

Join tokens

Примечание: в secure mode мутации join-token выполняются через QC (/api/v1/admin/secure/qc/*); wgbutler token create/revoke вернёт 409. Для secure mode используйте WGButlerAcademy.

wgbutler token create --ttl 3600
wgbutler token list
wgbutler token revoke <TOKEN_ID>

Nodes

Примечание: в secure mode wgbutler node set/delete пока отключены (вернут 409).

wgbutler node list
wgbutler node status

# Best-effort reachability signals (last state sync, handshake age when available)
wgbutler node reachability

wgbutler node set --id <NODE_ID> \
  --public-endpoint host:51820 \
  --advertised-subnets '10.1.0.0/16,10.2.0.0/16'

# Включить relay-режим на ноде (обычно на ноде с публичным endpoint)
wgbutler node set --id <NODE_ID> --relay true

wgbutler node delete <NODE_ID>

Примечание: удаление ноды запрещено, если к ней привязаны клиенты.

Clients

Примечание: в secure mode мутации клиентов через CLI (client create/delete/move) отключены (вернут 409); используйте WGButlerAcademy. Перенос клиента (move) в secure mode не поддерживается.

Создать клиента и получить конфиг (конфиг печатается в stdout):

wgbutler client create --name laptop > laptop.conf

Список клиентов:

wgbutler client list
wgbutler client list --attached-node <NODE_ID>

Удалить клиента:

wgbutler client delete <CLIENT_ID>

Перенести клиента на другую ноду и выдать новый конфиг:

wgbutler client move --to-node <TARGET_NODE_ID> <CLIENT_ID> > client.conf

HTTP API (кратко)

TLS/mTLS (admin first)

По умолчанию API работает по HTTP. Можно включить дополнительный HTTPS listener и переключить аутентификацию админ-эндпоинтов:

config.json (локально на каждой ноде):

CLI примеры:

# token auth (как раньше)
wgbutler token list

# mTLS auth (без X-Admin-Token)
wgbutler token list \
  --auth mtls \
  --api-endpoint https://HOST:51822 \
  --tls-ca /path/to/ca.pem \
  --tls-cert /path/to/admin.crt \
  --tls-key /path/to/admin.key

Secure mode (QC allowlist)

wgbutler поддерживает режим secure: состояние кластера становится «цепочкой коммитов», принимаемой только при наличии QC (quorum certificate) от фиксированного комитета.

Ключевые свойства:

Включение secure mode (1 запрос)

Условия:

Запрос:

admin_spki_sha256 — это SHA256(SPKI) публичного ключа mTLS сертификата администратора (hex).

Пример (возьми только hex-строку из вывода):

openssl x509 -in admin.crt -noout -pubkey \
  | openssl pkey -pubin -outform DER \
  | openssl dgst -sha256 -hex

Admin операции в secure mode (QC протокол)

В secure mode мутации state делаются через QC-endpoints:

Поддержанные операции QC сейчас:

Примечания:

Ограничения / допущения MVP

Эксплуатация (runbook)

Docker

В репозитории есть:

Сборка образа:

docker build -t wgbutler:local .

Запуск демона через compose (Linux; требуется /dev/net/tun и CAP_NET_ADMIN):

docker compose up -d wgbutler

Если нужно запускать образ из registry (latest), используй docker-compose.registry.yml:

docker compose -f docker-compose.registry.yml up -d wgbutler

На новом узле join можно сделать автоматически через oneshot-сервис wgbutler-join (он запустится перед wgbutler):

export WGBUTLER_JOIN_CLUSTER_IP=NODE1.PUBLIC.IP:51821
export WGBUTLER_JOIN_TOKEN=TOKEN_ID
# (optional) если у ноды есть reachable endpoint (например, публичный IP)
export WGBUTLER_JOIN_PUBLIC_ENDPOINT=NODE2.PUBLIC.IP:51820

docker compose -f docker-compose.registry.yml up -d wgbutler

Дополнительно (опционально):

Одноразовая инициализация первого узла (пример; подставь свои значения):

docker compose --profile init run --rm wgbutler-init \
  --network-name mynet \
  --network-cidr 10.0.0.0/16 \
  --public-endpoint YOUR.PUBLIC.IP:51820

После init можно запускать wgbutler (daemon) обычным docker compose up -d wgbutler.

Сборка

go build ./...

Linux binary (пример):

GOOS=linux GOARCH=amd64 go build -o wgbutler-linux-amd64 ./cmd/wgbutler