# zbrcheck.ru — доступ к VPS-edge + аварийный runbook

Как подключаться к проду «Земля без риска» (zbrcheck.ru) и диагностировать падения edge.
Топология добыта в инциденте 2026-06-05 (OOM от автообновлений). Подробно — Obsidian
`Земля без риска check/Runbook-доступ-и-инциденты.md` + Changelog ч.27.

> **UPDATE 2026-06-24 — HTTP/3 ОТКЛЮЧЁН на edge-Caddy.** Юзеры с VPN в Yandex Browser/Safari не открывали сайт: Caddy анонсировал `alt-svc: h3=":443"; ma=2592000` (QUIC/UDP, кэш 30 дней), а VPN режут UDP → браузер залипал на QUIC. Фикс: в глобальный блок `/etc/caddy/Caddyfile` добавлен `servers { protocols h1 h2 }` (после `order rate_limit before basicauth`). `caddy validate`→Valid, `systemctl reload caddy`, проверено: `alt-svc` исчез, сайты HTTP/2 200. **Откат:** restore `/etc/caddy/Caddyfile.bak-noh3-20260624-081251` + `systemctl reload caddy`. Нюанс: браузеры с уже закэшированным alt-svc могут до 30 дней пробовать h3, пока кэш не истечёт (помогает рестарт браузера). Новые юзеры — ок сразу.

## Топология (кто где)
- **VPS-edge** `193.108.113.35` (RuVDS, hostname `ruvds-nz5mu`, **крошечный: ~371 МБ RAM**,
  1 ГБ swap `/swap.img`, ~10 ГБ диск). Держит публичные домены.
  - Caddy на `:443` (`/etc/caddy/Caddyfile`): `zbrcheck.ru, www` → `reverse_proxy 127.0.0.1:18142 127.0.0.1:18143`; `pay.zbrcheck.ru` → `reverse_proxy 127.0.0.1:18444`.
  - **rathole-server** — systemd unit **`rathole-server.service`** (НЕ `rathole`!), конфиг `/etc/rathole/server.toml`. Слушает control `:2333` (0.0.0.0) + апстримы 18142/18143/18444 (loopback).
  - Ещё: Postfix+OpenDKIM (исходящая почта, :25), fail2ban, unattended-upgrades.
- **mac mini** `192.168.0.107` (user `cebers_mini`, **публичный IP `5.18.156.167`**). Тут вся логика:
  - frontend Next.js `:20141` (+ вторая инстанция `:20142` = web2 для LB), backend `:20140`, бот (robokassa-webhook на `127.0.0.1:8443`).
  - **rathole-client** — launchd `local.zemlya-rathole-client`, конфиг `/Users/cebers_mini/Services/zemlya-web/rathole/client.toml`. Маппинг: web→20141 (VPS 18142), web2→20142 (VPS 18143), pay→8443 (VPS 18444). `default_token` в client.toml (секрет, gitignored — не печатать).
  - SMTP-туннель: autossh `local.zemlya-smtp-tunnel` (`tunnel@193.108.113.35`, ключ `~/.ssh/zemlya_tunnel`, `-L 2525:127.0.0.1:25`).

## Доступ (ВАЖНО — порядок!)
- **mini** (из локалки): `ssh -i ~/.ssh/id_ed25519 cebers_mini@192.168.0.107`.
- **VPS root** — **только через мини** (ключ мини `~/.ssh/id_ed25519` авторизован как root на VPS; мой ключ с ноута — НЕ авторизован). Двойной хоп:
  ```
  ssh -i ~/.ssh/id_ed25519 cebers_mini@192.168.0.107 \
    'ssh -i ~/.ssh/id_ed25519 -o BatchMode=yes -o StrictHostKeyChecking=no root@193.108.113.35 "<cmd>"'
  ```
  - Пароль root (fallback) — в memory `zemlya_domain_zbrcheck_migration.md` (не дублирую).
  - Кавычки/`()` через двойной хоп ломаются → длинные скрипты слать **base64**: `B64=$(base64<script); ssh mini "ssh root@vps 'echo $B64|base64 -d|bash'"`.
  - mini→VPS иногда таймаутит «**during banner exchange**» при высоком load — это перегрузка sshd, не fail2ban; **retry 2-3 раза** решает.

