Files
obsidian-vault/family/how-to/kraken-access.md
T

32 KiB
Raw Blame History

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 <name> --format '{{.HostConfig.RestartPolicy.Name}}' (живой daemon), а не hostconfig.json на диске.

Команды диагностики (воспроизводимые)

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-<date>/.
  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:
    [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 <path> — юнит переживёт обрыв 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 цел.

Диагностика, доказывающая «бридж молчит»:

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:

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-<date>, /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}}' <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) были целы — только владелец не тот.

Фикс:

# 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)

Вход (проверено, работает):

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-приложение:

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.

Связанные заметки