Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b64d1aba5b | ||
|
|
cb230fe50e | ||
|
|
dbab96f7fd | ||
|
|
d34f25d544 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,3 +4,4 @@ npm-debug.log*
|
||||
*.swp
|
||||
.env
|
||||
.env.*
|
||||
Новости/
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# 00. НАЧНИ ОТСЮДА — amnezia_web-PRO
|
||||
|
||||
**Промпт для нового чата:**
|
||||
> Проект «Открытые проекты/amnezia_web-PRO» — полностью открытая веб-панель Amnezia (Node, `server.js` + `public/`). Закрытой версии нет (старая — в `Архив/amnezia_web-PRO_test`). Прочитай `PROJECT_INDEX.md` и `09. История и грабли`. Тесты — на school-friends (сервер) и school-it-kruzhok (клиент) через svault. Релиз: тег + GitHub API, затем Gitea, Notes, новость в @PCAdministration ботом PCA_jarvis_bot (токен `TG_BOT_TOKEN` в `~/jarvis-ru-windows/.env`).
|
||||
> Проект «Открытые проекты/amnezia_web-PRO» — полностью открытая веб-панель Amnezia (Node, `server.js` + `public/`). Закрытой версии нет (старая — в `Архив/amnezia_web-PRO_test`). Прочитай `PROJECT_INDEX.md` и `09. История и грабли`. Тесты — на school-friends (сервер) и school-it-kruzhok (клиент) через svault. Релиз: тег + GitHub API, затем Gitea, Notes, новость в группу PCA, тема «Новости» (chat_id -1003902709196, message_thread_id=131) ботом @PCAdmin27_bot (токен `TELEGRAM_MOD_BOT_TOKEN` в «Закрытые продукты/home_Friends_It/ДОСТУПЫ.md»); PCA_jarvis_bot не использовать. Gitea — pull-зеркало, обновлять mirror-sync.
|
||||
|
||||
## Оглавление
|
||||
- `PROJECT_INDEX.md` — что где лежит, установка
|
||||
- `09. История и грабли` — оглавление записей 09.N
|
||||
- `scripts/checks/` — проверки парка AWG (запускать внутри контейнера панели, читают /app/data/data.json)
|
||||
- `Новости/` — тексты новостей релизов (не в git)
|
||||
|
||||
@@ -2,4 +2,5 @@
|
||||
|
||||
- [09.1 Версия 1.3.0 — протоколы с сайта, каскад, домен, тема](<09.1 Версия 1.3.0 — протоколы с сайта, каскад, домен, тема.md>) — 23.10.2026
|
||||
- [09.2 Версия 1.4.0 — Xray VLESS, всё открыто](<09.2 Версия 1.4.0 — Xray VLESS, всё открыто.md>) — 23.10.2026
|
||||
- [09.3 Старые исправления июня 2026](<09.3 Старые исправления июня 2026.md>) — 13 частей 09.3.N, перенесены из Notes 23.10.2026
|
||||
- 04.10.2026 — проект переехал в папку-группу; код не менялся.
|
||||
|
||||
@@ -15,6 +15,19 @@
|
||||
- **СИМПТОМ:** форма установки видна при установленном Xray. **ПРИЧИНА:** CSS `.instance-form` перебивает атрибут `hidden`. **ИСПРАВЛЕНИЕ:** `style.display`.
|
||||
- Оба школьных сервера выходят в интернет через один NAT — проверка «по IP» не отличает туннель; проверять выключением клиента.
|
||||
|
||||
## 1.4.1 (23.10.2026)
|
||||
- Установщик сам ставит Docker (`get.docker.com`) на чистом сервере. На машине без Docker не проверялось — школьные все с Docker.
|
||||
- README: раздел «Быстрый старт» — 7 шагов от пустого VPS (порты, вход admin, протокол, клиент, Xray, домен, «если не работает»).
|
||||
- Убрана подсказка «задайте AWG_PROFILES» — сбивала новичков.
|
||||
- Проверено как у человека с GitHub: чистая установка `curl … | sudo bash` → вход admin → AWG 2.0 + клиент (рукопожатие, интернет) → Xray + клиент → обновление поверх (версия 1.4.1, клиенты на месте). Тестовое удалено.
|
||||
|
||||
## Проверка установщика на чистом сервере (23.10.2026)
|
||||
- LXC 199 на Proxmox .5 (Ubuntu 24.04, unprivileged, nesting+keyctl), без Docker → `curl -fsSL …/scripts/install.sh | bash` → Docker поставился сам, контейнеры `amnezia-admin` и `amnezia-web-landing` поднялись, :8080 = 200, `/api/login` с паролем admin = ok. Ошибок нет, 1.4.2 не понадобилась. LXC удалён.
|
||||
- Proxmox .5 и Gitea .153:3030 из сессии отвечают напрямую; в Gitea тег v1.4.1 есть.
|
||||
|
||||
## Публикация
|
||||
- Новость 1.4.0 — @PCAdmin27_bot, тема «Новости» (131), сообщение 881. PCA_jarvis_bot из группы выгнан.
|
||||
- Gitea — pull-зеркало: обновляется `mirror-sync` (push → 403). С мини .153 «недоступна» только из сессии Claude — ходить через `ssh andrey@127.0.0.1`.
|
||||
|
||||
## Осталось
|
||||
- Gitea (192.168.88.153) — Proxmox .5 был не в сети: `git push gitea main --tags`.
|
||||
- QR-кода для vless нет (ссылка копируется) — добавить, если попросят.
|
||||
|
||||
17
09.3 Старые исправления июня 2026.md
Normal file
17
09.3 Старые исправления июня 2026.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# 09.3 Старые исправления июня 2026
|
||||
|
||||
Оглавление частей: заметки из Notes до регламента (июнь–июль 2026), по одной на исправление.
|
||||
|
||||
- [09.3.1 Canonical public amnezia_web-PRO 06.06](<09.3.1 Canonical public amnezia_web-PRO 06.06.md>)
|
||||
- [09.3.2 Canonical amnezia_web-PRO status 21.06](<09.3.2 Canonical amnezia_web-PRO status 21.06.md>)
|
||||
- [09.3.3 Fix AWG auto profiles 21.06](<09.3.3 Fix AWG auto profiles 21.06.md>)
|
||||
- [09.3.4 Fix stale AWG profile snapshot 21.06](<09.3.4 Fix stale AWG profile snapshot 21.06.md>)
|
||||
- [09.3.5 Client import from Amnezia backup 21.06](<09.3.5 Client import from Amnezia backup 21.06.md>)
|
||||
- [09.3.6 Fix duplicate AWG instances 21.06](<09.3.6 Fix duplicate AWG instances 21.06.md>)
|
||||
- [09.3.7 Fix AWG instance labels 21.06](<09.3.7 Fix AWG instance labels 21.06.md>)
|
||||
- [09.3.8 Fix clients selected profile 21.06](<09.3.8 Fix clients selected profile 21.06.md>)
|
||||
- [09.3.9 Fix peers missing clientsTable 21.06](<09.3.9 Fix peers missing clientsTable 21.06.md>)
|
||||
- [09.3.10 Sync app-created Amnezia users 21.06](<09.3.10 Sync app-created Amnezia users 21.06.md>)
|
||||
- [09.3.11 Fix legacy clientsTable formats 21.06](<09.3.11 Fix legacy clientsTable formats 21.06.md>)
|
||||
- [09.3.12 Fix Amnezia source auto-discovery 22.06](<09.3.12 Fix Amnezia source auto-discovery 22.06.md>)
|
||||
- [09.3.13 Fix awg binary not found 22.06](<09.3.13 Fix awg binary not found 22.06.md>)
|
||||
17
09.3.1 Canonical public amnezia_web-PRO 06.06.md
Normal file
17
09.3.1 Canonical public amnezia_web-PRO 06.06.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# 09.3.1 Canonical public amnezia_web-PRO 06.06
|
||||
|
||||
_Старая заметка из Notes (июнь 2026), перенесена 23.10.2026. Оригинал: Архив/Старые заметки Notes 20261023._
|
||||
|
||||
amnezia_web-PRO canonical public repo — 06.06
|
||||
Keep one public project: https://github.com/andrey271192/amnezia_web-PRO
|
||||
Install
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo bash
|
||||
Defaults
|
||||
Fresh login: admin
|
||||
Fresh password: admin
|
||||
Change password after first login.
|
||||
GitHub
|
||||
Repo is public.
|
||||
Private download flow removed.
|
||||
Separate deploy bundle removed from active docs and notes.
|
||||
Commit: 05e6d00 docs: make pro repo public install source.
|
||||
23
09.3.10 Sync app-created Amnezia users 21.06.md
Normal file
23
09.3.10 Sync app-created Amnezia users 21.06.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# 09.3.10 Sync app-created Amnezia users 21.06
|
||||
|
||||
_Старая заметка из Notes (июнь 2026), перенесена 23.10.2026. Оригинал: Архив/Старые заметки Notes 20261023._
|
||||
|
||||
Commit: dfeabe0 feat: sync app-created peers into clients table
|
||||
Version: v1.2.36
|
||||
Задача
|
||||
Клиенты уже были созданы в приложении Amnezia. Их нужно подтянуть в веб-панель, а не создавать заново.
|
||||
Решение
|
||||
Добавлена кнопка Пользователи → Подтянуть из awg0.conf.
|
||||
POST /api/clients/sync-peers берёт активные [Peer] текущего инстанса и создаёт недостающие строки clientsTable.
|
||||
VPN-конфиг не пересоздаётся, контейнеры клиентов не трогаются.
|
||||
Имена создаются как Клиент IP или Peer KEY, потом можно переименовать.
|
||||
Экспорт .conf появится после импорта клиентского .conf, потому приватный ключ клиента есть только в приложении.
|
||||
Команда
|
||||
curl -fsSL "https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh?nocache=$(date +%s)" | sudo env SKIP_LANDING=1 bash
|
||||
Потом Ctrl+F5 → выбрать Инстанс → Пользователи → Подтянуть из awg0.conf.
|
||||
Проверено
|
||||
node --check server.js
|
||||
node --check public/app.js
|
||||
bash -n scripts/*.sh
|
||||
npm audit --audit-level=moderate: 0 vulnerabilities
|
||||
git diff --check
|
||||
17
09.3.11 Fix legacy clientsTable formats 21.06.md
Normal file
17
09.3.11 Fix legacy clientsTable formats 21.06.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# 09.3.11 Fix legacy clientsTable formats 21.06
|
||||
|
||||
_Старая заметка из Notes (июнь 2026), перенесена 23.10.2026. Оригинал: Архив/Старые заметки Notes 20261023._
|
||||
|
||||
Commit: 4e6ab2d fix: parse legacy clients table formats
|
||||
Version: v1.2.37
|
||||
Причина
|
||||
Старые клиенты могли не подтягиваться, если clientsTable не был массивом [{clientId,userData}], а имел object/map/nested формат другой версии Amnezia.
|
||||
Исправлено
|
||||
parseClientsTable поддерживает array, object map, nested clients/users/rows/items/data/clientList/clientsTable.
|
||||
clientRowId понимает clientId/id/publicKey/public_key/key/client_id и вложенные userData поля.
|
||||
Добавлен GET /api/clients/source-report для диагностики источников без полных ключей.
|
||||
Команда
|
||||
curl -fsSL "https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh?nocache=$(date +%s)" | sudo env SKIP_LANDING=1 bash
|
||||
Потом Ctrl+F5 → выбрать Инстанс → Пользователи → Подтянуть из awg0.conf.
|
||||
Если всё равно пусто
|
||||
Открыть в браузере после логина: /api/clients/source-report?profileId=awg и /api/clients/source-report?profileId=awg2
|
||||
20
09.3.12 Fix Amnezia source auto-discovery 22.06.md
Normal file
20
09.3.12 Fix Amnezia source auto-discovery 22.06.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# 09.3.12 Fix Amnezia source auto-discovery 22.06
|
||||
|
||||
_Старая заметка из Notes (июнь 2026), перенесена 23.10.2026. Оригинал: Архив/Старые заметки Notes 20261023._
|
||||
|
||||
Commit: b360095 fix: auto-discover amnezia client sources
|
||||
Version: v1.2.38
|
||||
Root cause
|
||||
Amnezia installs can keep old clients in /opt/amnezia/awg/wg0.conf, while profile pointed to /opt/amnezia/awg/awg0.conf. clientsTable can also live in /opt/amnezia/wireguard/clientsTable or have non-array format.
|
||||
Fix
|
||||
Runtime now scans config candidates: awg0.conf, wg0.conf, wireguard/wg0.conf.
|
||||
Chooses config with max [Peer] count.
|
||||
Runtime scans clientsTable candidates: awg/clientsTable and wireguard/clientsTable.
|
||||
Chooses clientsTable with max parsed client count.
|
||||
iface is inferred from selected config filename.
|
||||
source-report shows resolved confPath/clientsPath/iface.
|
||||
Command
|
||||
curl -fsSL "https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh?nocache=$(date +%s)" | sudo env SKIP_LANDING=1 bash
|
||||
Then Ctrl+F5 → select Instance → Users → Pull from awg0.conf.
|
||||
Source
|
||||
Amnezia issue #1615 mentions manual flow with /opt/amnezia/awg/wg0.conf and clientsTable; issue #2238 confirms clientsTable field variance.
|
||||
15
09.3.13 Fix awg binary not found 22.06.md
Normal file
15
09.3.13 Fix awg binary not found 22.06.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# 09.3.13 Fix awg binary not found 22.06
|
||||
|
||||
_Старая заметка из Notes (июнь 2026), перенесена 23.10.2026. Оригинал: Архив/Старые заметки Notes 20261023._
|
||||
|
||||
Commit: 8e5d51a fix: auto-detect wg binary in containers
|
||||
Version: v1.2.39
|
||||
Symptom
|
||||
При добавлении/подтягивании старых .conf ошибка: sh: awg: not found. В amneziawg контейнере awg binary отсутствует.
|
||||
Fix
|
||||
Runtime auto-detects binary inside container: preferred wgBinary, then wg for wg0.conf, then awg, then wg.
|
||||
show/pubkey/genkey/syncconf use resolved binary, not hardcoded profile.wgBinary.
|
||||
source-report and /api/clients expose resolved wgBinary.
|
||||
Command
|
||||
curl -fsSL "https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh?nocache=$(date +%s)" | sudo env SKIP_LANDING=1 bash
|
||||
Then Ctrl+F5 → Instance → Users → Pull from awg0.conf.
|
||||
20
09.3.2 Canonical amnezia_web-PRO status 21.06.md
Normal file
20
09.3.2 Canonical amnezia_web-PRO status 21.06.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# 09.3.2 Canonical amnezia_web-PRO status 21.06
|
||||
|
||||
_Старая заметка из Notes (июнь 2026), перенесена 23.10.2026. Оригинал: Архив/Старые заметки Notes 20261023._
|
||||
|
||||
Важно: amnezia_web-PRO_test — отдельный продукт/тестовая ветка. Canonical public product сейчас: amnezia_web-PRO.
|
||||
GitHub: https://github.com/andrey271192/amnezia_web-PRO
|
||||
Local: /Users/andrejbobyrev/andrey271192-repos/amnezia_web-PRO
|
||||
Last pushed commit: c202f0b — chore: add npm lockfile
|
||||
Правило
|
||||
amnezia_web-PRO — основной публичный продукт.
|
||||
amnezia_web-PRO_test — отдельный тестовый продукт, не смешивать с public PRO.
|
||||
amnezia-web-pro-deploy — legacy/старый deploy repo, не использовать как основной продукт.
|
||||
Install
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo bash
|
||||
Defaults
|
||||
Fresh login: admin
|
||||
Fresh password: admin
|
||||
Change password after first login.
|
||||
AWG issue from client
|
||||
Install-check видит два контейнера: amnezia-awg2 и amnezia-awg. Если веб показывает только awg2, причина в runtime-discovery/cache/UI-filter, не в Docker. Надо проверить конкретный VPS: docker ps, panel API/status, logs, затем исправить отображение обоих AWG profiles без ручного AWG_PROFILES.
|
||||
22
09.3.3 Fix AWG auto profiles 21.06.md
Normal file
22
09.3.3 Fix AWG auto profiles 21.06.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# 09.3.3 Fix AWG auto profiles 21.06
|
||||
|
||||
_Старая заметка из Notes (июнь 2026), перенесена 23.10.2026. Оригинал: Архив/Старые заметки Notes 20261023._
|
||||
|
||||
Repo: https://github.com/andrey271192/amnezia_web-PRO
|
||||
Commit: cbc20a1 — fix: auto-detect awg profiles on install
|
||||
Что исправлено
|
||||
Переустановка из GitHub работает для /opt/amnezia-admin без .git.
|
||||
Установщик сохраняет текущий порт панели.
|
||||
Установщик сохраняет текущий Docker volume /data.
|
||||
Перед заменой /opt/amnezia-admin создаётся backup папки.
|
||||
Если найден один контейнер amnezia-awg*, он становится AWG_CONTAINER.
|
||||
Если найдено 2+ контейнера amnezia-awg*, AWG_PROFILES создаётся автоматически и сохраняется в /root/amnezia-admin.awg-profiles.json.
|
||||
Dockerfile использует npm ci по package-lock.json.
|
||||
Что сказать пользователю
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo env SKIP_LANDING=1 bash
|
||||
После установки: обновить страницу Ctrl+F5. AWG контейнеры не удаляются и не пересоздаются.
|
||||
Проверено
|
||||
bash -n scripts/install.sh
|
||||
bash -n scripts/uninstall.sh
|
||||
node --check server.js
|
||||
npm audit --audit-level=moderate
|
||||
9
09.3.4 Fix stale AWG profile snapshot 21.06.md
Normal file
9
09.3.4 Fix stale AWG profile snapshot 21.06.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# 09.3.4 Fix stale AWG profile snapshot 21.06
|
||||
|
||||
_Старая заметка из Notes (июнь 2026), перенесена 23.10.2026. Оригинал: Архив/Старые заметки Notes 20261023._
|
||||
|
||||
Commit: 8ba2a26 — fix: refresh stale awg profile snapshots
|
||||
Причина повтора бага: старый /root/amnezia-admin.awg-profiles.json мог содержать один профиль. Installer восстанавливал его и не пересобирал profiles по двум контейнерам.
|
||||
Теперь если контейнеров amnezia-awg* два или больше, а восстановленный AWG_PROFILES содержит меньше двух container, installer автоматически пересобирает profiles и перезаписывает snapshot.
|
||||
rm -f /root/amnezia-admin.awg-profiles.json
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh?nocache=$(date +%s) | sudo env SKIP_LANDING=1 bash
|
||||
24
09.3.5 Client import from Amnezia backup 21.06.md
Normal file
24
09.3.5 Client import from Amnezia backup 21.06.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# 09.3.5 Client import from Amnezia backup 21.06
|
||||
|
||||
_Старая заметка из Notes (июнь 2026), перенесена 23.10.2026. Оригинал: Архив/Старые заметки Notes 20261023._
|
||||
|
||||
Project: amnezia_web-PRO
|
||||
Repo: https://github.com/andrey271192/amnezia_web-PRO
|
||||
Commit: cff27e2 feat: import clients from amnezia configs
|
||||
Что добавлено
|
||||
В панели появился блок Импорт клиента.
|
||||
Можно вставить готовый клиентский .conf или JSON backup Amnezia, если внутри есть текстовый .conf.
|
||||
Если peer уже есть в awg0.conf, дубль не создаётся: восстанавливается/обновляется строка clientsTable.
|
||||
Если peer отсутствует, он добавляется в текущий выбранный Инстанс.
|
||||
Исходный .conf сохраняется в userData.last_config, чтобы дальше работали экспорт и управление из веба.
|
||||
Добавлена защита: импортируемый .conf должен относиться к текущему серверу/инстансу по PublicKey сервера.
|
||||
Команда переустановки для пользователя
|
||||
curl -fsSL "https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh?nocache=$(date +%s)" | sudo env SKIP_LANDING=1 bash
|
||||
Проверено
|
||||
node --check server.js
|
||||
node --check public/app.js
|
||||
bash -n для всех scripts/*.sh
|
||||
npm audit --audit-level=moderate: 0 vulnerabilities
|
||||
git diff --check
|
||||
Что сказать пользователю
|
||||
Обновите панель командой выше, зайдите в веб, выберите нужный Инстанс и откройте блок Импорт клиента. Вставьте экспортированный клиентский .conf из приложения Amnezia или backup, где внутри есть этот .conf. После импорта клиент появится в таблице, а старые peer-дубли создаваться не будут.
|
||||
22
09.3.6 Fix duplicate AWG instances 21.06.md
Normal file
22
09.3.6 Fix duplicate AWG instances 21.06.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# 09.3.6 Fix duplicate AWG instances 21.06
|
||||
|
||||
_Старая заметка из Notes (июнь 2026), перенесена 23.10.2026. Оригинал: Архив/Старые заметки Notes 20261023._
|
||||
|
||||
Project: amnezia_web-PRO
|
||||
Commit: 8c67d7d fix: dedupe duplicate awg instances
|
||||
Version: v1.2.32
|
||||
Причина
|
||||
После переустановки один и тот же AWG контейнер мог попасть в список дважды: из AWG_PROFILES и из saved managed instances. Старый dedup был только по id, поэтому при разных id веб показывал две одинаковые карточки.
|
||||
Исправлено
|
||||
Dedup профилей по container + confPath + iface + clientsPath.
|
||||
/api/instances дополнительно дедупит runtime target после auto-resolve контейнера.
|
||||
load/save managed profiles чистит дубли из instances.json.
|
||||
Docs обновлены: раздел Инстансы задублировались.
|
||||
Команда для пользователя
|
||||
curl -fsSL "https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh?nocache=$(date +%s)" | sudo env SKIP_LANDING=1 bash
|
||||
После установки: Ctrl+F5 в браузере.
|
||||
Проверено
|
||||
node --check server.js
|
||||
node --check public/app.js
|
||||
npm audit --audit-level=moderate: 0 vulnerabilities
|
||||
git diff --check
|
||||
15
09.3.7 Fix AWG instance labels 21.06.md
Normal file
15
09.3.7 Fix AWG instance labels 21.06.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# 09.3.7 Fix AWG instance labels 21.06
|
||||
|
||||
_Старая заметка из Notes (июнь 2026), перенесена 23.10.2026. Оригинал: Архив/Старые заметки Notes 20261023._
|
||||
|
||||
Commit: a9a67af fix: show distinct awg instance labels
|
||||
Version: v1.2.33
|
||||
Причина
|
||||
У пользователя реально два контейнера: amnezia-awg2 и amnezia-awg. Порты и число клиентов разные, значит это не дубль. Но UI рисовал title по variant, поэтому обе карточки выглядели как AmneziaWG 2.0.
|
||||
Исправлено
|
||||
Карточка инстанса показывает profile label, а не только variant title.
|
||||
Backend лучше определяет variant по profile/container/label до чтения конфига.
|
||||
Docs уточнены: два разных контейнера с разными портами — нормальные два инстанса.
|
||||
Команда
|
||||
curl -fsSL "https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh?nocache=$(date +%s)" | sudo env SKIP_LANDING=1 bash
|
||||
Потом Ctrl+F5.
|
||||
18
09.3.8 Fix clients selected profile 21.06.md
Normal file
18
09.3.8 Fix clients selected profile 21.06.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# 09.3.8 Fix clients selected profile 21.06
|
||||
|
||||
_Старая заметка из Notes (июнь 2026), перенесена 23.10.2026. Оригинал: Архив/Старые заметки Notes 20261023._
|
||||
|
||||
Commit: cb5fca3 fix: load clients for selected profile
|
||||
Version: v1.2.34
|
||||
Симптом
|
||||
Переключатель Инстанс показывает правильный контейнер, но таблица Пользователи показывает клиентов от другого/старого инстанса.
|
||||
Причина
|
||||
Создание/экспорт уже передавали profileId явно, но /api/clients и операции таблицы опирались на cookie выбранного профиля. Cookie мог не примениться/устареть, поэтому список клиентов приходил не от выбранного инстанса.
|
||||
Исправлено
|
||||
GET /api/clients принимает явный profileId.
|
||||
disable/enable/rename/delete/disconnect-date используют runtimeFromExportRequest и body.profileId.
|
||||
Frontend передаёт profileId во все запросы таблицы клиентов.
|
||||
Docs обновлены.
|
||||
Команда
|
||||
curl -fsSL "https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh?nocache=$(date +%s)" | sudo env SKIP_LANDING=1 bash
|
||||
Потом Ctrl+F5.
|
||||
18
09.3.9 Fix peers missing clientsTable 21.06.md
Normal file
18
09.3.9 Fix peers missing clientsTable 21.06.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# 09.3.9 Fix peers missing clientsTable 21.06
|
||||
|
||||
_Старая заметка из Notes (июнь 2026), перенесена 23.10.2026. Оригинал: Архив/Старые заметки Notes 20261023._
|
||||
|
||||
Commit: fd66b0a fix: show peers missing clients table
|
||||
Version: v1.2.35
|
||||
Симптом
|
||||
Инстанс выбран правильно, но старые клиенты не появляются в таблице Пользователи.
|
||||
Причина
|
||||
UI строил список только из clientsTable. У старых/созданных приложением клиентов peer может быть в awg0.conf, а запись clientsTable отсутствовать или иметь другой формат.
|
||||
Исправлено
|
||||
GET /api/clients теперь возвращает union clientsTable + Peer из awg0.conf.
|
||||
Peer-only строки показываются как Peer xxxx… и помечаются missingClientTable.
|
||||
Rename/date/disable/delete умеют работать с peer-only строками.
|
||||
Для экспорта .conf всё равно нужен импорт клиентского .conf, потому приватный ключ клиента сервер не знает.
|
||||
Команда
|
||||
curl -fsSL "https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh?nocache=$(date +%s)" | sudo env SKIP_LANDING=1 bash
|
||||
Потом Ctrl+F5.
|
||||
@@ -9,7 +9,7 @@
|
||||
|---|---|
|
||||
| Папка проекта | `/Volumes/ssd/Мои проекты/Открытые проекты/amnezia_web-PRO/` |
|
||||
| Заметки | Apple Notes → `МОИ ПРОЕКТЫ` → папка `amnezia_web-PRO` |
|
||||
| GitHub (публичный) | https://github.com/andrey271192/amnezia_web-PRO |
|
||||
| GitHub (публичный) | https://git.bobyrev.com/PCA/amnezia_web-PRO |
|
||||
| Ветка прода | `main` |
|
||||
| Старая закрытая панель (архив, не развивается) | `/Volumes/ssd/Мои проекты/Архив/amnezia_web-PRO_test/` |
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
## Установка
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo bash
|
||||
curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/install.sh | sudo bash
|
||||
```
|
||||
|
||||
Первый вход: `admin` / `admin`, пароль сменить сразу.
|
||||
|
||||
48
README.md
48
README.md
@@ -2,6 +2,22 @@
|
||||
|
||||
Полностью открытая веб-панель для сервера Amnezia: все функции бесплатны, без платных или закрытых редакций. Один репозиторий, один установщик.
|
||||
|
||||
<img src="docs/screenshots/panel-1.4.png" alt="Панель amnezia_web-PRO 1.4: пользователи AmneziaWG, Xray VLESS-Reality, протоколы и инстансы" width="780"/>
|
||||
|
||||
**Что умеет:** клиенты AmneziaWG (создать, выключить, дата отключения, .conf), установка протоколов из браузера (AmneziaWG 1.x/2.0/3.0/3.1, WireGuard), Xray VLESS‑Reality, Cloudflare WARP и каскад через другой сервер, Telegram MTProto‑прокси, домен сервера в конфигах, светлая/тёмная тема.
|
||||
|
||||
**Установка** (Ubuntu 22.04/24.04, Debian 12, под root; Docker поставится сам):
|
||||
|
||||
```bash
|
||||
curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/install.sh | sudo bash
|
||||
```
|
||||
|
||||
Панель: `http://IP:8080`, вход — пароль `admin` (смените сразу). Код — [git.bobyrev.com/PCA/amnezia_web-PRO](https://git.bobyrev.com/PCA/amnezia_web-PRO) (GitHub-аккаунт заблокирован, старые ссылки raw.githubusercontent.com больше не работают).
|
||||
|
||||
## Что нового в 1.4.2
|
||||
|
||||
- **Проект переехал на [git.bobyrev.com/PCA/amnezia_web-PRO](https://git.bobyrev.com/PCA/amnezia_web-PRO)** — GitHub-аккаунт заблокирован. Установщик и обновление качают код оттуда. Старая команда с `raw.githubusercontent.com` больше не работает — используйте новую (выше).
|
||||
|
||||
## Что нового в 1.4.0
|
||||
|
||||
- **Xray VLESS‑Reality** — раздел «Xray VLESS‑Reality»: установка с выбором TCP‑порта и сайта‑маскировки, клиенты (создать, выключить/включить, удалить), ссылка `vless://` для Amnezia VPN, v2rayNG, Hiddify, Streisand, Happ. Файлы в `/opt/amnezia/xray` в том же формате, что у приложения Amnezia.
|
||||
@@ -33,7 +49,7 @@
|
||||
**1. Установите панель.** Зайдите на сервер по SSH и выполните:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo bash
|
||||
curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/install.sh | sudo bash
|
||||
```
|
||||
|
||||
В конце будет строка `Админ-панель: http://IP:8080`.
|
||||
@@ -101,7 +117,7 @@ sudo ufw allow 8080/tcp && sudo ufw allow 41010/udp # пример, если u
|
||||
### Public install from GitHub
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo bash
|
||||
curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/install.sh | sudo bash
|
||||
```
|
||||
|
||||
Панель после установки открывается по **`http://IP:HOST_PORT`** (по умолчанию `:8080`). Первый вход: **логин `admin`, пароль `admin`**. Смените пароль сразу после входа.
|
||||
@@ -111,13 +127,13 @@ curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/s
|
||||
Если `/opt/amnezia-admin` не git-репозиторий, это нормально: установщик скачивает свежий архив с GitHub, делает backup старой папки, сохраняет текущий порт и текущий Docker volume `/data`, затем пересобирает только контейнер панели **`amnezia-admin`**. Контейнеры AmneziaWG (`amnezia-awg`, `amnezia-awg2` и т.д.) не удаляются и не пересоздаются.
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo bash
|
||||
curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/install.sh | sudo bash
|
||||
```
|
||||
|
||||
Если не нужен лендинг на порту 80:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo env SKIP_LANDING=1 bash
|
||||
curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/install.sh | sudo env SKIP_LANDING=1 bash
|
||||
```
|
||||
|
||||
### Переменные окружения и `sudo`
|
||||
@@ -129,7 +145,7 @@ curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/s
|
||||
1. **`sudo -E bash`** вместо `sudo bash` (для большинства VPS достаточно):
|
||||
|
||||
```bash
|
||||
AWG_PROFILES='[{"id":"awg",…}]' curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo -E bash
|
||||
AWG_PROFILES='[{"id":"awg",…}]' curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/install.sh | sudo -E bash
|
||||
```
|
||||
|
||||
2. **Файл на VPS** (способ без `-E`): записать JSON **одной строкой** в **`/root/amnezia-admin.awg-profiles.json`** (например `umask 077; printf '%s\n' '[{"id":"awg",…}]' > /root/amnezia-admin.awg-profiles.json`), затем обычный **`curl … | sudo bash`** — установщик подставит профили из файла (см. абзац про снимок ниже таблицы).
|
||||
@@ -157,7 +173,7 @@ cd /opt/amnezia-admin && chmod +x scripts/install.sh && sudo SKIP_DOWNLOAD=1 bas
|
||||
|
||||
| Переменная | По умолчанию | Назначение |
|
||||
|------------|--------------|------------|
|
||||
| `GITHUB_REPO` | `andrey271192/amnezia_web-PRO` | Откуда качать архив |
|
||||
| `GITHUB_REPO` | `PCA/amnezia_web-PRO` | Откуда качать архив |
|
||||
| `BRANCH` | `main` | Ветка |
|
||||
| `INSTALL_DIR` | `/opt/amnezia-admin` | Куда распаковать исходники |
|
||||
| `DATA_DIR` | `/opt/amnezia-admin-data` | Том с `password.hash` и сессией |
|
||||
@@ -205,14 +221,14 @@ cd /opt/amnezia-admin && chmod +x scripts/install.sh && sudo SKIP_DOWNLOAD=1 bas
|
||||
|
||||
```bash
|
||||
AWG_PROFILES='[{"id":"awg","label":"AmneziaWG","container":"amnezia-awg","confPath":"/opt/amnezia/awg/awg0.conf","clientsPath":"/opt/amnezia/awg/clientsTable","iface":"awg0","wgBinary":"awg","pskPath":"/opt/amnezia/awg/wireguard_psk.key"},{"id":"legacy","label":"AmneziaWG Legacy","container":"amnezia-wg0","confPath":"/opt/amnezia/wireguard/wg0.conf","clientsPath":"/opt/amnezia/wireguard/clientsTable","iface":"wg0","wgBinary":"wg","pskPath":"/opt/amnezia/wireguard/wireguard_psk.key"}]' \
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo -E bash
|
||||
curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/install.sh | sudo -E bash
|
||||
```
|
||||
|
||||
**Пример 2** — оба конфигурационных набора внутри контейнера **`amnezia-awg`** (файл `wg0.conf` рядом с `awg0.conf` в `/opt/amnezia/awg/`):
|
||||
|
||||
```bash
|
||||
AWG_PROFILES='[{"id":"awg","label":"AmneziaWG","container":"amnezia-awg","confPath":"/opt/amnezia/awg/awg0.conf","clientsPath":"/opt/amnezia/awg/clientsTable","iface":"awg0","wgBinary":"awg","pskPath":"/opt/amnezia/awg/wireguard_psk.key"},{"id":"legacy","label":"AmneziaWG Legacy","container":"amnezia-awg","confPath":"/opt/amnezia/awg/wg0.conf","clientsPath":"/opt/amnezia/awg/clientsTable","iface":"wg0","wgBinary":"wg","pskPath":"/opt/amnezia/awg/wireguard_psk.key"}]' \
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo -E bash
|
||||
curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/install.sh | sudo -E bash
|
||||
```
|
||||
|
||||
Для **Legacy** часто используется обычный `wg`, для новой AmneziaWG — **`awg`**; поле **`pskPath`** желательно указывать явно, если путь к `wireguard_psk.key` нестандартный.
|
||||
@@ -299,7 +315,7 @@ cd /opt/amnezia-admin
|
||||
Пример установки / обновления с частично пустой панелью:
|
||||
|
||||
```bash
|
||||
UI_HIDE_SECTIONS=warp,cascade curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo -E bash
|
||||
UI_HIDE_SECTIONS=warp,cascade curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/install.sh | sudo -E bash
|
||||
```
|
||||
|
||||
Отдельные флаги **`UI_HIDE_USERS`**, **`UI_HIDE_WARP`**, **`UI_HIDE_CASCADE`**, **`UI_HIDE_MTPROTO`** (`1` или `true`) дублируют соответствующий токен.
|
||||
@@ -338,13 +354,13 @@ UI_HIDE_SECTIONS=warp,cascade curl -fsSL https://raw.githubusercontent.com/andre
|
||||
Проще всего для пути из исходников — та же команда, что при установке (данные в `DATA_DIR`, пароль и `AWG_PROFILES` сохранятся — профили подтягиваются из файла на VPS или из старого контейнера). Скрипт **подставит прежний внешний порт** контейнера `amnezia-admin`, если вы не передавали `HOST_PORT` и в коде по умолчанию стоит `8080`:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo bash
|
||||
curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/install.sh | sudo bash
|
||||
```
|
||||
|
||||
Если интерфейс после этого всё ещё старый — принудительно без кэша слоёв Docker:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo NO_CACHE=1 bash
|
||||
curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/install.sh | sudo NO_CACHE=1 bash
|
||||
```
|
||||
|
||||
Если проект уже лежит в `/opt/amnezia-admin` через git и вы подтянули изменения (`git pull`), пересоберите без повторной загрузки архива:
|
||||
@@ -370,13 +386,13 @@ sudo docker run --rm amnezia-admin:latest grep -Eo 'Новый клиент по
|
||||
## Удаление одной командой
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/uninstall.sh | sudo bash
|
||||
curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/uninstall.sh | sudo bash
|
||||
```
|
||||
|
||||
Полная очистка (контейнер, образ, данные панели и каталог `/opt/amnezia-admin`):
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/uninstall.sh | sudo REMOVE_IMAGE=1 REMOVE_DATA=1 REMOVE_SRC=1 bash
|
||||
curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/uninstall.sh | sudo REMOVE_IMAGE=1 REMOVE_DATA=1 REMOVE_SRC=1 bash
|
||||
```
|
||||
|
||||
---
|
||||
@@ -395,7 +411,7 @@ curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/s
|
||||
### Свой пароль при установке
|
||||
|
||||
```bash
|
||||
ADMIN_PASSWORD='ВашНадёжныйПароль' curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo -E bash
|
||||
ADMIN_PASSWORD='ВашНадёжныйПароль' curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/install.sh | sudo -E bash
|
||||
```
|
||||
|
||||
После первого успешного старта переменную `ADMIN_PASSWORD` из команды `docker run` убирайте — пароль уже в томе `DATA_DIR`.
|
||||
@@ -427,7 +443,7 @@ ADMIN_PASSWORD=localtest node server.js
|
||||
|
||||
| Способ | Ссылка |
|
||||
|--------|--------|
|
||||
| GitHub | [amnezia_web-PRO](https://github.com/andrey271192/amnezia_web-PRO) |
|
||||
| GitHub | [amnezia_web-PRO](https://git.bobyrev.com/PCA/amnezia_web-PRO) |
|
||||
| Boosty | [boosty.to/andrey27/donate](https://boosty.to/andrey27/donate) |
|
||||
| Ozon СБП | [Ozon СБП](https://finance.ozon.ru/apps/sbp/ozonbankpay/019dc200-2a5d-7931-a619-782d285f6798) |
|
||||
| Telegram | [@lot_andrey](https://t.me/lot_andrey) |
|
||||
@@ -450,7 +466,7 @@ MIT, см. [LICENSE](LICENSE).
|
||||
|
||||
---
|
||||
|
||||
- ⭐ **GitHub:** [andrey271192/amnezia_web-PRO](https://github.com/andrey271192/amnezia_web-PRO)
|
||||
- ⭐ **GitHub:** [PCA/amnezia_web-PRO](https://git.bobyrev.com/PCA/amnezia_web-PRO)
|
||||
- 💖 **Boosty:** [boosty.to/andrey27/donate](https://boosty.to/andrey27/donate)
|
||||
- 💳 **Ozon Bank (СБП):** [ссылка](https://finance.ozon.ru/apps/sbp/ozonbankpay/019dc200-2a5d-7931-a619-782d285f6798)
|
||||
- ✉️ **Telegram:** [@lot_andrey](https://t.me/lot_andrey)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
```
|
||||
2. Если строки нет, но `docker ps` показывает два контейнера вида `amnezia-awg*`, переустановите панель свежим установщиком из GitHub:
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/andrey271192/amnezia_web-PRO/main/scripts/install.sh | sudo env SKIP_LANDING=1 bash
|
||||
curl -fsSL https://git.bobyrev.com/PCA/amnezia_web-PRO/raw/branch/main/scripts/install.sh | sudo env SKIP_LANDING=1 bash
|
||||
```
|
||||
Установщик сам создаст **`AWG_PROFILES`** и сохранит **`/root/amnezia-admin.awg-profiles.json`**.
|
||||
3. Ручной JSON нужен только при нестандартных путях внутри AWG-контейнеров.
|
||||
|
||||
BIN
docs/screenshots/panel-1.4.png
Normal file
BIN
docs/screenshots/panel-1.4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 225 KiB |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "amnezia-admin",
|
||||
"version": "1.4.1",
|
||||
"version": "1.4.2",
|
||||
"private": false,
|
||||
"description": "amnezia_web-PRO — веб-панель AmneziaWG: несколько инстансов, WARP, каскад/Endpoint, экспорт .conf (Docker)",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;600;700&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet">
|
||||
<script>try{var t=localStorage.getItem("theme")||(matchMedia("(prefers-color-scheme: light)").matches?"light":"dark");document.documentElement.dataset.theme=t}catch(e){}</script>
|
||||
<link rel="stylesheet" href="/styles.css?v=1.4.1">
|
||||
<link rel="stylesheet" href="/styles.css?v=1.4.2">
|
||||
</head>
|
||||
<body class="page">
|
||||
<aside class="panel-promo-strip" role="complementary" aria-label="Поддержка и донат">
|
||||
<div class="panel-promo-strip-inner">
|
||||
<p class="panel-promo-subtitle muted">Поддержите проект через Boosty, Ozon СБП и Telegram — ниже те же ссылки в подвале.</p>
|
||||
<div class="panel-promo-links">
|
||||
<a class="panel-promo-a" href="https://github.com/andrey271192/amnezia_web-PRO" target="_blank" rel="noopener noreferrer">⭐ GitHub</a>
|
||||
<a class="panel-promo-a" href="https://git.bobyrev.com/PCA/amnezia_web-PRO" target="_blank" rel="noopener noreferrer">⭐ Git</a>
|
||||
<span class="panel-promo-sep" aria-hidden="true">·</span>
|
||||
<a class="panel-promo-a" href="https://boosty.to/andrey27/donate" target="_blank" rel="noopener noreferrer">💖 Boosty</a>
|
||||
<span class="panel-promo-sep" aria-hidden="true">·</span>
|
||||
@@ -39,7 +39,7 @@
|
||||
</form>
|
||||
<nav class="gate-donate muted" aria-label="Поддержка и донат">
|
||||
Поддержка веб‑панелей (вне этого сервера):<br/>
|
||||
<a href="https://github.com/andrey271192/amnezia_web-PRO" target="_blank" rel="noopener noreferrer">GitHub</a>
|
||||
<a href="https://git.bobyrev.com/PCA/amnezia_web-PRO" target="_blank" rel="noopener noreferrer">GitHub</a>
|
||||
<span class="gate-donate-dot" aria-hidden="true">·</span>
|
||||
<a href="https://boosty.to/andrey27/donate" target="_blank" rel="noopener noreferrer">Boosty</a>
|
||||
<span class="gate-donate-dot" aria-hidden="true">·</span>
|
||||
@@ -413,7 +413,7 @@
|
||||
<div class="support-line">
|
||||
<strong class="support-title">amnezia_web-PRO</strong>
|
||||
<span class="support-sep" aria-hidden="true">·</span>
|
||||
<a href="https://github.com/andrey271192/amnezia_web-PRO" target="_blank" rel="noopener noreferrer">⭐ GitHub · amnezia_web-PRO</a>
|
||||
<a href="https://git.bobyrev.com/PCA/amnezia_web-PRO" target="_blank" rel="noopener noreferrer">⭐ Git · amnezia_web-PRO</a>
|
||||
<span class="support-sep" aria-hidden="true">·</span>
|
||||
<a href="https://boosty.to/andrey27/donate" target="_blank" rel="noopener noreferrer">💖 Boosty</a>
|
||||
<span class="support-sep" aria-hidden="true">·</span>
|
||||
@@ -460,6 +460,6 @@
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<script src="/app.js?v=1.4.1" type="module"></script>
|
||||
<script src="/app.js?v=1.4.2" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
53
scripts/checks/audit2.py
Normal file
53
scripts/checks/audit2.py
Normal file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Сверяем ПОДНЯТЫЕ интерфейсы с их собственными конфигами.
|
||||
|
||||
Первый заход сравнивал wg0.conf с интерфейсом wg0, а в контейнере amnezia-awg
|
||||
поднят awg0 — отсюда ложные «расхождения».
|
||||
"""
|
||||
import json, sys
|
||||
sys.path.insert(0, "/app")
|
||||
from managers.ssh_manager import SSHManager
|
||||
|
||||
PROBE = r"""
|
||||
for c in $(docker ps --format '{{.Names}}' 2>/dev/null | grep '^amnezia-' | grep -vE 'nginx|frontend|backend|landing|xray|socks|ipsec|openvpn'); do
|
||||
for bin in awg wg; do
|
||||
docker exec $c sh -c "command -v $bin >/dev/null" 2>/dev/null || continue
|
||||
for i in $(docker exec $c sh -c "$bin show interfaces 2>/dev/null"); do
|
||||
live=$(docker exec $c sh -c "$bin show $i peers 2>/dev/null | grep -c ." | tr -d '\n')
|
||||
conf=""
|
||||
for f in /opt/amnezia/awg/$i.conf /opt/amnezia/awg/awg0.conf /opt/amnezia/awg/wg0.conf; do
|
||||
docker exec $c test -f $f 2>/dev/null && { conf=$f; break; }
|
||||
done
|
||||
[ -n "$conf" ] || { echo "$c $i live=$live конфиг=НЕ НАЙДЕН"; continue; }
|
||||
infile=$(docker exec $c grep -c '^\[Peer\]' $conf 2>/dev/null | tr -d '\n')
|
||||
echo "$c $i live=$live файл=$infile ($conf)"
|
||||
done
|
||||
done
|
||||
done
|
||||
"""
|
||||
|
||||
d = json.load(open("/app/data/data.json"))
|
||||
плохо = 0
|
||||
for s in d["servers"]:
|
||||
try:
|
||||
with SSHManager(s["host"], s.get("ssh_port", 22), s["username"],
|
||||
password=s.get("password") or None,
|
||||
private_key=s.get("private_key") or None,
|
||||
connect_timeout=8) as ssh:
|
||||
out, err, _ = ssh.run_command(PROBE, timeout=60)
|
||||
строки = [x.strip() for x in (out or "").splitlines() if x.strip()]
|
||||
if not строки:
|
||||
print(" ? %-26s нет поднятых интерфейсов" % s["name"][:26])
|
||||
continue
|
||||
for стр in строки:
|
||||
беда = False
|
||||
if "live=" in стр and "файл=" in стр:
|
||||
l = int(стр.split("live=")[1].split()[0])
|
||||
f = int(стр.split("файл=")[1].split()[0])
|
||||
беда = (l != f)
|
||||
плохо += 1 if беда else 0
|
||||
print(" %s %-26s %s" % ("!!" if беда else "ok", s["name"][:26], стр))
|
||||
except Exception as e:
|
||||
плохо += 1
|
||||
print(" !! %-26s НЕ ДОСТУЧАЛСЯ: %s" % (s["name"][:26], str(e)[:60]))
|
||||
print("\nрасхождений:", плохо)
|
||||
56
scripts/checks/audit_conf.py
Normal file
56
scripts/checks/audit_conf.py
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Целостность конфигов awg по всему парку: склейки, финальный перевод строки,
|
||||
проходит ли awg-quick strip и совпадает ли число пиров с живым интерфейсом."""
|
||||
import json, sys
|
||||
sys.path.insert(0, "/app")
|
||||
from managers.ssh_manager import SSHManager
|
||||
|
||||
PROBE = r"""
|
||||
for c in amnezia-awg2 amnezia-awg amnezia-awg31 amnezia-awg3 amnezia-awg-legacy; do
|
||||
docker ps --format '{{.Names}}' 2>/dev/null | grep -qx $c || continue
|
||||
for f in awg0.conf wg0.conf; do
|
||||
p=/opt/amnezia/awg/$f
|
||||
docker exec $c test -f $p 2>/dev/null || continue
|
||||
glue=$(docker exec $c grep -c '/32\[Peer\]' $p 2>/dev/null | tr -d '\n')
|
||||
end=$(docker exec $c sh -c "tail -c 1 $p | od -An -c | tr -d ' \n'")
|
||||
peers=$(docker exec $c grep -c '^\[Peer\]' $p 2>/dev/null | tr -d '\n')
|
||||
mode=$(docker exec $c stat -c %a $p 2>/dev/null | tr -d '\n')
|
||||
bin=wg; iface=wg0
|
||||
case $f in awg0.conf) bin=awg; iface=awg0;; esac
|
||||
if docker exec $c sh -c "$bin-quick strip $p > /dev/null 2>&1"; then strip=ok; else strip=СБОЙ; fi
|
||||
live=$(docker exec $c sh -c "$bin show $iface peers 2>/dev/null | grep -c ." | tr -d '\n')
|
||||
echo "$c/$f peers=$peers live=$live glue=$glue end=$end mode=$mode strip=$strip"
|
||||
done
|
||||
done
|
||||
"""
|
||||
|
||||
d = json.load(open("/app/data/data.json"))
|
||||
беда = 0
|
||||
for s in d["servers"]:
|
||||
try:
|
||||
with SSHManager(s["host"], s.get("ssh_port", 22), s["username"],
|
||||
password=s.get("password") or None,
|
||||
private_key=s.get("private_key") or None,
|
||||
connect_timeout=8) as ssh:
|
||||
out, err, _ = ssh.run_command(PROBE, timeout=60)
|
||||
строки = [x.strip() for x in (out or "").splitlines() if x.strip()]
|
||||
if not строки:
|
||||
print(" ? %-26s нет контейнеров awg (%s)" % (s["name"][:26], (err or "")[:40]))
|
||||
continue
|
||||
for стр in строки:
|
||||
плохо = ("glue=0" not in стр) or ("strip=ok" not in стр) or ("end=\\n" not in стр)
|
||||
if "peers=" in стр and "live=" in стр:
|
||||
try:
|
||||
p = int(стр.split("peers=")[1].split()[0])
|
||||
l = int(стр.split("live=")[1].split()[0])
|
||||
if p != l:
|
||||
плохо = True
|
||||
стр += " ← файл и интерфейс расходятся"
|
||||
except Exception:
|
||||
pass
|
||||
беда += 1 if плохо else 0
|
||||
print(" %s %-26s %s" % ("!!" if плохо else "ok", s["name"][:26], стр))
|
||||
except Exception as e:
|
||||
беда += 1
|
||||
print(" !! %-26s НЕ ДОСТУЧАЛСЯ: %s" % (s["name"][:26], str(e)[:60]))
|
||||
print("\nпроблемных строк:", беда)
|
||||
38
scripts/checks/check_conf.py
Normal file
38
scripts/checks/check_conf.py
Normal file
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Ищем склеенные строки в конфигах awg на всех серверах панели.
|
||||
|
||||
Имена переменных в пробе латиницей: sh внутри контейнеров кириллицу не берёт.
|
||||
"""
|
||||
import json, sys
|
||||
sys.path.insert(0, "/app")
|
||||
from managers.ssh_manager import SSHManager
|
||||
|
||||
ПРОБА = (
|
||||
"for c in amnezia-awg2 amnezia-awg amnezia-awg31 amnezia-awg3 amnezia-awg-legacy; do "
|
||||
" docker ps --format '{{.Names}}' 2>/dev/null | grep -qx $c || continue; "
|
||||
" for f in awg0.conf wg0.conf; do "
|
||||
" p=/opt/amnezia/awg/$f; "
|
||||
" docker exec $c test -f $p 2>/dev/null || continue; "
|
||||
" glue=$(docker exec $c grep -c '/32\\[Peer\\]' $p 2>/dev/null || echo 0); "
|
||||
" endnl=$(docker exec $c sh -c \"tail -c 1 $p | od -An -c | tr -d ' '\" 2>/dev/null); "
|
||||
" peers=$(docker exec $c grep -c '^\\[Peer\\]' $p 2>/dev/null || echo 0); "
|
||||
" echo \"$c/$f peers=$peers glue=$glue end=$endnl\"; "
|
||||
" done; done"
|
||||
)
|
||||
|
||||
d = json.load(open("/app/data/data.json"))
|
||||
for s in d["servers"]:
|
||||
try:
|
||||
with SSHManager(s["host"], s.get("ssh_port", 22), s["username"],
|
||||
password=s.get("password") or None,
|
||||
private_key=s.get("private_key") or None,
|
||||
connect_timeout=8) as ssh:
|
||||
out, err, _ = ssh.run_command(ПРОБА, timeout=40)
|
||||
for строка in (out or err).splitlines():
|
||||
строка = строка.strip()
|
||||
if not строка:
|
||||
continue
|
||||
плохо = ("glue=0" not in строка) or ("end=\\n" not in строка)
|
||||
print("%s %-26s %s" % (" !!" if плохо else " ", s["name"][:26], строка))
|
||||
except Exception as e:
|
||||
print(" %-26s СБОЙ: %s" % (s["name"][:26], str(e)[:50]))
|
||||
30
scripts/checks/check_garbage.py
Normal file
30
scripts/checks/check_garbage.py
Normal file
@@ -0,0 +1,30 @@
|
||||
"""Не осталось ли от проверок тестовых клиентов в clientsTable и в data.json."""
|
||||
import json, sys
|
||||
sys.path.insert(0, "/app")
|
||||
from managers.ssh_manager import SSHManager
|
||||
|
||||
МЕТКА = "__проверка_связи"
|
||||
d = json.load(open("/app/data/data.json"))
|
||||
|
||||
в_панели = [c for c in json.dumps(d, ensure_ascii=False).split('"') if МЕТКА in c]
|
||||
print("следов в data.json панели:", len(в_панели))
|
||||
|
||||
ПРОБА = (
|
||||
"for c in $(docker ps --format '{{.Names}}' 2>/dev/null | grep -E 'amnezia-(awg|wireguard|xray)'); do "
|
||||
" n=$(docker exec $c sh -c \"grep -o '%s[^\\\"]*' /opt/amnezia/awg/clientsTable /opt/amnezia/xray/clientsTable 2>/dev/null | wc -l\"); "
|
||||
" [ \"$n\" != \"0\" ] && echo \"$c: $n\"; done; echo готово" % МЕТКА
|
||||
)
|
||||
всего = 0
|
||||
for s in d["servers"]:
|
||||
try:
|
||||
with SSHManager(s["host"], s.get("ssh_port", 22), s["username"],
|
||||
password=s.get("password") or None,
|
||||
private_key=s.get("private_key") or None, connect_timeout=8) as ssh:
|
||||
o, _, _ = ssh.run_command(ПРОБА, timeout=40)
|
||||
строки = [x for x in (o or "").splitlines() if x.strip() and "готово" not in x]
|
||||
if строки:
|
||||
всего += len(строки)
|
||||
print(" !!", s["name"], строки)
|
||||
except Exception as e:
|
||||
print(" ?", s["name"][:26], str(e)[:40])
|
||||
print("серверов с остатками:", всего)
|
||||
59
scripts/checks/test_create.py
Normal file
59
scripts/checks/test_create.py
Normal file
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Боевая проверка: на каждом сервере и каждом протоколе создаём тестового
|
||||
клиента и тут же удаляем. Именно так работает кнопка «Добавить подключение».
|
||||
|
||||
Считаем пиров до и после: если после удаления число не вернулось — значит
|
||||
за нами остался мусор, и это надо видеть.
|
||||
"""
|
||||
import json, sys, time
|
||||
sys.path.insert(0, "/app")
|
||||
from managers.ssh_manager import SSHManager
|
||||
from managers.awg_manager import AWGManager
|
||||
|
||||
ИМЯ = "__проверка_связи_" + time.strftime("%d%m_%H%M")
|
||||
ПРОТОКОЛЫ = ("awg", "awg2", "awg3", "awg31", "wireguard")
|
||||
|
||||
d = json.load(open("/app/data/data.json"))
|
||||
итог = {"ok": 0, "сбой": 0, "мусор": 0}
|
||||
|
||||
for s in d["servers"]:
|
||||
протоколы = [p for p in ПРОТОКОЛЫ
|
||||
if (s.get("protocols", {}).get(p) or {}).get("installed")]
|
||||
if not протоколы:
|
||||
print(" – %-26s протоколов AWG не заведено" % s["name"][:26])
|
||||
continue
|
||||
for proto in протоколы:
|
||||
метка = "%s / %s" % (s["name"][:22], proto)
|
||||
try:
|
||||
ssh = SSHManager(s["host"], s.get("ssh_port", 22), s["username"],
|
||||
password=s.get("password") or None,
|
||||
private_key=s.get("private_key") or None,
|
||||
connect_timeout=10, connect_retries=1)
|
||||
ssh.connect()
|
||||
try:
|
||||
m = AWGManager(ssh)
|
||||
было = len(m._get_used_ips(proto))
|
||||
порт = (s["protocols"][proto] or {}).get("port", "55424")
|
||||
r = m.add_client(proto, ИМЯ, s["host"], порт)
|
||||
cid = r.get("client_id") or r.get("clientId")
|
||||
есть_конфиг = bool(r.get("config"))
|
||||
стало = len(m._get_used_ips(proto))
|
||||
m.remove_client(proto, cid)
|
||||
после = len(m._get_used_ips(proto))
|
||||
finally:
|
||||
ssh.disconnect()
|
||||
|
||||
если_чисто = (после == было)
|
||||
итог["ok" if (есть_конфиг and стало == было + 1) else "сбой"] += 1
|
||||
if not если_чисто:
|
||||
итог["мусор"] += 1
|
||||
print(" %s %-30s пиров %d → %d → %d конфиг=%s" % (
|
||||
"ok" if (есть_конфиг and стало == было + 1 and если_чисто) else "!!",
|
||||
метка, было, стало, после, "есть" if есть_конфиг else "НЕТ"))
|
||||
except Exception as e:
|
||||
итог["сбой"] += 1
|
||||
print(" !! %-30s %s" % (метка, str(e)[:70]))
|
||||
|
||||
print("\nсоздалось и убралось начисто: %d, сбоев: %d, осталось мусора: %d"
|
||||
% (итог["ok"], итог["сбой"], итог["мусор"]))
|
||||
@@ -2,7 +2,8 @@
|
||||
# Установка Amnezia Admin WebUI одной командой (см. README).
|
||||
set -euo pipefail
|
||||
|
||||
GITHUB_REPO="${GITHUB_REPO:-andrey271192/amnezia_web-PRO}"
|
||||
GITHUB_REPO="${GITHUB_REPO:-PCA/amnezia_web-PRO}"
|
||||
GIT_BASE="${GIT_BASE:-https://git.bobyrev.com}"
|
||||
BRANCH="${BRANCH:-main}"
|
||||
INSTALL_DIR="${INSTALL_DIR:-/opt/amnezia-admin}"
|
||||
DATA_DIR="${DATA_DIR:-/opt/amnezia-admin-data}"
|
||||
@@ -66,26 +67,24 @@ fi
|
||||
|
||||
if [[ "${SKIP_DOWNLOAD:-}" != "1" ]]; then
|
||||
echo "→ Клонирование релиза ${GITHUB_REPO} (${BRANCH})..."
|
||||
echo "→ Скачивание tar.gz с GitHub (вывода может не быть 1–10 мин.; при блокировках задайте зеркало GITHUB_REPO_URL_OVERRIDE или см. CURL_MAX_TIME ниже)."
|
||||
echo "→ Скачивание tar.gz с ${GIT_BASE} (вывода может не быть 1–10 мин.; при блокировках задайте зеркало GITHUB_REPO_URL_OVERRIDE или см. CURL_MAX_TIME ниже)."
|
||||
TMP=$(mktemp -d)
|
||||
CURL_OPTS=(
|
||||
-fsSL
|
||||
-H 'Cache-Control: no-cache'
|
||||
-H 'Pragma: no-cache'
|
||||
--connect-timeout "${CURL_CONNECT_TIMEOUT:-30}"
|
||||
--connect-timeout "${CURL_CONNECT_TIMEOUT:-15}"
|
||||
--max-time "${CURL_MAX_TIME:-900}"
|
||||
--retry "${CURL_RETRY:-2}"
|
||||
--retry-delay "${CURL_RETRY_DELAY:-5}"
|
||||
--retry-connrefused
|
||||
)
|
||||
if [[ "${INSTALL_SCRIPT_VERBOSE:-}" == "1" ]]; then CURL_OPTS+=(--progress-bar); fi
|
||||
CURL_URL="${GITHUB_REPO_URL_OVERRIDE:-}"
|
||||
if [[ -z "${CURL_URL}" ]]; then
|
||||
CURL_URL="https://github.com/${GITHUB_REPO}/archive/refs/heads/${BRANCH}.tar.gz"
|
||||
fi
|
||||
# ponytail: GitHub-аккаунт заблокирован (10.2026), код живёт на git.bobyrev.com.
|
||||
CURL_URL="${GITHUB_REPO_URL_OVERRIDE:-${GIT_BASE}/${GITHUB_REPO}/archive/${BRANCH}.tar.gz}"
|
||||
if ! curl "${CURL_OPTS[@]}" "${CURL_URL}" | tar xz -C "${TMP}"; then
|
||||
echo "Ошибка: не удалось скачать или распаковать архив (${CURL_URL})."
|
||||
echo "Подсказка: проверьте доступ к github.com, branch/repo, при необходимости export GITHUB_REPO_URL_OVERRIDE='…' или INSTALL_SCRIPT_VERBOSE=1."
|
||||
echo "Подсказка: проверьте доступ к git.bobyrev.com, при необходимости export GITHUB_REPO_URL_OVERRIDE='…' или INSTALL_SCRIPT_VERBOSE=1."
|
||||
exit 1
|
||||
fi
|
||||
echo "→ Перенос распакованного дерева в ${INSTALL_DIR}…"
|
||||
@@ -355,4 +354,4 @@ if [[ -f "${PASS_FILE}" ]]; then
|
||||
echo "Первый пароль: $(cat "${PASS_FILE}")"
|
||||
fi
|
||||
echo ""
|
||||
echo "Удаление: curl -fsSL https://raw.githubusercontent.com/${GITHUB_REPO}/${BRANCH}/scripts/uninstall.sh | sudo bash"
|
||||
echo "Удаление: curl -fsSL ${GIT_BASE}/${GITHUB_REPO}/raw/branch/${BRANCH}/scripts/uninstall.sh | sudo bash"
|
||||
|
||||
Reference in New Issue
Block a user