Homepage дашборд на dash.dttb.ru (LXC 145): live-виджеты Proxmox/NPM/Gitea/NC, Basic Auth

- LXC 145 homepage, Docker, 22 сервиса в 5 группах
- read-only доступы: PVEAuditor токен, Gitea PAT, NC app-password
- грабли: docker.io SNI-блок РКН (зеркало Яндекса), split-DNS hosts, NPM+authentik forward-auth
- authentik forward-auth отложен (localhost в authorize) → пока NPM Basic Auth

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
dttb
2026-06-27 00:22:42 +03:00
parent 9c11b205ec
commit 3fe379f12c
4 changed files with 106 additions and 5 deletions

View File

@@ -0,0 +1,68 @@
---
date: 2026-06-27
type: decision
tags: [dttb, dashboard, homepage, proxmox, authentik, npm]
---
# Homepage — единый дашборд home lab (LXC 145)
## Контекст
Зоопарк сервисов dttb разросся (42 VM/LXC). Нужна одна точка входа — карта инфраструктуры с живыми метриками. Выбран [Homepage](https://gethomepage.dev) (`gethomepage/homepage`) — нативные виджеты под бо́льшую часть стека.
## Что развёрнуто
- **LXC 145 `homepage`** — Debian 12, unprivileged + nesting/keyctl, 2 vCPU / 1 GB / 8 GB на `work`, статика **10.0.0.145**, nameserver 1.1.1.1.
- Docker `ghcr.io/gethomepage/homepage:latest`, `-p 3000:3000`, `--env-file /opt/homepage/.env`, volume `/opt/homepage/config`.
- Веб: **https://dash.dttb.ru** (NPM proxy host **id 42**, LE cert **id 134** до 2026-09-24) за **NPM Basic Auth** (access-list id 5, `oleg`/`OL260380eg`). LAN/NetBird — `http://10.0.0.145:3000` без авторизации.
- ⚠️ **authentik forward-auth НЕ боевой** (отложен) — см. грабли #4. Enforcement работал (unauth→302 в authentik), но embedded-outpost строит authorize-URL как `http://localhost` (игнорит `authentik_host_browser`, а `authentik_host=https://auth.dttb.ru` упирается в зависший hairpin LXC144→NPM). Плюс Олег ещё не прошёл 2FA-enrollment в authentik. Объекты (provider/app/outpost) оставлены готовыми, гейт пока Basic Auth.
- 5 групп / 22 сервиса: Инфраструктура, Облако и данные, AI-боты и инструменты, Доступ и безопасность, Дом-сеть-медиа.
## Live-виджеты (read-only доступы — не мастер-креды)
| Сервис | Виджет | Доступ |
|--------|--------|--------|
| Proxmox VE | proxmox | API-токен `homepage@pve!homepage` (роль **PVEAuditor**, privsep 0) |
| Nginx Proxy Manager | nginxproxymanager | логин it5870@yandex.ru (виджет сам берёт JWT) |
| Gitea | gitea | read-only PAT `homepage-dashboard` (scopes read:repository/issue/user/org/notification/misc) |
| Nextcloud | nextcloud | admin + **app-password** (serverinfo API) |
Остальное — ping-плитки (siteMonitor на внутренний IP): UniFi, Vaultwarden, LinkWarden, ZimaOS, Антошка, SwarmClaw, German, Open WebUI, OmniRoute, code-server, authentik, RustDesk, Mailcow, Amnezia, Home Assistant, WatchYourLAN, PBS, pve-147.
## Секреты
`/opt/homepage/.env` (chmod 600, **НЕ в vault, не в git**): `HOMEPAGE_VAR_*` (proxmox token, npm/nc creds, gitea token) + `HOMEPAGE_ALLOWED_HOSTS=dash.dttb.ru,10.0.0.145:3000,localhost:3000`. В `services.yaml` — только плейсхолдеры `{{HOMEPAGE_VAR_*}}`.
## Грабли (за них наступали)
1. **`download.docker.com` SNI-блок РКН** (`tlsv1 unrecognized name`) — DNS отдаёт реальный CloudFront, но РКН режет по SNI. Фикс: `docker.io` из репо Debian, а сам apt переключён на **`mirror.yandex.ru`** (deb.debian.org=Fastly тоже троттлится из РФ).
2. **Nextcloud-виджет и split-DNS**`dttb.ru` из контейнера (DNS 1.1.1.1) резолвится в публичный 176.62.183.186 → хайрпин через WAN. Фикс: `/etc/hosts``10.0.0.195 dttb.ru` (идёт прямо на NPM).
3. **NPM + authentik forward-auth, duplicate `location /`** — NPM кладёт `advanced_config` ПОСЛЕ своего `location /` (стр. 72 vs 96 в `42.conf`). Свой `location /` в сниппет = nginx duplicate location → конфиг не сохранится. Решение: `auth_request` на уровне **server** (наследуется в NPM-овский `location /`), а в `location /outpost.goauthentik.io` и `@goauthentik_proxy_signin`**`auth_request off;`** (иначе рекурсия auth-сабреквеста сам в себя).
4. **`http://localhost` в authorize-redirect** — embedded outpost не знал внешний URL. Фикс: outpost config **`authentik_host_browser=https://auth.dttb.ru`** + рестарт `server`/`worker` (config подхватывается рестартом, не сразу).
5. authentik objects: proxy provider pk **3** (`forward_single`, external_host https://dash.dttb.ru), application slug **`dash`**, привязан к embedded outpost `88286dc5-…`.
## NPM advanced_config (server-level auth_request)
```nginx
location /outpost.goauthentik.io {
auth_request off;
proxy_pass http://10.0.0.144:9000/outpost.goauthentik.io;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
location @goauthentik_proxy_signin {
internal; auth_request off;
add_header Set-Cookie $auth_cookie;
return 302 /outpost.goauthentik.io/start?rd=$request_uri;
}
auth_request /outpost.goauthentik.io/auth/nginx;
error_page 401 = @goauthentik_proxy_signin;
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
```
## TODO / можно докрутить
- **authentik forward-auth → боевой**: починить `localhost` в authorize (embedded outpost). Варианты: standalone-outpost контейнер на dash-LXC; либо разобраться, почему `authentik_host_browser` не применяется в 2026.5.3; нужен живой браузерный тест + 2FA-enrollment Олега. Тогда снять Basic Auth (access-list 5).
- UniFi/Vaultwarden можно перевести из плиток в live-виджеты (нужны read-only креды/токены).
См. [[../projects/dttb/proxmox-inventory#LXC 145 — homepage Dashboard]], [[2026-06-26-authentik-sso-deploy]].

View File

@@ -170,6 +170,21 @@ cd /var/lib/rustdesk-api && /usr/bin/rustdesk-api reset-admin-pwd <new-pw>
| OIDC Gitea | app `gitea`, client_id `AYl8jNZvJF7jh4c2nPhm1nRtD2XwkUK0DPwnvQ9e`, secret `UwsqG97S5REcuSgQLFQUHGp0JDKScR7fSIuIminNaZoVKca2JQzbb0PebePeBeaQhFKPjJOlu3kEmEEzod0oGtIArHKH492SnUBMO5aa5FgnAGjGzm9BB4RRYJo7wEMQ` | | OIDC Gitea | app `gitea`, client_id `AYl8jNZvJF7jh4c2nPhm1nRtD2XwkUK0DPwnvQ9e`, secret `UwsqG97S5REcuSgQLFQUHGp0JDKScR7fSIuIminNaZoVKca2JQzbb0PebePeBeaQhFKPjJOlu3kEmEEzod0oGtIArHKH492SnUBMO5aa5FgnAGjGzm9BB4RRYJo7wEMQ` |
| Recovery | сброс admin-пароля `ak change_password akadmin`; снять обяз. 2FA — PATCH стейджа `f3808685-…` `not_configured_action=skip` через API-токен. См. [[../../decisions/2026-06-26-authentik-sso-deploy]] | | Recovery | сброс admin-пароля `ak change_password akadmin`; снять обяз. 2FA — PATCH стейджа `f3808685-…` `not_configured_action=skip` через API-токен. См. [[../../decisions/2026-06-26-authentik-sso-deploy]] |
## Homepage Dashboard (LXC 145)
| Параметр | Значение |
|----------|----------|
| URL | https://dash.dttb.ru (NPM #42 → 10.0.0.145:3000, LE cert id134) |
| Basic Auth | `oleg` / `OL260380eg` (NPM access-list id 5) |
| LAN/NetBird | http://10.0.0.145:3000 (без авторизации) |
| LXC root | `10.0.0.145` — root / `1qaz!QAZ` |
| Секреты виджетов | `/opt/homepage/.env` (chmod 600, не в git): `HOMEPAGE_VAR_*` |
| Proxmox widget | API-токен `homepage@pve!homepage` = `26a880fa-36de-4703-ae84-fbcd8965f480` (роль **PVEAuditor**, read-only) |
| Gitea widget | read-only PAT `homepage-dashboard` = `b91a8434eb93404dbfef0ddf7b2676d23cbbfaf0` |
| Nextcloud widget | admin + app-password `IDE19XghEprCQG9p8as9NrwxEfI6BoXXxWZv0kremJkoOXtKCmNxj61JC8SLjZFPnhnwp4cp` |
| NPM widget | it5870@yandex.ru / 1qaz!QAZ (как NPM) |
| authentik (отложен) | proxy provider pk 3 `dash-forward`, app slug `dash`, embedded outpost. См. [[../../decisions/2026-06-27-homepage-dashboard-lxc145]] |
## SSH-ключи и доступы ## SSH-ключи и доступы
| Хост | Порт | Метод | | Хост | Порт | Метод |

View File

@@ -9,7 +9,7 @@ tags: [dttb, npm]
> **NPM LXC:** 103 (10.0.0.195) > **NPM LXC:** 103 (10.0.0.195)
> **Панель:** https://npm.dttb.ru > **Панель:** https://npm.dttb.ru
> >
> Последнее обновление: 2026-06-26 (добавлен auth.dttb.ru → authentik SSO/IdP LXC 144) > Последнее обновление: 2026-06-27 (добавлен dash.dttb.ru → Homepage Dashboard LXC 145)
--- ---
@@ -17,7 +17,7 @@ tags: [dttb, npm]
| Всего хостов | С SSL | Без SSL | Активных | | Всего хостов | С SSL | Без SSL | Активных |
|--------------|-------|---------|----------| |--------------|-------|---------|----------|
| 24 | 20 | 4 | 24 | | 25 | 21 | 4 | 25 |
--- ---
@@ -55,6 +55,7 @@ tags: [dttb, npm]
| 39 | `chat.dttb.ru` | 10.0.0.142:3000 | ✅ Let's Encrypt (id129) | ✅ | ✅ | ✅ | **Open WebUI** (LXC 142) — веб-клиент поверх OmniRoute | | 39 | `chat.dttb.ru` | 10.0.0.142:3000 | ✅ Let's Encrypt (id129) | ✅ | ✅ | ✅ | **Open WebUI** (LXC 142) — веб-клиент поверх OmniRoute |
| 40 | `german.dttb.ru` | 10.0.0.141:9119 | ✅ Let's Encrypt (id130) | ✅ | ✅ | ✅ | **Hermes Dashboard** (LXC 141) — веб-панель German; basic_auth `oleg`, см. credentials | | 40 | `german.dttb.ru` | 10.0.0.141:9119 | ✅ Let's Encrypt (id130) | ✅ | ✅ | ✅ | **Hermes Dashboard** (LXC 141) — веб-панель German; basic_auth `oleg`, см. credentials |
| 41 | `auth.dttb.ru` | 10.0.0.144:9000 | ✅ Let's Encrypt (id133) | ✅ | ✅ | ✅ | **authentik SSO/IdP** (LXC 144) — единый вход + 2FA. См. [[../../decisions/2026-06-26-authentik-sso-deploy]] | | 41 | `auth.dttb.ru` | 10.0.0.144:9000 | ✅ Let's Encrypt (id133) | ✅ | ✅ | ✅ | **authentik SSO/IdP** (LXC 144) — единый вход + 2FA. См. [[../../decisions/2026-06-26-authentik-sso-deploy]] |
| 42 | `dash.dttb.ru` | 10.0.0.145:3000 | ✅ Let's Encrypt (id134) | ✅ | ✅ | ✅ | **Homepage Dashboard** (LXC 145) — карта инфры + live-виджеты; **Basic Auth** `oleg`/`OL260380eg` (access-list 5); authentik forward-auth отложен. См. [[../../decisions/2026-06-27-homepage-dashboard-lxc145]] |
--- ---

View File

@@ -9,7 +9,7 @@ tags: [dttb, proxmox]
> **Основная нода:** pve (10.0.0.250) — описана ниже > **Основная нода:** pve (10.0.0.250) — описана ниже
> **Вторая нода (standalone):** pve (10.0.0.147) — отдельный хост i3-2100/15GB/SSD+1.8TB HDD, см. [[proxmox-pve-147]] (VM 100 ZimaOS, LXC 101 второй NPM) > **Вторая нода (standalone):** pve (10.0.0.147) — отдельный хост i3-2100/15GB/SSD+1.8TB HDD, см. [[proxmox-pve-147]] (VM 100 ZimaOS, LXC 101 второй NPM)
> >
> Последнее обновление: 2026-06-26 (добавлен LXC 144 authentik — SSO/IdP, auth.dttb.ru) > Последнее обновление: 2026-06-27 (добавлен LXC 145 homepage — дашборд, dash.dttb.ru)
--- ---
@@ -18,8 +18,8 @@ tags: [dttb, proxmox]
| Тип | Всего | Запущено | Остановлено | | Тип | Всего | Запущено | Остановлено |
|-----|-------|----------|-------------| |-----|-------|----------|-------------|
| QEMU VM | 15 | 5 | 10 | | QEMU VM | 15 | 5 | 10 |
| LXC | 26 | 16 | 10 | | LXC | 27 | 17 | 10 |
| **Итого** | **41** | **21** | **20** | | **Итого** | **42** | **22** | **20** |
--- ---
@@ -278,6 +278,23 @@ tags: [dttb, proxmox]
--- ---
### LXC 145 — homepage (Dashboard)
| Параметр | Значение |
|----------|----------|
| Статус | 🟢 running |
| IP | 10.0.0.145 (LAN, статика, nameserver 1.1.1.1) |
| ОС/рантайм | Debian 12, unprivileged + nesting/keyctl, Docker 20.10 (`docker.io` из репо Яндекса — `download.docker.com` SNI-блок РКН; apt тоже на `mirror.yandex.ru`) |
| Ресурсы | 2 vCPU / 1 GB / swap 512 MB / 8 GB (rootfs на `work`) |
| Стек | `ghcr.io/gethomepage/homepage:latest` (`-p 3000:3000`, `--env-file /opt/homepage/.env`, volume `/opt/homepage/config`) |
| Веб | **https://dash.dttb.ru** (NPM #42, LE id134, Basic Auth `oleg`/`OL260380eg`; authentik forward-auth отложен) · LAN/NetBird без авторизации `http://10.0.0.145:3000` |
| Live-виджеты | Proxmox (read-only token `homepage@pve!homepage`, роль PVEAuditor), NPM, Gitea (read-only PAT), Nextcloud (app-password). Остальное — ping-плитки |
| Секреты | `/opt/homepage/.env` (chmod 600, **не в vault**): HOMEPAGE_VAR_* + HOMEPAGE_ALLOWED_HOSTS |
| Грабли | `/etc/hosts`: `10.0.0.195 dttb.ru` — чтобы Nextcloud-виджет шёл на NPM напрямую (split-DNS), а не хайрпином через WAN |
| Tags | dashboard, homepage |
| Назначение | **Homepage — единый дашборд home lab** (карта инфры + живые метрики). См. [[../../decisions/2026-06-27-homepage-dashboard-lxc145]] |
---
## 🔴 Остановленные LXC ## 🔴 Остановленные LXC
| VMID | Имя | Назначение | | VMID | Имя | Назначение |