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

6.8 KiB
Raw Blame History

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

# Получить список endpoints (endpoint ID нужен для всех последующих запросов)
curl -s -H "X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=" \
  http://localhost:9000/api/endpoints | jq '.[].Id'
# Ожидаем: 1

Шаг 2 — Создать контейнер cloudflared через Portainer API

# Создать контейнер (не запускать)
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 — Запустить контейнер

CONTAINER_ID="<id из шага 2>"

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 — Проверить логи

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-контейнер с доступом к хосту:

# Создать 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/<alpine-id>/start"

Шаг 6 — Обновить Obsidian

После успешного запуска cloudflared — обновить статус в этой заметке: Статус: ⏳Статус: ✅ cloudflared запущен.


Что делает Alex вручную (после запуска)

  1. Открыть Cloudflare Zero Trust → Networks → Tunnels
  2. Найти туннель (должен появиться как активный после запуска контейнера)
  3. Нажать Edit → вкладка Public HostnameAdd 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):

# Один раз настроить ~/.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.


Проверка что туннель работает

# На Кракене: посмотреть статус контейнера
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

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