Files
wireguard-scripts/MVP.md
T
2026-10-11 22:46:09 +03:00

482 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WireGuard Manager: план MVP
## 1. Назначение проекта
WireGuard Manager — локальный Bash-скрипт для администрирования WireGuard на том же Linux-сервере, где запущен WireGuard.
Основные задачи проекта:
- просмотр состояния WireGuard;
- просмотр списка клиентов;
- добавление клиентов;
- удаление клиентов;
- получение клиентского конфига и QR-кода;
- диагностика конфигурации, сервиса и сети;
- ведение локального журнала административных операций;
- создание резервных копий перед изменением конфигурации.
Существующий `add-user.sh` используется как исходный пример, но его логика будет переработана в безопасные переиспользуемые функции.
## 2. Модель распространения и запуска
Проект не устанавливается в систему и не добавляется в `PATH`. Скрипт и сопутствующие файлы находятся в переносимой директории, например:
```text
/root/wireguard-manager/
├── wg-manager.sh
├── wg-manager.conf
├── add-user.sh
├── bin/
│ └── gum
├── backups/
├── logs/
└── tests/
```
Основная точка входа:
```bash
sudo /root/wireguard-manager/wg-manager.sh
```
CLI-команды вызываются через тот же файл:
```bash
sudo /root/wireguard-manager/wg-manager.sh status
sudo /root/wireguard-manager/wg-manager.sh list
sudo /root/wireguard-manager/wg-manager.sh add alice
sudo /root/wireguard-manager/wg-manager.sh diagnose
```
Скрипт определяет свою директорию через `BASH_SOURCE`, поэтому всю директорию проекта можно перемещать. Скрипты `install.sh` и `uninstall.sh` не нужны.
Установку или размещение зависимостей выполняет администратор сервера.
## 3. TUI
Для терминального интерфейса используется `gum`. Встроенный TUI на чистом Bash, а также интерфейсы на `dialog` и `whiptail` в MVP не планируются.
Поиск бинарника `gum` выполняется в следующем порядке:
1. Путь из переменной окружения `WG_MANAGER_GUM`.
2. `${SCRIPT_DIR}/bin/gum` рядом со скриптом.
3. Команда `gum` из `PATH`.
Если `gum` отсутствует:
- CLI-команды продолжают работать;
- при попытке открыть TUI выводится понятное сообщение об ошибке;
- скрипт не устанавливает и не скачивает `gum` автоматически.
### Главное меню
```text
WireGuard Manager
Интерфейс: wg0
Состояние: активен
Клиентов: 12 Активны недавно: 4
1. Состояние WireGuard
2. Список клиентов
3. Добавить клиента
4. Информация о клиенте
5. Показать QR-код / конфиг
6. Удалить клиента
7. Диагностика
8. Журнал операций
9. Резервные копии
0. Выход
```
TUI должен использовать возможности `gum` для меню, фильтрации списка клиентов, ввода данных, таблиц, подтверждений, просмотра длинного текста и индикации выполнения операций.
## 4. Архитектурный принцип
TUI не содержит бизнес-логику. Он только собирает ввод пользователя и вызывает те же функции, которые доступны через CLI.
Логические слои внутри `wg-manager.sh`:
1. Загрузка и проверка конфигурации.
2. Проверка прав и зависимостей.
3. Чтение состояния WireGuard.
4. Управление клиентами.
5. Безопасное изменение серверного конфига.
6. Резервное копирование и восстановление.
7. Диагностика.
8. Audit log.
9. CLI-маршрутизация.
10. TUI на `gum`.
Для MVP эти функции могут находиться в одном `wg-manager.sh`. Если файл станет слишком большим, их можно будет позднее вынести в `lib/*.sh`, сохранив прежнюю точку входа.
## 5. Конфигурация менеджера
Из `add-user.sh` необходимо убрать жёстко заданные параметры и перенести их в `wg-manager.conf`.
Пример состава конфигурации:
```bash
WG_INTERFACE="wg0"
WG_CONF="/etc/wireguard/wg0.conf"
CLIENT_DIR="/etc/wireguard/clients"
SERVER_ENDPOINT="vpn.example.com"
SERVER_PORT="51820"
SERVER_VPN_IP="10.9.0.1"
CLIENT_DNS="10.9.0.1,192.168.0.200"
VPN_SUBNET_PREFIX="10.9.0"
START_HOST="2"
END_HOST="254"
USE_IPV6="0"
IPV6_PREFIX="fd05:13:53::"
DEFAULT_CLIENT_MODE="full-tunnel"
RECENT_HANDSHAKE_SECONDS="180"
```
Конфигурация должна проверяться до выполнения любой операции. Неизвестные или небезопасные значения не должны напрямую подставляться в команды.
Рекомендуемые права:
```bash
chmod 700 /root/wireguard-manager
chmod 700 /root/wireguard-manager/wg-manager.sh
chmod 600 /root/wireguard-manager/wg-manager.conf
```
## 6. Функции MVP
### 6.1. Состояние WireGuard
Экран состояния показывает:
- имя интерфейса;
- состояние интерфейса и `wg-quick`-сервиса;
- публичный ключ сервера;
- UDP-порт;
- количество peers;
- время работы или доступную информацию о запуске сервиса;
- наличие предупреждений диагностики.
### 6.2. Список клиентов
Для каждого клиента показываются:
- имя;
- VPN-адрес;
- сокращённый публичный ключ;
- endpoint, если он известен;
- время последнего handshake;
- принятый и переданный трафик;
- вычисляемое состояние;
- признак, управляется ли клиент этим скриптом.
Предлагаемые состояния:
- `active` — handshake был недавно;
- `inactive` — клиент ранее подключался, но давно неактивен;
- `never` — handshake ещё не было;
- `unmanaged` — peer найден в WireGuard, но его имя и метаданные неизвестны менеджеру.
Источником текущего состояния является `wg show ... dump`. Серверный конфиг используется для постоянных параметров и сопоставления peers.
### 6.3. Добавление клиента
Операция добавления:
1. Проверяет имя клиента.
2. Проверяет отсутствие клиента, ключей и файлов с таким именем.
3. Находит свободный IP в заданном диапазоне.
4. Проверяет конфликты во всех `AllowedIPs`.
5. Создаёт private key, public key и preshared key.
6. Формирует серверный peer-блок.
7. Формирует клиентский конфиг.
8. Проверяет будущую серверную конфигурацию.
9. Создаёт резервную копию.
10. Атомарно сохраняет и применяет конфигурацию.
11. Сохраняет метаданные клиента.
12. Записывает административное действие в журнал.
Имя клиента допускает только безопасный ограниченный набор символов: латинские буквы, цифры, точку, подчёркивание и дефис.
MVP поддерживает два режима маршрутизации клиента:
- `full-tunnel` — весь IPv4-трафик идёт через VPN;
- `split-tunnel` — через VPN идут только указанные сети.
### 6.4. Просмотр и экспорт клиента
Для выбранного клиента доступны:
- сведения о peer;
- путь к клиентскому конфигу;
- просмотр конфига после отдельного подтверждения;
- QR-код через `qrencode`, если команда доступна;
- понятное сообщение и путь к конфигу, если `qrencode` отсутствует.
Приватные ключи и содержимое клиентских конфигов не записываются в audit log.
### 6.5. Удаление клиента
Удаление требует выбора клиента и явного подтверждения. Перед изменением создаётся резервная копия.
Операция:
1. Находит peer по сохранённому публичному ключу, а не только по имени.
2. Удаляет peer из будущей серверной конфигурации.
3. Проверяет новый конфиг.
4. Применяет изменение.
5. Удаляет или архивирует клиентские файлы согласно выбранной политике.
6. Записывает действие в audit log без секретов.
Для MVP безопаснее по умолчанию перемещать клиентские файлы в локальный архив, а не уничтожать безвозвратно.
### 6.6. Диагностика
Диагностика проверяет:
- запуск с необходимыми правами;
- наличие `wg`, `wg-quick`, `ip` и других обязательных команд;
- наличие серверного конфига;
- права на конфиги и ключи;
- наличие и состояние интерфейса;
- состояние `wg-quick@<interface>` при использовании systemd;
- возможность прочитать активную конфигурацию;
- корректность адресов и `AllowedIPs`;
- дублирующиеся адреса и пересекающиеся сети;
- включён ли IPv4 forwarding;
- IPv6 forwarding, если IPv6 включён в настройках;
- маршруты сервера;
- наличие ожидаемых NAT/firewall-правил;
- прослушивание настроенного UDP-порта;
- расхождение между конфигом на диске и активным состоянием;
- последние релевантные сообщения systemd journal.
Результат каждой проверки имеет статус `OK`, `WARN`, `FAIL` или `SKIP`. Команда диагностики возвращает ненулевой exit code при критических ошибках.
WireGuard не предоставляет полноценную историю клиентских подключений. Менеджер показывает текущее состояние, последние handshake и доступные системные журналы, но не заявляет их как полную историю активности пользователей.
### 6.7. Журнал операций
Локальный audit log содержит:
- дату и время;
- выполненную операцию;
- имя клиента, если применимо;
- результат;
- краткое описание ошибки;
- пользователя или UID, запустившего операцию.
В журнал запрещено записывать:
- private keys;
- preshared keys;
- полные клиентские конфиги;
- команды, содержащие секретные значения.
### 6.8. Резервные копии
Перед каждым изменением создаётся резервная копия серверного конфига и относящихся к операции метаданных.
MVP предоставляет:
- создание резервной копии;
- список резервных копий;
- восстановление выбранной копии с подтверждением;
- автоматический rollback при ошибке применения нового конфига;
- ограничение количества автоматически сохраняемых копий.
## 7. Безопасное изменение конфигурации
Изменение `wg0.conf` должно быть транзакционным:
1. Получить эксклюзивную блокировку через `flock`.
2. Повторно прочитать актуальное состояние после получения блокировки.
3. Проверить входные данные.
4. Создать backup.
5. Сформировать новый конфиг во временном файле с `umask 077`.
6. Проверить синтаксис и возможность преобразования конфига средствами WireGuard.
7. Установить правильные права и владельца.
8. Атомарно заменить рабочий файл.
9. Применить конфигурацию через `wg syncconf` и `wg-quick strip`.
10. Проверить итоговое активное состояние.
11. При ошибке восстановить предыдущий файл и активную конфигурацию.
12. Освободить блокировку и записать результат в журнал.
Нельзя сначала дописывать peer непосредственно в рабочий конфиг, как это сейчас делает `add-user.sh`, а затем надеяться, что применение завершится успешно.
## 8. CLI
Минимальный набор команд:
```text
wg-manager.sh Открыть TUI
wg-manager.sh status Состояние WireGuard
wg-manager.sh list Список клиентов
wg-manager.sh add NAME Добавить клиента
wg-manager.sh show NAME Информация о клиенте
wg-manager.sh config NAME Показать путь к клиентскому конфигу
wg-manager.sh qr NAME Показать QR-код
wg-manager.sh remove NAME Удалить клиента
wg-manager.sh diagnose Выполнить диагностику
wg-manager.sh backup Создать резервную копию
wg-manager.sh backups Показать резервные копии
wg-manager.sh restore BACKUP Восстановить резервную копию
wg-manager.sh log Показать audit log
wg-manager.sh help Показать справку
```
CLI должен иметь стабильные exit codes и пригодный для чтения текстовый вывод. Структурированный JSON-вывод не входит в обязательный объём MVP.
## 9. Метаданные клиентов
Комментарии вида `### Client NAME` можно поддерживать для читаемости и совместимости с существующим `add-user.sh`, но они не должны быть единственным источником данных.
Для управляемого клиента необходимо хранить как минимум:
- имя;
- публичный ключ;
- VPN-адрес;
- дату создания;
- путь к клиентскому конфигу;
- режим маршрутизации;
- статус управления.
Формат метаданных должен быть простым и обрабатываться стандартными средствами Bash без обязательной зависимости от `jq`. Серверный конфиг и фактическое состояние `wg` остаются источниками истины для сетевых параметров.
## 10. Зависимости
Обязательные:
- Bash;
- WireGuard tools: `wg`, `wg-quick`;
- стандартные Linux-команды, используемые скриптом;
- `flock` для защиты от параллельных изменений.
Для TUI:
- `gum`, предоставляемый или устанавливаемый администратором.
Необязательные:
- `qrencode` для QR-кодов;
- `systemctl` и `journalctl` для серверов с systemd;
- инструменты конкретного firewall: `nft` или `iptables`.
При отсутствии необязательной команды соответствующая функция должна показывать `SKIP` или понятное сообщение, а не завершать весь менеджер аварийно.
## 11. Тестирование
Большая часть тестов не должна требовать реального интерфейса WireGuard или изменения `/etc/wireguard`.
Необходимые сценарии:
- разбор серверного конфига;
- определение следующего свободного IP;
- обнаружение конфликтующих `AllowedIPs`;
- проверка имён клиентов;
- построение peer-блока;
- удаление только выбранного peer-блока;
- обработка unmanaged peers;
- успешное применение транзакции;
- rollback при ошибке применения;
- защита от параллельного запуска;
- отсутствие секретов в логах;
- работа CLI без `gum`;
- корректная ошибка TUI без `gum`;
- поиск локального и системного бинарника `gum`.
Для тестов используются fixtures конфигураций и mock-команды `wg`, `wg-quick`, `systemctl`, `ip`, `nft` и `iptables`, подставляемые через контролируемый `PATH`.
Дополнительные проверки качества:
- `shellcheck`;
- `bash -n`;
- единый формат shell-кода;
- тестирование на поддерживаемых версиях Bash.
## 12. Этапы реализации
### Этап 1. Каркас
- создать `wg-manager.sh`;
- реализовать загрузку конфигурации;
- определить директорию проекта;
- добавить обработку ошибок и временных файлов;
- добавить проверку root для изменяющих операций;
- реализовать CLI `help`, `status` и `list`.
### Этап 2. Модель клиентов
- разобрать существующий `wg0.conf`;
- связать имена, публичные ключи и адреса;
- отображать managed и unmanaged peers;
- добавить метаданные клиентов.
### Этап 3. Безопасные изменения
- перенести и переработать логику `add-user.sh`;
- добавить блокировку, backup, валидацию и rollback;
- реализовать `add` и `remove`;
- реализовать архивирование клиентских файлов.
### Этап 4. Диагностика и журнал
- добавить диагностические проверки;
- добавить статусы `OK/WARN/FAIL/SKIP`;
- добавить audit log без секретов;
- добавить просмотр резервных копий и восстановление.
### Этап 5. TUI на `gum`
- реализовать главное меню;
- таблицу и фильтрацию клиентов;
- формы добавления;
- карточку клиента;
- подтверждение удаления и восстановления;
- экраны диагностики, логов и резервных копий.
### Этап 6. Проверка MVP
- добавить fixtures и mocks;
- протестировать успешные и аварийные сценарии;
- проверить поведение на реальном тестовом интерфейсе WireGuard;
- подготовить README с примерами запуска и конфигурации.
## 13. Критерии готовности MVP
MVP считается готовым, если администратор может:
1. Скопировать или переместить директорию проекта на Linux-сервер.
2. Настроить `wg-manager.conf` без редактирования основной логики.
3. Запустить TUI через `wg-manager.sh` с предоставленным `gum`.
4. Использовать основные функции через CLI без TUI.
5. Просмотреть WireGuard и список известных клиентов.
6. Безопасно добавить клиента и получить его конфиг или QR-код.
7. Безопасно удалить клиента.
8. Выполнить диагностику и увидеть конкретные предупреждения и ошибки.
9. Просмотреть журнал административных операций без утечки ключей.
10. Восстановить конфигурацию из backup после неудачного изменения.
11. Не повредить рабочий конфиг при ошибке команды или параллельном запуске.
## 14. За пределами MVP
После завершения MVP можно добавить:
- временное отключение и повторное включение клиента без удаления;
- срок действия клиента;
- ротацию ключей;
- импорт существующих unmanaged peers;
- поддержку нескольких WireGuard-интерфейсов;
- шаблоны маршрутов и DNS для разных типов клиентов;
- экспорт диагностического отчёта;
- уведомления о проблемах;
- JSON-вывод для интеграций;
- локализацию интерфейса;
- дополнительные варианты поставки `gum` для разных архитектур.
Эти функции не должны задерживать выпуск первого работоспособного MVP.