24 KiB
Руководство по использованию Desktop приложения
Обзор
Desktop версия knocker-приложения предоставляет полный функционал порт-простукивания (port knocking) в виде автономного Electron приложения. Поддерживает как работу через внешний API сервер, так и локальное простукивание через Node.js.
Содержание
- Установка и запуск
- Режимы работы
- Конфигурация
- API контракты
- Локальное простукивание
- Интерфейс пользователя
- Примеры использования
- Устранение неполадок
- Разработка
Установка и запуск
Предварительные требования
- Node.js v18+
- npm v8+
- Операционная система: Windows, macOS, Linux
Установка зависимостей
cd desktop
npm install
Режимы запуска
Разработка
npm run dev
Сборка для продакшена
npm run build
Создание исполняемых файлов
npm run dist
Упаковка для конкретной платформы
# Windows
npm run dist:win
# macOS
npm run dist:mac
# Linux
npm run dist:linux
Переменные окружения
# Базовый URL API (опционально)
export KNOCKER_DESKTOP_API_BASE="http://localhost:8080/api/v1"
# Запуск в режиме разработки
npm run dev
Режимы работы
1. API режим (по умолчанию)
Приложение подключается к внешнему HTTP API серверу для выполнения операций простукивания.
Активация:
- Установить корректный
apiBase
URL в настройках - Например:
http://localhost:8080/api/v1
Возможности:
- ✅ HTTP API простукивание
- ✅ Шифрование/расшифровка YAML
- ✅ Полная функциональность backend сервера
2. Локальный режим
Приложение выполняет простукивание напрямую через Node.js сокеты без внешнего API.
Активация:
- Установить
apiBase
в""
(пустая строка) - Или установить
apiBase
в"internal"
Возможности:
- ✅ TCP простукивание
- ✅ UDP простукивание
- ❌ Шифрование/расшифровка (недоступно)
- ✅ Автономная работа
Локальное простукивание с gateway (Rust/Go helper)
- Если указано
gateway
(IP или имя интерфейса), Electron автоматически запускает встроенный helper из папкиbin/
:knock-local-rust
(Rust) — используется приоритетно, если присутствуетknock-local
(Go) — используется как fallback, если Rust-бинарь отсутствует
- Оба helper-а на Linux используют
SO_BINDTODEVICE
для надежной привязки к интерфейсу и обхода VPN/WireGuard. - Если
gateway
не указан — используется встроенная Node-реализация без привязки к интерфейсу.
Требования при разработке:
- Для Rust-хелпера ничего дополнительно не требуется (собирается скриптом
npm run rust:build
). - Для Go-хелпера должен быть установлен Go toolchain (скрипт
npm run go:build
). В релизных сборках оба бинаря включаются автоматически.
Важно (TCP): привязка интерфейса (SO_BINDTODEVICE
) устанавливается до connect()
. Это гарантирует, что исходящее TCP-соединение пойдёт через указанный интерфейс, а не в туннель.
3. Переключение между режимами
API → Локальный:
- Открыть настройки (Ctrl/Cmd + ,)
- Установить
apiBase: ""
илиapiBase: "internal"
- Сохранить настройки
- Перезапустить приложение
Локальный → API:
- Открыть настройки
- Установить корректный
apiBase
URL - Сохранить настройки
- Перезапустить приложение
Конфигурация
Файл конфигурации
Конфигурация сохраняется в: ~/.config/[app-name]/config.json
Структура конфигурации:
{
"apiBase": "http://localhost:8080/api/v1",
"gateway": "default-gateway",
"inlineTargets": "tcp:127.0.0.1:22;tcp:192.168.1.1:80",
"delay": "1s"
}
Поля конфигурации
Поле | Тип | Описание | По умолчанию |
---|---|---|---|
apiBase |
string | URL API сервера или "internal" | http://localhost:8080/api/v1 |
gateway |
string | Шлюз по умолчанию | "" |
inlineTargets |
string | Цели в inline формате | "" |
delay |
string | Задержка между целями | "1s" |
Редактирование конфигурации
Через интерфейс:
- Меню → Настройки
- Редактирование JSON в текстовом поле
- Кнопка "Сохранить"
Программно:
// Получить значение
const apiBase = await window.api.getConfig('apiBase');
// Установить значение
await window.api.setConfig('apiBase', 'http://new-api.com');
// Получить всю конфигурацию
const config = await window.api.getAllConfig();
// Установить всю конфигурацию
await window.api.setAllConfig(newConfig);
API контракты
HTTP API Endpoints (для API режима)
1. Выполнение простукивания
POST /api/v1/knock-actions/execute
Headers:
Content-Type: application/json
Authorization: Basic <base64(username:password)>
Body (YAML режим):
{
"config_yaml": "targets:\n - protocol: tcp\n host: 127.0.0.1\n ports: [22, 80]\ndelay: 1s"
}
Body (Inline режим):
{
"targets": "tcp:127.0.0.1:22;tcp:192.168.1.1:80",
"delay": "1s",
"verbose": true,
"waitConnection": false,
"gateway": "gateway.com"
}
Body (Form режим):
{
"targets": "tcp:127.0.0.1:22;tcp:192.168.1.1:80",
"delay": "2s",
"verbose": true,
"waitConnection": true
}
Response:
{
"success": true,
"message": "Knocking completed successfully"
}
2. Шифрование YAML
POST /api/v1/knock-actions/encrypt
Headers:
Content-Type: application/json
Authorization: Basic <base64(username:password)>
Body:
{
"yaml": "targets:\n - protocol: tcp\n host: 127.0.0.1\n ports: [22]"
}
Response:
{
"encrypted": "ENCRYPTED:base64-encoded-data"
}
3. Расшифровка YAML
POST /api/v1/knock-actions/decrypt
Headers:
Content-Type: application/json
Authorization: Basic <base64(username:password)>
Body:
{
"encrypted": "ENCRYPTED:base64-encoded-data"
}
Response:
{
"yaml": "targets:\n - protocol: tcp\n host: 127.0.0.1\n ports: [22]"
}
IPC API (для локального режима)
Локальное простукивание
Channel: knock:local
Request:
{
targets: string[], // ["tcp:127.0.0.1:22", "udp:192.168.1.1:53"]
delay: string, // "1s", "2m", "500ms"
verbose: boolean, // true/false
gateway: string // "192.168.1.1" (опционально)
}
Response:
{
success: boolean,
results: [
{
target: string,
success: boolean,
message: string
}
],
summary: {
total: number,
successful: number,
failed: number
}
}
Локальное простукивание _
Поддерживаемые протоколы
- TCP - создание соединения и немедленное закрытие
- UDP - отправка пакета данных (fire-and-forget)
Формат целей
protocol:host:port[:gateway]
Примеры:
tcp:127.0.0.1:22
udp:192.168.1.1:53
tcp:example.com:80:gateway.com
Поддержка Gateway
Gateway можно указать двумя способами:
- В строке цели:
tcp:host:port:gateway_ip
- Глобально через поле Gateway: используется для всех целей, если не указан в самой цели
Приоритет gateway:
- Gateway из строки цели имеет приоритет над глобальным
- Если gateway не указан, используется системный маршрут по умолчанию
Примеры использования gateway:
tcp:192.168.1.100:22:192.168.1.1 # Через конкретный gateway
tcp:127.0.0.1:22 # Системный маршрут
udp:example.com:53 # Системный маршрут
Формат задержек
1s
- 1 секунда500ms
- 500 миллисекунд (не поддерживается, используйте0.5s
)2m
- 2 минуты1h
- 1 час
Таймауты
- TCP: 5 секунд по умолчанию
- UDP: 5 секунд по умолчанию
Примеры локального простукивания
// Простое TCP простукивание
const result = await window.api.localKnock({
targets: ["tcp:127.0.0.1:22"],
delay: "1s",
verbose: true
});
// Множественные цели
const result = await window.api.localKnock({
targets: [
"tcp:127.0.0.1:22",
"udp:192.168.1.1:53",
"tcp:example.com:80"
],
delay: "2s",
verbose: false
});
Интерфейс пользователя
Главное окно
Поля конфигурации _
- API URL - адрес API сервера или "internal" для локального режима
- Gateway - шлюз по умолчанию
- Password - пароль для аутентификации
Режимы работы _
- Inline - простой текстовый формат целей
- YAML - структурированная YAML конфигурация
- Form - графический редактор целей
Inline режим
- Targets - цели в формате
protocol:host:port;protocol:host:port
- Delay - задержка между целями
- Verbose - подробный вывод
- Wait Connection - ожидание соединения
- Gateway - шлюз
YAML режим
- Config YAML - YAML конфигурация
- Server File Path - путь к файлу на сервере
- Encrypt/Decrypt - шифрование/расшифровка
Form режим
- Targets List - список целей с возможностью редактирования
- Add Target - добавление новой цели
- Remove - удаление цели
Меню приложения
Файл
- Открыть файл - загрузка YAML конфигурации
- Сохранить как - сохранение текущей конфигурации
- Выход - закрытие приложения
Настройки
- Настройки - открытие окна конфигурации
Справка
- О программе - информация о версии
- Документация - ссылки на документацию
Окно настроек
Редактирование конфигурации _
- JSON Editor - многострочное поле для редактирования
- Save - сохранение изменений
- Return - возврат к главному окну
Валидация
- Автоматическая проверка JSON синтаксиса
- Отображение ошибок валидации
- Предотвращение сохранения некорректных данных
Примеры использования
Пример 1: Базовое простукивание SSH
Цель: Открыть SSH доступ к серверу
Конфигурация:
{
"apiBase": "internal",
"gateway": "",
"inlineTargets": "tcp:192.168.1.100:22",
"delay": "1s"
}
Шаги:
- Установить режим "Inline"
- Ввести цель:
tcp:192.168.1.100:22
- Установить задержку:
1s
- Нажать "Выполнить"
Пример 2: Множественные цели
Цель: Простучать несколько сервисов
Конфигурация:
tcp:server1.com:22;tcp:server1.com:80;udp:server2.com:53
Задержка: 2s
Пример 3: YAML конфигурация
Файл конфигурации:
targets:
- protocol: tcp
host: 127.0.0.1
ports: [22, 80, 443]
wait_connection: true
- protocol: udp
host: 192.168.1.1
ports: [53, 123]
delay: 1s
path: /etc/knocker/config.yaml
Пример 4: Шифрование конфигурации
Шаги:
- Создать YAML конфигурацию
- Установить пароль
- Нажать "Зашифровать"
- Сохранить зашифрованный файл
Пример 5: Локальный режим с множественными целями
Конфигурация для локального режима:
{
"apiBase": "internal",
"inlineTargets": "tcp:127.0.0.1:22;tcp:127.0.0.1:80;udp:127.0.0.1:53",
"delay": "1s"
}
Пример 6: Использование Gateway
Простукивание через определенный интерфейс:
{
"apiBase": "internal",
"gateway": "192.168.1.1",
"inlineTargets": "tcp:192.168.1.100:22",
"delay": "1s"
}
Смешанное использование gateway:
tcp:127.0.0.1:22;tcp:192.168.1.100:22:192.168.1.1;udp:example.com:53
- Первая цель: без gateway (системный маршрут)
- Вторая цель: через gateway 192.168.1.1
- Третья цель: без gateway
Замечания по ошибкам:
- Если указан несуществующий интерфейс в
gateway
, helper вернёт критическую ошибку и код выхода 1. - При
waitConnection: false
сетевые отказы соединения трактуются как предупреждения, но ошибки привязки к интерфейсу — всегда ошибки.
Устранение неполадок
Общие проблемы
Проблема: "API URL не доступен"
Симптомы:
- Ошибки подключения к API
- Таймауты при выполнении операций
Решения:
- Проверить доступность API сервера
- Проверить правильность URL
- Проверить настройки файрвола
- Переключиться в локальный режим
Проблема: "Неправильный пароль"
Симптомы:
- HTTP 401 ошибки
- Отказ в доступе при шифровании
Решения:
- Проверить правильность пароля
- Убедиться в корректности base64 кодирования
- Проверить настройки аутентификации на сервере
Проблема: "Файл не найден"
Симптомы:
- Ошибки при открытии файлов
- "File not found" при сохранении
Решения:
- Проверить права доступа к файлам
- Убедиться в существовании директорий
- Проверить путь к файлу
Проблемы локального режима
Проблема: "No targets provided"
Причина: Не удалось извлечь цели из конфигурации
Решение:
- Проверить заполнение поля targets
- Убедиться в корректности формата
- Проверить режим работы (inline/yaml/form)
Проблема: "Unsupported protocol"
Причина: Использован неподдерживаемый протокол
Решение:
- Использовать только
tcp
илиudp
- Проверить синтаксис:
protocol:host:port
Проблема: "Connection timeout"
Причина: Цель недоступна или заблокирована
Решение:
- Проверить доступность цели
- Проверить настройки файрвола
- Убедиться в правильности IP/порта
Проблемы конфигурации
Проблема: "Invalid JSON"
Симптомы:
- Ошибки при сохранении настроек
- Невозможность загрузить конфигурацию
Решения:
- Проверить синтаксис JSON
- Использовать валидатор JSON
- Проверить экранирование специальных символов
Проблема: "Настройки не сохраняются"
Причина: Проблемы с правами доступа
Решение:
- Проверить права записи в директорию конфигурации
- Запустить от имени администратора (если необходимо)
- Проверить свободное место на диске
Диагностика
Логи приложения
# Windows
%APPDATA%/[app-name]/logs/
# macOS
~/Library/Logs/[app-name]/
# Linux
~/.config/[app-name]/logs/
DevTools
- Открыть DevTools (F12)
- Проверить Console на ошибки
- Проверить Network для API запросов
- Проверить Application → Local Storage
Командная строка
# Запуск с отладкой
npm run dev -- --enable-logging
# Проверка переменных окружения
echo $KNOCKER_DESKTOP_API_BASE
Разработка _
Структура проекта
desktop/
├── src/
│ ├── main/ # Main процесс
│ │ └── main.js # Основная логика
│ ├── preload/ # Preload скрипты
│ │ └── preload.js # IPC мост
│ └── renderer/ # Renderer процесс
│ ├── index.html # Главная страница
│ ├── renderer.js # UI логика
│ ├── settings.html # Страница настроек
│ └── settings.js # Логика настроек
├── package.json # Зависимости и скрипты
├── electron-builder.yml # Конфигурация сборки
└── README.md # Документация
Ключевые файлы
src/main/main.js
- Создание и управление окнами
- IPC обработчики
- Локальное простукивание
- Файловые операции
src/preload/preload.js
- Безопасный мост между процессами
- Экспорт API в renderer
src/renderer/renderer.js
- UI логика
- Обработка пользовательского ввода
- HTTP запросы к API
Добавление новых функций
1. Новый IPC метод
В main.js:
ipcMain.handle('new:method', async (_e, payload) => {
// Логика метода
return { success: true, data: result };
});
В preload.js:
contextBridge.exposeInMainWorld('api', {
// ... существующие методы
newMethod: async (payload) => ipcRenderer.invoke('new:method', payload)
});
В renderer.js:
const result = await window.api.newMethod(data);
2. Новый UI элемент
В index.html:
<button id="newButton">Новая функция</button>
В renderer.js:
qsi('#newButton')?.addEventListener('click', async () => {
// Логика обработки
});
Тестирование
Unit тесты
npm test
Интеграционные тесты
npm run test:integration
E2E тесты
npm run test:e2e
Сборка и деплой
Локальная сборка
npm run build
Создание дистрибутивов
npm run dist
Автоматические релизы
npm run release
Отладка
DevTools _
- Main процесс:
--inspect
флаг - Renderer процесс: F12 в приложении
Логирование
console.log('Debug info:', data);
console.error('Error:', error);
Профилирование
npm run dev -- --enable-profiling
Безопасность
Рекомендации
- Пароли: Используйте сильные пароли для аутентификации
- Сеть: Ограничьте доступ к API серверу
- Файлы: Не храните пароли в открытом виде
- Обновления: Регулярно обновляйте приложение
Ограничения
- Локальное простукивание выполняется с правами пользователя
- Не требует root/administrator прав
- Подчиняется системным ограничениям сетевого доступа
Поддержка
Контакты
- Документация: LOCAL_KNOCKING.md
- Исходный код: [GitHub Repository]
- Issues: [GitHub Issues]
Версии
- Текущая версия: 1.0
- Electron: v28+
- Node.js: v18+
Лицензия
[Указать лицензию]
Версия документации: 1.0
Дата создания: 2024
Совместимость: Electron Desktop App v1.0+