12 KiB
Executable File
🔒 Инструкция по безопасной настройке системных credentials
⚠️ Критически важно!
Система ТРЕБУЕТ установки credentials для системного администратора Guacamole.
API НЕ ЗАПУСТИТСЯ без этих переменных окружения. А клиент не запустится без установки ключа, инструкция есть в API
📋 Что нужно настроить
1. Создайте безопасный пароль для системного администратора
# Генерируем случайный пароль (32 символа)
openssl rand -base64 32
Пример вывода:
Xk7N9pQ2vT8mL5wR3jH6yU4aF1sD0eG9
🔧 Настройка для Production
Шаг 1: Измените пароль guacadmin в Guacamole
- Войдите в Guacamole UI как
guacadmin(дефолтный пароль:guacadmin) - Settings → Users → guacadmin → Change password
- Установите безопасный пароль, сгенерированный выше
- Сохраните изменения
Шаг 2: Обновите production.env
# Откройте production.env
nano GuacamoleRemoteAccess/production.env
# Найдите и обновите:
SYSTEM_ADMIN_USERNAME=guacadmin
SYSTEM_ADMIN_PASSWORD=Xk7N9pQ2vT8mL5wR3jH6yU4aF1sD0eG9 # ⬅️ Ваш пароль из Guacamole!
⚠️ Пароль ДОЛЖЕН совпадать с паролем guacadmin в Guacamole!
Шаг 3: Перезапустите API
cd GuacamoleRemoteAccess
docker compose restart remote_access_api
Шаг 4: Проверьте логи
docker compose logs remote_access_api | grep "System token"
✅ Успех: System token refreshed successfully
❌ Ошибка: Failed to authenticate system user → проверьте совпадение паролей
🛠️ Настройка для Development
Для локальной разработки можно использовать дефолтные credentials, НО:
Вариант 1: Дефолтные credentials (только для local dev)
# .env или encryption.env
SYSTEM_ADMIN_USERNAME=guacadmin
SYSTEM_ADMIN_PASSWORD=guacadmin
⚠️ НИКОГДА не используйте дефолтные credentials на серверах доступных из интернета!
Вариант 2: Безопасные credentials (рекомендуется)
То же самое что для Production (см. выше).
🔍 Зачем нужны системные credentials?
API использует системный токен для:
- ✅ Cleanup orphaned connections - удаление "мертвых" подключений после краша Redis
- ✅ Startup cleanup - очистка истекших подключений при старте
- ✅ System operations - служебные операции требующие прав администратора
Без системного токена:
- ❌ Orphaned connections будут накапливаться
- ❌ Cleanup при старте не будет работать
- ❌ API не запустится (security check)
🚨 Что происходит при отсутствии credentials?
# API выбросит ошибку при старте:
ValueError: SYSTEM_ADMIN_USERNAME and SYSTEM_ADMIN_PASSWORD environment
variables are required. Set these in your .env or production.env file for
security. Never use default credentials in production!
Контейнер упадет с ошибкой → необходимо установить переменные.
📝 Checklist перед деплоем
- Сгенерирован безопасный пароль (
openssl rand -base64 32) - Пароль guacadmin изменен в Guacamole UI
production.envобновлен с новым паролем- Пароли в Guacamole UI и
production.envсовпадают - API успешно запустился (
docker compose up -d) - Логи подтверждают успешную аутентификацию
- Дефолтные пароли НИГДЕ не используются
🔐 Дополнительные рекомендации безопасности
- Используйте secrets management (Docker Secrets, Vault, etc.) для production
- Ротируйте пароли регулярно (каждые 90 дней)
- Ограничьте доступ к
.envфайлам (chmod 600) - Никогда не коммитьте
.envфайлы в git (.gitignore) - Используйте SSL/TLS для Guacamole Admin UI
🆘 Troubleshooting
Проблема: Failed to authenticate system user
Причина: Пароль в production.env не совпадает с паролем guacadmin в Guacamole.
Решение:
# Проверьте пароль в Guacamole UI
# Убедитесь что SYSTEM_ADMIN_PASSWORD точно совпадает
docker compose restart remote_access_api
Проблема: SYSTEM_ADMIN_PASSWORD environment variables are required
Причина: Переменные окружения не установлены.
Решение:
# Убедитесь что .env или production.env загружен
docker compose config | grep SYSTEM_ADMIN
# Должны быть значения (не пустые)
Проблема: API запускается, но cleanup не работает
Причина: Системный токен не может быть получен (неверные credentials).
Решение: Проверьте логи и сверьте пароли.
🔑 КРИТИЧНО: Ed25519 Signing Key для ECDH
⚠️ Проблема: "Invalid server key signature - possible MITM attack!"
Если клиент не может войти и показывает ошибку подписи:
[key-exchange] Invalid server key signature - rejecting for security
[key-exchange] Failed to set server public key | "Invalid server key signature - possible MITM attack!"
[auth-service] Login failed
Причина: Клиент использует старый/неправильный TRUSTED_SIGNING_KEY!
📋 Как исправить:
Шаг 1: Получите текущий signing public key с сервера
# На сервере - извлекаем публичный ключ подписи
cd /usr/local/guacamole_project
docker compose exec remote_access_api python3 -c "
from api.auth.key_exchange import ecdh_key_exchange
from cryptography.hazmat.primitives import serialization
import base64
signing_pub = ecdh_key_exchange.signing_public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
print('Signing Public Key (base64):')
print(base64.b64encode(signing_pub).decode())
"
Пример вывода:
Signing Public Key (base64):
LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUNvd0JRWURLMlZ3QXlFQVlXSytycFozN0VldklYVG8yYzlYSGUrKzZyWG82WlI1UENxNkxDdE40Zm89Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=
Шаг 2: Обновите клиент
Откройте файл клиента:
MachineControlCenter/src/renderer/services/SignatureVerificationService.ts
Найдите (строка ~10-13):
private static readonly TRUSTED_SIGNING_KEYS = {
production: "LS0tLS1CRUdJTi...", // ← ЗАМЕНИТЕ этот ключ!
staging: "LS0tLS1CRUdJTi...",
};
Замените production ключ на ключ из Шага 1.
Шаг 3: Пересоберите клиент
cd MachineControlCenter
npm run build
npm run electron:build:win
🔍 Почему это происходит?
- Сервер генерирует Ed25519 ключ при первом запуске
- Ключ сохраняется в
/app/secrets/ed25519_signing_key.pem - Клиент должен знать публичную часть для проверки подписи
- Если ключи не совпадают → MITM защита блокирует вход
🛡️ Безопасность:
Это КРИТИЧНАЯ защита от MITM атак!
- ✅ Сервер подписывает каждый ephemeral ECDH ключ
- ✅ Клиент проверяет подпись перед key exchange
- ✅ Без правильной подписи → вход ЗАПРЕЩЕН
НЕ отключайте эту проверку! Вместо этого синхронизируйте ключи.
📝 Автоматизация (опционально):
Создайте скрипт для обновления клиента:
#!/bin/bash
# sync-signing-key.sh
# Получаем ключ с сервера
KEY=$(docker compose exec -T remote_access_api python3 -c "
from api.auth.key_exchange import ecdh_key_exchange
from cryptography.hazmat.primitives import serialization
import base64
signing_pub = ecdh_key_exchange.signing_public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
print(base64.b64encode(signing_pub).decode())
")
# Обновляем клиент (sed команда)
sed -i "s/production: \".*\"/production: \"$KEY\"/" \
../MachineControlCenter/src/renderer/services/SignatureVerificationService.ts
echo "✅ Signing key synced!"
echo "🔨 Rebuild client: cd ../MachineControlCenter && npm run build"
🆘 Troubleshooting:
Проблема: Ключ не извлекается с сервера
Причина: Файл /app/secrets/ed25519_signing_key.pem не существует.
Решение:
# Перезапустите API для генерации нового ключа
docker compose restart remote_access_api
# Проверьте логи
docker compose logs remote_access_api | grep "signing"
# Должно быть: "Server signing keypair generated successfully"
Проблема: После обновления ключа старые клиенты не могут войти
Причина: У них старый TRUSTED_SIGNING_KEY.
Решение: Пересоберите и распространите новую версию клиента.
Проблема: Хочу использовать один ключ для prod/staging/dev
Решение: Скопируйте ed25519_signing_key.pem между окружениями:
# С production сервера
docker compose exec remote_access_api cat /app/secrets/ed25519_signing_key.pem > signing_key.pem
# На staging/dev сервер
docker compose cp signing_key.pem remote_access_api:/app/secrets/ed25519_signing_key.pem
docker compose restart remote_access_api
📚 Связанные документы
DEPLOYMENT_API_GUIDE.md- полная инструкция по деплоюproduction.env- файл с переменными окруженияJWT-SECURITY-GUIDE.md- настройка JWT аутентификацииSignatureVerificationService.ts- код проверки подписи на клиентеkey_exchange.py- код генерации и подписи ключей на сервере