# Port-Knocker: как вам засунуть SPA в бинарь Go и остаться в живых Если вы когда-нибудь хотели постучаться в порты так, чтобы это не было больно вашим пальцам от набивания команд в терминале — этот гайд для вас. Мы возьмём консольный `port-knocker`, прицепим к нему SPA на Angular, засунем всё в один Go-бинарь и обернём это в Docker, чтобы запускать одним махом. ## Что сделаем - Веб-GUI на Angular для задания inline целей и YAML-конфигов, с шифрованием/дешифрованием - REST API на Gin: `/api/v1/knock-actions/*` - Базовая авторизация паролем через `GO_KNOCKER_SERVE_PASS` - Встраивание фронтенда в бинарь через `go:embed` - Docker и docker-compose для «поднял и поехал» ## Предварительно - Go >= 1.21 (у нас 1.23) - Node.js >= 20, npm - Docker (если хотите контейнером) ## Структура ``` text embed-gui-article/ back/ # скопированный и доработанный port-knocker cmd/serve.go # Gin сервер, API, Basic-Auth, раздача статики cmd/public/ # сборка Angular, встраивается go:embed ui/ # Angular 17 приложение (стартовый шаблон) Dockerfile # multi-stage: Angular -> Go -> runtime docker-compose.yml # запуск контейнера article.md # вы читаете это plan.md, уточнения.md # ТЗ и ответы ``` ## API кратко - POST `/api/v1/knock-actions/execute` - Тело (inline): `{ targets, delay, verbose, waitConnection, gateway }` - Тело (yaml): `{ config_yaml }` - POST `/api/v1/knock-actions/encrypt` → `{ encrypted: "ENCRYPTED:..." }` - POST `/api/v1/knock-actions/decrypt` → `{ yaml: "..." }` Авторизация: Basic c пустым логином и паролем = `GO_KNOCKER_SERVE_PASS`. ## Сборка и запуск локально - Собрать фронт и встроить (в репо уже встроено): ``` bash cd ui npm install npm run build cp -r dist/project-front/browser/* ../back/cmd/public/ ``` - Собрать сервер и запустить: ``` bash cd ../back go build -o knocker-serve . GO_KNOCKER_SERVE_PASS=devpass GO_KNOCKER_SERVE_PORT=8888 ./knocker-serve serve ``` - Открыть: `http://localhost:8888/` (указать пароль `devpass` в Basic-Auth) ## Docker ``` bash docker compose build GO_KNOCKER_SERVE_PASS=devpass docker compose up -d # Открыть http://localhost:8888/ ``` ## UI фичи (минимально жизненно необходимые) - Режим inline целей или YAML - Кнопки: Execute, Encrypt, Decrypt - Загрузка файла (YAML/ENCRYPTED) в форму - Скачивание YAML и результата (ENCRYPTED/YAML) ## Безопасность (по-простому) - Пароль обязателен: `GO_KNOCKER_SERVE_PASS` - Порт задаётся `GO_KNOCKER_SERVE_PORT` (дефолт 8888) - Ключ шифрования конфигов берётся из пароля (внутри – через SHA-256) - Файловые операции включены по умолчанию (отключить: `GO_KNOCKER_ENABLE_FILE_IO=0`) ## Faq — «Почему интерфейс на английском?» — Потому что порты — международные ребята. Им так проще понимать, когда их стучат. — «Где пасхалки?» — Только в CLI. В GUI — строго делово: стучим — открываем — уходим красиво. Удачных постукиваний! И помните: хороший стук всегда откроет нужную дверь.