init_guac
This commit is contained in:
342
guacamole_test_11_26/docs/Действительноважно.md
Executable file
342
guacamole_test_11_26/docs/Действительноважно.md
Executable file
@ -0,0 +1,342 @@
|
||||
# 🔒 Инструкция по безопасной настройке системных 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` - код генерации и подписи ключей на сервере
|
||||
|
||||
Reference in New Issue
Block a user