12 Commits

Author SHA1 Message Date
ede8e5f4d0 code-server auto-sync 2026-06-28T06:05:01+00:00 2026-06-28 06:05:01 +00:00
73ea32fa72 code-server auto-sync 2026-06-28T00:05:02+00:00 2026-06-28 00:05:02 +00:00
root
3298ebfe71 auto-backup claude-memory 2026-06-28_00:00 2026-06-28 00:00:46 +00:00
ea66be0c84 code-server auto-sync 2026-06-27T23:05:01+00:00 2026-06-27 23:05:01 +00:00
dttb
4d92eaca2e Merge branch 'main' of https://git.dttb.ru/oleg/knowledge-base 2026-06-28 02:01:02 +03:00
dttb
3f71986097 NPM: диск LXC 103 вырос 8G->16G; заметка про thin-пул 94.91%
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 02:01:01 +03:00
dcbd18f7f9 code-server auto-sync 2026-06-27T22:55:01+00:00 2026-06-27 22:55:01 +00:00
dttb
658049ef50 Merge branch 'main' of https://git.dttb.ru/oleg/knowledge-base 2026-06-28 01:54:36 +03:00
dttb
42d1b4ad85 NPM: troubleshooting disk-full LXC 103 (git push 500), защита логов
Корень падения git push по HTTPS: диск NPM 100% забит логами host-22
(trust_forwarded_proto warning флуд). Truncate + cron npm-log-cap (>200M).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 01:54:23 +03:00
8f1b609e56 code-server auto-sync 2026-06-27T22:50:02+00:00 2026-06-27 22:50:02 +00:00
dttb
ddb904ca21 Merge branch 'main' of https://git.dttb.ru/oleg/knowledge-base 2026-06-28 01:43:39 +03:00
dttb
58fd3fa17a mailcow dttb: спам-фикс, SSL, апдейт 2026-05c, BIMI+подпись, Roundcube, сбор почты
- фикс входящего спама: No-SNAT на OpenWrt (видел все письма как 10.0.0.1)
- SSL mail-портов: cert из NPM + cron-синхрон на Proxmox
- апдейт mailcow 2026-01 -> 2026-05c; урок: forward-zone unbound обязателен (RKN режет рекурсию)
- логотип UI, BIMI-SVG (Tiny PS) + хостинг, HTML-подпись
- Roundcube на /rc (bind-mount, public_html)
- внешний сбор почты Яндексом (IMAP/POP3)
- snippets: sync-mailcow-cert.sh, dttb-mail-branding/

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 01:43:19 +03:00
30 changed files with 1343 additions and 16 deletions

View File

@@ -0,0 +1,55 @@
---
date: 2026-06-28
type: audit
source: kb-audit-creds.py
tags: [audit, creds, reachability]
---
# Credentials reachability — 2026-06-28
Ping-проверка URL из [[../projects/dttb/credentials|credentials.md]].
Проверяется только reachability (HTTP status), не реальный логин.
- Всего URL: **28**
- ✓ Reachable: 25 / ⚠ Questionable: 3 / ❌ Unreachable: 0
## ⚠ Нестандартный ответ
| URL | Status | Detail |
|---|---|---|
| `https://remot.dttb.ru/swagger/index.html` | 404 | Not Found |
| `https://api.netbird.io` | 404 | Not Found |
| `https://api.netbird.io/api/setup-keys` | 404 | Not Found |
## ✓ Все ответили нормально
| URL | Status | Категория |
|---|---|---|
| `https://10.0.0.250:8006` | 200 | ✓ reachable |
| `https://pve.dttb.ru` | 200 | ✓ reachable |
| `http://10.0.0.143:5000` | 200 | ✓ reachable |
| `http://100.70.9.163:5000` | 200 | ✓ reachable |
| `http://10.0.0.189:3000` | 200 | ✓ reachable |
| `http://git.dttb.ru` | 200 | ✓ reachable |
| `http://10.0.0.195:81` | 200 | ✓ reachable |
| `https://npm.dttb.ru` | 200 | ✓ reachable |
| `https://remot.dttb.ru/_admin` | 200 | ✓ reachable |
| `https://dttb.ru` | 200 | ✓ reachable |
| `https://dttb.ru/remote.php/dav/files/admin` | 401 | ✓ auth-required (сервер жив) |
| `http://10.0.0.221` | 200 | ✓ reachable |
| `http://10.0.0.221:7681` | 200 | ✓ reachable |
| `https://vps.sweb.ru` | 200 | ✓ reachable |
| `https://api.sweb.ru/domains/dns` | 200 | ✓ reachable |
| `https://mail.niikn.com` | 200 | ✓ reachable |
| `http://192.168.1.22:81` | 200 | ✓ reachable |
| `https://german.dttb.ru` | 200 | ✓ reachable |
| `https://auth.dttb.ru` | 200 | ✓ reachable |
| `https://dash.dttb.ru` | 401 | ✓ auth-required (сервер жив) |
| `http://10.0.0.148:3000` | 200 | ✓ reachable |
| `https://edit.telegra.ph/auth/f1tfgzYpPpGlAr7cYHRzSeH59fYuNVB2V3fbCdypDc` | 200 | ✓ reachable |
| `https://api.telegra.ph/createPage` | 200 | ✓ reachable |
| `https://api.telegra.ph/editPage` | 200 | ✓ reachable |
| `https://telegra.ph/Nastrojka-VPN-04-24-2` | 200 | ✓ reachable |
---
*Автоматически через `scripts/kb-audit-creds.py`.*

View File

