# Kraken — Внешний доступ > # ✅ 2026-09-23 — КАНАЛ REVERSE ЖИВ + ТОПОЛОГИЯ УТОЧНЕНА > > **1. Reverse-туннель работает** (первая проверка после фикса гонки 2026-09-20): SOCKS `xray-reverse-portal:12345` → `92.62.77.233` ≠ TrueNAS `90.189.160.148`. Детали — [[personal/tech/xray-reverse-tunnel-kraken-truenas]]. > > 🔴 **2. IP Кра́кена ИЗМЕНИЛСЯ: `92.62.70.41` → `92.62.77.233`.** Прежний зафиксирован в этом документе и в `truenas-infrastructure.md` — при проверках брать актуальный из живого запроса. > > **3. Топология Кра́кена (проверено `ip -4 addr` + `ip route`, 2026-09-23):** > > ``` > eth0 192.168.1.14 metric 100 ← активный default route > wlan0 192.168.1.15 metric 600 > default via 192.168.1.1 dev eth0 src 192.168.1.14 > wg0 10.99.1.2/24 (VPS qentra удалён — звено мёртво) > ``` > > 🔴 **Кра́кен и Mac (`192.168.1.57`) — СОСЕДИ в одной подсети `192.168.1.0/24`**, шлюз `192.168.1.1` (ASUS RT-AC68U). **`192.168.2.2` (OpenWrt) — это шлюз сети TrueNAS, к сети Mac/Кра́кена отношения не имеет.** Не приписывать OpenWrt сети `192.168.1.x`. > > ⚠️ Следствие: с Mac до `192.168.2.197` маршрут идёт `gateway: 192.168.1.1` (проверено `route -n get`), а не через OpenWrt. Схема «статический маршрут `192.168.2.0/24 → 192.168.1.15` на ASUS» **работоспособна**, потому что Кра́кен — сосед в той же подсети, и обратный NAT делает он сам. Нюанс интерфейса (`.14` eth0 vs `.15` wlan0) — в [[personal/plans/lan-via-reverse-tunnel]]. > > ⚠️ **ASUS `192.168.1.1` по SSH недоступен** (`Permission denied` → `Connection closed`, порт 22 `closed`). Раньше в доке `home-network-config` вход был описан как `ssh -i ~/.ssh/id_rsa admin@192.168.1.1` — **сейчас не работает**. Правки маршрутов — только через веб-UI. > > **4. `xray-reverse-bridge` не имеет `inbounds`** — ключи конфига только `log`/`outbounds`/`routing`. Слушающих портов нет. Канал работает на отправку, принять трафик от роутера бриджу нечем. Разбор — [[personal/plans/lan-via-reverse-tunnel]]. > # ✅ 2026-09-20 — НАЙДЕНА ИСТИННАЯ ПРИЧИНА (2026-09-15 поломки): ГОНКА Docker ↔ монтирование USB-диска > > **Симптом 2026-09-15:** одновременно упали (1) reverse-туннель Kraken→TrueNAS (`kraken-user`) и (2) cloudflared SSH-туннель `ssh-kraken.qentra.top`. Обе поломки — **одна причина**, не две. > > ### Таймлайн последнего boot (Kraken) > | Событие | Время | > |---|---| > | Boot | Sep 15 **17:29:17** | > | Ядро видит `sda1` (USB HDD) | +130 с → **17:31:27** | > | **`dockerd` стартовал** (PID 1324) | **17:31:01** ← на **26 с раньше** диска | > | Диск смонтирован | **17:31:27** | > > **Механизм:** `/etc/docker/daemon.json` → `data-root` = `/srv/dev-disk-by-uuid-49e8f586-.../docker-data` (симлинк на `6194539b-...`). `docker.service` **не имеет `RequiresMountsFor=`** → не ждёт монтирования. dockerd на 17:31:01 открыл путь до появления диска → увидел пусто → загрузил **0 контейнеров**; через 26 с диск смонтировался поверх точки, но daemon уже держал пустое состояние в памяти. Перечитывания нет. > > ### Что НЕ потеряно (проверено живьём) > - `docker-data/containers/` = **4.7G, 35 контейнеров целы** (cloudflared, xray-reverse-bridge, jellyfin, sonarr, radarr, prowlarr, transmission, homeassistant, hermes-kraken, portainer, rclone, watchtower, flaresolverr, timemachine). > - Образы (21), 32 volume — на месте. Диск `sda1` 1.8T смонтирован, 242G свободно. > - `docker info` при этом рапортует `Containers=0` — **не верь ему, metadata на диске цела**. > > ### Побочные дефекты, найденные при разборе > 1. **`/etc/fstab` содержит ДУБЛЬ** строки для `6194539b`: OMV-блок + ручная строка `UUID=6194539b-...` → systemd: `Duplicate entry in '/etc/fstab'?`. > 2. **`docker.service`: `RequiresMountsFor=` пусто** — корень гонки. Drop-in нужен, чтобы dockerd ждал диск. > 3. ~~RestartPolicy=null → нужен ручной `docker start`~~ ❌ **ЭТО БЫЛО ОШИБОЧНОЕ ДОПУЩЕНИЕ.** Я прочитал `RestartPolicy.Name` из `hostconfig.json` (это reflection исходного `docker run`, там `null`), но в daemon state policy **есть**. Факт: после `systemctl restart docker` все 12 контейнеров с `unless-stopped` поднялись **сами**, ручной `docker start` не потребовался. Проверять политику надо `docker inspect --format '{{.HostConfig.RestartPolicy.Name}}'` (живой daemon), а не `hostconfig.json` на диске. > > ### Команды диагностики (воспроизводимые) > ```bash > ssh kraken 'docker ps -a --format "{{.Names}}\t{{.Status}}"' # пусто → daemon state пуст > ssh kraken 'ps -o pid,lstart,cmd -p $(pgrep -x dockerd)' # реальное время старта dockerd > ssh kraken 'systemctl show docker -p RequiresMountsFor' # пусто = нет зависимости от mount > ssh kraken 'uptime -s; findmnt /srv/dev-disk-by-uuid-6194539b-...' # когда boot / когда диск > ssh kraken 'sudo ls /srv/dev-disk-by-uuid-6194539b-.../docker-data/containers | wc -l' # 35 = целы > ``` > Питфолл: `systemctl show docker -p ExecMainStartTimestamp` дал stale `15:18:36`; **истинное время старта — `ps -o lstart`** = 17:31:01. > > ### План восстановления (согласован 2026-09-20) > 1. Backup: `/etc/fstab`, `/etc/docker/daemon.json`, `/home/kraken/xray-reverse/` → `/home/kraken/backups/docker-recovery-/`. > 2. **`sudo systemctl restart docker`** — диск уже смонтирован → daemon прочитает все 35 контейнеров. > 3. `docker start` по списку — ⚠️ **НЕ ПОТРЕБОВАЛСЯ**: оказалось, RestartPolicy в daemon state есть (`unless-stopped`), все 12 контейнеров поднялись автоматически после рестарта daemon. `hostconfig.json` на диске показывает `null` — это НЕ отражает реальную политику. Проверять через живой daemon: `docker inspect --format '{{.HostConfig.RestartPolicy.Name}}'`. > 4. Правка боевого: убрать дубль fstab + drop-in `RequiresMountsFor=/srv/dev-disk-by-uuid-6194539b-...` — **только с апрувом Alex**. Порядок: коммит ДО → правка → заливка → проверка Alex → коммит ПОСЛЕ. > 5. Проверка: `docker ps` все Up; reverse-канал `udp:reverse:0`; cloudflared tunnel. > 6. Версии Xray на бридже: оставить `26.4.25` + `network_mode: host` (проверенный фикс 2026-09-02) — открытый вопрос к Alex. > > **Статус (обновлено 2026-09-20): ✅ ФИКС ПРИМЕНЁН, ПРОВЕРЕН РЕАЛЬНЫМ REBOOT'ом, REBOOT-БЕЗОПАСЕН.** > > **Подтверждение живым reboot'ом (2026-09-20):** Alex выключил Kraken (`sudo shutdown -h now`), включил — **все 12 контейнеров поднялись сами** (`docker ps` не пуст). Ручных `docker start` не потребовалось. Гонка закрыта. > > **Полный разбор механики и фикса:** [[personal/tech/docker-data-root-mount-race]]. > > ⚠️ **После reboot `jellyfin` поднялся, но отдавал 503** — это **отдельный** дефект (образ 10.11.8 старше схемы БД 12.1.0.0, `no such column: p.Permission_Permissions_Guid`), НЕ связанный с гонкой. См. [[personal/tech/jellyfin-db-schema-mismatch]]. **Различать при диагностике:** контейнер не поднялся (гонка) vs поднялся, но падает внутри (своя ошибка). > > **Что сделано:** > 1. ✅ Backup: `/home/kraken/backups/docker-recovery-20260920-105228/` (fstab, daemon.json, xray-reverse). > 2. ✅ `sudo systemctl restart docker` → все 25 контейнеров загрузились, 12 поднялись автоматом (`cloudflared`, `xray-reverse-bridge` в т.ч.). > 3. ✅ Drop-in `/etc/systemd/system/docker.service.d/mounts.conf`: > ```ini > [Unit] > RequiresMountsFor=/srv/dev-disk-by-uuid-6194539b-03e0-4f33-986b-4da09834e82f/docker-data > After=srv-dev\x2ddisk\x2dby\x2duuid\x2d6194539b\x2d03e0\x2d4f33\x2d986b\x2d4da09834e82f.mount > ``` > Проверено: `systemctl show docker -p Requires -p After` → маунт-юнит в **Requires И After**. dockerd теперь физически не стартует раньше диска → **гонка закрыта**. > 4. ✅ `/etc/fstab`: убран дубль строки для `6194539b` + дубль bind-mount `/var/log/journal`. Осталось 1 вхождение (OMV-блок). Проверено грепом. > 5. ✅ Sanity `systemctl restart docker` после правок → `containers=25`, 11-12 Up. Критичные поднялись сами. > > ✅ **`hermes-kraken` — crash-loop РАЗОБРАН И ПОЧИНЕН (2026-09-20, отдельная от гонки причина).** > **Симптом:** `Restarting (1)` циклично, в логах `mkdir: cannot create directory '/opt/data': Permission denied`. > **Причина:** контейнер работает под **UID 1000:1000** (из образа, `user:` в compose не задан), `HOME=/opt/data` ← bind-mount из `/srv/.../docker/hermes/config`. На хосте этот каталог имел владельца **`10000:10000`** mode `700` (аномалия — UID 10000 больше нигде в `docker/` не встречается; похоже след от перерегистрации диска 15.09). 1000 ≠ 10000 + mode 700 → `Permission denied`. > **Фикс:** `sudo chown 1000:1000 …/docker/hermes/config` (сначала на верхнем уровне, затем `-R`). > ⚠️ **Питфолл:** `chown -R` по большому дереву на медленном USB-диске **не влезает в SSH-таймаут**. Запускать независимо: `sudo systemd-run --unit=hermes-chown --collect --property=Type=oneshot chown -R 1000:1000 ` — юнит переживёт обрыв SSH. Проверка: `systemctl is-active hermes-chown`. > **Результат:** контейнер `Up`, логи — чистый старт Gateway, API отвечает `404` на `/` (норма, рабочий эндпоинт `/v1/chat/completions`). > 📌 Три `mkdir: Permission denied` в начале лога после фикса — **остаток буфера от прошлого падения**, не текущие ошибки. > > **Питфолл (опровергнут):** `RestartPolicy` в `hostconfig.json` = `null`, но в daemon state policy есть → при рестарте daemon контейнеры **поднимаются сами**. Не пугаться `null`, не нужен ручной `docker start`. > > **Урок на будущее:** USB-диск на Kraken поднимается ~130 с. Любой сервис, зависящий от `docker-data` на этом диске, ОБЯЗАН иметь `RequiresMountsFor`. Теперь это обеспечено для docker.service. > # 🔴 2026-09-15 — KRAKEN НЕДОСТУПЕН ПО ВСЕМ ПУТЯМ (проверено с Mac) > > ⚠️ **ВНИМАНИЕ (обновлено 2026-09-20):** вывод этой секции был **ЧАСТИЧНО НЕВЕРЕН**. «Kraken недоступен» относилось к внешним путям (cloudflared `ssh-kraken.qentra.top`, WG `10.99.1.2`) — оба были down не из-за выключенной машины Kraken, а из-за **гонки docker↔mount** (см. секцию выше): `cloudflared`-контейнер просто не загрузился daemon'ом. По **LAN Kraken был жив всю дорогу** (`192.168.1.15`). Урок: «недоступен снаружи» ≠ «машина мертва» — проверять LAN и состояние docker daemon, прежде чем звонить провайдеру. > > **Симптом:** перестал работать клиент `kraken-user` в 3x-ui на TrueNAS. При разборе выяснилось — причина **не в БД и не в конфиге**, а в том, что **сам хост Kraken недоступен**. > > | Путь | Команда | Результат | > |---|---|---| > | Cloudflare SSH | `ssh ssh-kraken.qentra.top` | ❌ `Connection timed out during banner exchange` | > | WireGuard Direct | `ssh kraken@10.99.1.2:22` | ❌ `Operation timed out` | > | DNS | `host kraken` | ❌ `NXDOMAIN` (в `/etc/hosts` записи нет) | > > **Состояние TrueNAS-стороны (жива):** `xray-reverse-portal` Up 13 дней, порты `12345` (SOCKS) и `12346` (interconn) в LISTEN, конфиг `/mnt/RED_2TB/docker/reverse-portal/config.json` цел. > > **Диагностика, доказывающая «бридж молчит»:** > ```bash > docker exec xray-reverse-portal netstat -an | grep 12346 # пусто = от Kraken никто не звонит > curl -s --max-time 20 --socks5-hostname 127.0.0.1:12345 https://api.ipify.org # пусто (ждём 92.62.70.41) > ``` > Логи портала при этом содержат `app/dispatcher: non existing outTag: reverse-out` — **это не битый конфиг**, а ожидаемое следствие: `reverse-out` создаётся Xray'ем автоматически только пока бридж подключён (объявлен в `inbounds[interconn].clients[0].reverse.tag`, не в `.outbounds`). > > **Вывод:** нужно проверять Kraken со стороны панели хостинга/консоли провайдера — машина выключена либо сетевая недоступность. Решение Alex: **«подождём, может оживет»**. > > ⚠️ **Урок:** перед тем как искать причину в конфиге TrueNAS, проверять доступность самого Kraken. Полдня ушло на разбор 3x-ui, который к этой поломке отношения не имел. > > **Обновлено: 2026-09-04** > Updated: 2026-09-01 23:00 — диск/докер кракена поднялись после перезагрузки (тогда причина ещё не была известна; истинная — гонка docker↔mount, найдена 2026-09-20). ## Как зайти Везде `ssh kraken`. Резолвится через `~/.ssh/config` на Eagle: - **Дома** — напрямую по LAN (`192.168.1.15`) - **Снаружи** — ⚠️ через WireGuard (`10.99.1.2`) **БОЛЬШЕ НЕ РАБОТАЕТ**: VPS-узло (10.99.0.1/10.99.1.1) qentra.top **удалили 2026-09-01**. Альтернатива внешнего доступа обсуждается через Xray reverse (см. [[tech/xray-reverse-tunnel-kraken-truenas]]). > 🔴 **2026-09-15 — ПРИЧИНА НАЙДЕНА 2026-09-20: гонка docker ↔ монтирование диска.** Диск не «нестабилен» — он **монтируется медленно (~130 с)**, dockerd обгоняет. См. секцию выше. > ⚠️ **Kraken Docker на 2026-09-01:** Server 29.4.3, Docker Root Dir `/srv/dev-disk-by-uuid-6194539b-03e0-4f33-986b-4da09834e82f/docker-data`. **30 образов сохранены, но 0 контейнеров** (все прежние контейнеры — jellyfin/transmission/radarr/hermes-kraken и т.д. — не были видны daemon'ом после старта без диска). Причина — та же mount-race, НЕ дефект диска; после фикса 2026-09-20 такого не повторяется. > > 🔴 **Диск НЕ нестабилен.** Формулировка «USB-диск нестабилен» — ошибочное обобщение разового инцидента 2026-09-01 (циклы USB enumerate, `error -110/-62`, `Read Capacity(10) failed`). Истинная причина проблем с контейнерами — **mount race**: диск монтируется ~130 с, dockerd стартует раньше. Фикс (`RequiresMountsFor`) применён 2026-09-20, проверен живым reboot'ом — все контейнеры поднялись сами. **Не возвращать формулировку «диск нестабилен»** (Alex требовал её убрать, 2026-09-25). > Реальные ограничения HDD: 5400rpm, ~95 МБ/с на чтение — лимит механики, не USB и не дефект. ## Portainer (локально) `http://kraken:9000` API: ```bash BASE=http://localhost:9000 KEY="ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=" EP=3 # endpoint ID на Кракене = 3, не 1! ``` ## Hermes API `http://kraken:8642/v1/chat/completions` — OpenAI-compatible endpoint. ## Reverse Xray bridge (развёрнут 2026-09-01) - Контейнер **`xray-reverse-bridge`** в `/home/kraken/xray-reverse/` (compose + `config.json`), образ **`teddysun/xray:26.4.25`** + `network_mode: host` (проверенный фикс 2026-09-02). - Outbound VLESS+REALITY TCP → `mallexxx.duckdns.org:12346` (TrueNAS через OpenWrt DNAT), reverse tag `reverse-in`, egress freedom с `finalRules:[{action:allow}]`. - ✅ **End-to-end payload работает** (верифицировано 2026-09-02: SOCKS `12345` → egress IP Kraken). Полная история диагностики (регрессии #6612/#6242, docker bridge/NAT) — в [[tech/xray-reverse-tunnel-kraken-truenas]]. - ⚠️ 2026-09-15…20 контейнер был **не запущен** (гонка docker↔mount, см. шапку) — это единственная причина «туннель down». После рестарта daemon — снова Up. - ✅ **2026-09-23 — канал перепроверен end-to-end после починки гонки. Egress Кра́кена = `92.62.77.233`.** > 🔴 **IP Кра́кена ИЗМЕНИЛСЯ:** `92.62.70.41` (все старые записи) → **`92.62.77.233`** (2026-09-23, проверено через SOCKS портала). **Не доверять `92.62.70.41`**, брать актуальный живым запросом. - 🔧 **2026-09-23 — в конфиг бриджа добавлен inbound `lan-in`** (`dokodemo-door`, **`listen 0.0.0.0:12345`**, `followRedirect:true`, `sniffing:false`) + routing `lan-in → conn`. Прежде `inbounds` было **`null`** — бридж мог только отправлять в туннель, принимать не мог. - ⚠️ **`listen` обязан быть `0.0.0.0`, НЕ `127.0.0.1`.** С `127.0.0.1` REDIRECT-трафик с внешнего адреса не принимается — соединение отбивается мгновенно (`HTTP 000` за ~0.005 с). Ошибка проверена и исправлена. - Плюс на хосте Кра́кена: `iptables -t nat PREROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -p tcp -j REDIRECT --to-ports 12345`. - 🏁 **Задача, ради которой это ставилось, — ТУПИК.** Xray reverse намеренно не пускает forward-proxy в приватные сети: портал отдаёт `not allowed to use forward proxy`. Это штатная защита, не баг. Теория: [[personal/tech/xray-reverse-limits-private-network]]. Полное состояние: [[personal/plans/lan-access-via-reverse-tunnel]]. - ⚠️ **`iptables-persistent` НЕ установлен** — правило REDIRECT слетит при reboot. - Бэкапы: `config.json.bak-lan-in-20260923-130541`, `config.json.bak-listen0000-20260923-131655`, `config.json.bak-v3-`, `/home/kraken/backups/iptables.bak-20260923-130541`. - ⚠️ **`sudo` на Кра́кене через SSH требует `< /dev/null`** — иначе `Connection closed by remote host`. На Кра́кене **нет `ifconfig`** (использовать `ip addr`). ## Docker контейнеры (обновлено 2026-09-20, после фикса) ✅ **daemon видит все контейнеры. `containers=25`, 12 Up** (после восстановления гонки docker↔mount, см. шапку). Все 35 metadata-записей в `docker-data/containers/` целы. | Имя | Статус 2026-09-20 | Заметки | |-----|---------|---------| | xray-reverse-bridge | ✅ Up | образ `teddysun/xray:26.4.25`, `network_mode: host` (фикс 2026-09-02) | | cloudflared | ✅ Up | `cloudflare/cloudflared:latest`, `network_mode: host`, remote-managed по TUNNEL_TOKEN | | jellyfin / sonarr / radarr / prowlarr | ✅ Up | | | portainer / transmission / rclone / watchtower / flaresolverr | ✅ Up | | | hermes-kraken | ✅ Up | crash-loop вылечен 2026-09-20 (см. ниже) | | homeassistant | ⏹ `Exited (128)` 2 месяца назад | не поднимался, отдельная задача | | timemachine + alpine-* (6 шт.) | ⏹ Exited (0) | одноразовые/диагностические, норма | > **Питфолл про RestartPolicy (проверено):** `hostconfig.json` на диске показывает `RestartPolicy.Name = null`, но в daemon state политика `unless-stopped` есть → контейнеры поднимаются сами. Не пугаться `null`, не нужен ручной `docker start`. Проверять живой daemon: `docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' `. ## ✅ hermes-kraken — crash-loop вылечен 2026-09-20 (права каталога) > **Симптом:** `hermes-kraken` в вечном `Restarting (1)`. Логи циклично: > `mkdir: cannot create directory '/opt/data': Permission denied`. > > **НЕ связано** с гонкой docker↔mount (контейнер был запущен, но падал сам). | Что | Значение | |---|---| | Контейнер работает под | **UID 1000:1000** (`kraken`, задан в образе, не в compose) | | `/opt/data` примонтирован из | `…/docker/hermes/config` | | Владелец на хосте (было) | **10000:10000**, `drwx------` (700), mtime **Sep 15 15:37** | | Итог | 1000 ≠ 10000 + mode 700 → `Permission denied` на `mkdir /opt/data` | **Корень:** каталог `docker/hermes/config` после перерегистрации диска (15 сен) получил **чужой UID 10000** — след старого OMV-маппинга. `10000` больше нигде в `…/docker/` не встречается: все прочие каталоги либо `root:root`, либо `1000:1000`. Данные (`.env`, `auth.json`, `sessions/`, `cron/`, `response_store.db`) были целы — только владелец не тот. **Фикс:** ```bash # top-level — мгновенно sudo chown 1000:1000 /srv/dev-disk-by-uuid-6194539b-.../docker/hermes/config # рекурсивно — долго (медленный USB-HDD), запускать в фоне, НЕ блокируясь на SSH: sudo systemd-run --unit=hermes-chown --collect --property=Type=oneshot \ chown -R 1000:1000 /srv/dev-disk-by-uuid-6194539b-.../docker/hermes/config ``` Проверка: `sudo find …/docker/hermes -uid 10000` → пусто; контейнер `Up`; API `http://localhost:8642/` отвечает (`404` на `/` — норма, эндпоинт `/v1/chat/completions`). **Питфоллы:** - `chown -R` по большому дереву на USB-HDD идёт **минуты** → **обычный ssh-вызов рвётся по таймауту и правка НЕ применяется**. Запускать через `systemd-run … --collect` в фоне, потом проверять `systemctl is-active hermes-chown` и `ls -ldn` каталога. - Логи после старта содержат «хвост» прежних `mkdir` ошибок из буфера — не пугаться, если дальше идёт `Hermes Gateway Starting...` и скиллы синхронизированы. > ### 🔁 2026-09-23 — ПОВТОРНЫЙ СИМПТОМ, НАЙДЕН ДРУГОЙ КОРЕНЬ > > Kraken-агент сообщил: **«нет SSH доступа к хосту»**. Проверка: > ``` > sudo docker exec hermes-kraken ssh kraken-host "echo HELLO" > → No user exists for uid 1000 > ``` > Это **не про ключ** и **не связано** с crash-loop 2026-09-20. `ssh` падает на `getpwuid(1000)` — > **в `/etc/passwd` образа нет записи для uid 1000**, там только `hermes:x:10000:10000`. > Контейнер запущен под uid 1000 (из `USER` в образе), т.е. анонимный uid. > > **Не путать три разных вещи** (все они про uid и все ломались отдельно): > | Дефект | Что не так | Фикс | Дата | > |---|---|---|---| > | crash-loop `mkdir /opt/data: Permission denied` | владелец **файлов** на хосте = `10000:10000` | `chown 1000:1000` на хосте | 2026-09-20 ✅ | > | гонка docker↔mount | data-root на USB раньше dockerd | `RequiresMountsFor` drop-in | 2026-09-20 ✅ | > | `No user exists for uid 1000` | нет записи uid 1000 в **passwd образа** | завести `kraken` uid 1000 в Dockerfile | 2026-09-23 ⏳ план согласован | > > **Полный разбор + план фикса (вариант A):** [[family/how-to/hermes-docker-kraken]] → раздел > «ПЛАН: фикс uid 1000». Статус: **согласован, НЕ применён**. > > Дополнительно найдено: 3-й bind-mount `config/.ssh → /root/.ssh` при `HOME=/opt/data` — SSH его не > читает; в самом образе есть `entrypoint.sh` с логикой `gosu`/`usermod`, но вся она обёрнута в > `if [ "$(id -u)" = "0" ]` и при старте под 1000 **пропускается целиком**. ## Cloudflared туннель — публичные маршруты (состояние на 2026-09-04) Туннель `kraken` в Zero Trust, remote-managed по `TUNNEL_TOKEN`, `network_mode: host`, образ `cloudflare/cloudflared:latest`. Актуальный ingress конфиг (виден в логах cloudflared на Kraken, `INF Updated to new configuration`): ``` {"ingress":[ {"hostname":"kraken.qentra.top", "originRequest":{"httpHostHeader":"kraken.qentra.top"},"service":"http://localhost:8642"}, ← Hermes API {"hostname":"ssh-kraken.qentra.top", "service":"ssh://localhost:22"}, ← SSH (published application route) {"service":"http_status:404"} ← default catch-all ]} ``` ⚠️ **Важно (путаница была!):** `kraken.qentra.top` — это **HTTP-маршрут на `localhost:8642` (Hermes API)**, НЕ SSH. Поэтому SSH к `kraken.qentra.top:22` и не шёл. Под SSH создан отдельный hostname **`ssh-kraken.qentra.top`**. ### ✅ SSH-доступ работает через `ssh-kraken.qentra.top` (РАБОЧИЙ, 2026-09-04) **Вход (проверено, работает):** ```bash ssh kraken@ssh-kraken.qentra.top ``` `~/.ssh/config` блок: ``` Host ssh-kraken.qentra.top HostName ssh-kraken.qentra.top User kraken ProxyCommand cloudflared access ssh --hostname %h ``` Первый раз — авторизация cloudflared в Access-приложение: ```bash cloudflared access login ssh-kraken.qentra.top ``` Маршрут на Kraken (UP, контейнер) подхвачен ingress `ssh-kraken.qentra.top → ssh://localhost:22`; sshd на Kraken — `0.0.0.0:22`. DNS проксировано CF (104.21.x / 172.67.x). ### ⚠️ Питфол: почему `ssh.kraken.qentra.top` (двухуровневый) НЕ сработал Изначально под SSH добавлялся hostname `ssh.kraken.qentra.top` (`ssh.kraken` + `qentra.top`) → `ssh://localhost:22`, + Access Application (type SSH) + Service Token. Вход НЕ заработал. Решающий факт — на edge Cloudflare у этого hostname **НЕТ SSL/TLS-терминации**, в отличие от одиночных subdomain: ``` openssl s_client -connect ssh.kraken.qentra.top:443 → SSL alert 40 (handshake failure), no peer certificate curl https://ssh.kraken.qentra.top → ssl=1 handshake failure ``` Любой `cloudflared access login/ssh` и Service Token к чистому двухуровневому SSH-hostname не помогают — клиент не доходит даже до авторизации из-за отсутствия edge-TLS. **Решение, которое сработало:** использовать **одиночный subdomain через дефис** — `ssh-kraken.qentra.top` (покрывается Universal SSL `*.qentra.top`). На нём размещены тот же `published application route` SSH → `ssh://localhost:22` + Access Application. Вошло сразу. > Почему так: Universal SSL зоны покрывает `*.qentra.top` (1 уровень) и `qentra.top`, но НЕ `*.kraken.qentra.top` (2 уровня). Для 2-уровневого нужен Advanced Certificate — проще взять одиночный subdomain. ### Диагноз IPv4/IPv6 «жив, но шумит» (актуально для обоих hostname) - В логах cloudflared — часть `Registered tunnel connection ... protocol=quic`, но постоянные `ERR ... write udp [::]->198.41.x.x:7844: sendmsg: network is unreachable`. - **Причина: на Kraken НЕТ глобального IPv6** (только `::1` и link-local `fe80::`; роутер `192.168.1.1` IPv6 не выдаёт → `ping6 2606:4700::1111` = `Network is unreachable`). cloudflared пробует QUIC и по IPv6 → каналы падают; туннель выживает по IPv4-QUIC. - **Возможный фикс:** заставить cloudflared QUIC только по IPv4, чтобы убрать IPv6-шум. ### SSH через VPS reverse (независимо от cloudflared) Остаётся рабочим внешним путём: reverse SSH туннель через VPS `91.207.28.205:2223` (см. ниже), НЕ cloudflared. ## Связанные заметки - [[kraken-network]] — SSH, WG топология - [[wireguard-vpn]] — полное описание WG (⚠️ VPS-звено мёртво на 2026-09-01) - [[kraken-portainer-access]] - [[openmediavault-rpi5]] - [[tech/cloudflare-tunnel-ssh-published-route]] — генерализуемое руководство: SSH через Cloudflare Tunnel (1-уровневый subdomain + Universal SSL), питфолы