Files
obsidian-vault/personal/tech/cloudflare-tunnel-ssh-published-route.md
T
Taiga b53dd70a15 [2026-09-26 09:10:28] syncthing: personal/tech/archive-org-collection-harvest.md personal/tech/balda-go-fx-pitfalls.md personal/tech/bilety-oxota-interaktiv.md personal/tech/cloudflare-tunnel-ssh-published-route.md personal/tech/deepseek-language-drift.md personal/tech/docker-data-root-mount-race.md personal/tech/docker-mac-disk-issues.md personal/tech/docker_colima_setup.md personal/tech/eagle-dashboard-launchd.md personal/tech/hermes-agent-improvements.md personal/tech/hermes-browser-toolsets.md personal/tech/hermes-fork-vs-upstream.md personal/tech/hermes-git-repo.md personal/tech/hermes-memory-architecture.md personal/tech/hermes-secret-redaction-bypass.md personal/tech/hermes-self-improvement-review.md personal/tech/home-network-config.md personal/tech/inter-site-throughput-taiga-to-mac.md personal/tech/inter-site-throughput-taiga-to-mac.md.bak-nedstab2 personal/tech/jellyfin-db-schema-mismatch.md personal/tech/karabiner-keyboard-config.md personal/tech/kraken-media-inventory-facts.md personal/tech/kraken-truenas-media-copies.md personal/tech/lampa-jellyfin-plugin.md personal/tech/lampac-deployment.md personal/tech/lampac-torrserver.md personal/tech/llm-model-selection-2026.md personal/tech/mac-print-shared-services.md personal/tech/modbus-rtu-sniffer-debugging.md personal/tech/multistream-single-flow-limit.md personal/tech/multistream-single-flow-limit.md.bak-nedstab2 personal/tech/music-tags-repair-truenas.md personal/tech/obsidian-mcp-ecosystem.md personal/tech/original-xbox-2025-guide.md personal/tech/prowlarr-flaresolverr-cloudflare.md personal/tech/radarr-sonarr-phantom-records.md personal/tech/roundtrip-key-verification.md personal/tech/ryujinx-mac-setup.md personal/tech/skill-arr-media-stack-setup-additions.md personal/tech/skill-docker-data-root-mount-race.md personal/tech/skill-lampac-kraken-deploy.md personal/tech/tirith-trust.md personal/tech/truenas-local-tree-comparison.md personal/tech/truenas-nfs4-acl-and-arrmultiuser.md personal/tech/truenas-zfs-panic-recovery.md personal/tech/vault-doc-pruning.md personal/tech/vless-space-subscription-egress.md personal/tech/watchlist-sync-feed.md personal/tech/watchtower-docker-updates.md personal/tech/xray-outbound-subscription-3xui.md personal/tech/xray-reverse-limits-private-network.md personal/tech/xray-reverse-tunnel-kraken-truenas.md personal/tech/xray-reverse-tunnel-kraken-truenas.md.bak-nedstab2 personal/tech/yandex-music-api.md
2026-09-26 09:10:28 +00:00

5.0 KiB
Executable File
Raw Blame History

Cloudflare Tunnel: SSH через Published Application Route

Обновлено: 2026-09-04 (итог отладки захода на Kraken) Рабочий case с полными командами: family/how-to/kraken-access.md

Генерализуемые выводы про то, как сделать SSH через Cloudflare Tunnel (published application route), чтобы вход работал ssh user@host — через cloudflared на клиенте.

Ключевое правило: hostname должен быть 1-уровневым subdomain (БЕЗ точки до домена)

Симптом: двухуровневый subdomain вида ssh.kraken.qentra.top (ssh.kraken + точка + qentra.top) НЕ работает как SSH/TLS через Cloudflare.

Проверка (решающий факт) — на edge НЕТ TLS-терминации для 2-уровневого hostname:

openssl s_client -connect ssh.kraken.qentra.top:443 -servername ssh.kraken.qentra.top
# → SSL alert number 40 (handshake failure), "no peer certificate available"
curl -s https://ssh.kraken.qentra.top   # ssl=1 handshake failure

В отличие от 1-уровневого hostname (kraken.qentra.top), который отвечает:

openssl s_client -connect kraken.qentra.top:443 ...  # CN=qentra.top, verify ok

Почему: Universal SSL Cloudflare-зоны покрывает только *.domain (1 уровень wildcard) и сам domain. Он НЕ покрывает *.sub.domain (2 уровень). Для 2-уровневых нужен Advanced Certificate (SAN на полный двухуровневый wildcard) — обычно проще взять одиночный subdomain.

⚠️ ПИТФОЛ: Cloudflare-точка в hostname (a.b.domain) = 2 уровня по SSL, точка НЕ безобидна. Рабочая замена — один уровень с дефисом: ssh-kraken.qentra.top (покрывается *.qentra.top).

Правильная схема SSH через Tunnel (по доке Cloudflare)

На сервере/туннеле (Zero Trust):

  • Tunnels → туннель → Routes → Add route → Published application
  • Service: SSH → localhost:22 (или <ip>:22)
  • hostname использовать одиночный subdomain (ssh-kraken.qentra.top, не ssh.kraken...)

В Zero Trust Access:

  • Access → Applications → Add self-hosted (тип SSH, browser rendering off) на тот же hostname, с политикой (Allow / Service Token).
  • SSH-route без Access Application не даёт клиенту пройти даже до авторизации: cloudflared access login <ssh-host> → failed to get app info: ... tls: handshake failure.

На клиенте (cloudflared установлен): ~/.ssh/config:

Host ssh-kraken.qentra.top
  HostName ssh-kraken.qentra.top
  User kraken
  ProxyCommand cloudflared access ssh --hostname %h

Первый раз — авторизация: cloudflared access login ssh-kraken.qentra.top (откроет SSO/браузер). Дальше ssh kraken@ssh-kraken.qentra.top.

Client-side подводные камни

  • cloudflared access login <ssh-hostname> нельзя проверить по HEAD https://<ssh-host> — SSH-kind hostname НЕ терминирует HTTP/TLS, поэтому failed to get app info: tls: handshake failure — ожидаемо, если на маршруте нет Access App.
  • ~/.cloudflared/*-org-token = not-available означает, что cloudflared НЕ авторизован в Access org — разовый cloudflared access login обязателен.
  • Сам ssh к hostname:22 напрямую (без cloudflared в ProxyCommand) к проксированному DNS не работает — hostname за Cloudflare-Anycast, в туннель трафик попадает только через cloudflared-клиент.
  • network_mode: host (container cloudflared) — сервис напрямую видит локальные порты (sshd на 0.0.0.0:22).

Общий паттерн «жив, но шумит» cloudflared на origin без IPv6

Если у origin нет глобального IPv6 (роутер не выдаёт), cloudflared пытается поднять QUIC и по IPv6 → в логах постоянные ERR ... write udp [::]->198.41.x.x:7844: sendmsg: network is unreachable, соединения падают/retry. Туннель продолжает работать по IPv4-QUIC. Возможный фикс — заставить cloudflared использовать только IPv4.

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

  • family/how-to/kraken-access.md — рабочий живой пример (hostname ssh-kraken.qentra.top, ingress, команды)
  • family/how-to/kraken-portainer-access.md — деплой cloudflared-контейнера и логи туннеля