@@ -0,0 +1,101 @@
---
date: 2026-06-28
type: audit
source: kb-audit-dns.py
tags: [audit, dns]
---
# DNS resolve audit — 2026-06-28
Резолвим все домены из NPM через публичный DNS (8.8.8.8) и локальный роутер (10.0.0.1).
- Всего доменов: **35**
- NXDOMAIN на 8.8.8.8: 2 / пустой ответ локально: 1 / split-horizon: 27
## ❌ NXDOMAIN / не резолвится на 8.8.8.8 (публичный DNS)
| Домен | Локальный IP |
|---|---|
| `itilegent.ru` | (тоже нет) |
| `vpn.dttb.ru` | 10.0.0.195 |
## ⚠ Split-horizon — разные IP снаружи и внутри
Это нормально для *.dttb.ru (внешний Let's Encrypt IP vs локальный 10.0.0.195). Но неожиданный split может быть багом.
| Домен | Публичный (8.8.8.8) | Локальный (10.0.0.1) |
|---|---|---|
| `ai.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `auth.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `bit.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `bitrix24.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `bot.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `chat.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `dash.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `german.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `git.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `home.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `ip.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `link.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `mail.dttb.ru` | 176.62.183.186 | 10.0.0.107 |
| `matrix.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `npm.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `office.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `omni.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `plex.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `porteiner.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `pve.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `rec.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `remot.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `router.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `swarm.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `unifi.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `z.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
## ⚠ Пустой локальный резолв (роутер не знает)
- `itilegent.ru` (публичный: -)
## Полная таблица резолва
| Домен | 8.8.8.8 | 10.0.0.1 |
|---|---|---|
| `ai.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `ai.umnybot.ru` | 158.255.0.139 | 158.255.0.139 |
| `auth.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `bit.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `bitrix24.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `bot.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `chat.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `dash.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `german.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `git.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `home.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `ip.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `itilegent.ru` | — | — |
| `link.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `mail.dttb.ru` | 176.62.183.186 | 10.0.0.107 |
| `matrix.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `npm.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `office.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `omni.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `omni.umnybot.ru` | 158.255.0.139 | 158.255.0.139 |
| `plex.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `porteiner.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `pve.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `rec.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `remot.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `router.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `rustdesk.umnybot.ru` | 158.255.0.139 | 158.255.0.139 |
| `swarm.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `tg.umnybot.ru` | 158.255.0.139 | 158.255.0.139 |
| `umnybot.ru` | 158.255.0.139 | 158.255.0.139 |
| `unifi.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `vpn.dttb.ru` | — | 10.0.0.195 |
| `z.dttb.ru` | 176.62.183.186 | 10.0.0.195 |
| `zima.umnybot.ru` | 158.255.0.139 | 158.255.0.139 |
---
*Автоматически через `scripts/kb-audit-dns.py`.*

76
audit/2026-06-28-drift.md Normal file
View File

@@ -0,0 +1,76 @@
---
date: 2026-06-28
type: audit
source: kb-audit.py
tags: [audit, drift, infrastructure]
---
# KB drift audit — 2026-06-28
Сравнение живого `pct list` / `qm list` с [[../projects/dttb/proxmox-inventory|proxmox-inventory.md]]
- Живых гостей Proxmox: **47**
- Упомянуто в inventory: **46**
- В обоих: 46 / только в live: 1 / отсутствуют в live: 0
- Известны как удалённые: 0 (в `## 🗑️ Удалённые`)
## ⚠ В Proxmox есть, в inventory НЕТ (надо добавить)
| VMID | Type | Status | Name |
|---|---|---|---|
| 139 | LXC | running | severny-les |
## Полный живой список
| VMID | Type | Status | Name |
|---|---|---|---|
| 100 | VM | stopped | NV |
| 101 | LXC | stopped | n8n |
| 102 | LXC | stopped | SMB |
| 103 | LXC | running | NPM |
| 104 | VM | stopped | Agent-DVR |
| 105 | VM | stopped | Nextcloud-AIO-dttb.ru |
| 106 | VM | running | pbs |
| 107 | VM | running | Mailcow |
| 108 | LXC | stopped | zabbix |
| 109 | VM | stopped | itilelegent |
| 110 | VM | stopped | Cloud |
| 111 | VM | running | WinServer2025 |
| 112 | VM | running | cloud-dttb |
| 113 | LXC | running | VaultWarden |
| 114 | LXC | running | LinkWarden |
| 115 | LXC | running | watchyourlan |
| 116 | LXC | running | rustdeskserver |
| 117 | LXC | stopped | motioneye |
| 118 | LXC | stopped | plex |
| 119 | LXC | stopped | myspeed |
| 120 | VM | stopped | 7 |
| 121 | LXC | stopped | docker-windows |
| 122 | LXC | stopped | qbittorrent |
| 123 | LXC | stopped | proxmox-local |
| 124 | VM | stopped | Matrix |
| 125 | VM | stopped | datacentr |
| 126 | LXC | stopped | debian |
| 127 | VM | running | haos-17.0 |
| 128 | LXC | stopped | profi-parser |
| 129 | VM | stopped | profi-parser-vm |
| 130 | VM | running | Zima-OS |
| 131 | VM | stopped | ubuntu |
| 132 | LXC | running | code-server |
| 133 | VM | stopped | s1c-buzharovo |
| 134 | LXC | stopped | ZnamSecurityBot |
| 135 | LXC | running | swarmclaw |
| 136 | LXC | running | gitea |
| 137 | LXC | running | openclaw |
| 138 | LXC | stopped | vpn-proxy |
| 139 | LXC | running | severny-les |
| 140 | LXC | running | unifi |
| 141 | LXC | running | german |
| 142 | LXC | running | open-webui |
| 143 | LXC | running | amnezia-panel |
| 144 | LXC | running | authentik |
| 145 | LXC | running | homepage |
| 250 | VM | running | Nextcloud-AIO |
---
*Автоматически сгенерировано `scripts/kb-audit.py`. Применять правки — вручную после ревью.*

254
audit/2026-06-28-health.md Normal file
View File

@@ -0,0 +1,254 @@
---
date: 2026-06-28
type: audit
source: kb-health.py
score: 2800
tags: [audit, health, metric]
---
# KB health — 2026-06-28
**Score (меньше = лучше): `2800`**
Проверено файлов: 1754
## Разбивка
| Категория | Кол-во | Вес | Штраф |
|---|---:|---:|---:|
| broken_wikilinks | 31 | 10 | 310 |
| broken_paths | 171 | 10 | 1710 |
| missing_frontmatter | 25 | 3 | 75 |
| orphan_files | 68 | 2 | 136 |
| undated_todos | 534 | 1 | 534 |
| duplicate_basenames | 7 | 5 | 35 |
| **ИТОГО** | | | **2800** |
## Битые wikilinks
| Откуда | `[[таргет]]` |
|---|---|
| `decisions/2026-06-15-unifi-controller-homelab.md` | `[[feedback_dttb_dns_split_view]]` |
| `decisions/2026-06-26-authentik-sso-deploy.md` | `[[project_deapple_migration]]` |
| `decisions/2026-06-08-swarmclaw-lxc135-deploy.md` | `[[../snippets/spaceweb-dns-api]]` |
| `decisions/2026-05-26-omni-domain-and-update.md` | `[[feedback_spaceweb_dns_desync]]` |
| `decisions/2026-06-04-lipki-deco-p9-powerline-degradation.md` | `[[../claude-memory/feedback_lipki_deco_powerline]]` |
| `decisions/2026-05-23-glavtorg-autologon-off.md` | `[[feedback_vmware_workstation_session]]` |
| `decisions/2026-06-20-german-hermes-out-of-usage.md` | `[[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_omniroute_update]]` |
| `decisions/2026-06-20-german-hermes-out-of-usage.md` | `[[../../.claude/projects/-Users-ai-knowledge-base/memory/project_german_hermes]]` |
| `decisions/2026-06-20-german-hermes-out-of-usage.md` | `[[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_root_cause_recurring]]` |
| `decisions/2026-06-20-german-hermes-out-of-usage.md` | `[[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_root_cause_recurring]]` |
| `notes/claude/2026-06-22-045321-на-proxmox-homelab-установи-hermes-agent-я-его-буд.md` | `[[project_swarmclaw]]` |
| `notes/claude/2026-06-22-013250-на-proxmox-homelab-установи-hermes-agent-я-его-буд.md` | `[[feedback_antigravity_onboarding]]` |
| `projects/openwrt-4/credentials.md` | `[[../../.claude/projects/-Users-ai-knowledge-base/memory/reference_netbird_claude_diag]]` |
| `projects/dttb/proxmox-pve-147.md` | `[[../../claude-memory/project_alexandr_assistant]]` |
| `projects/dttb/finland-hostkey-vps.md` | `[[../../claude-memory/finland-vps-security]]` |
| `projects/benilux/kp-alexandr-umny-server.md` | `[[../../claude-memory/project_alexandr_assistant]]` |
| `projects/niikn/maul-pc.md` | `[[project_niikn_maxim_assistant]]` |
| `projects/niikn/maul-pc.md` | `[[../../snippets/netbird-claude-install.ps1]]` |
| `projects/niikn/maul-pc.md` | `[[../../snippets/clients/]]` |
| `projects/niikn/desktop-jt9qee4.md` | `[[../../snippets/netbird-claude-install.ps1]]` |
| `projects/niikn/desktop-35c8vmi.md` | `[[../../snippets/netbird-claude-install.ps1]]` |
| `projects/buzharovo/podkop-router.md` | `[[buzharovo-router]]` |
| `projects/buzharovo/podkop-router.md` | `[[reference_infra]]` |
| `projects/dttb/graphify-out/GRAPH_REPORT.md` | `[[_COMMUNITY_Community 0]]` |
| `projects/dttb/graphify-out/GRAPH_REPORT.md` | `[[_COMMUNITY_Community 1]]` |
| `projects/dttb/graphify-out/GRAPH_REPORT.md` | `[[_COMMUNITY_Community 2]]` |
| `projects/dttb/graphify-out/GRAPH_REPORT.md` | `[[_COMMUNITY_Community 3]]` |
| `snippets/podkop-reference.md` | `[[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_busybox_ip_br_flag\]]` |
| `snippets/podkop-reference.md` | `[[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_iphone_breaks_fakeip\]]` |
| `snippets/podkop-reference.md` | `[[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_root_cause_recurring]]` |
| `snippets/podkop-fakeip-diagnostics.md` | `[[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_openclaw_crash_loop]]` |
## Битые relative-пути
| Откуда | Путь |
|---|---|
| `decisions/2026-05-05-mac-dictation-groq-hammerspoon.md` | `../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_superwhisper_no_license.md` |
| `decisions/2026-05-05-mac-dictation-groq-hammerspoon.md` | `../../.claude/projects/-Users-ai-knowledge-base/memory/reference_groq_api.md` |
| `decisions/2026-05-05-mac-dictation-groq-hammerspoon.md` | `../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_superwhisper_no_license.md` |
| `notes/ru-geoblocked-services.md` | `../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_win11_unattended_upgrade.md` |
| `notes/ru-geoblocked-services.md` | `../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_nspd_blocks_mts.md` |
| `notes/claude/2026-06-23-185108-привет.md` | `projects/dttb/openwrt-router.md` |
| `notes/claude/2026-06-23-185108-привет.md` | `snippets/podkop-reference.md` |
| `notes/claude/2026-04-21-200915-охотхозяйство-с-openwrt-на-orange-pi-нужно-настрои.md` | `projects/dttb/vps-swtest.md` |
| `notes/claude/2026-05-21-102751-давай-проверим-openvrt-benelux.md` | `snippets/clients/alexandr-benelux-amnezia-reinstall.md` |
| `notes/claude/2026-04-24-194555-создай-учет-подключаемых-клиентов-со-всеми-данными.md` | `projects/dttb/credentials.md` |
| `notes/claude/2026-04-20-113423-найди-информацию-по-настройке-openwrt-и-podcop-в-н.md` | `decisions/2026-04-20-niikn-nspd-bypass-via-lionart.md` |
| `notes/claude/2026-04-28-122042-промт-для-claude-code-развёртывание-rustdesk-api-s.md` | `decisions/2026-04-28-rustdesk-lejianwen-pro-migration.md` |
| `notes/claude/2026-04-28-122042-промт-для-claude-code-развёртывание-rustdesk-api-s.md` | `projects/dttb/rustdesk.md` |
| `notes/claude/2026-04-28-122042-промт-для-claude-code-развёртывание-rustdesk-api-s.md` | `projects/dttb/credentials.md` |
| `notes/claude/2026-04-30-221054-найди-инфу-вчера-оксане-делали-доступ-через-рустде.md` | `projects/niikn/office-pc.md` |
| `notes/claude/2026-04-29-153123-сделай-красивую-ссылку-с-локацией-финляндия-для-ha.md` | `projects/dttb/proxmox-inventory.md` |
| `notes/claude/2026-04-29-153123-сделай-красивую-ссылку-с-локацией-финляндия-для-ha.md` | `projects/dttb/credentials.md` |
| `notes/claude/2026-05-29-234117-давай-проверим-openvrt-benelux.md` | `projects/dttb/proxmox-pve-147.md` |
| `notes/claude/2026-05-29-234117-давай-проверим-openvrt-benelux.md` | `projects/dttb/proxmox-inventory.md` |
| `notes/claude/2026-04-29-231939-сделай-красивую-ссылку-с-локацией-финляндия-для-ha.md` | `snippets/happ-routing-roscomvpn.md` |
| `notes/claude/2026-06-27-230948-httpsmaildttbrudomainadmin-можешь-найти-креды.md` | `projects/dttb/mailcow-dttb.md` |
| `notes/claude/2026-05-30-105828-давай-проверим-openvrt-benelux.md` | `projects/dttb/proxmox-pve-147.md` |
| `notes/claude/2026-04-24-194322-создай-учет-подключаемых-клиентов-со-всеми-данными.md` | `snippets/clients/yaroslav-amnezia-setup.md` |
| `notes/claude/2026-04-24-194322-создай-учет-подключаемых-клиентов-со-всеми-данными.md` | `snippets/apple-id-us-on-russia.md` |
| `notes/claude/2026-05-04-100627-можешь-составлять-графические-схемы-на-dttbruhttpd.md` | `projects/znamenskoye/network-topology-diagram.md` |
| `notes/claude/2026-04-20-115126-найди-информацию-по-настройке-openwrt-и-podcop-в-н.md` | `projects/mmfb/mikrotik.md` |
| `notes/claude/2026-04-20-115126-найди-информацию-по-настройке-openwrt-и-podcop-в-н.md` | `projects/niikn/mikrotik.md` |
| `notes/claude/2026-06-19-142423-10001-установи-обновление-sh-wget-o-httpsrawgithub.md` | `projects/dttb/credentials.md` |
| `notes/claude/2026-06-19-142423-10001-установи-обновление-sh-wget-o-httpsrawgithub.md` | `projects/dttb/proxmox-inventory.md` |
| `notes/claude/2026-04-24-165527-новый-клиент-ммфб-юрий-витальевич-нужно-подключить.md` | `projects/mmfb/yuri-vitalievich.md` |
| `notes/claude/2026-05-06-210824-superwhisper-можешь-проверить-не-работает.md` | `../knowledge-base/decisions/2026-05-05-mac-dictation-groq-hammerspoon.md` |
| `notes/claude/2026-06-11-235741-npm-api-креды-не-подходят-поищу-точные-логинпароль.md` | `projects/dttb/npm-proxy-hosts.md` |
| `notes/claude/2026-05-20-195902-давай-проверим-openvrt-benelux.md` | `decisions/2026-05-20-benelux-compromise.md` |
| `notes/claude/2026-05-28-131315-нужно-в-нетбирд-найти-и-настроить-подключение-к-эт.md` | `projects/niikn/maul-pc.md` |
| `notes/claude/2026-04-29-160010-сделай-красивую-ссылку-с-локацией-финляндия-для-ha.md` | `snippets/clients/yaroslav-happ-setup.md` |
| `notes/claude/2026-05-04-085317-можешь-составлять-графические-схемы-на-dttbruhttpd.md` | `projects/dttb/network-topology-diagram.md` |
| `notes/claude/2026-06-18-134919-добей-swarmclaw-по-хэндофу.md` | `snippets/podkop-agent-runbook.md` |
| `notes/claude/2026-05-21-104248-давай-проверим-openvrt-benelux.md` | `projects/benilux/credentials.md` |
| `notes/claude/2026-06-05-123547-давай-проверим-openvrt-benelux.md` | `decisions/2026-06-05-benelux-blackout-fw4-recovery.md` |
| `notes/claude/2026-04-29-071329-на-компе-юрия-продолжим-проверь-он-сети.md` | `projects/mmfb/otchet-yuri-2026-04.md` |
| `notes/claude/2026-05-23-133737-еще-клиент-ярослав-сервера-1с-главторг-жалуется-чт.md` | `projects/glavtorg/instruction-yaroslav-autologon.md` |
| `notes/claude/2026-05-27-191956-давай-проверим-openvrt-benelux.md` | `snippets/clients/alexandr-benelux-power-recovery.md` |
| `notes/claude/2026-04-21-203517-дай-мне-команду-в-сшел-виндовс-установка-нетбирд-и.md` | `/Users/ai/.claude/projects/-Users-ai-knowledge-base/memory/reference_netbird_claude_diag.md` |
| `notes/claude/2026-06-20-152229-npm-api-креды-не-подходят-поищу-точные-логинпароль.md` | `projects/backlog-current.md` |
| `notes/claude/2026-06-28-014229-httpsmaildttbrudomainadmin-можешь-найти-креды.md` | `projects/dttb/mailcow-dttb.md` |
| `notes/claude/2026-05-28-215219-102531240-администратор-ol260380eg-нужно-подключит.md` | `projects/mmfb/lionart-1c.md` |
| `notes/claude/2026-05-26-111148-нужно-на-omni-робуте-установить-ему-домен-у-тебя-е.md` | `memory/feedback_antigravity_onboarding.md` |
| `notes/claude/2026-05-26-111148-нужно-на-omni-робуте-установить-ему-домен-у-тебя-е.md` | `memory/MEMORY.md` |
| `notes/claude/2026-06-02-001742-есть-клиент-француз-у-него-есть-cudy-tr3000-с-podk.md` | `projects/openwrt-4/canal-plus-setup-runbook.md` |
| `notes/claude/2026-06-08-213054-найди-аналог-openclaw-для-меня-нужен-аркестратор-и.md` | `decisions/2026-06-08-swarmclaw-lxc135-deploy.md` |
| ... | +121 ещё |
## Без frontmatter (25)
- `decisions/2026-06-01-claude-remote-control-mobile.md`
- `decisions/2026-06-11-niikn-opyt-arhiv-100mb.md`
- `decisions/2026-05-05-mac-dictation-groq-hammerspoon.md`
- `notes/ru-geoblocked-services.md`
- `projects/dttb/znamenskoye-log.md`
- `projects/niikn/office-pc.md`
- `projects/niikn/_kbtmp_readme.md`
- `projects/niikn/kripto-arm.md`
- `projects/niikn/_kbtmp_claude.md`
- `projects/mmfb/yuri-vitalievich.md`
- `projects/mmfb/otchet-yuri-2026-04.md`
- `projects/dttb/graphify-out/GRAPH_REPORT.md`
- `snippets/happ-vpn-client-instruction.md`
- `snippets/invoice-template.md`
- `snippets/assets/happ-routing-roscomvpn/README-upstream.md`
- `claude-memory/servicedesk-dttb.md`
- `claude-memory/benelux.md`
- `claude-memory/nextcloud-dttb.md`
- `claude-memory/nvr-fix.md`
- `claude-memory/videonablyudenie.md`
- `claude-memory/znamenskoe-home.md`
- `claude-memory/niikn-nextcloud.md`
- `claude-memory/krasnogorsk.md`
- `claude-memory/mas-niikn.md`
- `claude-memory/MEMORY.md`
## Orphan — без бэклинков (68)
_Эти файлы никто не упоминает через `[[..]]`. Кандидаты на удаление или добавление ссылок._
- `decisions/2026-05-14-buzharovo-watchdog-public-only.md`
- `decisions/2026-04-30-niikn-culture-gov-fakeip-fix.md`
- `decisions/2026-06-01-claude-remote-control-mobile.md`
- `decisions/2026-06-17-niikn-deco-p9-backhaul-degradation.md`
- `decisions/2026-05-26-server-upgrade-z6-g4.md`
- `decisions/2026-06-27-benelux-foreign-banks-eu-exit.md`
- `decisions/2026-06-21-buzharovo-mcp-1c-deploy.md`
- `decisions/2026-04-20-niikn-nspd-bypass-via-lionart.md`
- `decisions/2026-06-11-niikn-opyt-arhiv-100mb.md`
- `decisions/2026-06-04-deapple-migration-roadmap.md`
- `decisions/2026-04-28-netbird-watchdog-lxc-132-137.md`
- `decisions/2026-05-05-mac-dictation-groq-hammerspoon.md`
- `decisions/2026-05-23-glavtorg-autologon-off.md`
- `decisions/2026-06-08-finland-vless-happ-dns-diag.md`
- `decisions/2026-05-08-buzharovo-1c-licensing-options.md`
- `decisions/2026-05-06-kb-search-overhaul.md`
- `decisions/2026-04-28-niikn-uookn-sev-gov-fakeip-fix.md`
- `decisions/2026-06-20-german-hermes-out-of-usage.md`
- `notes/ru-geoblocked-services.md`
- `projects/openwrt-4/STATUS-2026-06-03-eod.md`
- `projects/openwrt-4/session-handoff-2026-06-02.md`
- `projects/openwrt-4/client-letter.md`
- `projects/dttb/network-topology-diagram.md`
- `projects/glavtorg/instruction-yaroslav-autologon.md`
- `projects/benilux/kp-alexandr-umny-server.md`
- `projects/niikn/mailcow.md`
- `projects/niikn/NIIKN-Infrastructure.md`
- `projects/niikn/credentials.md`
- `projects/niikn/changelog.md`
- `projects/niikn/_kbtmp_tpl_decision.md`
- ... +38 ещё
## TODO без даты (534 шт в 99 файлах)
- `projects/backlog-current.md` — 39 шт
- `decisions/2026-06-04-deapple-migration-roadmap.md` — 13 шт
- `decisions/2026-04-30-rustdesk-pre-prod-audit.md` — 13 шт
- `projects/lipki/README.md` — 11 шт
- `templates/vpn-client.md` — 7 шт
- `decisions/2026-05-26-server-upgrade-z6-g4.md` — 6 шт
- `decisions/2026-04-29-rustdesk-client-deployment-package.md` — 6 шт
- `projects/buzharovo/severny-les-bot.md` — 6 шт
- `notes/claude/2026-05-30-223109-session.md` — 5 шт
- `notes/claude/2026-05-31-230412-session.md` — 5 шт
- `notes/claude/2026-06-01-115908-session.md` — 5 шт
- `notes/claude/2026-05-31-212135-session.md` — 5 шт
- `notes/claude/2026-05-31-150934-session.md` — 5 шт
- `notes/claude/2026-06-15-203254-session.md` — 5 шт
- `notes/claude/2026-05-30-143711-session.md` — 5 шт
- `notes/claude/2026-05-31-232509-session.md` — 5 шт
- `notes/claude/2026-06-08-161105-session.md` — 5 шт
- `notes/claude/2026-06-07-235211-session.md` — 5 шт
- `notes/claude/2026-06-08-160130-session.md` — 5 шт
- `notes/claude/2026-06-08-002741-session.md` — 5 шт
## Дубликаты имён (7)
- `README.md`:
- `README.md`
- `decisions/README.md`
- `notes/README.md`
- `projects/znamenskoye/README.md`
- `projects/openwrt-4/README.md`
- `projects/dttb/README.md`
- `projects/glavtorg/README.md`
- `projects/benilux/README.md`
- `projects/vishnevyy-sad/README.md`
- `projects/sergey/README.md`
- `projects/niikn/README.md`
- `projects/lipki/README.md`
- `projects/krasnogorsk/README.md`
- `projects/mmfb/README.md`
- `projects/buzharovo/README.md`
- `projects/peredelki/README.md`
- `projects/zelenograd/README.md`
- `projects/dttb/nextcloud-talk-bot/README.md`
- `snippets/README.md`
- `snippets/mac-dictation/README.md`
- `scripts/README.md`
- `nextcloud.md`:
- `projects/nextcloud.md`
- `projects/dttb/nextcloud.md`
- `network-topology-diagram.md`:
- `projects/znamenskoye/network-topology-diagram.md`
- `projects/dttb/network-topology-diagram.md`
- `projects/niikn/network-topology-diagram.md`
- `credentials.md`:
- `projects/openwrt-4/credentials.md`
- `projects/dttb/credentials.md`
- `projects/benilux/credentials.md`
- `projects/niikn/credentials.md`
- `projects/peredelki/credentials.md`
- `projects/dttb/ai-assistant-pilot/credentials.md`
- `proxmox-inventory.md`:
- `projects/dttb/proxmox-inventory.md`
- `projects/mmfb/proxmox-inventory.md`
- `server1c.md`:
- `projects/dttb/server1c.md`
- `projects/buzharovo/server1c.md`
- `mikrotik.md`:
- `projects/niikn/mikrotik.md`
- `projects/mmfb/mikrotik.md`
---
*Генерируется `scripts/kb-health.py`. JSON-версия в `audit/health-latest.json` для agent-loop.*

View File

@@ -0,0 +1,80 @@
---
date: 2026-06-28
type: audit
source: kb-audit-npm.py
tags: [audit, drift, npm]
---
# NPM drift audit — 2026-06-28
Сверка [[../projects/dttb/npm-proxy-hosts|npm-proxy-hosts.md]] с NPM API (https://npm.dttb.ru).
- Живых proxy hosts: **35**
- В KB: **31**
- Совпадений: 31 / новых: 4 / удалённых из NPM: 0 / с изменениями: 4
## ⚠ Новые hosts (в NPM есть, в KB нет)
| ID | Домены | Backend | SSL | Enabled |
|---|---|---|---|---|
| 26 | `router.dttb.ru` | `10.0.0.1:8080` | ✓ | on |
| 27 | `vpn.dttb.ru` | `10.0.0.141:8443` | - | on |
| 35 | `ai.umnybot.ru` | `10.0.0.239:9119` | ✓ | on |
| 37 | `umnybot.ru` | `10.0.0.103:3456` | - | on |
## 🔄 Изменения (ID совпадает, но что-то сменилось)
### #12 `bitrix24.dttb.ru`
- backend: KB=`10.0.0.223:8080` → live=`10.0.0.224:8080`
### #14 `remot.dttb.ru`
- backend: KB=`10.0.0.43:21114` → live=`10.0.0.244:21114`
### #22 `git.dttb.ru`
- ssl: KB=✗ → live=✓
### #33 `tg.umnybot.ru`
- backend: KB=`10.0.0.190:3000` → live=`10.0.0.221:80`
## Полный живой список
| ID | Домены | Backend | SSL | Enabled |
|---|---|---|---|---|
| 1 | `dttb.ru` | `10.0.0.230:11001` | ✓ | on |
| 2 | `office.dttb.ru` | `10.0.0.169:8080` | ✓ | on |
| 3 | `itilegent.ru` | `10.0.0.223:8080` | ✓ | on |
| 4 | `npm.dttb.ru` | `10.0.0.195:81` | ✓ | on |
| 5 | `porteiner.dttb.ru` | `10.0.0.10:9443` | ✓ | on |
| 6 | `pve.dttb.ru` | `10.0.0.250:8006` | ✓ | on |
| 9 | `ai.dttb.ru` | `10.0.0.179:8080` | ✓ | on |
| 10 | `bit.dttb.ru` | `10.0.0.217:8080` | ✓ | on |
| 11 | `link.dttb.ru` | `10.0.0.184:3000` | ✓ | on |
| 12 | `bitrix24.dttb.ru` | `10.0.0.224:8080` | ✓ | on |
| 13 | `ip.dttb.ru` | `10.0.0.112:8840` | ✓ | on |
| 14 | `remot.dttb.ru` | `10.0.0.244:21114` | ✓ | on |
| 15 | `plex.dttb.ru` | `10.0.0.200:32400` | ✓ | on |
| 16 | `home.dttb.ru` | `10.0.0.155:8123` | ✓ | on |
| 17 | `z.dttb.ru` | `10.0.0.220:80` | ✓ | on |
| 21 | `rec.dttb.ru` | `10.0.0.227:8091` | ✓ | on |
| 22 | `git.dttb.ru` | `10.0.0.189:3000` | ✓ | on |
| 23 | `matrix.dttb.ru` | `10.0.0.224:8080` | ✓ | on |
| 25 | `mail.dttb.ru` | `10.0.0.107:443` | ✓ | on |
| 26 | `router.dttb.ru` | `10.0.0.1:8080` | ✓ | on |
| 27 | `vpn.dttb.ru` | `10.0.0.141:8443` | - | on |
| 28 | `bot.dttb.ru` | `10.0.0.239:18789` | ✓ | on |
| 29 | `omni.dttb.ru` | `10.0.0.179:20128` | ✓ | on |
| 30 | `omni.umnybot.ru` | `10.0.0.163:20128` | ✓ | on |
| 31 | `zima.umnybot.ru` | `10.0.0.190:80` | ✓ | on |
| 32 | `swarm.dttb.ru` | `10.0.0.135:3456` | ✓ | on |
| 33 | `tg.umnybot.ru` | `10.0.0.221:80` | ✓ | on |
| 34 | `rustdesk.umnybot.ru` | `10.0.0.190:3005` | ✓ | on |
| 35 | `ai.umnybot.ru` | `10.0.0.239:9119` | ✓ | on |
| 36 | `unifi.dttb.ru` | `10.0.0.196:8443` | ✓ | on |
| 37 | `umnybot.ru` | `10.0.0.103:3456` | - | on |
| 39 | `chat.dttb.ru` | `10.0.0.142:3000` | ✓ | on |
| 40 | `german.dttb.ru` | `10.0.0.141:9119` | ✓ | on |
| 41 | `auth.dttb.ru` | `10.0.0.144:9000` | ✓ | on |
| 42 | `dash.dttb.ru` | `10.0.0.148:3000` | ✓ | on |
---
*Автоматически через `scripts/kb-audit-npm.py`.*

View File

@@ -0,0 +1,67 @@
---
date: 2026-06-28
type: audit
source: scripts/kb-objects-audit.py
tags: [audit, objects, frontmatter, links]
score: 99
---
# KB objects audit — 2026-06-28
**Score (меньше = лучше): `99`**
- Проектов с frontmatter: **14/14** (0 проблем)
- NetBird online-пиров без проектной карточки: **3**
- Битых wiki-ссылок `[[...]]`: **31**
## Frontmatter в projects/
✅ все проекты имеют валидный frontmatter
## Online netbird-пиры без проектной карточки
Эти пиры онлайн в NetBird, но не привязаны ни к одной projects/-странице.
Бот не сможет ответить «найди X» осмысленно — нет файла или alias.
Лечение: либо создать stub в `projects/<slug>/README.md` (см. `projects/lipki/` как образец),
либо добавить имя пира как полную строку в `aliases` подходящего проекта.
| NetBird-имя | IP | OS | Город |
|---|---|---|---|
| `DESKTOP-2IOQS54` | 100.70.82.83 | Windows 10 | Saransk |
| `DESKTOP-AGBMLPN` | 100.70.0.106 | Windows 11 | Helsinki |
| `DESKTOP-HL0BB05` | 100.70.235.80 | Windows 11 | Lipetsk |
## Битые wiki-ссылки
- [snippets/podkop-reference.md](snippets/podkop-reference.md) — `[[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_busybox_ip_br_flag\|памятка]]` → нет такого файла
- [snippets/podkop-reference.md](snippets/podkop-reference.md) — `[[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_iphone_breaks_fakeip\|памятка]]` → нет такого файла
- [snippets/podkop-reference.md](snippets/podkop-reference.md) — `[[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_root_cause_recurring|памятка: корень vs band-aid]]` → нет такого файла
- [snippets/podkop-fakeip-diagnostics.md](snippets/podkop-fakeip-diagnostics.md) — `[[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_openclaw_crash_loop|памятку про sing-box crash-loop]]` → нет такого файла
- [decisions/2026-06-15-unifi-controller-homelab.md](decisions/2026-06-15-unifi-controller-homelab.md) — `[[feedback_dttb_dns_split_view]]` → нет такого файла
- [decisions/2026-06-26-authentik-sso-deploy.md](decisions/2026-06-26-authentik-sso-deploy.md) — `[[project_deapple_migration]]` → нет такого файла
- [decisions/2026-06-08-swarmclaw-lxc135-deploy.md](decisions/2026-06-08-swarmclaw-lxc135-deploy.md) — `[[../snippets/spaceweb-dns-api]]` → нет такого файла
- [decisions/2026-05-26-omni-domain-and-update.md](decisions/2026-05-26-omni-domain-and-update.md) — `[[feedback_spaceweb_dns_desync]]` → нет такого файла
- [decisions/2026-06-04-lipki-deco-p9-powerline-degradation.md](decisions/2026-06-04-lipki-deco-p9-powerline-degradation.md) — `[[../claude-memory/feedback_lipki_deco_powerline]]` → нет такого файла
- [decisions/2026-05-23-glavtorg-autologon-off.md](decisions/2026-05-23-glavtorg-autologon-off.md) — `[[feedback_vmware_workstation_session]]` → нет такого файла
- [decisions/2026-06-20-german-hermes-out-of-usage.md](decisions/2026-06-20-german-hermes-out-of-usage.md) — `[[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_omniroute_update]]` → нет такого файла
- [decisions/2026-06-20-german-hermes-out-of-usage.md](decisions/2026-06-20-german-hermes-out-of-usage.md) — `[[../../.claude/projects/-Users-ai-knowledge-base/memory/project_german_hermes]]` → нет такого файла
- [decisions/2026-06-20-german-hermes-out-of-usage.md](decisions/2026-06-20-german-hermes-out-of-usage.md) — `[[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_root_cause_recurring]]` → нет такого файла
- [decisions/2026-06-20-german-hermes-out-of-usage.md](decisions/2026-06-20-german-hermes-out-of-usage.md) — `[[../../.claude/projects/-Users-ai-knowledge-base/memory/feedback_root_cause_recurring]]` → нет такого файла
- [projects/openwrt-4/credentials.md](projects/openwrt-4/credentials.md) — `[[../../.claude/projects/-Users-ai-knowledge-base/memory/reference_netbird_claude_diag|памятка]]` → нет такого файла
- [projects/dttb/proxmox-pve-147.md](projects/dttb/proxmox-pve-147.md) — `[[../../claude-memory/project_alexandr_assistant]]` → нет такого файла
- [projects/dttb/finland-hostkey-vps.md](projects/dttb/finland-hostkey-vps.md) — `[[../../claude-memory/finland-vps-security]]` → нет такого файла
- [projects/benilux/kp-alexandr-umny-server.md](projects/benilux/kp-alexandr-umny-server.md) — `[[../../claude-memory/project_alexandr_assistant]]` → нет такого файла
- [projects/niikn/maul-pc.md](projects/niikn/maul-pc.md) — `[[project_niikn_maxim_assistant|Максима Мауля]]` → нет такого файла
- [projects/niikn/maul-pc.md](projects/niikn/maul-pc.md) — `[[../../snippets/netbird-claude-install.ps1]]` → нет такого файла
- [projects/niikn/maul-pc.md](projects/niikn/maul-pc.md) — `[[rustdesk\|lejianwen-pro LXC 116]]` → нет такого файла
- [projects/niikn/maul-pc.md](projects/niikn/maul-pc.md) — `[[../../snippets/clients/|метод]]` → нет такого файла
- [projects/niikn/desktop-jt9qee4.md](projects/niikn/desktop-jt9qee4.md) — `[[../../snippets/netbird-claude-install.ps1]]` → нет такого файла
- [projects/niikn/desktop-jt9qee4.md](projects/niikn/desktop-jt9qee4.md) — `[[rustdesk\|lejianwen-pro LXC 116]]` → нет такого файла
- [projects/niikn/desktop-35c8vmi.md](projects/niikn/desktop-35c8vmi.md) — `[[../../snippets/netbird-claude-install.ps1]]` → нет такого файла
- [projects/niikn/desktop-35c8vmi.md](projects/niikn/desktop-35c8vmi.md) — `[[rustdesk\|lejianwen-pro LXC 116]]` → нет такого файла
- [projects/niikn/_kbtmp_claude.md](projects/niikn/_kbtmp_claude.md) — `[[двойные скобки]]` → нет такого файла
- [projects/buzharovo/podkop-router.md](projects/buzharovo/podkop-router.md) — `[[buzharovo-router|Cudy WR6500H 185.13.47.2]]` → нет такого файла
- [projects/buzharovo/podkop-router.md](projects/buzharovo/podkop-router.md) — `[[reference_infra]]` → нет такого файла
- [notes/claude/2026-06-22-045321-на-proxmox-homelab-установи-hermes-agent-я-его-буд.md](notes/claude/2026-06-22-045321-на-proxmox-homelab-установи-hermes-agent-я-его-буд.md) — `[[project_swarmclaw]]` → нет такого файла
- [notes/claude/2026-06-22-013250-на-proxmox-homelab-установи-hermes-agent-я-его-буд.md](notes/claude/2026-06-22-013250-на-proxmox-homelab-установи-hermes-agent-я-его-буд.md) — `[[feedback_antigravity_onboarding]]` → нет такого файла

View File

@@ -0,0 +1,124 @@
---
date: 2026-06-28
type: audit-proposed
source: kb-audit-propose.sh (Opus 4.7)
tags: [audit, proposed, inventory]
---
# Предложенные правки inventory — 2026-06-28
Сгенерировано Claude Opus на основе [[2026-06-28-drift|drift-отчёта]].
**Правки НЕ применены.** Ревью — ты. Apply — вручную.
Данные у меня все есть прямо в задании (оба файла inline), править ничего не нужно — выдаю анализ.
## 1. Резюме
Живых гостей 47, в inventory корректно отражено меньше. Аудит явно поймал только **LXC 139 severny-les** (нет в inventory), но сверка полного live-списка с inventory вскрывает ещё несколько расхождений: два запущенных VM (112, 130) числятся остановленными; два VMID из раздела «Удалённые» (129, 133) переиспользованы и снова живы; VMID 135 задвоен (running + Удалённые); сводная таблица и счётчики устарели (42→47).
## 2. Конкретные правки
### A. Добавить LXC 139 (флаг аудита) — раздел «🟢 Запущенные LXC»
```diff
+### LXC 139 — severny-les
+| Параметр | Значение |
+|----------|----------|
+| Статус | 🟢 running |
+| IP | (уточнить) |
+| Назначение | (уточнить) |
```
> В drift-отчёте только VMID/type/status/name. IP и назначение не выдумываю — пометил «уточнить».
### B. VM 112 cloud-dttb: stopped → running
Live: `112 VM running cloud-dttb`. В inventory он в таблице «🔴 Остановленные VM».
```diff
@@ Остановленные VM (QEMU) @@
-| 112 | cloud-dttb | 8 | 16 GB | 80 GB | — |
```
И добавить блок в «🟢 Запущенные VM»:
```diff
+### VM 112 — cloud-dttb
+| Параметр | Значение |
+|----------|----------|
+| Статус | 🟢 running |
+| CPU | 8 vCPU |
+| RAM | 16 GB |
+| Диск | 80 GB |
+| Назначение | (уточнить) |
```
### C. VM 130 Zima-OS: stopped → running
Live: `130 VM running Zima-OS`. В inventory — в остановленных (детали есть: IP 10.0.0.221).
```diff
@@ Остановленные VM (QEMU) @@
-| 130 | Zima-OS | 4 | 12 GB | 32 GB | ZimaOS NAS — 10.0.0.221, веб `dttb`/`1qaz!QAZ` (см. credentials) |
```
```diff
+### VM 130 — Zima-OS
+| Параметр | Значение |
+|----------|----------|
+| Статус | 🟢 running |
+| CPU | 4 vCPU |
+| RAM | 12 GB |
+| Диск | 32 GB |
+| IP | 10.0.0.221 (веб `dttb`/`1qaz!QAZ`, см. credentials) |
+| Назначение | ZimaOS NAS |
```
### D. VM 129 profi-parser-vm — VMID переиспользован (см. предупреждения)
Live: `129 VM stopped profi-parser-vm`. В inventory 129 числится только в «🗑️ Удалённые» как Clawdbot.
Добавить в «🔴 Остановленные VM»:
```diff
+| 129 | profi-parser-vm | — | — | — | VM-пара к LXC 128 profi-parser (уточнить) |
```
Аннотировать историческую строку (VMID переиспользован):
```diff
@@ 🗑️ Удалённые (история) @@
-| 129 | Clawdbot | ~апрель 2026 | Данные перенесены на code-server (132) ... |
+| 129 | Clawdbot | ~апрель 2026 | Данные на code-server (132) `/root/backup-lxc129/`. ⚠️ VMID 129 переиспользован под VM profi-parser-vm |
```
### E. VM 133 s1c-buzharovo — VMID переиспользован
Live: `133 VM stopped s1c-buzharovo`. В inventory 133 только в «Удалённые» как clawdbot-1.
```diff
+| 133 | s1c-buzharovo | — | — | — | (уточнить; вероятно 1С Бужарово) |
```
```diff
@@ 🗑️ Удалённые (история) @@
-| 133 | clawdbot-1 | ~апрель 2026 | Функционал мигрирован на openclaw (137) |
+| 133 | clawdbot-1 | ~апрель 2026 | Мигрирован на openclaw (137). ⚠️ VMID 133 переиспользован под VM s1c-buzharovo |
```
### F. VMID 135 задвоен
Live: `135 LXC running swarmclaw` (в inventory корректный блок уже есть). Но 135 также висит в «Удалённые» как whisper-bot.
```diff
@@ 🗑️ Удалённые (история) @@
-| 135 | whisper-bot | ~апрель 2026 | — |
+| 135 | whisper-bot | ~апрель 2026 | удалён; ⚠️ VMID 135 переиспользован под LXC swarmclaw |
```
### G. Обновить «Сводка»
```diff
-| QEMU VM | 15 | 5 | 10 |
-| LXC | 27 | 17 | 10 |
-| **Итого** | **42** | **22** | **20** |
+| QEMU VM | 18 | 7 | 11 |
+| LXC | 29 | 17 | 12 |
+| **Итого** | **47** | **24** | **23** |
```
> Пересчёт по live-списку: VM 18 (7 running/11 stopped), LXC 29 (17 running/12 stopped).
### H. Обновить шапку
```diff
-> Последнее обновление: 2026-06-27 (добавлен LXC 145 homepage ...)
+> Последнее обновление: 2026-06-28 (drift-аудит: +LXC 139 severny-les; 112/130 → running; VMID 129/133/135 переиспользованы)
```
## 3. Предупреждения
- **Аудит занизил drift.** `kb-audit.py` сверяет только наличие VMID (упомянут/нет), а не статус и не роль. Поэтому он показал «46/46 совпало» и поймал лишь 139 — расхождения по статусу (112, 130) и переиспользованные VMID (129, 133, 135) скрипт не видит. Стоит доработать аудит на сверку status/name.
- **Переиспользование VMID (129, 133, 135).** Не из выдумки — прямо из live-списка отчёта: 129=profi-parser-vm, 133=s1c-buzharovo, 135=swarmclaw, тогда как в «Удалённые» те же VMID = Clawdbot/clawdbot-1/whisper-bot. Это разные сущности на одном номере. Я предложил **сохранить историю** + пометку, а не удалять строки. Реши, как вести: возможно, в «Удал될» лучше указывать дату и не держать сырой VMID, который потом переиспользуется.
- **Нет данных для деталей.** Для 139, 112, 129, 133 в отчёте нет IP/CPU/RAM/назначения — везде проставил «уточнить», ничего не сочинял. Для 130 детали взял из существующей строки inventory.
- **s1c-buzharovo** по имени похоже на 1С-сервер Бужарово (в памяти есть проект роутера Бужарово), но в отчёте подтверждения роли нет — поэтому «вероятно», не факт.
Если хочешь, могу применить эти правки к `proxmox-inventory.md` (тогда выйди из plan mode или дай добро).

View File

@@ -1,13 +1,13 @@
{ {
"date": "2026-06-21", "date": "2026-06-28",
"score": 2285, "score": 2800,
"counts": { "counts": {
"broken_wikilinks": 23, "broken_wikilinks": 31,
"broken_paths": 132, "broken_paths": 171,
"missing_frontmatter": 23, "missing_frontmatter": 25,
"orphan_files": 62, "orphan_files": 68,
"undated_todos": 512, "undated_todos": 534,
"duplicate_basenames": 6 "duplicate_basenames": 7
}, },
"weights": { "weights": {
"broken_wikilinks": 10, "broken_wikilinks": 10,
@@ -17,5 +17,5 @@
"undated_todos": 1, "undated_todos": 1,
"duplicate_basenames": 5 "duplicate_basenames": 5
}, },
"files_scanned": 1431 "files_scanned": 1754
} }

View File

@@ -15,9 +15,8 @@
## VPN / Подкоп (Podkop v0.7.14) ## VPN / Подкоп (Podkop v0.7.14)
- sing-box 1.12.22, статус: running - sing-box 1.12.22, статус: running
- Секция main: VPN через awg0 (AmneziaWG); списки `russia_inside`,`telegram`,`meta`; `user_domains` (dynamic): `githubusercontent.com` + **иностранные сервисы клиента** `vodafone.es`,`edf.fr`,`emiratesnbd.com`,`mabanque.bnpparibas`,`connexion-mabanque.bnpparibas` (добавлены 2026-06-27 — шли мимо туннеля российским WAN-IP, иностранные банки гео/санкц-блок: BNP 403, EDF 503, ENBD 403; через выход → 200/404) - Секция main: VPN через awg0 (AmneziaWG), список russia_inside
- Секция Vless: прокси VLESS (202.71.12.186:443, Reality) - Секция Vless: прокси VLESS-Singapore (202.71.12.186:443, Reality)
- **EXIT = Финляндия/Hostkey** (`202.71.12.186`, ip-api: Helsinki, Hostkey B.V.) — НЕ Сингапур, как писалось в старых доках («VLESS-Singapore»). EU-выход — то, что нужно для ES/FR/AE-сайтов клиента.
- DNS: DoH (https://common.dot.dns.yandex.net/dns-query), bootstrap: 77.88.8.8 - DNS: DoH (https://common.dot.dns.yandex.net/dns-query), bootstrap: 77.88.8.8
- ВАЖНО: DNS переключён с UDP на DoH, т.к. домашний роутер (10.0.0.1) перехватывает порт 53 и имеет свой подкоп — двойная обработка вызывала context deadline exceeded - ВАЖНО: DNS переключён с UDP на DoH, т.к. домашний роутер (10.0.0.1) перехватывает порт 53 и имеет свой подкоп — двойная обработка вызывала context deadline exceeded
- FakeIP: 198.18.0.0/15, работает - FakeIP: 198.18.0.0/15, работает

View File

@@ -0,0 +1,33 @@
---
date: 2026-06-27
type: claude-session
session_id: cf0fcbca-45e5-4c86-9af4-0126868e3b68
started: 2026-06-26T20:32:39.557Z
ended: 2026-06-27T19:12:31.306Z
messages: 7
tools: [AskUserQuestion, Bash, Edit, Read, TaskOutput, TaskStop, ToolSearch, Workflow, Write, mcp__ccd_session__spawn_task]
tags: [claude, session]
---
# https://gethomepage.dev/widgets/services/nextcloud/ если все мои сервисы собрать
## Запрос
https://gethomepage.dev/widgets/services/nextcloud/ если все мои сервисы собрать как думаешь?
## Итог (последний ответ Claude, до 500 симв.)
Готово. `dash.dttb.ru` → 200, закоммичено.
## Группа «OpenWrt роутеры» — все 10
Веерный скан vault (6 читателей по регионам + сведение) собрал все OpenWrt-роутеры. Пингую каждый по NetBird с дашборда:
**Онлайн (7):** Дом, Sergey, Lipki, Benelux, НИИКН-VM101, Бужарово Сев.лес, Знаменское-3
**Down (3):** Olivier (Canal+), Переделки (vault помечал «возможно offline с 08.05»), Красногорск
Каждая плитка — статус + клик на LuCI. Домашний мониторю по LAN `10.0.0.1` (его NetBird-адрес не отвечает).
---
*Автосохранено из session [`cf0fcbca`](file:///Users/ai/.claude/projects/-Users-ai-knowledge-base/cf0fcbca-45e5-4c86-9af4-0126868e3b68.jsonl) — 7 сообщ., тулы: AskUserQuestion, Bash, Edit, Read, TaskOutput, TaskStop, ToolSearch, Workflow, Write, mcp__ccd_session__spawn_task*

View File

@@ -0,0 +1,27 @@
---
date: 2026-06-27
type: claude-session
session_id: ac82ac49-7dd6-476e-9fd0-e10687c8867c
started: 2026-06-27T19:43:29.595Z
ended: 2026-06-27T20:05:18.062Z
messages: 2
tools: [Bash]
tags: [claude, session]
---
# https://mail.dttb.ru/domainadmin/ можешь найти креды
## Запрос
https://mail.dttb.ru/domainadmin/ можешь найти креды
## Итог (последний ответ Claude, до 500 симв.)
Подтвердилось — вот корень:
**`@zone[0] name=lan masq=1`** — на LAN-зоне роутера включён masquerade. Входящее письмо идёт `WAN:25 → DNAT → 10.0.0.107`, пакет уходит в LAN-зону, и из-за `masq=1` роутер подменяет source на свой `10.0.0.1`. Поэтому mailcow видит `10.0.0.1` вместо реального IP отправителя — отсюда RDNS_NONE + HFILTER_HOSTNAME_UNKNOWN на всём и R_SPF_FAIL для строгих.
То есть это **не про `support@`** — бьёт по всем входящим сервера. `support@` просто новый: Bayes не выучил ham, и
---
*Автосохранено из session [`ac82ac49`](file:///Users/ai/.claude/projects/-Users-ai-knowledge-base/ac82ac49-7dd6-476e-9fd0-e10687c8867c.jsonl) — 2 сообщ., тулы: Bash*

View File

@@ -0,0 +1,29 @@
---
date: 2026-06-27
type: claude-session
session_id: ac82ac49-7dd6-476e-9fd0-e10687c8867c
started: 2026-06-27T19:43:29.595Z
ended: 2026-06-27T20:09:48.676Z
messages: 3
tools: [Bash, Edit, Read]
tags: [claude, session]
---
# https://mail.dttb.ru/domainadmin/ можешь найти креды
## Запрос
https://mail.dttb.ru/domainadmin/ можешь найти креды
## Итог (последний ответ Claude, до 500 симв.)
Готово. Записал корень и фикс в [mailcow-dttb.md](projects/dttb/mailcow-dttb.md) (auto-sync на code-server закоммитит).
## Итог
**Причина:** на домашнем роутере `10.0.0.1` LAN-зона была с `masq=1` — входящая почта `WAN:25 → 10.0.0.107` SNAT'илась в `10.0.0.1`, и сервер видел этот адрес как отправителя **всех** писем. Отсюда `RDNS_NONE + HFILTER_HOSTNAME_UNKNOWN` (+10.5) на каждом входящем. Новый `support@` тонул, старый ящик вытягивал обученный Bayes.
**Сделано:** точечное правило `No-SNAT-to
---
*Автосохранено из session [`ac82ac49`](file:///Users/ai/.claude/projects/-Users-ai-knowledge-base/ac82ac49-7dd6-476e-9fd0-e10687c8867c.jsonl) — 3 сообщ., тулы: Bash, Edit, Read*

View File

@@ -0,0 +1,31 @@
---
date: 2026-06-27
type: claude-session
session_id: ac82ac49-7dd6-476e-9fd0-e10687c8867c
started: 2026-06-27T19:43:29.595Z
ended: 2026-06-27T20:55:10.007Z
messages: 5
tools: [Bash, Edit, Read, Write]
tags: [claude, session]
---
# https://mail.dttb.ru/domainadmin/ можешь найти креды
## Запрос
https://mail.dttb.ru/domainadmin/ можешь найти креды
## Итог (последний ответ Claude, до 500 симв.)
Готово по обоим фронтам.
## SSL (твоя задача)
Сертификат на почтовых портах был просрочен с 2 июня — клиенты IMAP/SMTP на него и ругались. Заменил на свежий из NPM (до 1 авг), поставил авто-синхрон cron'ом, чтобы не повторилось. Все порты (25/465/587/993/995) отдают валидный cert. Web был в порядке.
→ как соберёшься — кинь письмо с Яндекса на `support@dttb.ru`, проверю score (это с прошлой задачи про спам).
## MEMORY.md (по требованию хука)
Индекс памяти раздулся до ~28.8 КБ (близко к лимиту
---
*Автосохранено из session [`ac82ac49`](file:///Users/ai/.claude/projects/-Users-ai-knowledge-base/ac82ac49-7dd6-476e-9fd0-e10687c8867c.jsonl) — 5 сообщ., тулы: Bash, Edit, Read, Write*

View File

@@ -0,0 +1,29 @@
---
date: 2026-06-28
type: claude-session
session_id: ac82ac49-7dd6-476e-9fd0-e10687c8867c
started: 2026-06-27T19:43:29.595Z
ended: 2026-06-27T21:26:28.486Z
messages: 5
tools: [AskUserQuestion, Bash, Edit, Read, Write]
tags: [claude, session]
---
# https://mail.dttb.ru/domainadmin/ можешь найти креды
## Запрос
https://mail.dttb.ru/domainadmin/ можешь найти креды
## Итог (последний ответ Claude, до 500 симв.)
Готово. mailcow обновлён и проверен.
## Что сделано
- **Снапшот** `pre_update_20260627` (откат: `qm rollback 107 pre_update_20260627`) — удали через недельку стабильной работы.
- **Обновление `2026-01``2026-05c`** через `./update.sh -f`. Перед запуском откатил локальные правки конфигов (иначе merge-конфликт), после — проверил.
- **SSL уцелел**: наш cert (до 1 авг) на всех портах, cron-синхрон жив.
- **forward-zone unbound (8.8.8.8) убрал осознанно**: новый unbound резолвит рекурсивно, а forw
---
*Автосохранено из session [`ac82ac49`](file:///Users/ai/.claude/projects/-Users-ai-knowledge-base/ac82ac49-7dd6-476e-9fd0-e10687c8867c.jsonl) — 5 сообщ., тулы: AskUserQuestion, Bash, Edit, Read, Write*

View File

@@ -0,0 +1,31 @@
---
date: 2026-06-28
type: claude-session
session_id: ac82ac49-7dd6-476e-9fd0-e10687c8867c
started: 2026-06-27T19:43:29.595Z
ended: 2026-06-27T21:42:49.450Z
messages: 6
tools: [AskUserQuestion, Bash, Edit, Read, Write]
tags: [claude, session]
---
# https://mail.dttb.ru/domainadmin/ можешь найти креды
## Запрос
https://mail.dttb.ru/domainadmin/ можешь найти креды
## Итог (последний ответ Claude, до 500 симв.)
Готово — логотип `dttb` стоит.
## Что сделал
- Поставил монограмму в оба слота mailcow (`MAIN_LOGO` + `MAIN_LOGO_DARK` в Redis) — она на странице входа и в шапке интерфейса.
- Взял **PNG**, а не SVG: в твоём SVG текст нарисован шрифтом `SG`, а когда mailcow грузит логотип как `<img>`, кастомный шрифт недоступен → «dttb» отрисовался бы дефолтным шрифтом. В PNG начертание уже впечёно в растр — выглядит точно как задумано.
- Ужал 2048→1024 (лимит mailcow 1920), вес 54 КБ.
## Проверь
Открой https:
---
*Автосохранено из session [`ac82ac49`](file:///Users/ai/.claude/projects/-Users-ai-knowledge-base/ac82ac49-7dd6-476e-9fd0-e10687c8867c.jsonl) — 6 сообщ., тулы: AskUserQuestion, Bash, Edit, Read, Write*

View File

@@ -0,0 +1,30 @@
---
date: 2026-06-28
type: claude-session
session_id: ac82ac49-7dd6-476e-9fd0-e10687c8867c
started: 2026-06-27T19:43:29.595Z
ended: 2026-06-27T21:55:59.940Z
messages: 7
tools: [AskUserQuestion, Bash, Edit, Read, Write]
tags: [claude, session]
---
# https://mail.dttb.ru/domainadmin/ можешь найти креды
## Запрос
https://mail.dttb.ru/domainadmin/ можешь найти креды
## Итог (последний ответ Claude, до 500 симв.)
Сделал, что можно без твоего участия. Итог по двум частям:
## 1. BIMI (лого у отправителя в инбоксе)
✅ Собрал валидный SVG (конверт, профиль **SVG Tiny PS** — без шрифта, поэтому годен; монограмма со шрифтом `SG` для BIMI не подходит)
✅ Захостил публично: https://mail.dttb.ru/bimi/dttb.svg (проверено из интернета — 200, `image/svg+xml`)
✅ DMARC у тебя `p=quarantine` — BIMI принимает
**Осталась 1 DNS-запись** — её сам не добавлю (API Spaceweb требует сессию панели, токена нет). Добавь в `vps.sw
---
*Автосохранено из session [`ac82ac49`](file:///Users/ai/.claude/projects/-Users-ai-knowledge-base/ac82ac49-7dd6-476e-9fd0-e10687c8867c.jsonl) — 7 сообщ., тулы: AskUserQuestion, Bash, Edit, Read, Write*

View File

@@ -0,0 +1,27 @@
---
date: 2026-06-28
type: claude-session
session_id: ac82ac49-7dd6-476e-9fd0-e10687c8867c
started: 2026-06-27T19:43:29.595Z
ended: 2026-06-27T22:08:38.835Z
messages: 9
tools: [AskUserQuestion, Bash, Edit, Read, Write]
tags: [claude, session]
---
# https://mail.dttb.ru/domainadmin/ можешь найти креды
## Запрос
https://mail.dttb.ru/domainadmin/ можешь найти креды
## Итог (последний ответ Claude, до 500 симв.)
Готово. Чиню честно: **это была моя ошибка** — при апдейте я убрал forward-zone из unbound, посчитав её устаревшей. На деле она load-bearing: рекурсивный DNS на твоём провайдере режется RKN, поэтому без forward postfix перестал резолвить домены отправителей и отбивал всё входящее (`450 Domain not found`). Несколько секунд после апдейта работало из кеша — это меня и обмануло.
## Что сделано
- Вернул `forward-zone → 8.8.8.8/1.1.1.1` в unbound + рестарт.
- Проверил: unbound резолвит, postfix прини
---
*Автосохранено из session [`ac82ac49`](file:///Users/ai/.claude/projects/-Users-ai-knowledge-base/ac82ac49-7dd6-476e-9fd0-e10687c8867c.jsonl) — 9 сообщ., тулы: AskUserQuestion, Bash, Edit, Read, Write*

View File

@@ -0,0 +1,30 @@
---
date: 2026-06-28
type: claude-session
session_id: ac82ac49-7dd6-476e-9fd0-e10687c8867c
started: 2026-06-27T19:43:29.595Z
ended: 2026-06-27T22:27:19.545Z
messages: 9
tools: [AskUserQuestion, Bash, Edit, Read, Write]
tags: [claude, session]
---
# https://mail.dttb.ru/domainadmin/ можешь найти креды
## Запрос
https://mail.dttb.ru/domainadmin/ можешь найти креды
## Итог (последний ответ Claude, до 500 симв.)
Готово — **Roundcube поставлен и работает.**
## Как зайти
**https://mail.dttb.ru/rc/** — логин полным адресом + пароль (напр. `support@dttb.ru` / `1qaz!QAZ`). Скин Elastic, заголовок «dttb Mail». Вход проверил — работает.
## Что под капотом
- Контейнер Roundcube рядом с mailcow, отдаётся **родным nginx на `/rc`** — без нового поддомена и без записи в Spaceweb DNS (wildcard `*.dttb.ru` у тебя нет, иначе пришлось бы тебя просить добавить запись).
- Своя БД, IMAP/SMTP к mailcow внутри docker-сети
---
*Автосохранено из session [`ac82ac49`](file:///Users/ai/.claude/projects/-Users-ai-knowledge-base/ac82ac49-7dd6-476e-9fd0-e10687c8867c.jsonl) — 9 сообщ., тулы: AskUserQuestion, Bash, Edit, Read, Write*

View File

@@ -0,0 +1,33 @@
---
date: 2026-06-28
type: claude-session
session_id: ac82ac49-7dd6-476e-9fd0-e10687c8867c
started: 2026-06-27T19:43:29.595Z
ended: 2026-06-27T22:37:55.277Z
messages: 10
tools: [AskUserQuestion, Bash, Edit, Read, Write]
tags: [claude, session]
---
# https://mail.dttb.ru/domainadmin/ можешь найти креды
## Запрос
https://mail.dttb.ru/domainadmin/ можешь найти креды
## Итог (последний ответ Claude, до 500 симв.)
Всё на стороне mailcow готово: `:995` (POP3S) и `:993` (IMAPS) открыты из интернета, cert валиден, у всех ящиков dttb доступ по imap/pop3 включён. Делать надо **в самом Яндексе** — он будет подключаться к `mail.dttb.ru` и забирать почту.
## В Яндекс.Почте
Настройки (⚙️) → **Все настройки****«Сбор почты с других ящиков»** → добавить ящик.
Если попросит вручную указать сервер:
| Параметр | Значение |
|---|---|
| Протокол | **POP3** (сборщик Яндекса работает по POP3) |
| Сервер | `mail.dttb.r
---
*Автосохранено из session [`ac82ac49`](file:///Users/ai/.claude/projects/-Users-ai-knowledge-base/ac82ac49-7dd6-476e-9fd0-e10687c8867c.jsonl) — 10 сообщ., тулы: AskUserQuestion, Bash, Edit, Read, Write*

View File

@@ -0,0 +1,35 @@
---
date: 2026-06-28
type: claude-session
session_id: ac82ac49-7dd6-476e-9fd0-e10687c8867c
started: 2026-06-27T19:43:29.595Z
ended: 2026-06-27T22:40:38.301Z
messages: 11
tools: [AskUserQuestion, Bash, Edit, Read, ToolSearch, WebSearch, Write]
tags: [claude, session]
---
# https://mail.dttb.ru/domainadmin/ можешь найти креды
## Запрос
https://mail.dttb.ru/domainadmin/ можешь найти креды
## Итог (последний ответ Claude, до 500 симв.)
Проверил — я был неправ про «только POP3». Актуально: **сборщик Яндекса работает по IMAP и даже использует его по умолчанию.**
## IMAP-сбор — параметры (на нашей стороне всё готово)
| Параметр | Значение |
|---|---|
| Протокол | **IMAP** |
| Сервер | `mail.dttb.ru` |
| Порт | `993` |
| Шифрование | **SSL вкл.** |
| Логин | полный адрес, напр. `support@dttb.ru` |
| Пароль | пароль ящика |
В Яндексе: ⚙️ → Все настройки → «Сбор почты с других ящиков» → ввести адрес+пароль (сервер подхватится сам,
---
*Автосохранено из session [`ac82ac49`](file:///Users/ai/.claude/projects/-Users-ai-knowledge-base/ac82ac49-7dd6-476e-9fd0-e10687c8867c.jsonl) — 11 сообщ., тулы: AskUserQuestion, Bash, Edit, Read, ToolSearch, WebSearch, Write*

View File

@@ -0,0 +1,30 @@
---
date: 2026-06-28
type: claude-session
session_id: ac82ac49-7dd6-476e-9fd0-e10687c8867c
started: 2026-06-27T19:43:29.595Z
ended: 2026-06-27T22:42:29.835Z
messages: 12
tools: [AskUserQuestion, Bash, Edit, Read, ToolSearch, WebSearch, Write]
tags: [claude, session]
---
# https://mail.dttb.ru/domainadmin/ можешь найти креды
## Запрос
https://mail.dttb.ru/domainadmin/ можешь найти креды
## Итог (последний ответ Claude, до 500 симв.)
Сохранено в [mailcow-dttb.md](projects/dttb/mailcow-dttb.md) — раздел «Внешний сбор почты (Яндекс и др.)»: параметры IMAP/POP3, что Яндекс-сборщик по умолчанию IMAP, разница протоколов и обратное направление (Sync job с Яндекса).
Заодно за эту сессию в той же заметке уже зафиксировано всё:
- фикс входящего спама (SNAT на роутере)
- SSL mail-портов + авто-синхрон cert из NPM
- апдейт mailcow `2026-05c` + **урок про обязательный forward-zone unbound**
- логотип UI, BIMI + подпись
- Roundcube на `
---
*Автосохранено из session [`ac82ac49`](file:///Users/ai/.claude/projects/-Users-ai-knowledge-base/ac82ac49-7dd6-476e-9fd0-e10687c8867c.jsonl) — 12 сообщ., тулы: AskUserQuestion, Bash, Edit, Read, ToolSearch, WebSearch, Write*

View File

@@ -0,0 +1,28 @@
---
date: 2026-06-28
type: claude-session
session_id: ac82ac49-7dd6-476e-9fd0-e10687c8867c
started: 2026-06-27T19:43:29.595Z
ended: 2026-06-27T22:47:31.058Z
messages: 13
tools: [AskUserQuestion, Bash, Edit, Read, ToolSearch, WebSearch, Write]
tags: [claude, session]
---
# https://mail.dttb.ru/domainadmin/ можешь найти креды
## Запрос
https://mail.dttb.ru/domainadmin/ можешь найти креды
## Итог (последний ответ Claude, до 500 симв.)
Запушено и подтверждено: **локальный HEAD == origin/main == `ddb904c`**. Всё в Gitea.
## Но всплыла проблема с NPM
Обычный `git push` на `git.dttb.ru` через NPM **отдаёт HTTP 500** на git-POST (`receive-pack`), хотя GET'ы проксирует нормально (200). Пришлось пушить через SSH-туннель прямо в Gitea (10.0.0.189:3000), минуя NPM.
Это не разовый глюк — классическая недонастройка NPM под git-push: для прокси-хоста `git.dttb.ru` в Advanced нет `client_max_body_size 0;` и `proxy_request_buffering off;
---
*Автосохранено из session [`ac82ac49`](file:///Users/ai/.claude/projects/-Users-ai-knowledge-base/ac82ac49-7dd6-476e-9fd0-e10687c8867c.jsonl) — 13 сообщ., тулы: AskUserQuestion, Bash, Edit, Read, ToolSearch, WebSearch, Write*

View File

@@ -0,0 +1,30 @@
---
date: 2026-06-28
type: claude-session
session_id: ac82ac49-7dd6-476e-9fd0-e10687c8867c
started: 2026-06-27T19:43:29.595Z
ended: 2026-06-27T22:58:56.670Z
messages: 15
tools: [AskUserQuestion, Bash, Edit, Read, ToolSearch, WebSearch, Write]
tags: [claude, session]
---
# https://mail.dttb.ru/domainadmin/ можешь найти креды
## Запрос
https://mail.dttb.ru/domainadmin/ можешь найти креды
## Итог (последний ответ Claude, до 500 симв.)
Готово — всё под лимитом, память сохранена.
## Итог: проблема push'а решена (и причина была не в том, что я думал)
**Корень оказался глубже:** диск LXC 103 (NPM) был **на 100% забит** — поэтому nginx не мог буферизировать тело git-push (POST) на диск и отдавал 500. Не недонастройка прокси, а disk-full. Забили его NPM-логи хоста `git.dttb.ru`: `access.log` 601M + `error.log` 568M, который флудил варнингом `trust_forwarded_proto` на каждый запрос (баг NPM), а диск всего 7.8G.
**Что сделал:**
1.
---
*Автосохранено из session [`ac82ac49`](file:///Users/ai/.claude/projects/-Users-ai-knowledge-base/ac82ac49-7dd6-476e-9fd0-e10687c8867c.jsonl) — 15 сообщ., тулы: AskUserQuestion, Bash, Edit, Read, ToolSearch, WebSearch, Write*

View File

@@ -1,5 +1,5 @@
--- ---
date: 2026-06-27 date: 2026-06-28
type: index type: index
source: scripts/kb-objects-map.py source: scripts/kb-objects-map.py
tags: [index, registry, objects, netbird] tags: [index, registry, objects, netbird]
@@ -7,7 +7,7 @@ tags: [index, registry, objects, netbird]
# Реестр объектов и netbird-пиров # Реестр объектов и netbird-пиров
Авто-сгенерировано `2026-06-27T19:15` из [[dttb/netbird-inventory]] + frontmatter в `projects/`. Авто-сгенерировано `2026-06-28T06:00` из [[dttb/netbird-inventory]] + frontmatter в `projects/`.
**Не править вручную** — перепишется. Источник правды — frontmatter в каждом README. **Не править вручную** — перепишется. Источник правды — frontmatter в каждом README.
- Проектов: **23**, из них с netbird-привязкой: **9** - Проектов: **23**, из них с netbird-привязкой: **9**

View File

@@ -6,6 +6,9 @@ tags: [dttb, mail]
# Mailcow dttb.ru (VM 107, 10.0.0.107) # Mailcow dttb.ru (VM 107, 10.0.0.107)
> **Версия:** `2026-05c` (обновлено 2026-06-28 с `2026-01` через `./update.sh -f`; снапшот отката `qm snapshot 107` = `pre_update_20260627`, удалить после недели стабильной работы).
> 🚨 **УРОК АПДЕЙТА:** при апдейте откатывал tracked-правки конфигов и НЕ вернул forward-zone в unbound.conf → **почта легла** (postfix не резолвил MX/домены отправителей → reject `450 Domain not found` на всё входящее). Рекурсивный unbound на этом провайдере НЕ работает (RKN режет доступ к корневым DNS), forward-zone — **load-bearing**. Восстановлено возвратом forward-zone (см. ниже). **На будущих апдейтах unbound.conf forward-zone НЕ удалять / вернуть сразу после.** postfix-overrides (main.cf) mailcow восстанавливает сам.
## Общая информация ## Общая информация
- **Web UI:** https://mail.dttb.ru (через NPM proxy host #25, SSL cert #106) - **Web UI:** https://mail.dttb.ru (через NPM proxy host #25, SSL cert #106)
- **Admin:** admin / 1qaz!QAZ - **Admin:** admin / 1qaz!QAZ
@@ -19,6 +22,8 @@ tags: [dttb, mail]
- **Ящики:** - **Ящики:**
- admin@dttb.ru (пароль: 1qaz!QAZ) - admin@dttb.ru (пароль: 1qaz!QAZ)
- noreply@dttb.ru (пароль: 1qaz!QAZ) - noreply@dttb.ru (пароль: 1qaz!QAZ)
- support@dttb.ru (пароль: 1qaz!QAZ)
- (плюс codex1..8@umnybot.ru, assistant@umnybot.ru — контур Александра)
## Подключение ## Подключение
- **SMTP:** mail.dttb.ru:587 (STARTTLS) или mail.dttb.ru:465 (SMTPS) - **SMTP:** mail.dttb.ru:587 (STARTTLS) или mail.dttb.ru:465 (SMTPS)
@@ -31,8 +36,8 @@ tags: [dttb, mail]
- **MAILCOW_HOSTNAME:** mail.dttb.ru - **MAILCOW_HOSTNAME:** mail.dttb.ru
- **SKIP_LETS_ENCRYPT:** y (SSL через NPM) - **SKIP_LETS_ENCRYPT:** y (SSL через NPM)
- **SKIP_UNBOUND_HEALTHCHECK:** y - **SKIP_UNBOUND_HEALTHCHECK:** y
- **Unbound:** forward-zone к 8.8.8.8/1.1.1.1 в unbound.conf (обязательно для доставки!) - **Unbound:** ⚠️ **ОБЯЗАТЕЛЬНА forward-zone** к 8.8.8.8/1.1.1.1 в `data/conf/unbound/unbound.conf` (в самом конце файла). Рекурсивный резолвинг на этом провайдере НЕ работает (RKN режет корневые DNS) → без forward почта не доставляется (postfix reject `450 Domain not found`). Это НЕ band-aid, а необходимость. 2026-06-28 убрал по ошибке → положил почту, вернул. Минус 8.8.8.8: Spamhaus отшивает публичные резолверы, но postscreen_dnsbl_sites завязан на конкретные коды 127.0.0.x → ложных reject не даёт. После рестарта unbound даёт резолв через ~5-10 сек (не паниковать раньше). Проверка: `docker exec ...unbound... drill gmail.com @127.0.0.1` (ANSWER:>0).
- **SSL:** self-signed cert для SMTP/IMAP (mail.dttb.ru), NPM cert для HTTPS web - **SSL:** web (:443) — cert NPM; mail-порты (25/465/587/993/995) — тот же LE-cert из NPM, синхронизируется cron'ом (см. ниже «SSL на mail-портах»)
- **Docker контейнеры:** 18 шт (postfix, dovecot, rspamd, nginx, mysql, redis и др.) - **Docker контейнеры:** 18 шт (postfix, dovecot, rspamd, nginx, mysql, redis и др.)
## OpenWrt проброс портов → 10.0.0.107 ## OpenWrt проброс портов → 10.0.0.107
@@ -62,6 +67,65 @@ tags: [dttb, mail]
- ⚠️ **PTR отсутствует** — единственная дыра доставляемости. Strict-провайдеры (Gmail → спам, Mail.ru → reject) штрафуют письма с IP без reverse DNS. - ⚠️ **PTR отсутствует** — единственная дыра доставляемости. Strict-провайдеры (Gmail → спам, Mail.ru → reject) штрафуют письма с IP без reverse DNS.
- ⚠️ **IP = OOO Istranet** (`netname istranet`, RU), не Spaceweb. PTR ставит Istranet (как интернет-провайдер по этому WAN-IP), не регистратор DNS. - ⚠️ **IP = OOO Istranet** (`netname istranet`, RU), не Spaceweb. PTR ставит Istranet (как интернет-провайдер по этому WAN-IP), не регистратор DNS.
- 🔸 В DNS висит лишний `TXT @ "mailru-domain: 09KURdxlbSVmAm4O"` — остаток попытки привязать Mail.ru для домена; на Mailcow не влияет, можно убрать. - 🔸 В DNS висит лишний `TXT @ "mailru-domain: 09KURdxlbSVmAm4O"` — остаток попытки привязать Mail.ru для домена; на Mailcow не влияет, можно убрать.
## Брендинг писем — BIMI + подпись (2026-06-28)
**Цель:** логотип dttb при отправке писем со всех ящиков.
**BIMI** (лого-аватар у отправителя в инбоксе Apple Mail и др.; Gmail/Yahoo требуют платный VMC ~$1000/год — пока без него):
- SVG (профиль **SVG Tiny PS**, конверт без текста — шрифт `SG` для BIMI не годится): `data/web/bimi/dttb.svg` на mailcow → публично `https://mail.dttb.ru/bimi/dttb.svg` (200, image/svg+xml, проверено снаружи). Исходник в `snippets/dttb-mail-branding/dttb-bimi.svg`.
- DMARC уже `p=quarantine` — BIMI-eligible.
- **ОСТАЛОСЬ (DNS, у Олега/в Spaceweb-панели vps.sweb.ru):** TXT `default._bimi.dttb.ru` = `v=BIMI1; l=https://mail.dttb.ru/bimi/dttb.svg;`. API sweb требует сессию панели (токена в vault нет) — автоматом не добавить.
**Подпись с логотипом** (`snippets/dttb-mail-branding/signature.html`, лого-PNG `https://mail.dttb.ru/bimi/dttb-logo.png`):
- Готовый HTML-сниппет под вставку в SOGo (Preferences→Mail) и в клиенты (Thunderbird/iPhone).
- ⚠️ Серверного футера «на всех клиентов» НЕ ставил: вставка тела после DKIM-подписи Rspamd ломает DKIM. Корректный путь — footer-milter ДО Rspamd (отдельный проект, не делал).
## Внешний сбор почты (Яндекс и др.) — 2026-06-28
Чтобы внешний сервис (напр. Яндекс) **забирал** почту из ящика dttb.ru к себе. Настраивается **на стороне Яндекса** (он подключается к нам), на mailcow ничего не нужно — `:993`/`:995` открыты из интернета, cert валиден, imap/pop3 у всех ящиков dttb включены (`attributes.imap_access/pop3_access=1`).
Параметры подключения для любого сборщика:
| | IMAP | POP3 |
|---|---|---|
| Сервер | `mail.dttb.ru` | `mail.dttb.ru` |
| Порт | `993` | `995` |
| Шифрование | SSL | SSL |
| Логин | полный адрес (`support@dttb.ru`) | то же |
**Яндекс:** ⚙️ → Все настройки → «Сбор почты с других ящиков» → адрес+пароль (сервер подхватится). **Яндекс-сборщик по умолчанию IMAP** (не POP3, как было раньше). IMAP = зеркалит всю структуру папок + статусы, но нельзя выбрать целевую папку. POP3 = только Входящие, зато можно сложить в конкретную папку/метку. Первый сбор за пару минут, далее от неск. раз/час до раза в неск. дней (решает Яндекс).
Справка: https://yandex.ru/support/mail/web/preferences/collector.html
**Обратное направление** (mailcow забирает с Яндекса в ящик dttb): mailcow UI → ящик → **Sync jobs**, IMAP `imap.yandex.ru:993`, для Яндекса нужен **пароль приложения** (не основной).
## Roundcube — второй вебмейл (2026-06-28)
Поставлен рядом с SOGo, **на `https://mail.dttb.ru/rc/`** (родной nginx mailcow, без нового поддомена/DNS/NPM — wildcard *.dttb.ru НЕТ). Скин Elastic, заголовок «dttb Mail».
- Контейнер `roundcube-mailcow` (`roundcube/roundcubemail:latest-fpm-alpine`) через `docker-compose.override.yml`.
- БД `roundcube` в mysql-mailcow (юзер `roundcube` / `df8de490bea7641fd34904cc95b29428`), схема создаётся образом сама (`initdb.sh --update`).
- IMAP `ssl://dovecot:993`, SMTP `tls://postfix:587` (внутр. алиасы сети); cert CN=mail.dttb.ru ≠ имя контейнера → в `data/conf/roundcube/extra.php` выключена проверка cert (`imap/smtp_conn_options verify_peer=false`) — трафик внутри docker-бриджа.
- Файлы вебрута: **bind** `./data/web/rc``/var/www/html` (НЕ named-том: у nginx mailcow rootfs read-only, том в /web/rc не примонтировать). nginx видит их через существующий `/web`. Новый Roundcube 1.6 — вебрут в `public_html/`, поэтому в nginx alias = `/web/rc/public_html/`, SCRIPT_FILENAME = `/var/www/html/public_html/$rcfile`.
- nginx-локация: `data/conf/nginx/site.roundcube.custom` (подключается через `include site.*.custom` в sites-default). `ROUNDCUBEMAIL_REQUEST_PATH=/rc/`.
- Вход проверен (admin@dttb.ru → 302 _task=mail). Плагины: archive, zipdownload, managesieve.
- ⚠️ На апдейтах mailcow override и data/web/rc untracked — переживают; при больших обновлениях Roundcube — `docker compose pull roundcube-mailcow && up -d` (схема обновится сама).
## Логотип UI (2026-06-28)
Кастомный логотип `dttb` (монограмма) на странице входа/в шапке. Хранится в **Redis** ключами `MAIN_LOGO` + `MAIN_LOGO_DARK` как `data:image/png;base64,...` (как делает UI → Customize). Поставлен **PNG** (не SVG: в SVG текст шрифтом `SG`, который в `<img>` не доступен → ставится дефолтный). Источник: `~/Downloads/export/dttb-01-monogram.png` (ужат 2048→1024, лимит mailcow 1920). Сброс: UI → Customize → Reset, или `redis-cli DEL MAIN_LOGO MAIN_LOGO_DARK`.
## SSL на mail-портах (фикс 2026-06-27)
`SKIP_LETS_ENCRYPT=y` → ACME-контейнер mailcow ничего не делает. Cert для mail-портов владеет **NPM** (`npm-106`, ECDSA LE, авто-продление). При установке (Mar 7) его положили в `data/assets/ssl/` **вручную** и забыли про продление → **cert протух 2 июня 2026**, клиенты IMAP/SMTP ругались на сертификат.
**Решение:** авто-синхрон cert из NPM в mailcow.
- Скрипт: `/root/sync-mailcow-cert.sh` на **Proxmox** `10.0.0.250` (копия в `snippets/sync-mailcow-cert.sh`).
- Берёт `pct exec 103 -- cat /data/compose/2/letsencrypt/live/npm-106/{fullchain,privkey}.pem`, сравнивает fingerprint с `10.0.0.107:/opt/mailcow-dockerized/data/assets/ssl/cert.pem`, при отличии — бэкап + замена + reload postfix/dovecot/nginx.
- SSH Proxmox→mailcow по ключу `/root/.ssh/mailcow_sync`.
- Cron: `/etc/cron.d/mailcow-cert-sync` — ежедневно 04:30, лог `/var/log/mailcow-cert-sync.log`.
- Ручной прогон: `/root/sync-mailcow-cert.sh`.
- Cert: ECDSA P-384, LE E-series; пару проверять по pubkey (`openssl rsa` на нём врёт — даёт пустой modulus).
## ⚠️ КОРНЕВОЙ ФИКС входящего спама (2026-06-27)
Жалоба: письма на `support@dttb.ru` (новый ящик) падают в спам, на старые ящики — нет.
**Корень:** на домашнем OpenWrt (`10.0.0.1`) у LAN-зоны было `masq=1`. Входящее `WAN:25 → DNAT → 10.0.0.107` уходило в LAN-зону и **SNAT'илось в `10.0.0.1`** → postfix/rspamd видели source = `10.0.0.1` для **ВСЕХ** внешних писем.
Следствие на каждом входящем: `RDNS_NONE=2.0` + `HFILTER_HOSTNAME_UNKNOWN=8.5` (+10.5), а у строгих отправителей ещё `R_SPF_FAIL=8.0` (SPF против 10.0.0.1) → reject (так резались «Welcome to NetBird»). Бьёт по всему серверу; старый ящик спасал только обученный Bayes (ham 3..5), новый `support@` тонул.
**Фикс (UCI, не сырой nft — грабли fw4):** на `10.0.0.1` добавлено `config nat 'No-SNAT-to-Mailcow'` (src=lan, proto=tcp, dest_ip=10.0.0.107, target=ACCEPT) + `fw4 reload`. Стоит в srcnat до masquerade.
**Проверено:** тест с внешнего `89.111.140.86` → rspamd увидел реальный `89.111.140.86` (не `10.0.0.1`). Для отправителей с нормальным PTR/MX/DKIM (Яндекс/Gmail) +10.5 больше не срабатывает.
Не трогал глобальный `lan masq=1` (на нём может висеть VPN/podkop-маршрутизация) — фикс точечный и обратимый (`uci delete firewall.@nat[0]`).
- 🔸 **SSH-доступ к VM не работает ни одним ключом** (id_rsa «claude-code-matrix-project», id_ed25519, ключ Proxmox). VM клонирована с НИИКН VM 106 → несёт чужой authorized_keys. Управление возможно через web-UI (admin/1qaz!QAZ); для шелла — добавить ключ через Proxmox console. - 🔸 **SSH-доступ к VM не работает ни одним ключом** (id_rsa «claude-code-matrix-project», id_ed25519, ключ Proxmox). VM клонирована с НИИКН VM 106 → несёт чужой authorized_keys. Управление возможно через web-UI (admin/1qaz!QAZ); для шелла — добавить ключ через Proxmox console.
## Вариант «почтовый шлюз через VPS» (оценка 2026-06-18) ## Вариант «почтовый шлюз через VPS» (оценка 2026-06-18)

View File

@@ -120,3 +120,16 @@ location /.well-known/matrix/client {
## SSL-сертификаты ## SSL-сертификаты
Большинство сертификатов выданы через Let's Encrypt с email `it5870@yandex.ru`. Большинство сертификатов выданы через Let's Encrypt с email `it5870@yandex.ru`.
---
## Troubleshooting
### git push даёт HTTP 500 / API NPM 502 → диск LXC 103 переполнен (2026-06-28)
**Симптом:** `git push` на git.dttb.ru → `RPC failed; HTTP 500`, при этом GET'ы проксируются (200); админ-API NPM (:81) → 502.
**Корень:** диск LXC 103 (NPM) был **100% забит** → nginx не может буферизировать тело POST (push) на диск, node-app не пишет → 500/502. GET'ы маленькие, проходят.
**Что забило:** логи прокси-хоста 22 (`git.dttb.ru`): `proxy-host-22_access.log` 601M + `error.log` 568M. error.log флудит варнинг NPM `using uninitialized "trust_forwarded_proto" variable` на каждый запрос (баг NPM), диск всего 7.8G.
**Фикс:** truncate логов (`: > файл`, не rm — nginx держит хэндл) → освободилось ~1.2G. Защита от повтора: `/usr/local/bin/npm-log-cap.sh` + cron `/etc/cron.d/npm-log-cap` (hourly, обрезает любой NPM-лог > 200M до последних 10M in-place).
**Обход на время диск-фула:** push напрямую в Gitea минуя NPM — SSH-туннель `ssh -L 3000:10.0.0.189:3000 root@10.0.0.250`, затем `git push http://oleg:***@localhost:3000/oleg/knowledge-base.git`.
**Диск LXC 103 вырос 8G→16G** (2026-06-28, `pct resize 103 rootfs +8G`, онлайн без простоя; стало 43% занято). ⚠️ thin-пул `pve/data` при этом был **94.91%** — латентный риск хоста; место освобождать prune старых docker-образов / снапшотов (напр. `pre_update_20260627` VM107 после недели стабильности).
**Остаётся (корень):** варнинг trust_forwarded_proto в NPM (лечится обновлением NPM) — генератор флуда логов; cron npm-log-cap пока держит.

View File

@@ -0,0 +1,8 @@
<svg version="1.2" baseProfile="tiny-ps" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
<title>dttb</title>
<rect width="1024" height="1024" fill="#2A6FDB"/>
<g transform="translate(232 222) scale(4.827586)" fill="none" stroke="#ffffff" stroke-width="7" stroke-linecap="round" stroke-linejoin="round">
<rect x="6" y="20" width="104" height="76" rx="14"/>
<path d="M10 28 L58 64 L106 28"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@@ -0,0 +1,13 @@
<table style="border-collapse:collapse;font-family:Arial,Helvetica,sans-serif;color:#161616;font-size:13px">
<tr>
<td style="padding-right:14px;vertical-align:middle">
<img src="https://mail.dttb.ru/bimi/dttb-logo.png" width="56" height="56" alt="dttb"
style="display:block;border-radius:12px;border:0">
</td>
<td style="vertical-align:middle;border-left:3px solid #2A6FDB;padding-left:14px">
<div style="font-weight:700;font-size:15px;line-height:1.2">Олег Батлаев</div>
<div style="color:#555;line-height:1.4">dttb.ru</div>
<div style="line-height:1.4"><a href="mailto:support@dttb.ru" style="color:#2A6FDB;text-decoration:none">support@dttb.ru</a></div>
</td>
</tr>
</table>

View File

@@ -0,0 +1,50 @@
#!/bin/bash
# sync-mailcow-cert.sh
# Копирует LE-сертификат mail.dttb.ru из NPM (LXC 103) в mailcow (VM 107)
# и перезагружает почтовые сервисы ТОЛЬКО при изменении сертификата.
# Причина: mailcow с SKIP_LETS_ENCRYPT=y не продлевает cert сам; cert владеет NPM.
# История: cert на mail-портах протух 2026-06-02, чинили вручную 2026-06-27.
set -euo pipefail
NPM_CTID=103
NPM_DIR="/data/compose/2/letsencrypt/live/npm-106"
MC_HOST="root@10.0.0.107"
MC_KEY="/root/.ssh/mailcow_sync"
MC_SSL="/opt/mailcow-dockerized/data/assets/ssl"
SSHMC="ssh -i $MC_KEY -o StrictHostKeyChecking=no -o ConnectTimeout=10 $MC_HOST"
TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT
pct exec "$NPM_CTID" -- cat "$NPM_DIR/fullchain.pem" > "$TMP/cert.pem"
pct exec "$NPM_CTID" -- cat "$NPM_DIR/privkey.pem" > "$TMP/key.pem"
# sanity-проверки
openssl x509 -in "$TMP/cert.pem" -noout >/dev/null 2>&1 || { echo "$(date '+%F %T') ERR: битый cert из NPM"; exit 1; }
[ -s "$TMP/key.pem" ] || { echo "$(date '+%F %T') ERR: пустой key из NPM"; exit 1; }
CPUB=$(openssl x509 -in "$TMP/cert.pem" -noout -pubkey | openssl md5)
KPUB=$(openssl pkey -in "$TMP/key.pem" -pubout 2>/dev/null | openssl md5)
[ "$CPUB" = "$KPUB" ] || { echo "$(date '+%F %T') ERR: cert и key не пара"; exit 1; }
NEW=$(openssl x509 -in "$TMP/cert.pem" -noout -fingerprint -sha256)
CUR=$($SSHMC "openssl x509 -in $MC_SSL/cert.pem -noout -fingerprint -sha256" 2>/dev/null || echo none)
if [ "$NEW" = "$CUR" ]; then
echo "$(date '+%F %T') cert не изменился — пропуск"
exit 0
fi
echo "$(date '+%F %T') обнаружен новый cert — деплой"
scp -i "$MC_KEY" -o StrictHostKeyChecking=no "$TMP/cert.pem" "$TMP/key.pem" "$MC_HOST:/tmp/"
$SSHMC "
set -e
cd /opt/mailcow-dockerized
TS=\$(date +%Y%m%d-%H%M%S)
cp $MC_SSL/cert.pem $MC_SSL/cert.pem.bak-\$TS
cp $MC_SSL/key.pem $MC_SSL/key.pem.bak-\$TS
mv /tmp/cert.pem $MC_SSL/cert.pem
mv /tmp/key.pem $MC_SSL/key.pem
chmod 644 $MC_SSL/cert.pem; chmod 600 $MC_SSL/key.pem
docker compose exec -T postfix-mailcow postfix reload >/dev/null 2>&1 || docker compose restart postfix-mailcow
docker compose exec -T dovecot-mailcow dovecot reload >/dev/null 2>&1 || docker compose restart dovecot-mailcow
docker compose exec -T nginx-mailcow nginx -s reload >/dev/null 2>&1 || true
"
echo "$(date '+%F %T') задеплоен: $NEW"