Files
Remote-Control-Center/guacamole_test_11_26/docs/Действительноважно.md
2025-11-25 09:58:37 +03:00

343 lines
12 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🔒 Инструкция по безопасной настройке системных credentials
## ⚠️ Критически важно!
**Система ТРЕБУЕТ установки credentials для системного администратора Guacamole.**
API **НЕ ЗАПУСТИТСЯ** без этих переменных окружения. А клиент не запустится без установки ключа, инструкция есть в API
---
## 📋 Что нужно настроить
### 1. **Создайте безопасный пароль для системного администратора**
```bash
# Генерируем случайный пароль (32 символа)
openssl rand -base64 32
```
**Пример вывода:**
```
Xk7N9pQ2vT8mL5wR3jH6yU4aF1sD0eG9
```
---
## 🔧 Настройка для Production
### **Шаг 1: Измените пароль guacadmin в Guacamole**
1. Войдите в Guacamole UI как `guacadmin` (дефолтный пароль: `guacadmin`)
2. **Settings****Users****guacadmin****Change password**
3. Установите **безопасный пароль**, сгенерированный выше
4. Сохраните изменения
### **Шаг 2: Обновите `production.env`**
```bash
# Откройте production.env
nano GuacamoleRemoteAccess/production.env
# Найдите и обновите:
SYSTEM_ADMIN_USERNAME=guacadmin
SYSTEM_ADMIN_PASSWORD=Xk7N9pQ2vT8mL5wR3jH6yU4aF1sD0eG9 # ⬅️ Ваш пароль из Guacamole!
```
⚠️ **Пароль ДОЛЖЕН совпадать с паролем guacadmin в Guacamole!**
### **Шаг 3: Перезапустите API**
```bash
cd GuacamoleRemoteAccess
docker compose restart remote_access_api
```
### **Шаг 4: Проверьте логи**
```bash
docker compose logs remote_access_api | grep "System token"
```
**Успех:** `System token refreshed successfully`
**Ошибка:** `Failed to authenticate system user` → проверьте совпадение паролей
---
## 🛠️ Настройка для Development
Для локальной разработки можно использовать дефолтные credentials, **НО:**
### **Вариант 1: Дефолтные credentials (только для local dev)**
```bash
# .env или encryption.env
SYSTEM_ADMIN_USERNAME=guacadmin
SYSTEM_ADMIN_PASSWORD=guacadmin
```
⚠️ **НИКОГДА не используйте дефолтные credentials на серверах доступных из интернета!**
### **Вариант 2: Безопасные credentials (рекомендуется)**
То же самое что для Production (см. выше).
---
## 🔍 Зачем нужны системные credentials?
API использует системный токен для:
1.**Cleanup orphaned connections** - удаление "мертвых" подключений после краша Redis
2.**Startup cleanup** - очистка истекших подключений при старте
3.**System operations** - служебные операции требующие прав администратора
**Без системного токена:**
- ❌ Orphaned connections будут накапливаться
- ❌ Cleanup при старте не будет работать
- ❌ API не запустится (security check)
---
## 🚨 Что происходит при отсутствии credentials?
```python
# 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`)
- [ ] Логи подтверждают успешную аутентификацию
- [ ] Дефолтные пароли **НИГДЕ не используются**
---
## 🔐 Дополнительные рекомендации безопасности
1. **Используйте secrets management** (Docker Secrets, Vault, etc.) для production
2. **Ротируйте пароли регулярно** (каждые 90 дней)
3. **Ограничьте доступ к `.env` файлам** (`chmod 600`)
4. **Никогда не коммитьте** `.env` файлы в git (`.gitignore`)
5. **Используйте SSL/TLS** для Guacamole Admin UI
---
## 🆘 Troubleshooting
### Проблема: `Failed to authenticate system user`
**Причина:** Пароль в `production.env` не совпадает с паролем guacadmin в Guacamole.
**Решение:**
```bash
# Проверьте пароль в Guacamole UI
# Убедитесь что SYSTEM_ADMIN_PASSWORD точно совпадает
docker compose restart remote_access_api
```
### Проблема: `SYSTEM_ADMIN_PASSWORD environment variables are required`
**Причина:** Переменные окружения не установлены.
**Решение:**
```bash
# Убедитесь что .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 с сервера**
```bash
# На сервере - извлекаем публичный ключ подписи
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):
```typescript
private static readonly TRUSTED_SIGNING_KEYS = {
production: "LS0tLS1CRUdJTi...", // ← ЗАМЕНИТЕ этот ключ!
staging: "LS0tLS1CRUdJTi...",
};
```
Замените `production` ключ на ключ из **Шага 1**.
---
#### **Шаг 3: Пересоберите клиент**
```bash
cd MachineControlCenter
npm run build
npm run electron:build:win
```
---
### 🔍 Почему это происходит?
1. **Сервер генерирует Ed25519 ключ** при первом запуске
2. **Ключ сохраняется** в `/app/secrets/ed25519_signing_key.pem`
3. **Клиент должен знать публичную часть** для проверки подписи
4. **Если ключи не совпадают** → MITM защита блокирует вход
---
### 🛡️ Безопасность:
**Это КРИТИЧНАЯ защита от MITM атак!**
- ✅ Сервер подписывает каждый ephemeral ECDH ключ
- ✅ Клиент проверяет подпись перед key exchange
- ✅ Без правильной подписи → вход ЗАПРЕЩЕН
**НЕ отключайте эту проверку!** Вместо этого синхронизируйте ключи.
---
### 📝 Автоматизация (опционально):
Создайте скрипт для обновления клиента:
```bash
#!/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` не существует.
**Решение:**
```bash
# Перезапустите 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` между окружениями:
```bash
# С 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` - код генерации и подписи ключей на сервере