# Kraken — Portainer Access & Cloudflared SSH Tunnel > Статус: ⏳ cloudflared pending deploy (см. инструкции ниже) ## Portainer | Параметр | Значение | |---|---| | URL (локальный) | http://localhost:9000 | | Auth header | `X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=` | | Endpoint ID | 1 (local Docker) | ## Cloudflare Tunnel Token ``` eyJhIjoiODFlOGYwYThmMzg5ZTllNzg3NGFmMTE3NGQxYzIxOTIiLCJ0IjoiNjQxMGI0YTYtZWUyMS00MTczLWJhMzItMTcwOGY1MjNlNDMyIiwicyI6Ik9XWmpNVEkxWVRFdE9EWXpZaTAwWlRjNExXSTBaVFl0TkdNeU16Z3daV0pqTW1RMyJ9 ``` --- ## Задача для Кракен Hermes Поднять `cloudflare/cloudflared` в Docker через Portainer API. После запуска Alex добавит SSH-поддомен в Cloudflare Zero Trust (вручную, как делал для `zulip.qentra.top`). ### Шаг 1 — Проверить Portainer и Docker endpoint ```bash # Получить список endpoints (endpoint ID нужен для всех последующих запросов) curl -s -H "X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=" \ http://localhost:9000/api/endpoints | jq '.[].Id' # Ожидаем: 1 ``` ### Шаг 2 — Создать контейнер cloudflared через Portainer API ```bash # Создать контейнер (не запускать) curl -s -X POST \ -H "X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=" \ -H "Content-Type: application/json" \ "http://localhost:9000/api/endpoints/1/docker/containers/create?name=cloudflared" \ -d '{ "Image": "cloudflare/cloudflared:latest", "Cmd": ["tunnel", "--no-autoupdate", "run"], "Env": [ "TUNNEL_TOKEN=eyJhIjoiODFlOGYwYThmMzg5ZTllNzg3NGFmMTE3NGQxYzIxOTIiLCJ0IjoiNjQxMGI0YTYtZWUyMS00MTczLWJhMzItMTcwOGY1MjNlNDMyIiwicyI6Ik9XWmpNVEkxWVRFdE9EWXpZaTAwWlRjNExXSTBaVFl0TkdNeU16Z3daV0pqTW1RMyJ9" ], "HostConfig": { "RestartPolicy": {"Name": "unless-stopped"}, "NetworkMode": "host" } }' | jq -r '.Id' # Сохранить полученный container ID ``` ### Шаг 3 — Запустить контейнер ```bash CONTAINER_ID="" curl -s -X POST \ -H "X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=" \ "http://localhost:9000/api/endpoints/1/docker/containers/${CONTAINER_ID}/start" # Ожидаем: пустой ответ или 204 No Content = OK ``` ### Шаг 4 — Проверить логи ```bash curl -s \ -H "X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=" \ "http://localhost:9000/api/endpoints/1/docker/containers/${CONTAINER_ID}/logs?stdout=true&stderr=true&tail=30" \ | strings # Ожидаем в логах: # INF Registered tunnel connection connIndex=0 ... protocol=http2 # INF Connection ... registered connIndex=0..3 ``` ### Шаг 5 — Создать docker-compose.yml для постоянного управления Через Alpine-контейнер с доступом к хосту: ```bash # Создать alpine контейнер, который запишет compose-файл на хост curl -s -X POST \ -H "X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=" \ -H "Content-Type: application/json" \ "http://localhost:9000/api/endpoints/1/docker/containers/create?name=alpine-setup" \ -d '{ "Image": "alpine:latest", "Cmd": ["sh", "-c", "mkdir -p /host/home/kraken/cloudflared && cat > /host/home/kraken/cloudflared/docker-compose.yml << '"'"'EOF'"'"'\nservices:\n cloudflared:\n image: cloudflare/cloudflared:latest\n container_name: cloudflared\n restart: unless-stopped\n command: [\"tunnel\", \"--no-autoupdate\", \"run\"]\n environment:\n - TUNNEL_TOKEN=eyJhIjoiODFlOGYwYThmMzg5ZTllNzg3NGFmMTE3NGQxYzIxOTIiLCJ0IjoiNjQxMGI0YTYtZWUyMS00MTczLWJhMzItMTcwOGY1MjNlNDMyIiwicyI6Ik9XWmpNVEkxWVRFdE9EWXpZaTAwWlRjNExXSTBaVFl0TkdNeU16Z3daV0pqTW1RMyJ9\n network_mode: host\nEOF\necho DONE"], "HostConfig": { "Binds": ["/:/host"], "AutoRemove": true } }' | jq -r '.Id' # Запустить alpine контейнер curl -s -X POST \ -H "X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=" \ "http://localhost:9000/api/endpoints/1/docker/containers//start" ``` ### Шаг 6 — Обновить Obsidian После успешного запуска cloudflared — обновить статус в этой заметке: `Статус: ⏳` → `Статус: ✅ cloudflared запущен`. --- ## Что делает Alex вручную (после запуска) 1. Открыть [Cloudflare Zero Trust → Networks → Tunnels](https://one.dash.cloudflare.com/) 2. Найти туннель (должен появиться как активный после запуска контейнера) 3. Нажать **Edit** → вкладка **Public Hostname** → **Add a public hostname**: - Subdomain: `ssh` - Domain: `kraken.qentra.top` (или другой по вкусу) - Service type: **SSH** - URL: `localhost:22` 4. Сохранить → DNS запись создаётся автоматически > Повторить для других сервисов если нужно: > - `omv.kraken.qentra.top` → HTTP → `localhost:80` > - `portainer.kraken.qentra.top` → HTTP → `localhost:9000` --- ## SSH-доступ через Cloudflare Tunnel (с любой машины) После настройки поддомена Alex создаёт скилл на Eagle для доступа к Кракену через тоннель (аналог Таига через alpine+portainer): ```bash # Один раз настроить ~/.ssh/config на Eagle: Host ssh.kraken.qentra.top ProxyCommand cloudflared access ssh --hostname %h User kraken IdentityFile ~/.ssh/id_rsa StrictHostKeyChecking no # Подключиться: ssh ssh.kraken.qentra.top ``` > ⚠️ `cloudflared` должен быть установлен на клиентской машине (Eagle). > На Eagle уже есть — он используется для `zulip.qentra.top`. --- ## Проверка что туннель работает ```bash # На Кракене: посмотреть статус контейнера docker ps | grep cloudflared # Логи cloudflared docker logs cloudflared --tail 20 # С Eagle (после настройки DNS): тест SSH ssh -o ProxyCommand="cloudflared access ssh --hostname ssh.kraken.qentra.top" \ -i ~/.ssh/id_rsa kraken@ssh.kraken.qentra.top whoami ``` --- ## Связанные заметки - [[openmediavault-rpi5]] — настройка Kraken (Docker, Hermes, структура папок) - [[truenas-infrastructure]] — Taiga (аналогичный подход через Portainer) - [[obsidian-sync]] — синхронизация vault