## Аварийный runbook (edge down / watchdog алерты)
1. **Снаружи:** `curl -m12 -o/dev/null -w '%{http_code}\n' https://zbrcheck.ru/` (ждём 200), `https://pay.zbrcheck.ru/robokassa/result` (400 на пустой GET = норма), `nc -z 193.108.113.35 22`.
2. **mini здоров?** на мини: `launchctl list|grep zemlya`, `curl -m5 127.0.0.1:20140/` (200) и `:20141/` (200), `pgrep -fl rathole.*client`.
3. **VPS:** двойным хопом — `systemctl is-active caddy rathole-server`; `ss -tlnp`; `cat /proc/loadavg`; `free -m`; `dmesg -T|grep -i oom`; `journalctl -u rathole-server -n20`. Туннель установлен? `ss -tn state established|grep :2333` (должны быть коннекты с 5.18.156.167).
4. **Флап (часть 200 / часть timeout)** → пересобрать пул туннеля: на мини `launchctl kickstart -k gui/$(id -u)/local.zemlya-rathole-client`, подождать ~8с, перепроверить п.1 ×10.
5. **OOM в dmesg** (`apt-daily-upgrade`/`unattended-upgr` killed) → это известная причина; профилактика уже стоит (swappiness=60 + MemoryHigh/Max на apt-юнитах). Если повторяется — апгрейд RAM VPS.

## Известные грабли / TODO
- VPS слишком мал (371 МБ) под Caddy+rathole+Postfix+OpenDKIM+fail2ban+apt → класс OOM-проблем. **Апгрейд RAM снял бы.**
- rathole `:2333` открыт на 0.0.0.0 → сканеры флудят («Failed to deserialize hello»). TODO: ufw/iptables ограничить до IP мини (5.18.156.167) — если IP статичный.

## НСПД-задержки: НЕ от детекта браузера (проверено 2026-06-17)
Гипотезу «гонять НСПД через CloakBrowser (анти-детект, `~/.cloakbrowser`) быстрее/надёжнее обычного Playwright» **проверил реальным A/B на мини и отверг.** 5 КН, cold-start, plain (UA Chrome120) vs stealth (`cb.launch_context(stealth_args=True)`, venv `~/.venvs/cloakbrowser`, есть playwright 1.60) — времена **идентичны до 0.1с**. WAF НСПД обычный Chromium сейчас НЕ блокирует (fetch `/api/geoportal/v2/search/geoportal` отдаёт JSON за 0.1с сразу после навигации). Задержки = (1) ~4.6с фикс-`wait_for_timeout` в `_prepare_nspd_page` бота (0.5+1.5+3.0с «отстояться») + (2) последовательный перебор 7 тематик (`NSPD_THEMATIC_SEARCH_IDS=(1,2,3,4,5,7,10)`) × медленный серверный API НСПД на редких/ненайденных КН (до 14–42с; земля находится на tid=1 за ~5с). Другой браузер бьёт в тот же медленный API → не лечит. **CloakBrowser в бот НЕ внедряем.** Рычаг задержек (если понадобится) — урезать перебор тематик/ожидание в `nspd.py`, но это правка ядра хрупкого SPOF → только с согласия владельца. Грабли: НСПД на сертификате рос. УЦ → любой клиент нужен с `ignore_https_errors=True` (иначе `ERR_CERT_AUTHORITY_INVALID`). Аналогия: у gemini-web узкое место тоже было IP, а не отпечаток. Скрипты: `/tmp/nspd_cloak_test.py`, `/tmp/nspd_cloak_multi.py` на мини. Детали — Obsidian Decision D-cloakbrowser-nspd.
