Порты и доступ
Короткое правило: наружу nkt не открывается никогда. Интерфейс хоста и хаба слушает loopback; хаб сам ходит к хостам по SSH; всё остальное — внутренние порты, которые открывать в интернет не нужно.
Сводка
| Порт | Где слушает | Кто подключается | Открывать наружу? |
|---|---|---|---|
8077/tcp | хост и хаб, 127.0.0.1 | ваш браузер (туннель или прокси); хаб — через SSH | нет, только через SSH-туннель или прокси с TLS |
8443/tcp | хаб в Docker (проброс на 8077) | ваш браузер | только за прокси с TLS |
8446/tcp | хост и хаб, хост из NKT_ADDR | ваш браузер — пробросы портов Kubernetes | так же, как интерфейс |
22/tcp | управляемые хосты | хаб | с адреса хаба |
8078/tcp | управляемые хосты (резервный канал) | хаб | с адреса хаба |
3142/tcp | управляемые хосты, 127.0.0.1 | apt и containerd на хосте (обратный SSH-проброс от хаба) | нет |
443/tcp, 80/tcp | VPS с nkt-edge | по ролям edge: GitHub, GitLab, CI (вебхуки), n8n и скрипты (API), Slack (колбэки); 80 — certbot | да — это их назначение |
8444/tcp | VPS с nkt-edge | хаб (туннель) | с адреса хаба; можно всем — вход по токену |
51820/udp | хосты кластера на WireGuard | соседние хосты кластера | между хостами кластера |
6443, 80, 443 | хост с кластером (DNAT) | клиенты кластера | по желанию, «пробросить наружу» |
8077: интерфейс и API
И nkt, и хаб по умолчанию слушают 127.0.0.1:8077 (NKT_ADDR), а cookie сессии ходит только по HTTPS (NKT_COOKIE_SECURE=true). Способы добраться:
- SSH-туннель —
ssh -L 8077:127.0.0.1:8077 -L 8446:127.0.0.1:8446 user@hostиhttp://127.0.0.1:8077; в env-файлеNKT_COOKIE_SECURE=false. Второй-Lнужен только для пробросов портов Kubernetes. - HTTPS самого nkt —
NKT_TLS_ENABLED=true(самоподписанный или ваш сертификат) иNKT_ADDR=0.0.0.0:8077, если открываете в локальной сети. - Обратный прокси с TLS — nginx или Caddy перед
127.0.0.1:8077.
На управляемом хосте API nkt слушает только loopback; хаб ходит к нему через SSH-туннель. Порт — NKT_HUB_HOST_API_PORT хаба (по умолчанию 8077) или своё поле «порт API» у хоста, если 8077 там занят.
DANGER
Доступ к nkt равносилен root на хосте, к хабу — root на всех хостах. Прокси с TLS без отдельной аутентификации (VPN, SSO, allow-list адресов) в интернет не выставляйте.
Пример nginx (интерфейс и API, включая WebSocket):
server {
listen 443 ssl;
server_name nkt.example.com;
ssl_certificate /etc/letsencrypt/live/nkt.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nkt.example.com/privkey.pem;
# allow 203.0.113.0/24; deny all; # ограничьте, кому можно
location / {
proxy_pass http://127.0.0.1:8077;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 1h;
client_max_body_size 0; # загрузка образов и файлов
}
}Запросы, меняющие состояние, nkt принимает только со своего origin (заголовки Sec-Fetch-Site/Origin против Host), поэтому прокси должен передавать исходный Host. Другие разрешённые origin — NKT_CORS_ORIGINS.
8446: пробросы портов Kubernetes
«Открыть в браузере» у пода или сервиса делает kubectl port-forward и открывает приложение на отдельном порту — у него свой origin, и приложение пода не видит cookie nkt. Адрес — NKT_FORWARD_ADDR, по умолчанию тот же хост, что в NKT_ADDR, и порт 8446; TLS — тот же, что у интерфейса.
- Через SSH-туннель пробросьте и 8446 (см. выше).
- За прокси заведите для пробросов отдельное имя или порт и скажите nkt, как их видит браузер:
NKT_FORWARD_PUBLIC_URL=https://fwd.example.com. NKT_FORWARD_ADDR=offвыключает отдельный порт: пробросы идут по пути интерфейса в песочнице (Content-Security-Policy: sandbox). Простые страницы работают, приложения с JavaScript и cookie — не всегда.
В Docker Compose и манифесте Kubernetes порт 8446 уже опубликован.
Хаб → хосты: 22 и 8078
Хаб подключается к хостам сам — входящие к хабу не нужны, белый адрес тоже.
- SSH (22) — установка, обновления, туннель к API хоста. На хосте достаточно разрешить SSH с адреса хаба.
- Резервный канал (8078) — на случай, когда SSH недоступен (упал sshd, протухли учётные данные): хаб дозванивается на этот порт тем же адресом, что и SSH; TLS с закреплённым отпечатком и токен на хост. Порт —
NKT_HUB_TUNNEL_PORT. Если закрыт — колонка «Канал» у хоста серая. Файрвол, закрывший все входящие, закроет и его.
Кэш пакетов: 3142
Хаб держит к хосту обратный SSH-проброс: на хосте 127.0.0.1:3142 (NKT_HUB_APTCACHE_PORT) ведёт в кэширующий прокси хаба. Порт живёт только на loopback хоста, открывать ничего не нужно. См. Кэш пакетов.
Вход для хаба за NAT: вебхуки, API, боты
Что приходит к хабу снаружи и как без открытого хаба:
| Что | Путь на хабе | Без открытого хаба |
|---|---|---|
| вебхук конвейера | POST /api/hub/hooks/{id} | опрос репозитория или registry; nkt-edge с ролью «вебхуки» |
| API-токены (n8n, CI, скрипты) | /api/hub/…, /api/hosts/… | nkt-edge с ролью «API» — только подписанные запросы |
| команды и кнопки Slack | POST /api/hub/callbacks/slack/… | nkt-edge с ролью «колбэки» |
| бот Telegram, исходящие вебхуки, оповещения Slack | — | вход не нужен: хаб ходит наружу сам (443 к Telegram, Slack, адресатам) |
| проверки сайтов «снаружи» | — | nkt-edge с ролью «проверки снаружи»: хаб просит edge по туннелю |
Edge принимает своё на 443 и передаёт хабу по туннелю, который хаб держит сам (8444 на VPS).
Если хаб уже за прокси и вебхуки хочется принимать напрямую, откройте наружу только эти пути (/api/hub/callbacks/ — если нужен Slack):
location /api/hub/hooks/ {
proxy_pass http://127.0.0.1:8077;
proxy_set_header Host $host;
client_max_body_size 1m;
}
location /api/hub/callbacks/ {
proxy_pass http://127.0.0.1:8077;
proxy_set_header Host $host;
client_max_body_size 1m;
}
location / { deny all; } # остальное — только из VPN или по allow-listВебхук без верной подписи хаб отвергает (401), повтор той же доставки — тоже.
Кластеры
- WireGuard между хостами кластера — UDP 51820 между ними.
- Пробросить наружу — DNAT с портов хоста (
6443,80,443по умолчанию, любой можно заменить или обнулить) на control plane. Без проброса кластер доступен только из сети хоста.