Commit 2436bd23 authored by Vitaly Lipatov's avatar Vitaly Lipatov

Track auto-memory corpus (lessons, feedback, projects, references, objects)

Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
parent 8bbe609c
---
name: build-requests-via-kanban
description: Запросы на сборку/упаковку пакетов — через Kanban (категория git-alt), не через GitLab issue в alt-packaging-agents
metadata:
type: feedback
---
Запросы на сборку/упаковку пакетов («собрать X в Сизиф/p10») оформляются **через Kanban**, категория **git-alt** — а НЕ через GitLab-issue в проекте alt-packaging-agents.
**Why:** Пользователь поправил: я завёл issue в GitLab `etersoft/alt-packaging-agents` на упаковку `python3-module-cvdupdate`, а надо было карточку в Kanban («Мне кажется, запросы на сборку надо через Kanban делать»). Kanban — единый трекер таких задач, там же лежат аналогичные (напр. #208 «Собрать opentabletdriver в Сизиф», #220 cvdupdate).
**How to apply:**
1. Для «собрать/упаковать пакет в Сизиф/p10» → `kanban_create`, `category: "git-alt"`, title вида «Собрать <pkg> в Сизиф (...)», priority medium/high.
2. В content: суть, апстрим (PyPI/GitHub, лицензия, deps), контекст/бага, куда ставится, приёмка.
3. НЕ плодить issues в GitLab alt-packaging-agents для таких запросов (этот проект — не трекер RFE на сборку).
4. Другие kanban-категории: `EPM` (epm play рецепты, repack-техники), `Lavtomate` (MCP-инструменты), `Main`.
Связано: [[install-from-package-not-pip]] (почему понадобилась упаковка cvdupdate), бага Etersoft #19179, kanban #220.
---
name: feedback-cleanup-only-known
description: "При просьбе «почисти/убери» удалять ТОЛЬКО уже известное/оговорённое, не выискивать новое и не удалять найденное самовольно"
metadata:
node_type: memory
type: feedback
originSessionId: 27861819-a22e-4906-9c5e-02fdbd7542bb
---
Когда просят «почисти», «убери лишнее», «сразу почисти» — удалять **только то, что уже явно известно/перечислено в разговоре** (например, лишних пользователей, которых я сам перед этим назвал).
**Why:** 2026-06-07 на новом контейнере iot (CT 585) по «сразу почисти» я полез `docker ps`/`ss`/`find` искать что ещё убрать и снёс рабочий docker-стек **natsmesh** (проект pv, развёрнут им же ночью на этом боксе) через `docker system prune -af`. Пользователь: «зачем ты всё снёс?? нужно было чистить то, о чём ты уже знал, а не выискивать новое». Спасло то, что конфиги/creds/сертификаты и сам бинарь worker'а лежали в /home/pv/natsmesh — восстановил пересборкой образа. Локально собранные docker-образы `prune -af` удаляет НЕОБРАТИМО (нет в реестре).
**How to apply:**
- «Почисти» = убрать ровно то, что уже обсудили/перечислили. Не расширять область самостоятельно.
- НЕ запускать discovery (`docker ps`, `ss`, `find`) ради поиска «что бы ещё удалить».
- Особенно осторожно с `docker system prune -af`, `docker rmi`, `userdel`, удалением данных — это необратимо. Если кажется, что есть ещё мусор — СПРОСИТЬ, а не удалять.
Связано: [[feedback-no-unauthorized-actions]], [[project-clean-template-etersoft-p11]], [[reference-create-lxc-container-pve]].
---
name: install-from-package-not-pip
description: На продакшен-серверах ставить инструменты из системных пакетов, не pip-в-venv; если не упаковано — упаковывать
metadata:
type: feedback
---
На производственных серверах инструменты ставятся из **системных пакетов** (ALT — `epm install`, Rocky/EL — `dnf`/EPEL rpm), а **не** через `pip install` в Python-venv.
**Why:** Пользователь поправил установку `cvdupdate` через `pip install` в `/opt/cvdupdate/venv` на зеркалах ClamAV (баг Etersoft #19179, hetzner+fond): «Нужно было ставить из пакета». Пакет отслеживается пакетным менеджером, обновляется вместе с системой, консистентен с инфраструктурой; pip-venv на проде — неуправляемый кусок.
**How to apply:**
1. Перед тем как ставить Python-инструмент на прод, ПЕРВЫМ ДЕЛОМ `epm search` (ALT) / `dnf search` (+EPEL) — есть ли пакет.
2. Если пакета нет — не падать в pip-venv, а **предлагать упаковать** (ALT-спека `python3-module-...`). Запрос на сборку — через **Kanban, категория git-alt** (см. [[build-requests-via-kanban]]), НЕ через GitLab alt-packaging-agents.
3. pip-venv допустим **только** как явно обозначенный временный stopgap, пока пакет не готов — с пометкой TODO и планом замены.
4. Проверять сразу оба дистро, если хосты разные (у нас hetzner=Rocky, fond=ALT).
Связано: [[lesson_lavtomate_bug_create_confirmation]] (бага #19179 по этому инциденту).
---
name: feedback-ip-openness-tiers
description: Всегда выбирать IP (192.168.0.x / 10.20.30.x / 91.232.225.x) по необходимой степени открытости сервиса — не светить публичным без нужды
metadata:
node_type: memory
type: feedback
originSessionId: 9c0556d2-80fc-44a4-b1a3-4db2e9d46f37
---
Всегда выбирать IP-адрес для нового сервиса/CT в зависимости от необходимой степени открытости. Не давать публичный IP без явной необходимости.
Три уровня (сети на border / PVE):
- **192.168.0.0/24** (vmbr0, gw 192.168.0.1) — office LAN, самый внутренний. Рабочие станции (lav=192.168.0.55), офисная сеть.
- **10.20.30.0/24** (vmbr1, gw 10.20.30.1) — серверный/CT-сетевой блок, внутренняя инфраструктура. Маршрутизируемо внутри Etersoft, НЕ публично. Шаблон template-CT 720 тут (10.20.30.246).
- **91.232.225.0/24** (vmbr1, gw 91.232.225.1) — реально маршрутизируемый публичный блок, доступен из интернета на произвольных портах. ТОЛЬКО для сервисов, которые должны быть открыты наружу (публичные зеркала, шлюзы обхода, и т.п.).
vmbr1 — общий мост, несёт ОБЕ подсети (91.232.225/24 и 10.20.30/24); CT выбирает свою подсеть IP+gw. Проверять свободный IP в нужной зоне (обе DNS-зоны + ping).
**Why:** Лишний публичный IP = ненужная атак-поверхность. VPN-шлюз к облаку 1С-Рарус (bug #19181) изначально erroneously получил 91.232.225.106 «чтобы GRE не уперся в NAT» — но на border грузится nf_conntrack_pptp, NAT'd PPTP-out работает; переведён на 10.20.30.x.
**How to apply:** При создании CT/сервиса сначала спросить/определить нужный уровень открытости → 192.168.0.x (офис) / 10.20.30.x (внутр. серверы) / 91.232.225.x (публичный). Дефолт — наименее открытая подходящая сеть.
Связано: [[reference-create-lxc-container-pve]], [[project-rarus-1c-vpn-gateway]], [[lesson-dns-free-ip-check-both-zones]]
---
name: feedback_password_request_only
description: Пароли получать ТОЛЬКО через lavtomate password_request с одобрением пользователя; не читать автономно, не хранить plaintext
metadata:
type: feedback
---
Для получения паролей использовать **только** lavtomate `mcp__lavtomate__password_request` (запрос → пользователь одобряет в web UI → пароль выдаётся разово). Решено 2026-06-26.
**Why:** Максимум контроля и аудита — каждый доступ к паролю проходит через явное одобрение человека. Ничего, что Claude может прочитать автономно (плоский файл, rbw-agent), не считается безопасным: защищено лишь настолько, насколько защищён builder и сессия.
**How to apply:**
- Когда нужен пароль — вызывать `password_request` (service + зачем), НЕ грепать секреты по файлам/серверам и НЕ читать `.storage`/конфиги ради кредов.
- НЕ заводить автономные механизмы чтения (rbw, bw, плоский credentials.md «для Claude»).
- Источник правды для паролей — Vaultwarden (bitwarden.eterfund.ru), но Claude достаёт их не напрямую, а через одобрение в password_request.
- Отклонили варианты: Vaultwarden+rbw (автономное чтение) и плоский файл `credentials.md`.
---
name: feedback-use-epm-for-packages
description: Любые операции с пакетами — ТОЛЬКО через epm. Если epm есть — не обходить его (никаких прямых apt/rpm/dnf). Если нет — сначала поставить epm.
metadata:
node_type: memory
type: feedback
originSessionId: 27861819-a22e-4906-9c5e-02fdbd7542bb
---
Все операции с пакетами выполнять **через `epm`** (ALT eepm) — он унифицирует apt/rpm/dnf/yum/pacman и т.д.
**Why:** пользователь дважды поправлял, когда я лез напрямую в `apt-cache search` / `apt-get install` («не надо перепрыгивать на apt»). epm — стандарт на наших машинах и переносим между дистрибутивами.
**How to apply:**
- Если `epm` **установлен** (на наших хостах почти всегда) — **НЕ обходить** его прямыми `apt-get`/`apt-cache`/`rpm`/`dnf`/`yum`. Использовать epm-глаголы.
- Если `epm` **отсутствует** — сначала **поставить** его: на ALT `apt-get install -y eepm`, универсально — установщик с eepm.ru; затем работать через epm.
- `sudo` перед epm **не нужен** — он сам повышает привилегии.
Частые команды:
- установить: `epm install ПКТ` (`epm i`), неинтерактивно `-y`
- удалить: `epm e ПКТ`
- поиск (в т.ч. по `epm play`): `epm search ТЕКСТ`
- установлен ли / версия: `epm -q ПКТ`; чей файл: `epm qf ФАЙЛ`; список файлов: `epm ql ПКТ`
- репозитории: `epm rl`
- обновить индекс/систему: `epm update`, `epm full-upgrade`, обновить пакет: `epm ei`
- доп. софт: `epm play`
Связано: [[feedback-never-bypass-epm-play]] (не обходить epm play ручной загрузкой бинарей).
---
name: lav desktop - Hyprland on Deferred
description: Machine lav (192.168.0.55) setup - Deferred + Ximper + Hyprland, greetd, dual BenQ monitors
type: project
---
Машина lav (192.168.0.55) — десктоп, обновлён 2026-04-09.
**Система:**
- ALT Deferred (снимок Sisyphus) + репозитории Ximper Linux
- `epm repo add ximper` — подключает Ximper-репо через пакет ximper-repos
- `apt-conf-deferred` — правильно настраивает sources.list (Deferred + Ximper Additives/Substrates)
- SSH: `ssh lav@lav` (не `ssh lav` — там другой пользователь)
- root SSH: ключ добавлен в /root/.ssh/authorized_keys
**DE/WM:**
- Hyprland + greetd (regreet графический greeter)
- Конфиг greetd: `/etc/greetd/config.toml` → regreet-hyprland.toml
- lightdm отключён, greetd включён
- Мониторы: DP-1, DP-2 (оба BenQ 2560x1440). DP-2 слева, DP-1 справа
- Раскладка: us,ru, переключение CapsLock (grp:caps_toggle)
- Конфиги Ximper скопированы из /etc/skel/.config/ (hypr, kitty, waybar, swaync, wofi, wlogout, swappy)
**Засыпание отключено:**
- systemd: замаскированы sleep/suspend/hibernate/hybrid-sleep targets
- hypridle: убран listener с `systemctl suspend`
**Проблемы при обновлении:**
- `epm fix` / `apt-get -f install` падают если cwd — NFS-хомдир (rpm: Unable to open current directory). Решение: `cd /tmp`
- Deferred-снимок может быть старее p11 (Qt5 5.15.17 vs 5.15.18). Для даунгрейда: Pin `release l=Sisyphus` с Priority 1001
- `epm downgrade` не работает с `-y` (нужен `--force-yes`). Лучше вручную: preferences + `apt-get -y --force-yes dist-upgrade`
- `runlevel5.target` удалён при обновлении → `systemctl set-default graphical.target`
- lightdm некорректно настраивает wayland-сессию (input-устройства не привязываются к Hyprland)
**Why:** переход на Wayland для тестирования Ximper/Hyprland
**How to apply:** при работе с lav учитывать что это Deferred+Ximper, greetd, Hyprland
---
name: builder-robot-gear-bad-owner-group
description: "builder-robot: первичная группа 5021 без имени (NFS /srv). При ручном запуске gear создавал etersoft.tar с безымянной группой rpmbuild падал «Bad owner/group». Лечится TMPDIR в setgid-каталоге с именованной группой /srv/builder-robot/tmp/gearbuild. Cron-сборки не задевает."
metadata:
type: project
---
`builder-robot` (сервер сборки) имеет первичную группу **5021 без имени**; `/srv` примонтирован по NFS. При ручном запуске `gear` создавал `etersoft.tar`, в который попадала безымянная группа (gid 5021), из-за чего `rpmbuild` падал с ошибкой **«Bad owner/group»**.
## Фикс
Задать `TMPDIR` в **setgid-каталоге с именованной группой**: `/srv/builder-robot/tmp/gearbuild`. В setgid-каталоге новые файлы наследуют именованную группу каталога → tar получает корректного owner/group.
## Важно
- **Cron-сборки это не задевает** — проблема проявляется только при ручном (интерактивном) запуске gear.
- Корень проблемы — безымянная первичная группа на NFS-маунте; rpmbuild требует, чтобы owner/group в архиве имели имена.
## См. также
- [[lesson_builder_tmp_cleanup]] — чистка /tmp на builder (systemd-tmpfiles 10d, stmpclean отключён)
- [[lesson_hasher_slow_spacer_arc]] — NFS/ARC spacer при hasher init на builder64
---
name: lesson-evpn-ikev2-strongswan-cert
description: "evpn.eterfund.ru (91.232.225.181) IKEv2/strongSwan: конфиг в /etc/strongswan/swanctl (НЕ /etc/swanctl!), LE cert через certbot, deploy-hook добавлен; нюансы перевыпуска cert"
metadata:
node_type: memory
type: reference
originSessionId: 27861819-a22e-4906-9c5e-02fdbd7542bb
---
# evpn.eterfund.ru — IKEv2 (strongSwan) сервер
Доступ: `ssh -p32 root@evpn.eterfund.ru` (91.232.225.181). На хосте ДВА VPN на одном LE-сертификате `evpn.eterfund.ru`:
- **ocserv** (OpenConnect, :443)
- **strongSwan IKEv2** (charon-systemd, :500/:4500), EAP-MSCHAPv2
## Где что лежит (важно!)
- Боевой swanctl-конфиг: **`/etc/strongswan/swanctl/swanctl.conf`** — НЕ `/etc/swanctl/`! (swanctl default-dir тут /etc/strongswan/swanctl). conn `ikev2-vpn`, pool `vpn-pool` (10.235.0.2-254), `include users/*.conf` — per-user EAP (lav, mais, kostet, fiersik, ximper, akv, kondratyuk, rufus).
- Серверный cert: `local { certs = certificate.pem }``/etc/strongswan/swanctl/x509/certificate.pem` (симлинк).
- LE: `certbot certificates` → только `evpn.eterfund.ru`, lineage `/etc/letsencrypt/live/evpn.eterfund.ru/`. Есть мёртвая старая lineage `vpn.eterfund.ru` (без renewal, архив 2018) — НЕ использовать.
- Активный демон: `systemctl … strongswan` (charon-systemd + `ExecStartPost=swanctl --load-all`). `strongswan-starter` disabled. Бинаря-обёртки `ipsec` нет; stroke = `/usr/libexec/strongswan/stroke`. legacy `/etc/strongswan/ipsec.conf` НЕ используется (был мой ложный след; бэкапы .bak-* там же).
## Инцидент 2026-06-06: клиенты (MikroTik) AUTHENTICATION_FAILED, cert expired
Две причины, обе исправлены:
1. **charon держал старый cert в памяти** — после продления 10 мая никто не перечитал strongSwan (certbot `post_hook` дёргал только ocserv). `swanctl --load-creds`/`--flush-certs` НЕ убирают старый cert из памяти → нужен **`systemctl restart strongswan`** (0 активных SA — безопасно).
2. **certificate.pem указывал на leaf-only `cert.pem`** → charon не слал промежуточный R13, клиент не строил цепочку. Исправлено: симлинк переведён на **`fullchain.pem`** (leaf+R13).
`ln -sf /etc/letsencrypt/live/evpn.eterfund.ru/fullchain.pem /etc/strongswan/swanctl/x509/certificate.pem`
Добавлен deploy-hook `/etc/letsencrypt/renewal-hooks/deploy/strongswan.sh``systemctl restart strongswan` (чтобы продление впредь подхватывалось; reload недостаточно — стейл-cert остаётся в памяти).
## Как тестировать IKEv2-cert (харнесс)
С хоста без своего IPsec (`ssh epm@epm-sisyphus`, там поставлен strongswan ради charon-cmd):
```
echo PASS | sudo /usr/sbin/charon-cmd --host evpn.eterfund.ru --profile ikev2-eap \
--identity USER --eap-identity USER --cert /tmp/isrg.pem
```
`--cert` ОБЯЗАТЕЛЬНО (charon-cmd не берёт системный CA сам; ISRG Root X1 извлечь из `/etc/pki/tls/cert.pem`). Успех cert = строка `authentication of 'evpn.eterfund.ru' with RSA_... successful`. Без валидного EAP-аккаунта дальше будет `EAP_MSCHAPV2 method failed` — это норм, cert уже доказан.
## Где вести баги по VPN (ПРАВИЛО)
- **Etersoft#16295** «Поддержка VPN-серверов Etersoft» (REOPENED, mais) — зонтичная: по любым инцидентам/сопровождению VPN-серверов СВЕРЯТЬСЯ и ПИСАТЬ сюда (с work_time).
- **Etersoft#18005** «Развернуть VPN IKEv2 и L2TP» (RESOLVED, mais) — здесь развёрнута сама IKEv2/swanctl-схема (изначально на vpn-test.eterfund.ru, боевой evpn по образцу). Дописывать только уточнения к самой схеме развёртывания.
- Инцидент с cert (2026-06-06) задокументирован комментариями в обе.
Связано: [[feedback-never-bypass-epm-play]] (epm install strongswan).
---
name: hasher-builder64-arc-spacer
description: "hsh -i читает rpm-пакеты по NFS из /var/ftp/{pub,pvt} = spacer. При холодном ARC = 5 мин, при тёплом = ~55 сек. nfsd threads сам по себе не был узким местом."
metadata:
node_type: memory
type: project
originSessionId: 371f3387-17ea-4b5b-9302-c757a5f64f06
---
## Архитектура (на 2026-06-01)
- **builder64** — VM 294 на aspetos (28 GB RAM, 4 vCPU)
- `/tmp` на builder64 = **локальный** virtio-диск `/dev/vda` 168 GB ext4 — туда пишутся hasher chroots в `/tmp/.private/<user>/hasher-*/`
- `/srv` ← aspetos NFS (где живёт loginhsh скрипт, используется мало)
- `/home` ← aspetos NFS (минимальное использование при hasher init)
- `/var/ftp/{pub,pvt,tmp}`**spacer** NFS (192.168.0.38) — **тут лежит RPM mirror**
## Главная находка
hsh-чрут пишется на ЛОКАЛЬНЫЙ vda, но **rpm-пакеты apt читает с spacer'а** через NFS. `apt.conf` использует `file:/var/ftp/pub/...` и `file:/var/ftp/pvt/...` — это NFS-mount к spacer, не локальный путь.
## Измерения (loginhsh -i -t на builder64)
| Условие | Wall | CPU | Major faults |
|---|---|---|---|
| Cold spacer ARC | 4:52 | 5% | 1,774,000 |
| Warm spacer ARC (повтор сразу) | 0:55.88 | 24% | 1,862 |
| 64 nfsd threads + warm | 1:02.84 | 21% | 1,875 |
При **тёплом ARC** разница 1000× по major faults — основная замедлялка это NFS round-trip за каждой страницей кода `rpm`/`apt`/`gpg`/`perl`/`mc` при холодном кэше.
## Что НЕ помогло
- **Увеличение nfsd threads на spacer с 8 до 64**: не дало эффекта при текущем уровне нагрузки. 8 хватало.
- Оставлено 64 (через `/etc/nfs.conf` секция `[nfsd]` `threads=64`) на случай пиков. Бэкап `/etc/nfs.conf.bak-<timestamp>`.
## Что вероятно поможет (не применяли)
1. **Поднять ARC max на spacer** — сейчас `c_max=9.7 GB` при 128 GB RAM. Холодный ARC бьёт hasher переменно (когда что-то крупное вытесняет: бэкапы, scrub, массовые builds).
2. **FS-Cache (cachefilesd + fsc) на builder64 для `/var/ftp/pub`** — кэшировать rpm на локальный диск. Помогает повторным чтениям. Дисковый износ для 1.5 GB/день — пренебрежим (TBW SSD рассчитан на годы).
3. **Локальный hasher workdir** уже работает — chroot на /tmp = local vda. Менять не нужно.
## Симптомы «у меня hasher тормозит»
Если `hsh -i` >> 1 минуты — проверить:
1. ARC hit rate на spacer: `awk '/^hits/ {h=$3} /^misses/ {m=$3} END {print h/(h+m)*100}' /proc/spl/kstat/zfs/arcstats`
2. ARC size vs c_max: `awk '/^size/ {print $3} /^c\s/ {print $3} /^c_max/ {print $3}' /proc/spl/kstat/zfs/arcstats`
3. Активность на spacer (что вытесняет): `zpool iostat 2 3`, `top`
4. Page cache на builder64: `free -h`, `vmstat 2 5`
---
name: lesson-igw-telegram-ipv6-broken
description: "На igw обход Telegram работает по IPv4, но битый по IPv6 клиенты SOCKS должны резолвить локально (socks5, не socks5h)"
metadata:
node_type: memory
type: reference
originSessionId: 426a0a85-231e-4dc8-80d1-18f9632b9be0
---
# igw: обход Telegram рабочий по IPv4, битый по IPv6
На **igw** (91.232.225.13) есть policy-routing для обхода блокировок: `ip rule``from all lookup telegram`,
таблица `telegram` гонит Telegram-подсети (149.154.160.0/20, 91.108.4.0/22 и др.) через туннель-шлюз **91.232.225.142**.
**Общий IPv6 работает везде** (igw/egw/hetzner: `curl -6 https://ipv6.google.com` → 200; есть global v6 и
default-маршрут). Сломан **именно Telegram-обход по IPv6**.
**По IPv4 — работает** (`curl -4 https://api.telegram.org` → 302). **По IPv6 — НЕ работает** (таймаут).
## Топология обхода (разобрано 2026-06-05)
Telegram заблокирован на обычном выходе, гоняется через GRE-туннели в hetzner egw. Шлюзы (rDNS):
- `91.232.225.142` = **gre-hetzner2** (v4), `2a03:5a00:c:20::142` — его v6 на LAN. gre1: `local .142 remote 178.105.209.27`, внутр. `fd40::2↔fd40::1`. Есть `ip6tables NETMAP -s 2a03:5a00:c:20::/118 -o gre1 --to 2a01:4f9:c010:cf42::/118` (hetzner-префикс) + MASQUERADE, fwd=1.
- `2a03:5a00:c:20::122` = **gre.hetzner** (старый), `::127` = **gre.vdska** (резерв, metric 20).
- hetzner egw (135.181.95.108): сам Telegram v6 достаёт (302), fwd=1, но v6-MASQUERADE только `fd32::/126`.
**Рабочий шлюз для Telegram-v6 — `::122` (hostname `gre`, НЕ gre-hetzner2, его игнорировать).** На `gre`: gre1 UP
`local .122 remote 135.181.95.108 (hetzner)`, внутр. `fd32::2↔fd32::1`, NETMAP `-s 2a03:5a00:c:20::/118 --to
2a01:4f9:c010:cf42::/118` + MASQUERADE, fwd=1. Удалённый конец `fd32::1` пингуется (6.9 мс).
Но **транзит Telegram-v6 через gre1 не работает**: с коробки `gre` даже мелкий `ping6` до Telegram (2001:67c:4e8::)
= 100% loss (НЕ MTU — крупный тоже; MSS-clamp нет ни v4, ни v6). При этом:
- **Общий IPv6 здоров везде**: `ya.ru`/google по v6 = 302 с igw, egw, **и с самой коробки `gre`** (идёт обычным
default-маршрутом `via 2a03:5a00:c:20::1`, не в туннель). Так что проблема НЕ в IPv6 как таковом.
- **hetzner сам** Telegram-v6 достаёт (302), и даже **с источником `fd32::1`** (свой конец туннеля) = 302; обратный
маршрут NETMAP-префикса `2a01:4f9:c010:cf42::/118 via fd32::2 dev gre1` есть; MASQ `fd32::/126` крутится (81M пакетов).
Итог по tcpdump на hetzner gre1+eth0 (2026-06-05): найдено ДВЕ причины.
**Причина 1 — NETMAP не работает на Hetzner (on-link /64, нет NDP-proxy).** На коробке `gre` правило
`-s 2a03:5a00:c:20::/118 -o gre1 -j NETMAP --to 2a01:4f9:c010:cf42::/118` стоит ПЕРЕД catch-all MASQUERADE.
Трафик igw(`::13`)/egw(`::14`) → NETMAP → `2a01:4f9:c010:cf42::13/14`. Дамп: SYN доходит до hetzner и форвардится
в Telegram, но SYN-ACK НЕ возвращается. **Корень:** на hetzner /64 настроен `noprefixroute` (on-link на eth0),
`proxy_ndp=0`, ndppd нет → Hetzner НЕ маршрутизирует /64 на хост, апстрим доставляет пакеты через NDP, а хост
отвечает на NDP только за свои адреса (`::1`); на NETMAP-адреса (`::13/::14`) ответа нет → обратный трафик дропается.
А трафик самой коробки `gre` (src `fd32::2`) попадает в MASQUERADE → реальный `::1` (на него NDP отвечает) → работает
(в дампе полный TLS-обмен, 302). Подтверждено коррелированным тестом: когда `hz1_direct=302`, `igw(NETMAP)=000`.
**Ответ на «возможен ли нормальный NETMAP на Hetzner» (доки Hetzner + тесты 2026-06-05):**
По докам Hetzner: на **dedicated и CX-line** VPS /64 **МАРШРУТИЗИРУЕТСЯ** на link-local адаптера (шлюз `fe80::1`) —
любой адрес из /64 пригоден, NDP на каждый не нужен. Только на старых **VQ/VX** /64 on-link (шлюз `::1`).
Наши узлы (hz1 и egw2) — шлюз `fe80::1` = **routed-модель → NETMAP штатно поддержан, ndppd НЕ нужен**.
- Подтверждение: в дампе NETMAP-поток egw (`::14`) ↔ Microsoft работал (обмен данными) → механизм исправен.
- Поэтому мои тесты с `proxy_ndp`/назначением адреса ничего не меняли — проблема НЕ в NDP.
- Док `router/docs/egw-ogw-gateways.md:231` про on-link — формулировка вводит в заблуждение; на самом деле routed.
Остаточная странность: `igw`(NETMAP `::13`) → Telegram стабильно 000 даже при одновременном `hz1_direct`=302 —
причина специфична для этого источника/назначения (плюс флап Telegram-v6 на hz1). Не до конца локализовано, но
**неважно: egw2 Telegram-v6 держит стабильно (302 ×6)** → решение = направить обход на egw2 (вариант B), NETMAP там
легитимен (routed-/64). MASQUERADE — запасной вариант (источник = реальный `::1`, проверенно работает).
ICMP-ping к Telegram — не индикатор: Telegram не отвечает на ICMPv6 echo (google/cloudflare пингуются).
**Причина 2 — флап Telegram v6 с самого hetzner #1.** `curl -6` к Telegram с egw.eterhost.ru то 302, то 000
(`ya.ru` v6 стабилен). То есть путь hetzner#1 → Telegram v6 нестабилен независимо от NAT.
## Два узла на Hetzner (важно!)
- **egw.eterhost.ru = hetzner.egw** = `135.181.95.108` / `2a01:4f9:c010:cf42::1` (узел #1). Telegram v6 — ФЛАПАЕТ.
- **egw2.eterhost.ru** = `178.105.209.27` / `2a01:4f8:c015:abd8::1`, Hetzner FSN1 (узел #2, ssh порт **22**).
Telegram v6 — **стабильно 302 ×3**. Без v6-NAT.
Боевой обход Telegram-v6 идёт через `gre` (`::122`) → gre1 → **hetzner #1** (флапающий) с битым NETMAP.
Коробка **gre-hetzner2** (`.142`/`::142`) — туннель на **egw2** (#2), но NETMAP-ит в префикс #1 (`cf42`, не `abd8`),
egw2 без NAT → даже `ya.ru` v6 = 000. Поэтому НЕ использовать (подтверждено).
Возможный фикс (НЕ применял, требует решения): обход Telegram-v6 направить на egw2 (стабильный) с корректным
NAT, ИЛИ на `gre` заменить NETMAP→MASQUERADE (клиенты пойдут с реального адреса hetzner) + разобраться с флапом #1.
Практический обход: клиенты ходят в Telegram по IPv4 (`socks5://` локальный DNS в IPv4-only контейнерах).
## Следствие для SOCKS-прокси microsocks (igw:1080)
microsocks запущен `-i ::` (dual-stack). Когда клиент просит **remote DNS** (`socks5h://`), microsocks сам резолвит
api.telegram.org, glibc отдаёт сначала AAAA → идёт по битому IPv6 → виснет. Когда клиент использует **локальный DNS**
(`socks5://`) и сам IPv4-only — отдаёт прокси IPv4-литерал → коннект по рабочему IPv4 → ОК.
- **Клиенты прокси для Telegram: используйте `socks5://`, НЕ `socks5h://`.**
- `microsocks -b <IPv4>` вместе с `-i ::` ломает listener (перестаёт отвечать) — НЕ применять.
- Тест с igw localhost (`--socks5 127.0.0.1:1080`) обманчив (loopback к ::-сокету ведёт себя иначе) — тестировать с
реального клиента: `curl --socks5 91.232.225.13:1080 https://api.telegram.org/`.
Использует это: [[reference-ruskru-telegram-notifier]]. Связанное про telemt/обходы: [[lesson-telemt-middle-proxy-egress-match]].
---
name: lesson_ikev2_beget_cert_dns_fix
description: ikev2.beget (.130) обход-шлюз — почему лёг и как чинился (certbot/cert/DNS/CA/start_action)
metadata:
node_type: memory
type: project
originSessionId: 14186ced-b55d-4e55-aa31-d3b9dee9d8f9
---
ikev2.beget.ogw = CT **91.232.225.130** (hostname `ikev2`), IKEv2/strongSwan-swanctl клиент к beget VDS (217.12.37.55 = `beget.ogw.eterhost.ru` = `rogohapla.beget.app`). microsocks :1080 экспортит трафик через туннель (exit 217.12.37.55). Лежал с ~мая 2026, починен 2026-06-15. **Несколько наложенных причин:**
1. **certbot на beget сломан**: pip поставил `urllib3 2.2.3` в `/usr/local/lib/python3.8` (перекрыл системный 1.25.8), убрал модуль `urllib3.contrib.appengine`, нужный старому `requests_toolbelt`/certbot 0.40 → certbot падал с ImportError на каждом запуске (letsencrypt.log пустой). Фикс: `pip3 install 'urllib3<2'` (1.26.20).
2. → LE-серт `rogohapla.beget.app` протух 4 мая. Плюс renewal был `authenticator = standalone`, а :80 занят nginx (vhost chat.eterfund.ru, serves `/.well-known/acme-challenge/` из `/var/www/html`) → `StandaloneBindError`. Переключил на **webroot**: `certbot certonly --webroot -w /var/www/html -d rogohapla.beget.app --cert-name ... --force-renewal`.
3. **Перечитка серта в charon**: `ipsec reload && ipsec rereadall` НЕ подхватывает новый leaf — charon отдаёт старый кэшированный серт. Нужен **`ipsec restart`**. Поэтому `renew_hook` в `/etc/letsencrypt/renewal/rogohapla.beget.app.conf` сменил на `ipsec restart`.
4. **CT не доверял новой цепочке**: новый серт идёт `leaf ← YR2 ← ISRG Root YR ← ISRG Root X1`, а x509ca-хранилище CT (`/etc/strongswan/swanctl/x509ca/`) было ПУСТОЕ (нет якоря; «Root YR» в системном bundle CT отсутствует). Положил туда `chain.pem` beget (YR2+Root YR) + `ISRG_Root_X1.pem` из системного bundle → `swanctl --load-all`. Также charon на CT кэширует полученный серт в памяти — после смены серта нужен `systemctl restart strongswan` на CT.
5. **«Курица-яйцо» с DNS**: resolv.conf на CT = `8.8.8.8/8.8.4.4`, недостижимы без default route (его ставит туннель). У рабочего аналога **.120** resolv.conf = локальный `91.232.225.10` (достижим всегда). Фикс на .130: добавил статические маршруты `8.8.8.8`/`8.8.4.4 via 91.232.225.1` в `/etc/systemd/network/10-eth0.network` (рядом с уже имевшимся `Destination=217.12.37.55`).
6. **Автостарт**: у .130 не было `start_action` (в отличие от .120). Добавил `start_action = start` в child `vpn` в `/etc/strongswan/swanctl/conf.d/beget.conf`. (В `/etc/rc.d/rc.local` ещё есть `sleep 10; swanctl --initiate --child vpn`.) Поднятие: `swanctl --initiate --ike vpn` затем `--child vpn`; маршрут default через `ipsec1` ставит updown `/usr/local/bin/rw-updown.sh`.
**ГРАБЛИ networkd**: сеть CT на **systemd-networkd**, активен только `10-eth0.network` (сортируется раньше `eth0.network`+drop-in `eth0.network.d/monitoring.conf`). `networkctl reload` ВЫЧИЩАЕТ маршруты, которых нет в активном файле — снёс `10.20.30.0/24 via 91.232.225.1` (был только в неактивном monitoring.conf), из-за чего сломался обратный путь к telegraf-хосту (мониторинг показал down, хотя с igw прокси работал). Перенёс `Destination=10.20.30.0/24` в `10-eth0.network`.
Мониторинг см. [[lesson_proxy_monitoring_functional_check.md]]. Серт теперь до 13 сен 2026, автообновление webroot — боевой прогон прошёл (staging --dry-run зависает, это артефакт staging).
---
name: lesson_mail_cert_renewal_webroot_hook
description: "mail.etersoft.ru Let's Encrypt renewal webroot auth + deploy-hook; две причины сломанного обновления (фикс 2026-07-04)"
metadata:
node_type: memory
type: reference
originSessionId: b383b2ce-248b-4e35-be70-ce592001dc88
---
Сертификат **mail.etersoft.ru** (Let's Encrypt, 16 SAN: mail/imap/smtp .etersoft.ru + .com/.net/.org, mail.eterhost.ru, smtp.eterhost.ru, autoconfig/autodiscover.etersoft.ru).
**Механизм обновления:**
- `/etc/cron.weekly/letsencrypt``certbot renew`, **webroot** auth, путь `/var/spool/nginx/tmp/client` (см. `/etc/letsencrypt/renewal/mail.etersoft.ru.conf`).
- После успешного renewal certbot запускает deploy-hooks из `/etc/letsencrypt/renewal-hooks/deploy/`. Там `update_pem.sh` → симлинк на `/etc/postfix/tls/update_pem.sh`, который раскладывает live-сертификат:
- **Postfix**: combined fullchain+privkey → `/etc/postfix/tls/mail.etersoft.ru_full.pem` (ОДИН файл для cert и key: `smtpd_tls_cert_file = smtpd_tls_key_file`).
- **Cyrus**: cert → `/var/lib/imap/ssl/mail.etersoft.ru.crt`, key → `/var/lib/imap/ssl/etersoft.pem` (`tls_server_cert`/`tls_server_key` в `/etc/imapd.conf`).
- Перезапускает postfix, cyrus-imapd, nginx.
- nginx сам читает `/etc/letsencrypt/live/mail.etersoft.ru/fullchain.pem` напрямую (sites-enabled.d/mail.etersoft.ru.conf).
**Две причины, из-за которых почта сидела на протухшем сертификате (инцидент 2026-07-04):**
1. Cron делал `serv nginx stop` перед `certbot renew` — рудимент от старого standalone-auth. webroot **требует поднятый nginx** → challenges падали, `All renewals failed` (логи Jun 21/28). Убрано: теперь cron только `certbot renew`.
2. Deploy-hook был подвязан **только** через устаревший `--renew-hook` в cron-строке. Ручной `certbot --expand --webroot` (11 апр, добавляли домены autoconfig/imap.*/smtp.*) прошёл **без хука** → копии для Postfix/Cyrus не обновились, mail так и служил сертификатом от 4 апр (истёк 3 июл). Фикс: хук перенесён в каталог `/etc/letsencrypt/renewal-hooks/deploy/` (срабатывает при **любом** renewal).
**Диагностика:** сравнить `openssl s_client -connect mail:PORT` (что служится) с `certbot certificates` (что в live). Расхождение дат = копии для демона не обновились. Проверять все порты: 993/465/443/25(STARTTLS).
См. также [[lesson_mail_postfix_sasl_config_path]] — пути postfix на mail.etersoft.ru.
---
name: matrix-etersoft-synapse-disk-telegram-bridge
description: matrix.etersoft.ru = Synapse на CT 291 (border), доступ ssh alias `matrix` порт 32; media_store пухнет из-за Telegram-моста mautrix-telegram на tele.eterfund.ru; диск переполнялся, расширен +20G; мост выключен 2026-06-14
metadata:
type: project
---
## Matrix-сервер etersoft
- **Homeserver:** `matrix.etersoft.ru` = **91.232.225.42**, Synapse (на 2026-06-14 — v1.148.0).
- **Хост:** LXC **CT 291** на **border** (PVE), ZFS `pool0/subvol-291-disk-0`, hostname внутри `matrix`.
- **SSH:** alias **`matrix`** в `~/.ssh/config` → порт **32**. Заходить `ssh -p32 root@matrix.etersoft.ru` (lav@ НЕ пускает; нужен ssh-agent с ключом id_rsa — на builder ключи на диске отклоняются, нужен `ssh-add`). На самом порту 22 — refused.
- **Веб-клиент:** Element на `chat.eterfund.ru` (91.232.225.105), `.well-known` указывает homeserver на `matrix.etersoft.ru:443`. (Старая заметка про бэкенд на enceladus 192.168.0.17 — устарела, см. [[chat-eterfund-ru-architecture-and-gyle-ip-collision]].)
- **БД:** PostgreSQL на **10.20.30.119**, база/юзер `eter_matrix`, пароль — в `/etc/synapse/homeserver.yaml` (на контейнере нет `psql`, но есть `python3`+`psycopg2`: запрос через `python3 -` с psycopg2.connect).
- Конфиг Synapse: `/etc/synapse/homeserver.yaml`; appservice-регистрации в `app_service_config_files`.
## Переполнение диска (инцидент 2026-06-14)
Симптом: «файлы не отправляются». Причина: диск CT 291 — **100% (119G/119G, и inode 100%)**.
Расширил ZFS-subvol: `ssh root@border 'pct resize 291 rootfs +20G'` → стало 139G, 20G свободно.
В пуле `pool0` на border было ~162G free, запас есть.
Куда уходит место: `/var/lib/synapse/media_store` = **116G**, из них `local_content` **102G**.
Топ по `local_media_repository`: **`@telegrambot:matrix.etersoft.ru` = 75G (55502 файлов)** — это Telegram-мост, не человек. Остальное — puppet-юзеры `@telegram_<id>`. Всего local media ~99G / 105540 файлов. Живые люди — сотни МБ.
## Telegram-мост (mautrix-telegram)
- Зеркалит в Synapse media_store **всё медиа** из связанных публичных Telegram-чатов (фото/видео/стикеры) → отсюда рост.
- Связанные чаты (по числу участников): PLAFON ЧАТ (3550), Кают-компания Альт Линукс (3086), Альт Линукс (2518), ALT Gnome Chat (1892), EPM сообщество, LINUX-GAMING.RU, Ximper, ALT KDE/Mobile, Hyprland и др. (~40+ комнат) + внутренние «Etersoft инфраструктура/для сотрудников».
- **Рабочий мост запущен НЕ на matrix**, а на отдельном хосте **`tele.eterfund.ru`** (IPv6 2a03:5a00:c:20::135), ssh порт **32**, оболочка по умолчанию — **fish** (команды гнать через `bash -lc`). systemd-сервис `mautrix-telegram.service`, слушал `0.0.0.0:29317`, конфиг `/etc/mautrix-telegram/config.yaml` + `/etc/mautrix-telegram/registration.yaml`.
- Регистрация в Synapse: `/etc/synapse/mautrix-telegram-registration.yaml`, `url: https://tele.eterfund.ru:29317`, `id: telegram`, `bot_username: telegrambot`.
- На самом matrix остался незадействованный `/etc/mautrix-telegram` (placeholder-конфиг) + пустой `/var/lib/mautrix-telegram`**удалены 2026-06-14** (косметика, места не дали).
## Действия 2026-06-14
- Расширен диск CT 291 на +20G (pct resize).
- Удалены пустышки `/etc/mautrix-telegram`, `/var/lib/mautrix-telegram` на matrix.
- **Контейнер `tele.eterfund.ru` выключен (`poweroff`)** по указанию — мост остановлен, новые медиа от `@telegrambot` не поступают. Synapse работает.
## How to apply
- Освобождение места по мосту (только бридж, без потери данных людей): Synapse Admin API
`DELETE /_synapse/admin/v1/users/@telegrambot:matrix.etersoft.ru/media?before_ts=<ms>&size_gt=<bytes>`.
- Глобальный `media_retention` в homeserver.yaml (`local_media_lifetime`/`remote_media_lifetime`) — только server-wide, локальное чистится по last-access (щадит активные файлы людей).
- Кэш federation (восстановим): `remote_content` ~8.7G + `remote_thumbnail` ~985M.
- Запустить мост обратно: поднять CT `tele` через PVE-host, `mautrix-telegram.service` поднимется из автозапуска.
- Поставить мониторинг свободного места CT 291 (netdata уже стоит) в Uptime Kuma.
## Связанные
- [[chat-eterfund-ru-architecture-and-gyle-ip-collision]]
- [[feedback_no_unauthorized_actions]]
---
name: lesson-office-home-nfs-mount-fail
description: "office build-хосты монтируют /home с homeserver (aspetos, NFSv4); home.mount может упасть при загрузке и не повториться ssh по ключу ломается"
metadata:
node_type: memory
type: reference
originSessionId: d5fd66e6-c744-47dd-9f22-7810d755d391
---
Office-хосты (builder-c10 192.168.0.83 и подобные) монтируют `/home` с **homeserver = aspetos.office.etersoft.ru (192.168.0.46)** по NFSv4 (`/etc/fstab`: `homeserver:/home /home nfs ...`).
**Симптом:** `ssh <host>` под lav вдруг отказывает (`Permission denied (publickey)`), хотя host-key совпадает и хост жив.
**Причина:** systemd-юнит `home.mount` может **разово таймаутнуться при загрузке** и больше не повторить попытку — `/home` остаётся непримонтированным месяцами. Под ним виден локальный **скелет** со старыми каталогами и пустым `authorized_keys` (только строка-комментарий) → вход по ключу падает. Раньше выручал Kerberos/GSSAPI, но в неинтерактивной сессии (Claude) тикета нет (`klist` пуст).
**НЕ писать ключ в скелет!** Сначала проверить монтирование: `mountpoint /home`, `df -h /home`, `systemctl status home.mount`.
**Ложный след:** `showmount -e homeserver``RPC: Unable to receive` — это НЕ признак мёртвого NFS. aspetos — NFSv4-сервер (без mountd/rpcbind, которые опрашивает showmount). Проверка, что NFS жив: смонтирован ли `homeserver:/home` на другом хосте (напр. builder64).
**Фикс:** `systemctl reset-failed home.mount; systemctl start home.mount` (поднимается сразу, если NFS жив), либо просто перезагрузка хоста — после ребута `home.mount` active, /home монтируется на этапе загрузки.
**Отложено (2026-06-12):** упрочнить через `x-systemd.automount` в fstab на office-билдерах, чтобы /home поднимался при первом обращении и сбой загрузки не оставлял хост со скелетом. Пререквизиты на builder-c10 есть (systemd 249, ядерный autofs, systemd-fstab-generator; пакет-демон autofs НЕ нужен). Правка одной строки fstab + `systemctl daemon-reload`, ребут не обязателен. Не применяли по решению lav.
См. docs/nfs.md (aspetos/spacer, manage-gids, FS-Cache).
---
name: lesson-pptp-nat-nf-conntrack-helper
description: "PPTP/FTP/пр. через Linux-NAT не работают, если на ядре ≥4.7 nf_conntrack_helper=0 (дефолт): хелперы не пристёгиваются автоматически. Фикс явное CT-правило в raw-таблице"
metadata:
node_type: memory
type: reference
originSessionId: 9c0556d2-80fc-44a4-b1a3-4db2e9d46f37
---
# PPTP/FTP через Linux NAT: грабля с nf_conntrack_helper=0
Симптом: PPTP-клиент за Linux-NAT — управляющий TCP 1723 соединяется (call established), но LCP отваливается по таймауту. tcpdump показывает: **GRE исходящий (SNAT'нутый) уходит, ответный GRE от сервера доходит до NAT-бокса, но не доезжает до клиента** (de-SNAT для GRE не срабатывает).
Корень: с ядра ~4.7 `net.netfilter.nf_conntrack_helper = 0` по умолчанию → conntrack-хелперы (`nf_conntrack_pptp`/`nf_nat_pptp`, `nf_conntrack_ftp` и пр.) **НЕ пристёгиваются к соединениям автоматически**, даже если модули загружены. Без хелпера PPTP не парсит управляющий канал → нет expectation для GRE → ответный GRE не матчится и дропается/уходит локально.
Проверка:
```
sysctl net.netfilter.nf_conntrack_helper # 0 = авто-хелперы выключены
iptables -t raw -S | grep -i helper # нет CT-правил = хелперы не активированы
cat /proc/net/netfilter/nf_conntrack_expect # пусто = expectations не создаются
```
Фикс (предпочтительно, targeted): явное CT-правило в raw-таблице —
```
iptables -t raw -A PREROUTING -p tcp --dport 1723 -j CT --helper pptp
```
Персистировать в `/etc/sysconfig/iptables` (секция `*raw` с `:PREROUTING ACCEPT`/`:OUTPUT ACCEPT` + COMMIT; проверить `iptables-restore --test`). Альтернатива (проще, но шире/менее безопасно): `sysctl net.netfilter.nf_conntrack_helper=1`.
Диагностика «ответный GRE не до клиента»: захват на NAT-боксе `tcpdump -ni any "proto 47"` (БЕЗ фильтра по client-IP — SNAT меняет адрес, фильтр его скроет). Сравнить `In` на внешнем iface и `Out`/`vmbr Out` на внутреннем.
Реальный кейс: priv (91.232.225.1 = 10.20.30.1 на vmbr0, ядро 5.10) — PPTP-клиент rca-gw (10.20.30.250) не работал, пока не добавили CT-правило. См. [[project-rarus-1c-vpn-gateway]].
Связано: [[feedback-ip-openness-tiers]], [[lesson-pptp-rarus-chap-secrets-domain]]
---
name: lesson-pptp-rarus-chap-secrets-domain
description: "pppd/PPTP с NT-доменом: name БЕЗ префикса DOMAIN\\user обратный слеш ломает матчинг chap-secrets 'No auth is possible'. MPPE через require-mppe-128, stateless по умолчанию"
metadata:
node_type: memory
type: reference
originSessionId: 9c0556d2-80fc-44a4-b1a3-4db2e9d46f37
---
# pppd + PPTP с NT-доменом: грабли
При настройке PPTP-клиента (pppd 2.5.2, [[project-rarus-1c-vpn-gateway]]) к серверу с NT-доменом (Rarus, домен `guestrarus`):
1. **`name` БЕЗ префикса `DOMAIN\user`**. Если задать `name "guestrarus\\1R59262U1"`, pppd на стадии LCP пишет **`No auth is possible`** и отвергает `<auth chap MS-v2>` — потому что `have_chap_secret()` не находит запись в `chap-secrets` для имени с обратным слешём (мэтчинг ломается), и CHAP убирается из allow-options. Решение: `name "1R59262U1"` (чистый логин); NT-домен сервер знает сам. В chap-secrets: `1R59262U1 rca <PASS> *`.
2. **`noauth` и `refuse-chap` — не виновники** «No auth is possible» (первое подозрение было на них, но убирание не помогло). Реальная причина — пункт 1 (отсутствие секретa для имени).
3. **MPPE**: `require-mppe-128` + stateless по умолчанию. Опции `mppe-stateless` НЕ существует (pppd 2.5.2 — ошибка «unrecognized option»); stateful включается через `mppe-stateful`. Переговор: сервер предлагает stateful (+C), клиент настаивает на stateless → `MPPE 128-bit stateless compression enabled`. Нужен модуль `ppp_mppe` на хосте (в LXC — проброс /dev/ppp).
4. Глобальный `/etc/ppp/options` в ALT-шаблоне содержит **`noauth` + `replacedefaultroute`** — последний украдёт default route (ломает изоляцию VPN-шлюза). Для выделенного CT переписать в `lock`.
В шаблоне CT 720 NetworkManager НЕ установлен — только etcnet; raw pppd валиден.
Связано: [[project-rarus-1c-vpn-gateway]]
---
name: lesson_proxy_monitoring_functional_check
description: "Мониторинг SOCKS5-прокси шлюзов обхода функциональная проверка через curl, а не TCP-порт"
metadata:
node_type: memory
type: project
originSessionId: 14186ced-b55d-4e55-aa31-d3b9dee9d8f9
---
Мониторинг прокси-шлюзов обхода (карта `proxy` в health.json / веб-UI route-web-api на igw) делается на хосте **telegraf** (telegraf.office.etersoft.ru, 10.20.30.130, там же InfluxDB БД `gateways` + Grafana).
**Проблема (была до 2026-06-15):** `/etc/telegraf/telegraf.d/proxy-check.conf` использовал `[[inputs.net_response]] protocol=tcp` к `91.232.225.X:1080`. microsocks держит порт :1080 открытым даже когда апстрим-туннель мёртв → `result_code=0` всегда → мониторинг показывал все прокси зелёными, хотя ~16 из 28 реально не работали (весь vdska, весь sprintbox, xray.hetzner, amneziawg.hetzner, openconnect.hetzner, cloak.*, ovpn.* и др.).
**Фикс:** заменено на `[[inputs.exec]]``/etc/telegraf/check-proxies.sh` (interval 30s, timeout 20s). Скрипт параллельно делает `curl -m8 --socks5-hostname IP:1080 http://www.gstatic.com/generate_204` по каждому шлюзу и эмитит line protocol `net_response,gateway=NAME result_code=0i|1i,response_time=Ts`. Измерение/поле те же (`net_response`/`result_code`), route-health.sh не менялся (читает `SELECT last(result_code) FROM net_response WHERE time>now()-1m GROUP BY gateway`, 0=up).
**Добавить новый шлюз** — только правка списка `GATEWAYS` в `/etc/telegraf/check-proxies.sh` (единый источник, IP-список уже не в .conf). Тогда же добавлены отсутствовавшие: gre.hetzner2 (egw2, .142), gre.selectel.ogw (.141), ikev2.fr (.140), ikev2.gr (.139).
**Важно:** proxy `result_code` в route-health.sh используется только для ОТОБРАЖЕНИЯ (health.json `proxy` map + json_gw), failover-решения по-прежнему на ping-loss/vpn/iperf. Изменение мониторинга не влияет на маршрутизацию.
Бэкап старого конфига: `proxy-check.conf.bak-20260615-2119` на хосте telegraf. Перезапуск: `systemctl restart telegraf`. route-health.timer на igw — каждую минуту; прогон долгий (~135s), бывают наложения.
Связано: [[project_decommission_sprintbox.md]] (sprintbox-прокси мертвы — ожидаемо).
...@@ -6,7 +6,7 @@ originSessionId: 81ac66de-af1f-4f27-9c31-301f5806f8c5 ...@@ -6,7 +6,7 @@ originSessionId: 81ac66de-af1f-4f27-9c31-301f5806f8c5
--- ---
# warp.egw (CT 703 на border, IP .134) # warp.egw (CT 703 на border, IP .134)
- Лимит памяти выставлен **1024/1024** MB (был 512/512 — утечка warp-svc приводила к OOM раз в 1-2 недели). - Лимит памяти выставлен **2048/1024** MB (поднял 2026-06-12 с 1024; OOM повторялись и на 1024: 30.04/05.05/10.05/27.05). warp-svc похоже течёт/пухнет под трафиком — после рестарта RSS ~84 МБ (cgroup ~203 МБ), а до OOM дорастал до ~1 ГБ. Если OOM повторятся и на 2048 — следить за RSS warp-svc, возможно баг клиента. `pct set 703 -memory 2048` применяется на лету.
- В `/etc/systemd/system/warp-svc.service.d/cleanup-stale-nft.conf``ExecStartPre=-/usr/sbin/nft delete table inet cloudflare-warp`. Снимает stale ruleset перед стартом, разрывает курицу-яйцо после OOM SIGKILL. - В `/etc/systemd/system/warp-svc.service.d/cleanup-stale-nft.conf``ExecStartPre=-/usr/sbin/nft delete table inet cloudflare-warp`. Снимает stale ruleset перед стартом, разрывает курицу-яйцо после OOM SIGKILL.
- `systemctl stop warp-svc` (clean) сам корректно удаляет таблицу. Только SIGKILL (OOM, kill -9) — нет. - `systemctl stop warp-svc` (clean) сам корректно удаляет таблицу. Только SIGKILL (OOM, kill -9) — нет.
- При проблемах "warp не пингуется снаружи / Failed to perform happy eyeballs": `nft list table inet cloudflare-warp` — если таблица есть, а интерфейса CloudflareWARP в `ip a` нет → stale ruleset. Лечится `systemctl restart warp-svc` (drop-in отработает). - При проблемах "warp не пингуется снаружи / Failed to perform happy eyeballs": `nft list table inet cloudflare-warp` — если таблица есть, а интерфейса CloudflareWARP в `ip a` нет → stale ruleset. Лечится `systemctl restart warp-svc` (drop-in отработает).
......
# border (PVE-нода)
PVE-хост в кластере MIAC. CPU: **AMD Opteron 6164 HE** (2010, K10, **без AES-NI**), 24 потока. Доступ: `ssh root@border`.
Сети: vmbr1 (ether2) = публичный 91.232.225.0/24. Storage: `zpool` (ZFS).
Несёт много eterfund-гестов (jitsi, turn, dns, matrix CT 291, telemt.test, evpn CT 264 и др.).
## Changelog
### 2026-06-26 — с border сняты два VPN-гостя
- **Что:** CT 258 (vpn.eterfund.ru) и VM 292 (vpn.office.etersoft.ru) мигрированы на enceladus (Ryzen, AES-NI). С border ушли полностью.
- **Зачем:** Opteron 6164 HE без AES-NI делал OpenVPN-крипту софтовой → упор в ядро. Подробности: [[project_vpn_migrate_enceladus_aesni]].
- **evpn (CT 264) ОСТАЛСЯ на border** — его не переносили (IKEv2/strongSwan, см. [[lesson_evpn_ikev2_strongswan_cert]]).
# enceladus (PVE-нода)
PVE-хост в кластере MIAC. CPU: **AMD Ryzen 9 9950X** (Zen5, 32 потока, AES-NI ✅), 123 ГБ RAM. Доступ: `ssh root@enceladus` (192.168.0.17, порт 22; lav@ — нет ключа).
Сети: vmbr0 = офис 192.168.0/24, **vmbr1 (enp8s0) = публичный 91.232.225.0/24** (gw .1). Storage: `zpool` (ZFS, ~245 ГБ свободно на 2026-06-26).
Бэкенд chat.eterfund.ru (telemt CT 691). Несёт также host03, gitlab, rt, bugs, ximper и др.
## Changelog
### 2026-06-26 — приняты два VPN-гостя с border
- **Что:** на enceladus мигрированы CT 258 (vpn.eterfund.ru) и VM 292 (vpn.office.etersoft.ru) с border — ради AES-NI.
- VM 292 после переезда получила `cpu: host` (иначе AES-NI скрыт).
- Диски легли на storage `zpool`. Сетевой публичный сегмент тот же (vmbr1) → IP гостей не менялись.
- См. [[objects/vpn.eterfund.ru]], [[objects/vpn.office.etersoft.ru]], [[project_vpn_migrate_enceladus_aesni]].
# host03.eterhost.ru
Хостинг-нода Etersoft. **IP 91.232.225.9**, доступ `ssh -p32 root@host03`.
Виртуализация — **OpenVZ (legacy)**, `vzctl`/`vzlist`. Готовится **миграция** на новую платформу.
Справка по nginx/HTTPS/конфигам: `.claude/docs/host03.md`.
## Железо хоста
- CPU 6 ядер, RAM **22 ГБ** (постоянно занята: free ~120 МБ + ~16 ГБ cache).
- Диски: `/` 15 ГБ (59%), **`/var/lib/vz` 276 ГБ (81%, 51 ГБ свободно)** — приватки контейнеров.
- nginx **1.16.1** (фронт), **158 server_name**.
## Архитектура
- **nginx-фронт на хосте** терминирует TLS (Let's Encrypt), проксирует на бэкенды через переменную `set $subserver http://<ip>` (НЕ upstream-блок → при недоступности бэкенда отдаёт 502, не 503).
- Конфиги сайтов: `/etc/nginx/sites-enabled.d/*.conf` (+ автоген `generated/`). MediaWiki-сайты подключают `include/mediawiki.conf` (путь `location / → try_files → @proxy`).
- Бэкенды — **отдельные OpenVZ-контейнеры**, у каждого крупного сайта свой CT. Плюс общие: **CT 91 mysql** (192.168.3.91), **CT 188 memcached**, multi-site `sites41/43/47/81/390`.
## Контейнеры (vzlist, 2026-06-27)
| CT | hostname | IP |
|----|----------|----|
| 57 | etersoft.ru | 192.168.0.57 |
| 91 | **mysql** (общая БД) | 192.168.3.91 |
| 166 | nsud | .166 |
| **167** | **soulibre.ru** | .167 |
| 168 | kb.etersoft.ru | .168 |
| 169 | winehq.org.ru | .169 |
| 171 | wiki.eterfund.ru | .171 |
| 172 | pro.pravlub.ru | .172 |
| 173-179 | agiosignatios/agioslogos/psaltiki/patronas/todogroup/togaf/damaskin | .173-.179 |
| 182 | wiki.etersoft.ru | .182 |
| 183/184 | wikilivres.ru / org.wikilivres.ru | .183/.184 |
| 188 | **memcached** | 192.168.3.188 |
| 341/343/347/381/390 | sites41/43/47/81/sites (multi-site Apache) | 192.168.3.x |
| 444 | icecast | — |
| 151/202/348 | stopped (radio-spb/mebok/sites48) | — |
Бэкенды MediaWiki — prefork-Apache + PHP 7.4, **MySQL вынесен в CT 91** (в самих сайт-контейнерах mysqld не крутится).
## Лимиты nginx (важно для диагностики)
- `worker_processes 4`, `worker_connections 1024` → потолок ~4096 соединений (в простое уже ~2200!).
- `/etc/nginx/httpconf-available.d/limit_zone.conf`: глобально `limit_conn ipconlim 128` (per-IP); зоны `reqlim 10r/s`, `hostreqlim 10r/s` (ключ `$host`), `statreqlim 100r/s`, `mediareqlim 5r/s` — применяются точечно через `include/limits/*.inc`.
- **Грабли:** у soulibre `error_log ... crit` → события `limit_req` (`[error]`) НЕ пишутся в лог. Чтобы увидеть причину 503 — временно `crit``warn`, reload, потом вернуть.
## Changelog
### 2026-06-27 — массовые 503 на soulibre.ru (ДОКАЗАННАЯ причина)
- **Симптом:** soulibre.ru плавающе отдаёт 503, реально **1 685 200 ответов 503/сутки** (~60% запросов). Даже 1 запрос в 6 сек ловит 503; wikilivres.ru (тот же движок/хост) и etersoft.ru — чисто.
- **503 рисует nginx, НЕ бэкенд.** Apache в CT 167 за сутки отдал **0 ответов 503** (200/404/302/301/304), mod_status Load 0.5 — перегрузки нет. Бэкенд ни при чём (важно: первая гипотеза про «маленький CT 167 захлёбывается» оказалась неверной).
- **Корень (пойман через временный `error_log info`):** зона **`limit_req zone=hostreqlim`** (`limit_req_zone $host ... rate=10r/s`, burst 30) — лимит keyed по **домену, а не по IP**. Весь soulibre.ru делит **один бакет 10 r/s**. Скрапер-ботнет (ротация IP, фейковые UA `Gecko/9047`, `MSIE 6.0; Windows NT 11.0`) льёт ~35+ r/s на дорогие страницы MediaWiki (`Служебная:Свежие_правки`, `api.php?action=feedrecentchanges`, `Служебная:Вход`) → бакет вечно пуст (excess +30) → мгновенный 503 ВСЕМ (любой IP, любая частота). Лог: `limiting requests, excess: 30 by zone "hostreqlim", server: soulibre.ru`.
- **Почему не лечилось само (2 связанные ошибки):**
1. **`error_log .../soulibre.ru-error.log crit`** подавляет `[error]`-строки limit_req → причина невидима.
2. **fail2ban `nginx-excess`** читает `soulibre.ru-error.log` и банит по строке `limiting requests... by zone` — но из-за `crit` получает пусто → **скраперов не банит** → поток не спадает. (fail2ban в целом работает: 15k+ банов всего, но банит и легитимных — Googlebot 66.249.66.x, Bingbot 207.46.13.x, наш hetzner 135.181.95.108.)
- **Про IP:** `real_ip` в nginx закомментирован (`# real_ip_header X-Real-IP; # set_real_ip_from 91.232.225.22`). Внешние клиенты сохраняют реальные IP (в логах «все разные» — верно), коллапс в один IP только для офисного трафика через NAT priv = **91.232.225.2**. На этот 503 не влияет (hostreqlim и так per-$host).
- **«Больше воркеров» не нужно:** ни nginx, ни Apache не упёрлись; это per-domain rate-limit.
- **Лечение (по возрастанию):** (1) **самое дешёвое и важное — поднять у soulibre `error_log crit`→`error`**, тогда fail2ban начнёт видеть и банить скраперов, нагрузка спадёт; (2) добавить soulibre `include include/deny.conf` (у wikilivres есть, у soulibre **нет**); (3) поднять/убрать hostreqlim для soulibre или кэшировать анонимов (ботнет ходит как аноним); (4) в миграцию заложить anon-кэш + бот-митигейшн + нормальный sizing/PHP-FPM.
- hostreqlim определена в `httpconf-available.d/limit_zone.conf` (symlink из enabled), применяется через цепочку mediawiki-инклудов (`include/limits/dynamic.inc`).
- **fail2ban здесь бесполезен:** ботнет меняет IP на каждый запрос (из 3163 IP в логе лимита 3134 встречаются 1 раз) → `maxretry=3` не срабатывает. Бан по IP не вариант, нужно резать паттерн.
#### Что сделано (РЕШЕНО, 2026-06-27, всё с бэкапами .bak-*)
1. `soulibre.ru.conf`: `error_log crit → error` (вернуло видимость + питание fail2ban).
2. `soulibre.ru.conf`: добавлен `include include/deny.conf` (был только у wikilivres).
3. `soulibre.ru.conf`: **429-блок** для внешних анонимов (`$internal_access=0` и без cookie `UserID|UserName`) на `api.php`, `?action=`, `title=Служебная:*` (encoded `%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F`). Реализация — connection-flag через `set $sl_ext/$sl_bot` + `if ($sl_block="11") return 429;` (вставлено после `include deny.conf`). `return 429` отрабатывает в server-rewrite фазе **до** limit_req → 429 НЕ тратит квоту hostreqlim.
4. `httpconf-available.d/limit_zone.conf`: `hostreqlim` rate **10 → 30 r/s** (глобально; зона per-`$host`, каждый домен по 30).
- **Результат:** офис `/` 11/20→**0/20** 503; в последних 2000 запросах **0×503**, 1957×429 (боты), бэкенд load 0.00. Боты режутся 429, живые читатели проходят.
- Боты бьют по `Служебная:Свежие_правки`/`Связанные_правки`/`Ссылки_сюда`, `api.php?action=feed*`, `Служебная:Вход` (~98% трафика). Чистые URL статей (`/Название`) — <2%.
# priv (91.232.225.1 = 10.20.30.1 на vmbr0; ядро 5.10.198-std-def-alt1)
Центральный офисный маршрутизатор. Доступ: `ssh -p32 priv.etersoft.ru` (lav, потом sudo). Linux (не MikroTik), iptables. vmbr0 несёт сразу 91.232.225.0/24 и 10.20.30.0/24 (один L2-сегмент). Аплинки ether1/ether3 (SNAT 10.20.30/24 → 91.232.225.1 при выходе через ether1/ether3).
## 2026-07-03 — PPTP helper для NAT 10.20.30 (bug #19181)
- PPTP-клиент из 10.20.30 (rca-gw) не работал через NAT: control TCP 1723 OK, LCP timeout (ответный GRE не доходил до клиента). Корень: `net.netfilter.nf_conntrack_helper=0` (дефолт ядра ≥4.7) → хелперы не пристёгиваются автоматически. См. [[lesson-pptp-nat-nf-conntrack-helper]].
- Добавлено в `/etc/sysconfig/iptables` (новая секция `*raw`):
`-A PREROUTING -p tcp -m tcp --dport 1723 -j CT --helper pptp`
Бэкап: `/etc/sysconfig/iptables.pre-pptp-helper`.
- Модули `nf_conntrack_pptp`+`nf_nat_pptp` в `/etc/modules-load.d/pptp-nat.conf`.
- FORWARD policy ACCEPT, без state/INVALID-правил (GRE не дропается файрволом — проблема была именно в хелпере).
- Можно откатить: убрать `*raw` секцию (или восстановить из .pre-pptp-helper), удалить modules-load файл.
# rca-gw (CT 652, 10.20.30.250)
Изолированный PPTP-шлюз к облаку 1С-Рарус. bug #19181. См. [project_rarus_1c_vpn_gateway.md](../project_rarus_1c_vpn_gateway.md).
(Создан 2026-07-02 как 91.232.225.106; 2026-07-03 перенесён на внутренний 10.20.30.250.)
## 2026-07-02 — создание + Фаза 1
- Клон template-CT 720 на border (full, zpool), VMID 652, hostname rca-gw.
- IP 91.232.225.106/24, gw 91.232.225.1, vmbr1. etcnet: исправлен `ipv4route` (default), `network.service` enabled.
- `/etc/pve/lxc/652.conf`: проброс `/dev/ppp` (`lxc.cgroup2.devices.allow: c 108:0 rwm` + bind mount).
- Хост border: `/etc/modules-load.d/pptp-rca.conf` (ppp_generic, ppp_mppe, pptp, nf_conntrack_pptp).
- Пакеты в CT: ppp, pptp-client, ppp-pptp.
- Конфиги: `/etc/ppp/peers/rca-rarus` (MPPE-128, nodefaultroute, name 1R59262U1 без домена), `/etc/ppp/chap-secrets`, `/etc/ppp/ip-up.local` (route 172.22.0.0/16), глобальный `/etc/ppp/options`=`lock`.
- systemd: `rca-pptp.service` (pppd nodetach), `rca-firewall.service` (`/usr/local/sbin/rca-firewall.sh` — NAT + DROP inbound с ppp0). `/etc/sysctl.d/99-rca-gw.conf` (ip_forward=1).
- Результат: туннель поднимается, MPPE 128-bit stateless, маршрут 172.22.0.0/16 через ppp0, default route через breth0 (изоляция), входящие с ppp0 режутся.
## 2026-07-03 — полный переезд на NetworkManager-pptp
- Установлены NetworkManager + NetworkManager-pptp (после `epm update` — было 404).
- `/etc/NetworkManager/NetworkManager.conf`: `plugins=keyfile` (убран etcnet-alt, который держал breth0 «без управления»). `/etc/net/ifaces/breth0``breth0.disabled-etcnet`. `network.service` отключён.
- NM-профиль breth0 (ethernet, static). NM-профиль rca-rarus (vpn pptp): require-mppe + require-mppe-128, domain=guestrarus, never-default, routes=172.22.0.0/16, vpn.persistent=yes. Пароль в vpn.secrets.
- Грабли: (1) NM «ассумит» уже поднятый breth0 как external при restart — лечится down/up, на чистом буте нет. (2) без require-mppe-128 NM просит legacy/56 и сервер отвергает MPPE. (3) NM VPN autoconnect при буте ненадёжен → юнит `rca-vpn-up.service`.
- Удалён `/etc/ppp/ip-up.local` (маршрутом теперь рулит NM ipv4.routes). `rca-pptp.service` (raw pppd) отключён. `rca-firewall.service` After=NetworkManager-wait-online.
- onboot=1. Проверено: после ребута CT всё поднимается автоматически (breth0 под NM, ppp0 MPPE 128, маршрут, файрвол, интернет, изоляция).
- TODO: URL публикации 1С от Rarus → тест OData; ограничить FORWARD до IP клиентской машины.
## 2026-07-03 — перенос на 10.20.30.250 + фикс PPTP-through-NAT на priv
- Перенесён с публичного 91.232.225.106 на внутренний **10.20.30.250/24** (gw 10.20.30.1 = priv; принцип открытости [[feedback-ip-openness-tiers]]). pct net0 + NM-профиль breth0 обновлены.
- PPTP через NAT priv поначалу ломался: control TCP 1723 OK, но LCP timeout (ответный GRE не доходил до CT). Корень: на priv `nf_conntrack_helper=0` → PPTP-хелпер не активировался (см. [[lesson-pptp-nat-nf-conntrack-helper]]).
- Фикс на priv: `iptables -t raw -A PREROUTING -p tcp --dport 1723 -j CT --helper pptp``/etc/sysconfig/iptables`, секция `*raw`) + модули `nf_conntrack_pptp`/`nf_nat_pptp` в `/etc/modules-load.d/pptp-nat.conf`. Бэкап `iptables.pre-pptp-helper`.
- После фикса: PPTP на 10.20.30 работает (MPPE 128-bit stateless), переживает ребут CT (авто-восстановление: breth0 под NM, ppp0, маршрут, файрвол, интернет, изоляция).
- Шлюз теперь на внутреннем IP, ничего не торчит наружу.
# vpn.eterfund.ru (CT 258)
Внешний OpenVPN-сервер (full-tunnel). Доступ: `ssh -p32 root@vpn.eterfund.ru`.
Сервисы: `openvpn-server@eterfund` (udp/1195, 10.233.0.0/16, AES-256-GCM/SHA256, redirect-gateway), `openvpn-server@azbyka`.
Конфиги: `/etc/openvpn/server/eterfund.conf`, ключи в `/etc/openvpn/pki/`, клиентские .ovpn в `/etc/openvpn/ovpn/` (генерит `muvpn.sh`). Демон в chroot `/var/lib/openvpn`.
## Changelog
### 2026-06-26 — перенос с border на enceladus (ради AES-NI)
- **Что:** PVE-миграция контейнера CT 258 с хоста `border` на `enceladus` (оба в кластере MIAC). Команда: `pct migrate 258 enceladus --restart` (даунтайм 1:21).
- **Зачем:** border = Opteron 6164 HE без AES-NI → софтовый AES-256-GCM, однопоточный openvpn упирался в ядро (~49% CPU постоянно). enceladus = Ryzen 9 9950X с AES-NI.
- **Результат:** внутри CT теперь AES-NI есть (LXC видит флаги хоста), нагрузка openvpn ~49%→~0. IP (.180/.94/.69/.68 + 10.20.30.180), tun0/tun1, сервисы — без изменений. Storage тот же (`zpool`), публичный сегмент тот же (vmbr1 / 91.232.225.0/24) → IP/MAC не менялись, клиенты переподключились по keepalive.
- **Конфиги гостя НЕ трогались.** Изменился только хост размещения.
- Баг: Etersoft#16295. См. [[project_vpn_migrate_enceladus_aesni]].
# vpn.office.etersoft.ru (VM 292)
Офисный OpenVPN-сервер (KVM-гость). Доступ: `ssh vpn.office` (lav, не root).
Сервис: `openvpn-server@server`. Сети: net0 vmbr1 = 91.232.225.22 (публичный), net1 vmbr0 = 192.168.0.211 (офис), плюс wg0/tun0 (192.168.10.0/25).
Конфиг: `/etc/openvpn/server/server.conf`, демон в chroot `/var/lib/openvpn`.
## Changelog
### 2026-06-26 — перенос с border на enceladus + cpu host (ради AES-NI)
- **Что:** PVE-миграция VM 292 с `border` на `enceladus`. Оффлайн: `qm stop 292``qm migrate 292 enceladus --targetstorage zpool --with-local-disks` (0:55) → **`qm set 292 --cpu host`**`qm start 292`.
- **Зачем:** border без AES-NI; до переноса тип CPU был `kvm64` (скрывает AES-NI). На enceladus (Ryzen 9 9950X) + `cpu host` AES-NI открылся.
- **КРИТИЧНО:** без `qm set --cpu host` AES-NI остаётся скрытым даже на Ryzen — kvm64 не пробрасывает флаг.
- **Результат:** внутри VM CPU = Ryzen 9 9950X, AES-NI есть; нагрузка openvpn 18.6%→0.5%. IP 91.232.225.22 / 192.168.0.211, wg0/tun0, сервис `openvpn-server@server` — без изменений.
- **Изменён конфиг VM:** `/etc/pve/qemu-server/292.conf` → добавлено `cpu: host` (было по умолчанию kvm64). Конфиги внутри гостя НЕ трогались.
- Преда при старте: `iothread is only valid with virtio disk or virtio-scsi-single` — существующая, некритичная (scsi0 с iothread=1). На работу не влияет.
- Баг: Etersoft#16295. См. [[project_vpn_migrate_enceladus_aesni]].
---
name: project_alteros_lxc_build
description: "Задача сделать сборочный LXC AlterOS на PVE из docker-образа, аналогично redos"
metadata:
node_type: memory
type: project
originSessionId: 14186ced-b55d-4e55-aa31-d3b9dee9d8f9
---
**Задача (начата 2026-06-17):** из Docker-образа AlterOS x86_64 сделать LXC на PVE для сборки, аналогично уже сделанному **redos**-LXC.
**Выбранный образ:** `korinf-x86-64-alteros-9-wine-11.0:latest` (на builder64, 12.9GB) — wine-вариант AlterOS 9.
**Требования (от пользователя):**
1. rootfs из docker: `docker export | pigz > ~/tmp/claude/alteros9-wine11-rootfs.tar.gz` (экспорт запущен 2026-06-17).
2. Доменное имя **alteros.office.etersoft.ru**.
3. Выделенный IP (офисная сеть; проверить forward+reverse зоны, см. [[lesson_dns_free_ip_check_both_zones.md]], записать сразу).
4. **Доменная аутентификация** (AD/SSSD) — в репозитории есть `dc-client/tune_sssd.sh`.
5. **Монтирование как в `ssh redos`** — повторить mount'ы существующего redos-LXC (вероятно /home через NFS + сборочные каталоги).
6. Повторить общий конфиг redos-LXC (нода, storage, сеть, unprivileged?, ostype).
**Процедура Docker→LXC:** `docker create``docker export | pigz` → tar.gz → перенос на PVE-хост → `pct create <vmid> <tmpl> --ostype ... --net0 ... --rootfs ...` → пост-фиксы (getty/console, root pw/ssh, network, sssd, mounts).
**Эталон `ssh redos`** = VM 142 `redos64.office.etersoft.ru` (192.168.0.6) на aspetos, RED OS 8.0.2, QEMU (НЕ LXC). Сеть **vmbr0 = 192.168.0.0/24**, gw 192.168.0.1, ns **192.168.0.1**, search **office.etersoft.ru**. NFS в fstab: homeserver:/home→/home, srvserver:/srv→/srv, ftpserver:/{pvt,tmp,pub}→/var/ftp/*. Доменная auth — SSSD (`passwd: files sss systemd`, AD, dc.etersoft.ru=10.20.30.20). homeserver=srvserver=192.168.0.46 (aspetos), ftpserver=192.168.0.38 (spacer).
**СОЗДАНО (2026-06-18):** **CT 620 `alteros`** на gefest (vmbr0=192.168.0.13, zpool pool0).
- privileged, `features: nesting=1,mount=nfs` (NFS в privileged LXC работает!), ostype centos, 8c/8G/64G, onboot.
- IP **192.168.0.140/24**, gw .1, ns 192.168.0.1, search office.etersoft.ru (как redos).
- rootfs из `local:vztmpl/alteros9-wine11-rootfs.tar.gz` (docker export korinf-x86-64-alteros-9-wine-11.0). AlterOS 9.5 Agile Phoenix, systemd PID1.
- **SSH работает**: `ssh root@192.168.0.140` (ключи lav в authorized_keys). sshd enabled+active.
- **NFS**: все 5 монтирований активны, fstab почищен (рудиментарные root/boot/swap закомментированы; образ уже имел ftpserver-строки).
**ГРАБЛИ:** `pct` (perl -T) падает на унаследованной `ENV` из шелла — перед `pct exec` делать `unset ENV`. PVE storage id = `zpool` (не pool0). VMID 617 заняли под VM → взял 620.
**DNS:** ✅ добавлено через dns-skill — `alteros.office.etersoft.ru A 192.168.0.140` (зона office.etersoft.ru, serial→2026061810) + PTR `140` (0.168.192.in-addr.arpa, serial→2026061801) на хосте `dhcp` (BIND), git commit 513f948. Резолв OK в обе стороны.
**Проверено:** wine на месте, epm 3.64.56-alt1alteros, /home (NFS) показывает доменные home (aalyaev, ahtoh, ...). Контейнер рабочий для сборки под root.
**ОСТАЛОСЬ (отложено пользователем 2026-06-18 — «позже»):**
- Доменная аутентификация SSSD (AD join) — `dc-client/tune_sssd.sh Administrator`, нужен пароль AD Administrator + FQDN hostname (сейчас hostname короткий `alteros`; redos64 имеет FQDN). Без джойна логин только под root по ключу.
---
name: project-clean-template-etersoft-p11
description: "TODO: почистить LXC-шаблон template-etersoft-p11 (CT 720 на border) от residue, чтобы клоны были чистыми"
metadata:
node_type: memory
type: project
originSessionId: 27861819-a22e-4906-9c5e-02fdbd7542bb
---
# TODO: почистить template-etersoft-p11 (CT 720 на border)
Шаблон тащит мусор во все клоны. Почистить сам шаблон. Чек-лист (по факту разбора клона iot/CT 585, 2026-06-07):
- **docker-стеки в /opt**: `/opt/remnawave`, `/opt/remnanode` (remnawave/remnanode — VPN-панели), плюс `/home/pv/natsmesh` (broker+worker). Решить, что из этого должно быть в ШАБЛОНЕ, а что — только в конкретных клонах.
- **Лишние пользователи**: kondratyuk, stas, anton, diff, peertube, tss, go-socks5-server. Последний с битым tcb (нет /etc/tcb/<user>, запись в passwd осталась → userdel падает «не удалось заблокировать shadow», чистить вручную sed по /etc/{passwd,group,gshadow}).
- **root authorized_keys**: page, root@server.office, bombastermax, katze, mais, lav — оставить только нужные.
- **root shell = fish** (/usr/bin/fish) — неудобно для bash-скриптов/heredoc; решить, менять ли на bash.
- **enabled-сервисы**: docker.service, iptables.service, conntrack-log.service — нужны ли в шаблоне.
## ВАЖНО про чистку клонов (урок 2026-06-07)
При клонировании НЕ считать docker-стеки/юзеров автоматически мусором! На iot я снёс docker-стек natsmesh (это рабочий проект pv), хорошо что данные в /home/pv/natsmesh уцелели (prune убил только контейнеры+образы, не конфиги/creds/сертификаты) и восстановилось через `docker compose up -d`. Перед чисткой клона — спрашивать, что из содержимого нужно.
Связано: [[reference-create-lxc-container-pve]].
---
name: project-dchat-telemt-greek-tunnel-down
description: "d.chat.eterfund.ru (telemt Telegram MTProxy на divserver) не работает лежит IPsec-туннель divserver↔parentglobal к греческому exit. Диагноз готов, фикс отложен 2026-06-05"
metadata:
node_type: memory
type: project
originSessionId: 27861819-a22e-4906-9c5e-02fdbd7542bb
---
# d.chat.eterfund.ru не работает — диагноз 2026-06-05 (фикс отложен)
**d.chat.eterfund.ru** → CNAME `div.eterhost.ru` (divserver, 46.148.53.122). Это **telemt Telegram-MTProxy** в middle-proxy ME-режиме (`use_middle_proxy=true`, ad_tag `a248912d...`, pool_size=8). Конфиг: `/etc/telemt/config.toml`.
## Цепочка выхода (egress) к Telegram
```
telemt (divserver, src 10.43.0.2) ──ipsec1──> parentglobal (10.43.0.1, Греция) ──MASQUERADE──> 94.69.12.186 ──> Telegram DC
```
parentglobal = **gr.egw.etersoft.ru**, за NAT (Cosmote/Греция, динамич. 94.69.12.186), доступ: `ssh -p 10337 etersoft@anyssh.ru` (reverse-SSH), потом sudo. Связан с [[reference-remote-ssh-access]], [[lesson-telemt-middle-proxy-egress-match]].
## Корень проблемы
IPsec-туннель **divserver↔parentglobal (10.43.0.0/30) лежит**:
- divserver: `ping -I 10.43.0.2 10.43.0.1` 100% потерь, `No route to host` к Telegram, `swanctl --list-sas` пуст. Conn `parentglobal` загружен (IKEv2, dpd 30s), но SA нет; в charon-логе только сканеры, ноль попыток к peer.
- parentglobal: conn `divserver` загружен, но SA нет и **ноль попыток** инициировать (в логах пусто). Туннель к .139 (`site-to-site`) — ESTABLISHED, жив.
- Итог: telemt все коннекты к Telegram-DC (149.154.x:8888/:443) висят в `SYN-SENT` → d.chat не работает.
Греческий exit сам жив: parentglobal→Telegram :443 = OK; .139 выходит как 94.69.12.186.
## Фикс выполнен (runtime) 2026-06-06 — d.chat работает
Было ДВЕ причины:
1. **IPsec-туннель лежал, не переподнимался.** Поднял с parentglobal: `sudo swanctl --initiate --ike divserver --child s2s` (PSK parentglobal.eterfund.ru↔divserver.eterhost.ru, remote=d.chat.eterfund.ru; proposals AES_GCM_16_256 — всё ОК, нужна была только инициация). conn `divserver` БЕЗ `start_action` → после падения SA сам не возвращался.
2. **На divserver пропал policy-route для telemt** (telemt `bind_addresses=["10.43.0.2"]`, ipsec1). Аналог rule 50 (gre1→table 200) для ipsec1 отсутствовал. Добавил:
`ip route replace default via 10.43.0.1 dev ipsec1 table 201`
`ip rule add from 10.43.0.2 lookup 201`
Результат: telemt 51+ ESTAB к Telegram, ME-pool здоров, STUN видит 94.69.12.186 (= зарегистрированный egress, ME-режим), :443 слушает, трафик идёт.
## Персистентность СДЕЛАНА 2026-06-06 (переживёт ребут обоих хостов)
- **divserver** `/etc/systemd/system/ipsec1.service` (enabled, Before=strongswan): создаёт ipsec1 (xfrm if_id 43, 10.43.0.2/30) + `ip route replace default via 10.43.0.1 dev ipsec1 table 201` + `ip rule add from 10.43.0.2 lookup 201 priority 51`. Бэкап .bak-*. conn-responder `parentglobal` грузится strongswan ExecStartPost (conf.d/parentglobal.conf, if_id 43).
- **parentglobal** conn `divserver` (`/etc/strongswan/swanctl/conf.d/divserver.conf`): уже имел `start_action=start`+`close_action=start`+`dpd_action=restart`, но не был загружен в charon — сделал `swanctl --load-all` (грузится и при старте через ExecStartPost). Инициатор (за NAT), remote=d.chat.eterfund.ru, PSK.
- **parentglobal** MASQUERADE персистentен в **etcnet fw** `/etc/net/ifaces/default/fw/iptables/nat/POSTROUTING` (был пуст!): добавил `-s 10.10.10.4/30 -o enp3s0 -j MASQUERADE` (для .139) и `-s 10.43.0.0/30 -o enp3s0 -j MASQUERADE` (для divserver). iptables.service на parentglobal disabled — фаервол держит etcnet fw (docker/podman нет).
Сценарии ребута: divserver↓→ parentglobal по close/dpd переинициирует, маршрут уже в ipsec1.service. parentglobal↓→ start_action инициирует, MASQ из etcnet fw, divserver отвечает.
Связано: [[lesson-telemt-middle-proxy-egress-match]] (egress=registered IP для ME), [[reference-remote-ssh-access]], [[lesson-anyssh-ru-in-91232225]], [[lesson-etcnet-hooks]].
## Побочное (отдельно)
Сертификат `/etc/ssl/chat.eterfund.ru/fullchain.pem` на divserver (и на .43/.140) имеет SAN только `chat.eterfund.ru`, без `d.chat.eterfund.ru` → в браузере ошибка имени. Для telemt fake-TLS неважно. Cert раздаётся централизованно на все 3 узла (одинаковый, LE, выпуск 2026-05-08). nginx vhost (`server_name chat.eterfund.ru d.chat.eterfund.ru`) проксирует на web.matrix.etersoft.ru — это камуфляж-бэкенд.
---
name: project-iperf3-monitoring-frgr
description: "ЗАПЛАНИРОВАНО (не делать пока) настроить iperf3-мониторинг для туннелей ikev2.fr/ikev2.gr через установленный туннель, чтобы route-health красил их зелёным"
metadata:
node_type: memory
type: project
originSessionId: d5fd66e6-c744-47dd-9f22-7810d755d391
---
**Статус:** запланировано 2026-06-12, выполнять по отдельной команде. Выбран вариант (1).
**Проблема:** в left-column мониторинга на igw (route-web-api) ikev2.fr (.140) и ikev2.gr (.139) показываются `dead`, хотя туннели подняты. `route-health.sh` (строки 134-145) бракует туннельный шлюз, если нет данных iperf3, а у fr/gr их нет. `vpn_status=1` и ping loss=0 у обоих — живые.
**Топология:**
- ikev2.fr = CT 704 на border (91.232.225.140), пир rpi 78.193.2.190 (дом, Франция, за NAT). Доступ к rpi: `ssh -p 10338 root@anyssh.ru` (reverse-SSH). Туннель поднимает docker-контейнер `ikev2-fr` (образ `ikev2-fr-client`) на rpi; рядом `tunnel-fr`, `autoheal`.
- ikev2.gr = CT 706 на border (91.232.225.139), пир 94.69.12.186 (Греция). **Доступа к gr-пиру в заметках НЕТ — нужно получить.**
- Внутренний туннель: наша сторона `ipsec0 = 10.10.10.5/30`, дальняя = **10.10.10.6** (в netns туннельного контейнера). CT 704/706 → 10.10.10.6 = 0% потерь (проверено). Child SA: 0.0.0.0/0 ↔ 0.0.0.0/0, policy-based.
**Корень бага iperf3:** в `/etc/telegraf/telegraf.conf` на CT 704/706 цель iperf3 скопирована из шаблона egress-VDS: `iperf3-telegraf.sh 10.77.0.1 20` → 10.77.0.1 недостижим (100% loss). Надо `10.10.10.6`. Плюс на дальней стороне нет запущенного iperf3-сервера (бинарь на rpi-хосте есть, в контейнере `ikev2-fr` — нет, слушателя :5201 нет).
**План (вариант 1):**
1. Наша сторона (безопасно, контролируем): в telegraf.conf на CT 704 и CT 706 поправить цель `10.77.0.1``10.10.10.6`, `systemctl restart telegraf` (на ALT — `serv telegraf restart`).
2. Дальняя сторона: добавить iperf3-сервер (`iperf3 -s -B 10.10.10.6`) в docker-compose туннельного контейнера (`ikev2-fr` на rpi и аналог для gr), слушающий 10.10.10.6:5201, персистентно (переживёт пересоздание контейнера). Для gr — сперва получить доступ к пиру.
3. Проверка: `SELECT last(success) FROM iperf3 WHERE gateway='ikev2.fr'` на InfluxDB 10.20.30.130 (db gateways) → 1; затем `route-health.sh` на igw покрасит зелёным.
**Справка по дизайну мониторинга:** telegraf на каждом шлюзовом контейнере, gateway-тег в `[global_tags]`, iperf3 раз в 5 мин на внутренний IP удалённого узла (для egress-VDS это 10.77.0.1). Скрипт `router/scripts/iperf3-telegraf.sh` (iperf3 -c SERVER -t5 --json). Док: `router/docs/telegraf-monitoring.md`. См. [[reference_remote_ssh_access]].
---
name: project-rarus-1c-vpn-gateway
description: "Изолированный PPTP-шлюз к облаку 1С-Рарус (bug #19181): CT 652 rca-gw на border, 91.232.225.106. NetworkManager-pptp + MPPE. Рабочий, переживает ребут. Ждёт URL публикации (OData) от Rarus"
metadata:
node_type: memory
type: project
originSessionId: 9c0556d2-80fc-44a4-b1a3-4db2e9d46f37
---
# VPN-шлюз к облаку 1С-Рарус (bug #19181)
Цель: автоматизация (OData/HTTP) к базе 1С БУХ 3.0 в облаке Rarus (rarus-cloud.ru) через изолированный шлюз, чтобы Rarus НЕ имел доступа к нашим сетям.
## Где что
- **CT 652 `rca-gw`** на **border** (клон template-CT 720, ALT p11, full clone на zpool). `onboot=1`.
- **IP 10.20.30.250/24** (внутренний, vmbr1, gw 10.20.30.1 = priv). SSH: `ssh root@10.20.30.250` (shell **fish** → команды через `bash -s` heredoc или `bash -lc`; `epm` читает stdin — давать ему `</dev/null`).
- В `/etc/pve/lxc/652.conf` проброшен **`/dev/ppp`** (`lxc.cgroup2.devices.allow: c 108:0 rwm` + `lxc.mount.entry`).
- На хосте border в `/etc/modules-load.d/pptp-rca.conf`: ppp_generic, ppp_mppe, pptp, nf_conntrack_pptp.
## Конфигурация (NetworkManager-pptp — рабочая, переживает ребут)
- Сетевой менеджер: **NetworkManager** (`plugins=keyfile` в `/etc/NetworkManager/NetworkManager.conf`). etcnet `network.service` **отключён**, `/etc/net/ifaces/breth0` переименован в `breth0.disabled-etcnet` (плагин etcnet-alt забирал интерфейс → NM держал «без управления»).
- NM-профиль **breth0**: ethernet, static 91.232.225.106/24, gw 91.232.225.1, dns 91.232.225.10. После `systemctl restart NetworkManager` NM «ассумил» уже поднятый интерфейс как external (CONNECTED_LOCAL) → лечится полным down/up (detached restorer). На чистом буте проблемы нет.
- NM-профиль **rca-rarus** (vpn, pptp): gateway=rca.1c-hosting.com, user=1R59262U1, **domain=guestrarus**, refuse-eap/pap/chap/mschap=yes, **require-mppe=yes + require-mppe-128=yes** (КРИТИЧНО — без `-128` NM просит legacy/56 (-S +L) и сервер ConfRej-ит весь mppe → «peer refused»; см. [[lesson-pptp-rarus-chap-secrets-domain]]), ipv4.method=auto, never-default=yes, routes=172.22.0.0/16, vpn.persistent=yes. Пароль через `vpn.secrets` (password-flags=0, в keyfile).
- **NM VPN autoconnect при буте ненадёжен** (иногда даже попытки нет) → юнит **`rca-vpn-up.service`**: oneshot, After=NetworkManager-wait-online, поднимает `nmcli con up rca-rarus` с ретраями.
- Файрвол `rca-firewall.service` (`/usr/local/sbin/rca-firewall.sh`): NAT MASQUERADE ppp0→172.22.0.0/16; INPUT/FORWARD с ppp0 DROP (кроме ESTABLISHED,RELATED). FORWARD breth0→ppp0 пока открыт (TODO: ограничить до IP клиентской машины).
- `ip_forward=1` в `/etc/sysctl.d/99-rca-gw.conf`.
- Сервисы (все enabled): NetworkManager, rca-firewall, rca-vpn-up.
## Проверено
- ppp0 поднимается на буте автоматически, MPPE 128-bit stateless, маршрут 172.22.0.0/16 через ppp0.
- default route остаётся через breth0 (изоляция). Интернет работает.
- Входящие с ppp0 режутся файрволом.
- Переживает ребут CT (и onboot=1 — ребут хоста border).
## Блокеры Фазы 2 (от Rarus)
- **URL веб-публикации базы** `1R59262_BUH3_yCQJBgHDe3` — нужен для теста OData `GET <URL>/odata/standard.odata/$metadata`.
- Включён ли стандартный OData для инфобазы.
- Отдельный read-only пользователь 1С под интеграцию (НЕ пароль ЛК).
- Сменить пароль ЛК после настройки.
## DNS и доступ к 1С (расследовано 2026-07-03)
- Облачный DNS **172.22.0.22/.21** работает на свежих PPTP-сессиях (после фикса хелпера на priv). Домен облака — **guestrarus.local**. Ранее таймаутился на stale-сессии (control без хелпера) — НЕ пул-зависимое, проверено переподключениями.
- **rca-1c-200.guestrarus.local = 172.22.1.210** (узлы кластера 201/202 = .211/.212; rca-wsus-01 = 172.22.0.200).
- НО: подсеть кластера 172.22.1.x для VPN-клиентов L3/L4 закрыта (1941/80/443/3389 filtered, ping loss). Облако даёт VPN-клиенту DNS, но НЕ прямой доступ к кластеру 1С (тонкий клиент на rca-1c-200:1941 не работает через VPN). Только опубликованные ресурсы → доступ через веб-публикацию/OData (URL ждём от Rarus).
- PPTP-хелпер на priv — КРИТЕРИЙ корректного соединения: без него DNS/данные не идут (см. [[lesson-pptp-nat-nf-conntrack-helper]]).
## Статус
- Шлюз полностью рабочий и персистентный. **Задача приостановлена** (2026-07-03) до ответа Rarus по URL публикации/OData.
## Параметры VPN (от Rarus)
Шлюз `rca.1c-hosting.com` (94.79.29.241-243), логин `1R59262U1`, домен `guestrarus`, MPPE require (128-bit), MSCHAPv2, подсеть 172.22.0.0/16. RDP: rca-farm-03.1c-hosting.com. Кластер 1С: rca-1c-200:1941.
## Решение заказчика
Скрипт автоматизации на **отдельной машине** (не внутри шлюза) → нужен FORWARD для конкретного клиентского IP (пока TBD).
## История
- 2026-07-02: Фаза 1 через raw pppd (рабочая, зафиксирована). См. changelog.
- 2026-07-03: полный переезд на NetworkManager-pptp (решение заказчика, как в ТЗ).
- 2026-07-03: перенос с публичного 91.232.225.106 на внутренний **10.20.30.250** (принцип открытости). PPTP через NAT priv поначалу ломался (LCP timeout) — корень: на priv `nf_conntrack_helper=0` → PPTP-хелпер не активировался. Фикс: на priv raw-правило `iptables -t raw -A PREROUTING -p tcp --dport 1723 -j CT --helper pptp` (персистировано в `/etc/sysconfig/iptables`, секция `*raw`). См. [[lesson-pptp-nat-nf-conntrack-helper]]. После — PPTP на 10.20.30 работает, переживает ребут CT.
## Важно про priv
- Изменение на priv (центральный роутер): добавлена `*raw` секция с CT-правилом `iptables -t raw -A PREROUTING -p tcp --dport 1723 -j CT --helper pptp` в `/etc/sysconfig/iptables` (бэкап `iptables.pre-pptp-helper`). Модули `nf_conntrack_pptp`+`nf_nat_pptp` персистированы в `/etc/modules-load.d/pptp-nat.conf`. Фикс переживает ребут priv.
Связано: [[reference-create-lxc-container-pve]], [[feedback-lxc-via-ssh-not-pct]], [[lesson-pptp-rarus-chap-secrets-domain]], [[lesson-pptp-nat-nf-conntrack-helper]], [[feedback-ip-openness-tiers]]
---
name: project_vaultwarden_password_broker
description: ОТЛОЖЕНО — брокер паролей lavtomate password_request ↔ Vaultwarden; дизайн готов, реализация не начата
metadata:
type: project
---
**Статус: ОТЛОЖЕНО 2026-06-26** (по решению пользователя). Дизайн и инструкция готовы, реализация не начата.
Цель: пароли Claude получает ТОЛЬКО через lavtomate `password_request` с одобрением человека; на approve lavtomate сам достаёт секрет из Vaultwarden (коллекция `infra-claude`), Claude не держит мастер-ключ, plaintext не хранится. Правило: [[feedback_password_request_only]].
- **Полная инструкция:** `.claude/docs/vaultwarden-lavtomate-bridge.md` (10 разделов: Vaultwarden-сторона, bw CLI на хосте, systemd-credential для bootstrap-секрета, логика обработчика с проверкой коллекции, аудит, тесты, откат).
- Vaultwarden пустой — заводить с нуля. Источник правды для паролей решено сделать им (bitwarden.eterfund.ru).
## Что осталось сделать
1. **Vaultwarden (админ, могу я):** организация `Etersoft Infra` + коллекция `infra-claude` + сервис-аккаунт `claude-broker` (read-only, только эта коллекция) + API-key.
2. **Секреты для ручного admin-доступа** (kuma, grafana, ha-divserver) — уже перенесены в password store через rooter: `ssh rooter@server pass show <name>` (store `/var/lib/admin-pass` на server, root-only; доступ gated SSH-ключами rooter). Раньше лежали plaintext в `.claude/secrets/credentials.md` (gitignored). Для **Claude-автоматизации** целевой остаётся Vaultwarden (коллекция `infra-claude`, брокер ниже).
3. **lavtomate (dev, НЕ я — мейнтейнеры gitlab.eterfund.ru/etersoft/...lavtomate):** §2–§7 инструкции — bw CLI, unlock-сессия, обработчик password_request с проверкой коллекции.
4. **После связки:** удалить плоский `credentials.md`.
## Открытый вопрос
- Версия systemd на CT 653 (lavtomate) — поддерживает ли `systemd-creds`/`LoadCredentialEncrypted` (нужен ≥251). Не проверено. Если нет — fallback env-файл `0600`.
- Не выяснено: `password_request` сейчас просто показывает поле для ручного ввода, или уже куда-то ходит. От этого зависит, нужен ли dev-этап или сразу работает «ручной ввод из Vaultwarden».
Критичное (AD admin, CA-ключи, root) в `infra-claude` НЕ класть — оставить за ручным вводом в password_request.
---
name: project_vpn_migrate_enceladus_aesni
description: ВЫПОЛНЕНО 2026-06-26 — перенос vpn.eterfund (CT 258) и vpn.office (VM 292) с border на enceladus ради AES-NI (Ryzen)
metadata:
type: project
---
**✅ ВЫПОЛНЕНО 2026-06-26 ~07:48–07:53** (под присмотром, оба этапа успешно):
- CT 258 (vpn.eterfund): `pct migrate 258 enceladus --restart` за 1:21. Внутри теперь Ryzen 9 9950X, AES-NI ✅, IP .180/.94/.69/.68 на месте, openvpn@eterfund+@azbyka active, нагрузка 49.3%→~0.
- VM 292 (vpn.office): `qm stop` + `qm migrate 292 enceladus --targetstorage zpool --with-local-disks` за 0:55, затем `qm set 292 --cpu host` (КРИТИЧНО) + `qm start`. AES-NI ✅, IP .22/192.168.0.211 на месте, openvpn@server active, 18.6%→0.5%.
- Отписано в баг Etersoft#16295. Откатов не было.
- (Ночной автономный запуск 04:04 был прерван пользователем — ничего не выполнил; сделали утром вручную.)
Ниже — исходный план (оставлен для истории).
---
Перенос двух VPN-гостей **с border на enceladus** ради аппаратного AES-NI и быстрого ядра. evpn (CT 264) **НЕ трогаем** — пользователь не просил.
## Почему
- Оба VPN сейчас на **border** (физ. CPU `AMD Opteron 6164 HE`, 2010, **без AES-NI**) → AES-256-GCM считается софтово, демон openvpn упирается в одно ядро (он однопоточный). vpn.eterfund = full-tunnel `redirect-gateway`, процесс ел ~49.5% (1 ядро), CPU-time 34450 мин.
- **enceladus** = `AMD Ryzen 9 9950X` (Zen5, 32 потока, AES-NI ✅, 123G RAM/41 free). border и enceladus в одном PVE-кластере **MIAC** (6 нод: aspetos, gefest, border, hektor, spacer, enceladus).
- В Sisyphus только `openvpn-2.6.19` (на серверах 2.6.12); пакета `openvpn3` НЕТ (и в ветке 3 нет серверной части для Linux).
## Что переносим
| Гость | Где сейчас | Тип | Диск | Примечание |
|---|---|---|---|---|
| vpn.eterfund.ru | CT 258 @ border | LXC | `zpool:subvol-258-disk-0` 8G | full-tunnel; IP внутри (etcnet): .180/.94/.69/.68 + 10.20.30.180 |
| vpn.office.etersoft.ru | VM 292 @ border | KVM | `zpool:vm-292-disk-0` 5G | net0 vmbr1=91.232.225.22, net1 vmbr0=192.168.0.211 |
## Условия (всё проверено, перенос чистый)
- enceladus имеет тот же storage **`zpool`** (zfspool, active) → диски едут через zfs send/recv.
- enceladus **`vmbr1` несёт тот же `91.232.225.0/24`** (там telemt .3/.105, ximper .173, gw .1) → публичные IP сохраняются. enceladus `vmbr0` = офисный 192.168.0/24 (для net1 vpn.office).
- IP/MAC сохраняются (IP внутри гостей, MAC в конфиге) → клиенты переподключатся сами по keepalive.
- Миграция **оффлайн** (CPU Opteron→Ryzen, live нельзя). Даунтайм каждого ~2–5 мин (диски маленькие).
## КРИТИЧНО
- **CT 258 (LXC):** видит флаги CPU хоста напрямую → AES-NI заработает на enceladus **автоматически**, правок не нужно.
- **VM 292 (KVM):** тип CPU по умолчанию `kvm64` **скрывает AES-NI даже на Ryzen** → после переноса ОБЯЗАТЕЛЬНО `qm set 292 --cpu host` (или x86-64-v3) и перезагрузка, иначе крипта останется софтовой.
## Шаги
Этап 1 — vpn.eterfund (главный больной, проще):
```
# на border:
pct migrate 258 enceladus --restart
```
Этап 2 — vpn.office:
```
# на border:
qm stop 292
qm migrate 292 enceladus --targetstorage zpool
# на enceladus:
qm set 292 --cpu host
qm start 292
```
После каждого: проверить публичные IP, подключение клиента, `grep aes /proc/cpuinfo` внутри гостя (для VM — что флаг появился), нагрузку процесса openvpn.
Откат: `pct/qm migrate ... border` обратно; есть PBS-бэкапы.
## Доступы
- border: `ssh root@border`; enceladus: `ssh root@enceladus`
- vpn.eterfund: `ssh -p32 root@vpn.eterfund.ru`; vpn.office: `ssh vpn.office` (lav)
См. также: [[lesson_evpn_ikev2_strongswan_cert]] (evpn рядом, CT 264, не трогаем).
---
name: reference-create-lxc-container-pve
description: "Создание нового LXC-контейнера на PVE: клонировать template-CT 720 (template-etersoft-p11, ALT p11) на border, СНАЧАЛА сменить IP, потом старт"
metadata:
node_type: memory
type: reference
originSessionId: 27861819-a22e-4906-9c5e-02fdbd7542bb
---
# Создание LXC-контейнера на нашем PVE
## Шаблон системы
- **CT 720 `template-etersoft-p11`** на **border** (`ssh root@border`) — готовый template-CT, ALT p11, ostype altlinux, `template: 1`. Это и есть «шаблон системы», из него клонируем новые контейнеры.
- rootfs на storage **`zpool`** (ZFS, `basevol-720-disk-0`). Сеть шаблона: `net0 name=breth0,bridge=vmbr1,ip=10.20.30.246/24,gw=10.20.30.1`. features `nesting=1`, проброшен `/dev/net` (tun).
## Публичные адреса
Office-блок **91.232.225.0/24 — реально маршрутизируемый публичный** (не NAT): IP из него доступен из интернета на произвольных портах (фильтрация отдельных портов — на igw/priv). Мост для этого /24 — **vmbr1**, шлюз **91.232.225.1**, nameserver 91.232.225.10, searchdomain etersoft.ru.
Свободный IP искать через [[lesson-dns-free-ip-check-both-zones]] (прямая+обратная зоны + ping). Блок 104–109 в обратной зоне помечен free. Назначение диапазонов: 150–169 devel-CT, 180–189 fund, 190–199 эксперименты, 201–254 office-компы.
## Процедура клонирования
1. `pvesh get /cluster/nextid` → свободный VMID.
2. `pct clone 720 <VMID> --hostname <name> --full 1 --storage zpool` (full clone; template нельзя стартовать, только клон).
3. **СНАЧАЛА сменить IP, ПОТОМ запускать** (важно! [[см. общее правило]]):
- `pct set <VMID> -net0 name=breth0,bridge=vmbr1,gw=91.232.225.1,ip=<IP>/24,type=veth` (без hwaddr → PVE сгенерит новый MAC; имя оставлять **breth0**, чтобы совпало с etcnet шаблона).
- ALT использует etcnet, PVE не всегда полностью прописывает конфиг: `pct mount <VMID>`, проверить/поправить `/etc/net/ifaces/breth0/{ipv4address,default}` (ipv4address=`<IP>/24`, default=`default via 91.232.225.1`), `pct unmount <VMID>`.
4. `pct start <VMID>`, затем проверить `pct exec <VMID> -- ip -br a` и пинг шлюза.
5. DNS: A-запись + PTR через [[reference-remote-ssh-access]]/dns-навык (на ns1).
6. SSH-доступ: добавить ключ в `/root/.ssh/authorized_keys` (или пользователю + sudo).
Связано: [[feedback-lxc-via-ssh-not-pct]] (после поднятия ходить в CT через ssh root@<ip>, не pct exec).
---
name: reference-download-etersoft-mirror
description: "download.etersoft.ru ALT-зеркало доступ, скрипт синка rsync_all.sh, какие компоненты зеркалятся"
metadata:
node_type: memory
type: reference
originSessionId: d5fd66e6-c744-47dd-9f22-7810d755d391
---
ALT Linux зеркало `download.etersoft.ru` (91.232.225.28), отдаёт `/var/ftp/pub/ALTLinux` по HTTP.
- **Доступ:** `ssh downloader@download` (хост `download`). Репозиторий скриптов: `~downloader/etersoft-admin-essentials` (origin = `git@gitlab.eterfund.ru:etersoft/etersoft-admin-essentials.git`, та же репа, что и `pub.gitlab` локально). gpush/gpull работают.
- **Синк-скрипт:** `etersoft-cron/rsync_all.sh`, cron в 06:40 (полный прогон) и 4×/день `rsync_all.sh Sisyphus`. Качает с `rsync://ftp.basealt.ru/ALTLinux`. Логи: `~downloader/rsync_all.log`, `rsync_sisyphus.log`, `rsync_contents.log`.
- **Важно:** скрипт синкает payload только перечисленных компонентов (`classic`, `debuginfo`, и с 2026-06 — `gostcrypto`, `checkinstall` через цикл `OPTIONAL_COMPONENTS`), но шаг 2 тянет ВЕСЬ `base/` (индексы всех компонентов апстрима). Если у апстрима появится новый компонент, его индекс приедет автоматически, а payload — нет → apt получит 404 на все его пакеты. Лечится добавлением компонента в синк + ручным дозеркаливанием.
- Каталоги `RPMS.<component>/` у апстрима — симлинки в pool, поэтому rsync с `--copy-links`.
См. [[feedback_use_epm_for_packages]].
---
name: reference_eter_tv_xiaomi
description: "Телевизор Xiaomi (Eter-TV) в офисной сети IP, MAC, как подключиться"
metadata:
node_type: memory
type: reference
originSessionId: 00841af3-baca-4a84-adcf-f03526d87bd1
---
Телевизор Xiaomi (Android TV) в офисе:
- **IP:** 192.168.8.211 (сеть 8/24, динамический пул — см. [[lesson_dhcp_8net_dynamic_range]])
- **Hostname:** `Eter-TV`
- **MAC:** `50:e4:78:f7:52:b8`
- Найден через DHCP-лизы на dhcp.office (192.168.0.210): `/var/lib/dhcp/dhcpd/state/dhcpd.leases`
**SSH недоступен** (из коробки на Android TV нет sshd): порт 22 — connection refused, 5555 (ADB) закрыт, 8080 закрыт. Устройство в сети, ping проходит.
Чтобы получить доступ:
- В «Для разработчиков» на этом ТВ есть **только «Отладка по USB»**, пункта «Отладка по сети» НЕТ. Поэтому ADB по сети включается через USB:
1. Включить «Отладка по USB» (режим разработчика: Настройки → Об устройстве → 7 раз по версии сборки).
2. Подключить ТВ кабелем к ПК с `adb`, подтвердить авторизацию на ТВ.
3. `adb tcpip 5555` — перевести демон в сетевой режим.
4. `adb connect 192.168.8.211:5555` (порт слушает до перезагрузки ТВ).
- Загвоздка: у ТВ часто нет USB device-порта; может понадобиться USB-A↔USB-A / OTG, иначе сетевой ADB не включить.
- SSH — только через сторонний APK (например SimpleSSHD).
Другие Xiaomi в 8/24 (не ТВ): `Xiaomi-14-Pro` (8.149, телефон), `xiaomi-fryer` (8.126, аэрогриль).
---
name: reference_eterventcontrol
description: "eterventcontrol управление вентиляцией офиса (Modbus + FastAPI), где код, где запущен, порт"
metadata:
node_type: memory
type: reference
originSessionId: 127a3012-0746-43d6-89a5-719f3ca01d7d
---
**eterventcontrol** — сервис управления вентиляцией офиса (Modbus TCP → приточки, FastAPI/uvicorn API).
## Где код
- Репозиторий: `/srv/lav/Projects/git-eter/eterventcontrol` (Python, отдельный git-проект, НЕ в etersoft-admin-essential)
- Запуск: `python3 -m eterventcontrol.main loop` (он же `/usr/bin/eterventcontrol loop`)
- Есть `services/eterventcontrol.service` (ExecStart=/usr/bin/eterventcontrol loop), но на server он НЕ установлен как сервис
## Где запущен
- Машина **server** = `192.168.0.1`
- **API: http://192.168.0.1:8000** (uvicorn/FastAPI; в коде дефолт `127.0.0.1:8000`, host переопределён на LAN-адрес 192.168.0.1)
- Крутится как обычный процесс, НЕ через systemd: `serv eterventcontrol status``not-found`, автозапуск выключен (запущен вручную/из другого места — родитель не уточнён)
## Порты (дефолты в коде)
- API: **8000** (`main.py` api_cfg)
- Modbus TCP к устройству вентиляции: **502** (`vent_device.py`, `modbus_client.py`)
- InfluxDB (метрики): **8086** (`influx_client.py`)
---
name: reference-igw-route-api
description: "HTTP-API «Управление маршрутами» на igw.etersoft.ru (route-web-api) bypass/direct/geo списки, проверка домена через шлюзы, экспорт маршрутов. Самодокументированное: /swagger + /api/openapi.json"
metadata:
type: reference
---
# Route Management API — igw.etersoft.ru
Веб-API управления списками маршрутизации bypass/direct/geo на **igw** (91.232.225.13).
Сервер: Python `BaseHTTP` (3.12.7), слушает **порт 80 (HTTP)**, НЕ HTTPS (443 закрыт — connection refused).
Исходников сервера в этом репо НЕТ — код живёт на самом igw.
**Самодокументация:**
- `http://igw.etersoft.ru/swagger` — Swagger UI (грузит openapi.json)
- `http://igw.etersoft.ru/api/openapi.json` — полная OpenAPI 1.0.0 спецификация
- Веб-морда: `http://igw.etersoft.ru/` («Управление маршрутами — igw»)
## Эндпоинты (из OpenAPI)
**Списки доменов (3 режима: bypass / direct / geo):**
- `GET /api/list` — все записи трёх списков `{bypass:[], direct:[], geo:[]}` (2026-07: 64/2/11).
- `POST /api/add` `{domain, mode}` — добавить; если домен в друпом списке — переместит. → `{ok,domain,mode}`. 409 если конфликт.
- `POST /api/remove` `{domain, mode}` — удалить. 404 если нет.
- `POST /api/move` `{domain, from, to}` — переместить между списками.
**googlevideo CDN:**
- `GET /api/googlevideo``{patterns:[], count}` (2026-07: 510).
- `POST /api/googlevideo` `{domain}` — конкретный домен (напр. `rr3---sn-q4flrnsd.googlevideo.com`) нормализуется в паттерн `rr[1-8]---sn-...`, добавляется если новый. → `{ok,pattern,added}`.
**Состояние маршрутизации (read-only):**
- `GET /api/status``{updated`(unix)`pending`(неприменённые изменения), remaining`(сек до цикла), duration`}`. Применение по таймеру (~300s цикл).
- `GET /api/active` — действующие правила из `all-routes.json` (формирует `route-update.sh`): `{updated, groups:{...}}`.
- `GET /api/export/groups` — группы с числом IP и именами списков: cloudflare-warp, dgw, egw, gre, hetzner, ogw, zapret (zapret — общий реестр ~155k v4).
**Экспорт resolved IP:**
- `GET /api/export?group=&list=&proto=&format=&aggregate=&mikrotik_list=` — formats: `text`, `mikrotik`, `json`; aggregate: 0/1(смежные)/2(умная).
**Проверка блокировки (главный тест-эндпоинт):**
- `POST /api/check` `{domain}` — прогоняет домен/URL через шлюзы последовательно (curl через SOCKS5).
- `Accept: text/event-stream` → SSE (стрим по каждому шлюзу), иначе JSON `{domain, checks:{gateway:...}}`.
- Это и есть «тестирование через API igw» — проверить, через какой шлюз домен доступен/скорость.
## Примеры (read-only безопасно)
```bash
curl -sS http://igw.etersoft.ru/api/status
curl -sS http://igw.etersoft.ru/api/list
curl -sS http://igw.etersoft.ru/api/export/groups
# тест домена (активная проверка, может быть долгой):
curl -sS -H 'Content-Type: application/json' -H 'Accept: application/json' \
-d '{"domain":"youtube.com"}' http://igw.etersoft.ru/api/check
```
Связано: мониторинг шлюзов — [[lesson_proxy_monitoring_functional_check]]; SOCKS5-прокси igw:1080 и обход — [[lesson_igw_telegram_ipv6_broken]], [[reference_ruskru_telegram_notifier]].
---
name: reference-ruskru-telegram-notifier
description: "Сервис уведомлений @ruskru в Telegram на sites43 (CT 343, host03); SOCKS-прокси на igw, гоча socks5 vs socks5h"
metadata:
node_type: memory
type: reference
originSessionId: 426a0a85-231e-4dc8-80d1-18f9632b9be0
---
# @ruskru Telegram-нотификатор (sites43 / CT 343 на host03)
Бот `@ruskru_sender_bot` шлёт сообщения в канал `@ruskru`. Живёт в контейнере
**CT 343** (sites43.host03.eterhost.ru, 192.168.3.43) на host03. Доступ: `ssh -p32 root@host03`,
файлы контейнера на ноде: `/var/lib/vz/root/343/...`.
## Компоненты
- **Спул**: `/home/rusk/telegram-spool/` — файлы-сообщения; `.wait` = отложен на след. запуск, `.done` = отправлен.
- **lav-комплект**: `/home/lav/bin/send_tg.sh` (cron lav: `*/6 8-23 * * *`) → вызывает `send.py` (telebot).
- **rusk-комплект** (параллельный, рабочий образец): `/home/rusk/www/rusk.ru/tools/telegram/{send.py,send_tg.sh}`;
cron rusk: `news_to_telegram.php` (*/5 8-23) и `news_to_telegram_t.php` (20:00) — пишут в тот же спул.
- Бот-токен `470777011:...` хардкодом в обоих `send.py`.
## КРИТИЧНО: Telegram заблокирован на выходе → только через SOCKS-прокси
Telegram (149.154.160.0/20, 91.108.x) недоступен с обычного выхода host03 (через priv 91.232.225.1).
`send.py` обязан ходить через SOCKS5-прокси **microsocks на igw**: `91.232.225.13:1080`:
```python
from telebot import apihelper
apihelper.proxy = {'https':'socks5://91.232.225.13:1080'}
```
- **Зависимость:** для `socks5://` в `requests`/telebot нужен пакет **`python3-module-socks`** (PySocks). Без него —
`requests.exceptions.InvalidSchema: Missing dependencies for SOCKS support`. Поставлен в CT 343 2026-06-05.
- **Только `socks5://` (локальный DNS), НЕ `socks5h://`!** Контейнер IPv4-only → резолвит api.telegram.org в IPv4 →
прокси коннектится по IPv4 (рабочий маршрут `table telegram` → 91.232.225.142). С `socks5h` (remote DNS) microsocks на
igw резолвит AAAA и идёт по **битому IPv6-обходу** (route `via 2a03:5a00:c:20::122 table telegram` пингуется, но Telegram
по v6 таймаутит) → отправка виснет. См. [[lesson-igw-telegram-ipv6-broken]].
- `send_tg.sh` должен иметь `python3 send.py "$(cat "$i")" || exit` — БЕЗ `|| exit` сообщение помечается `.done`
даже при сбое (теряется) и cron шлёт traceback на почту.
Проверка пути без спама в канал:
`vzctl exec 343 'curl --socks5 91.232.225.13:1080 https://api.telegram.org/bot<TOKEN>/getMe'`
## История
2026-06-04: lav-копия `send.py` была от 2017 без прокси (rusk-копию правили 2026-04-22, добавив прокси) → cron сыпал
`Network is unreachable`. Привёл lav-комплект к рабочему виду (прокси + `|| exit`). microsocks на igw НЕ менял
(`-i ::` исходный); `-b <ipv4>` ломает listener при `-i ::` — не использовать.
Связано: [[reference-remote-ssh-access]], docs `host03.md`.
---
name: reference_telemt_fleet_ja4_monitoring
description: "telemt-флот chat.eterfund.ru обновление 3.4.18, beobachten JA4-диагностика, мониторинг в InfluxDB/Grafana"
metadata:
node_type: memory
type: reference
originSessionId: 14186ced-b55d-4e55-aa31-d3b9dee9d8f9
---
Бэкенды chat.eterfund.ru (telemt MTProxy): **e5/.105** (91.232.225.105, ALT p11, хост `telemt`, осн. chat.eterfund.ru), **d.chat**=divserver (46.148.53.122, ssh root@div.eterhost.ru), **s.chat**=schat (139.100.207.140, selectel, Ubuntu 24.04), **b.chat**=beget (217.12.37.55, Ubuntu 20.04). Связано: [[lesson_chat_eterfund_telemt_oom]], [[lesson_telemt_middle_proxy_egress_match]], [[lesson_divserver_telemt_mtproxy]].
## Обновление telemt (3.x.x → 3.4.18), всё через epm (НЕ обходить — [[feedback_never_bypass_epm_play]])
- Ставится через `epm play` (deb `…-epm1.repacked`), `/usr/bin/telemt` = wrapper → реальный бинарь `/opt/telemt/telemt`.
- `epm play --latest telemt` блокируется «already installed» → **`epm play --remove telemt` затем `epm play --latest telemt`** (бэкап бинаря+конфига заранее).
- **ГРАБЛИ:** старая eepm (<3.64.6x) при repack оставляет бинарь **gzip-сжатым**`Exec format error`, сервис падает. Лечение: **сначала `epm ei`** (обновить eepm), потом `epm play`. (На beget eepm 3.64.58 — словили; обновил до 3.64.64, repack починился.)
- SYN-limiter (фича 3.4.18) рулит nft → нужен **CAP_NET_ADMIN** (telemt бежит от User=telemt с CAP_NET_BIND_SERVICE). Добавить в юнит/drop-in: `AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_ADMIN` + `CapabilityBoundingSet=...`. Ошибки «must be root» при рестарте — от shutdown старого инстанса, не критично. Конфиг telemt в `/etc/telemt/config.toml` (не пакетный `/etc/telemt.toml`).
## JA4-диагностика (beobachten, фича с 3.4.14)
- Включить: в `[general]``beobachten = true` + `beobachten_minutes = 60`, рестарт.
- Смотреть **локально** (порты только 127.0.0.1:9090 + 0.0.0.0:9091, но :9091 за фаерволом провайдеров — снаружи недоступен):
- текст: `curl http://127.0.0.1:9090/beobachten` (секции `[TLS-scanner]`, `[expected_64_got_0]`, `tls_fingerprints.by_fingerprint/by_ip/by_cidr`)
- JSON: `curl http://127.0.0.1:9091/v1/runtime/tls-fingerprints?limit=N``data.data.by_fingerprint[]` с `ja4,total,auth_success,bad_or_probe`.
- **Поля:** `auth_success` = прошёл MTProxy-аутентификацию (живой клиент), `bad_or_probe` = сканер/DPI-проба. JA4 `t13`=TLS1.3 `t12`=TLS1.2, `d`=есть SNI `i`=нет, цифры=шифры/расширения, `h1/h2`=ALPN. GREASE рандомит JA3, но JA4 стабилен → агрегировать по JA4.
## Централизованный мониторинг (вариант telegraf→InfluxDB→Grafana)
На каждом бэкенде: `/etc/telegraf/scrape-telemt-ja4.py` (python: curl localhost:9091 → агрегат по JA4 → influx line protocol) + `/etc/telegraf/telegraf.d/telemt-ja4.conf` (`[[inputs.exec]]` interval 60s). telegraf уже шлёт в **telegraf.office.etersoft.ru:8086, db `gateways`**, host-тег = имя бэкенда.
- Измерения: **`telemt_beobachten`** (host-сводка: total_auth, total_probe, real_client_ja4, distinct_ja4), **`telemt_ja4`** (теги host,ja4; поля total, auth_success, bad_or_probe).
- Развёрнуто на ВСЕХ 4 бэкендах (2026-06-22): beget, schat, divserver, **e5/.105** (host-тег в InfluxDB: beget/schat/divserver/**telemt**).
- **e5 — ALT Sisyphus** (не p11!), telemt ALT-нативный пакет (НЕ epm-play): обновлять из girar-задания — `apt-repo add <task>``apt-get update``epm install telemt``apt-repo rm <task>`. Версия 3.4.18-alt1 уже в Sisyphus, задание #422377 — тест для p11. Юнит ALT-пакета: User=telemt → нужен CAP_NET_ADMIN drop-in.
- Картина по эндпоинтам (2026-06-22): **beget/divserver обслуживают живых клиентов** (auth сотни/десятки, разные JA4); **e5 (основной chat) — частично** (auth ~47, но probe ~988, тяжёлое зондирование); **schat — сплошь probe** (auth=0, 1000 probe) → блокировка РАЗНАЯ по эндпоинтам, beobachten это показывает в реальном времени.
## Блокировка ТСПУ (2026, из разведки + beobachten)
DPI палит по триаде **JA4 Telegram + один SNI + много ClientHello на один ip:port**. JA4 формирует КЛИЕНТ (мобильный TG с непатченным fingerprint — фиксы только Desktop). Лечится: рассредоточение ip:port, «одобренный» SNI (напр. rusk.ru=91.232.225.80, наш реальный сайт), смена протокола (VLESS+Reality). Конфиг маски: один SNI на инстанс telemt (`tls_domain`); фронтить реальный домен через `mask_host`.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment