Add initial files
This commit is contained in:
@@ -0,0 +1,481 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user