logboard/docs/security.md

751 lines
23 KiB
Markdown
Raw Permalink 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.

# Безопасность LogBoard+
**Автор:** Сергей Антропов
**Сайт:** https://devops.org.ru
## Содержание
1. [Обзор безопасности](#обзор-безопасности)
2. [Генерация ключей](#генерация-ключей)
3. [Аутентификация](#аутентификация)
4. [Настройка HTTPS](#настройка-https)
5. [Доступ к Docker](#доступ-к-docker)
6. [Сетевая безопасность](#сетевая-безопасность)
7. [Мониторинг безопасности](#мониторинг-безопасности)
8. [Рекомендации для продакшена](#рекомендации-для-продакшена)
## Обзор безопасности
LogBoard+ включает в себя несколько уровней безопасности для защиты доступа к логам и системной информации. Правильная настройка безопасности критически важна для продакшена.
### Уровни безопасности
1. **Аутентификация** - JWT токены для доступа к API
2. **Шифрование** - Защита чувствительных данных
3. **Сетевая безопасность** - HTTPS, файрвол, ограничение доступа
4. **Docker безопасность** - Ограничение прав доступа к Docker socket
5. **Мониторинг** - Логирование событий безопасности
## Генерация ключей
### SECRET_KEY
SECRET_KEY используется для подписи JWT токенов. Это критически важный ключ для безопасности аутентификации.
#### Генерация SECRET_KEY
**Метод 1: OpenSSL (рекомендуется)**
```bash
# Генерация 32-байтового ключа в hex формате
openssl rand -hex 32
# Пример вывода: 8a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6
# Генерация 64-байтового ключа (для максимальной безопасности)
openssl rand -hex 64
# Пример вывода: 8a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6...
```
**Метод 2: Python**
```bash
# Использование Python для генерации
python3 -c "import secrets; print(secrets.token_hex(32))"
# Пример вывода: 8a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6
# Генерация через Python скрипт
python3 -c "
import secrets
import base64
key = secrets.token_bytes(32)
print('Hex:', key.hex())
print('Base64:', base64.b64encode(key).decode())
"
```
**Метод 3: Node.js**
```bash
# Использование Node.js
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Пример вывода: 8a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6
```
#### Требования к SECRET_KEY
- **Длина:** Минимум 32 байта (64 символа в hex)
- **Энтропия:** Используйте криптографически стойкий генератор случайных чисел
- **Уникальность:** Каждая установка должна иметь уникальный ключ
- **Хранение:** Храните в безопасном месте, не в коде
### ENCRYPTION_KEY
ENCRYPTION_KEY используется для шифрования чувствительных данных в приложении.
#### Генерация ENCRYPTION_KEY
**Метод 1: OpenSSL (рекомендуется)**
```bash
# Генерация 32-байтового ключа шифрования
openssl rand -hex 32
# Пример вывода: 1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0t1u2v3w4x5y6z7
# Генерация ключа для AES-256
openssl rand -base64 32
# Пример вывода: 1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0t1u2v3w4x5y6z7
```
**Метод 2: Python с Fernet**
```bash
# Генерация ключа для Fernet (Base64)
python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
# Пример вывода: 1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0t1u2v3w4x5y6z7
# Генерация через Python скрипт
python3 -c "
import secrets
import base64
key = secrets.token_bytes(32)
print('Hex:', key.hex())
print('Base64:', base64.b64encode(key).decode())
print('Fernet:', base64.urlsafe_b64encode(key).decode())
"
```
**Метод 3: Скрипт генерации ключей**
Создайте файл `generate_keys.sh`:
```bash
#!/bin/bash
# Скрипт генерации ключей безопасности для LogBoard+
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
echo "=== Генерация ключей безопасности для LogBoard+ ==="
echo ""
# Проверка наличия OpenSSL
if ! command -v openssl &> /dev/null; then
echo "OpenSSL не найден. Установите OpenSSL для генерации ключей."
exit 1
fi
echo "Генерация SECRET_KEY..."
SECRET_KEY=$(openssl rand -hex 32)
echo "SECRET_KEY=$SECRET_KEY"
echo ""
echo "Генерация ENCRYPTION_KEY..."
ENCRYPTION_KEY=$(openssl rand -hex 32)
echo "ENCRYPTION_KEY=$ENCRYPTION_KEY"
echo ""
echo "Генерация пароля пользователя..."
USER_PASSWORD=$(openssl rand -base64 16 | tr -d "=+/" | cut -c1-16)
echo "LOGBOARD_PASS=$USER_PASSWORD"
echo ""
echo "Обновление .env файла..."
if [ -f .env ]; then
# Создание резервной копии
cp .env .env.backup.$(date +%Y%m%d_%H%M%S)
echo "Создана резервная копия .env"
# Обновление ключей
sed -i "s/^SECRET_KEY=.*/SECRET_KEY=$SECRET_KEY/" .env
sed -i "s/^ENCRYPTION_KEY=.*/ENCRYPTION_KEY=$ENCRYPTION_KEY/" .env
sed -i "s/^LOGBOARD_PASS=.*/LOGBOARD_PASS=$USER_PASSWORD/" .env
echo "Ключи обновлены в .env"
else
echo "Файл .env не найден. Создайте его из env.example"
fi
echo ""
echo "=== Рекомендации по безопасности ==="
echo "1. Сохраните ключи в безопасном месте"
echo "2. Не передавайте ключи через незащищенные каналы"
echo "3. Регулярно обновляйте ключи"
echo "4. Используйте разные ключи для разных окружений"
echo ""
echo "Генерация ключей завершена!"
```
```bash
# Установка прав на выполнение
chmod +x generate_keys.sh
# Запуск генерации
./generate_keys.sh
```
#### Требования к ENCRYPTION_KEY
- **Длина:** 32 байта для AES-256
- **Формат:** Hex или Base64
- **Энтропия:** Криптографически стойкий генератор
- **Уникальность:** Уникальный для каждой установки
### Проверка качества ключей
```bash
# Проверка энтропии ключа
python3 -c "
import secrets
import base64
def check_entropy(key_hex):
# Преобразование hex в байты
key_bytes = bytes.fromhex(key_hex)
# Подсчет уникальных байтов
unique_bytes = len(set(key_bytes))
total_bytes = len(key_bytes)
# Вычисление энтропии
entropy = unique_bytes / total_bytes
print(f'Длина ключа: {total_bytes} байт')
print(f'Уникальных байтов: {unique_bytes}')
print(f'Энтропия: {entropy:.2%}')
if entropy > 0.8:
print('Ключ имеет хорошую энтропию')
else:
print('Ключ может иметь низкую энтропию')
# Проверка вашего ключа
key = '8a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6'
check_entropy(key)
"
```
## Аутентификация
### JWT токены
LogBoard+ использует JWT (JSON Web Tokens) для аутентификации.
#### Структура JWT токена
```json
{
"header": {
"alg": "HS256",
"typ": "JWT"
},
"payload": {
"sub": "admin",
"exp": 1642234567,
"iat": 1642230967
},
"signature": "HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), SECRET_KEY)"
}
```
#### Настройка JWT
```bash
# В .env файле
SECRET_KEY=your-secret-key-here
SESSION_TIMEOUT=3600 # Время жизни токена в секундах
```
#### Безопасность JWT
1. **Используйте сильный SECRET_KEY**
2. **Установите разумное время жизни токена**
3. **Используйте HTTPS для передачи токенов**
4. **Регулярно обновляйте токены**
### Пароли пользователей
#### Генерация безопасного пароля
```bash
# Генерация пароля с OpenSSL
openssl rand -base64 16 | tr -d "=+/" | cut -c1-16
# Пример вывода: aB3cD4eF5gH6iJ7k
# Генерация пароля с Python
python3 -c "
import secrets
import string
def generate_password(length=16):
alphabet = string.ascii_letters + string.digits + '!@#$%^&*'
return ''.join(secrets.choice(alphabet) for _ in range(length))
print('Пароль:', generate_password(16))
"
# Генерация пароля с pwgen
pwgen -s 16 1
```
#### Требования к паролям
- **Длина:** Минимум 12 символов
- **Сложность:** Буквы, цифры, специальные символы
- **Уникальность:** Не используйте пароли по умолчанию
- **Хранение:** Храните в безопасном месте
## Настройка HTTPS
### Самоподписанные сертификаты (для тестирования)
```bash
# Генерация приватного ключа
openssl genrsa -out private.key 2048
# Генерация сертификата
openssl req -x509 -new -nodes -key private.key -sha256 -days 365 -out certificate.crt
# Или одной командой
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout private.key -out certificate.crt \
-subj "/C=RU/ST=Moscow/L=Moscow/O=Company/CN=localhost"
```
### Let's Encrypt сертификаты (для продакшена)
```bash
# Установка certbot
sudo apt install certbot python3-certbot-nginx
# Получение сертификата
sudo certbot --nginx -d your-domain.com
# Автоматическое обновление
sudo crontab -e
# Добавить строку:
# 0 12 * * * /usr/bin/certbot renew --quiet
```
### Nginx конфигурация с HTTPS
```nginx
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
# SSL сертификаты
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
# SSL настройки
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Безопасные заголовки
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
location / {
proxy_pass http://localhost:9001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket поддержка
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Таймауты
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
```
## Доступ к Docker
### Ограничение прав доступа
```bash
# Создание группы docker
sudo groupadd docker
# Добавление пользователя в группу
sudo usermod -aG docker $USER
# Проверка прав
ls -la /var/run/docker.sock
# Должно быть: srw-rw-rw- 1 root docker 0 Jan 15 10:00 /var/run/docker.sock
# Перезагрузка группы
newgrp docker
```
### Альтернативные методы
#### Метод 1: Docker API с TLS
```bash
# Генерация CA ключа
openssl genrsa -aes256 -out ca-key.pem 4096
# Генерация CA сертификата
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
# Генерация серверного ключа
openssl genrsa -out server-key.pem 4096
# Генерация серверного сертификата
openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr
# Подпись серверного сертификата
openssl x509 -req -days 365 -sha256 \
-in server.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out server-cert.pem
# Настройка Docker daemon
sudo mkdir -p /etc/docker
sudo cp ca.pem server-cert.pem server-key.pem /etc/docker/
# Конфигурация Docker daemon
sudo tee /etc/docker/daemon.json <<EOF
{
"tls": true,
"tlscacert": "/etc/docker/ca.pem",
"tlscert": "/etc/docker/server-cert.pem",
"tlskey": "/etc/docker/server-key.pem",
"hosts": ["tcp://0.0.0.0:2376", "unix:///var/run/docker.sock"]
}
EOF
# Перезапуск Docker
sudo systemctl restart docker
```
#### Метод 2: Docker API с аутентификацией
```bash
# Создание пользователя для API
sudo useradd -r -s /bin/false docker-api
# Настройка прав
sudo usermod -aG docker docker-api
# Конфигурация в .env
DOCKER_HOST=tcp://localhost:2375
DOCKER_TLS_VERIFY=1
DOCKER_CERT_PATH=/path/to/certs
```
## Сетевая безопасность
### Настройка файрвола
```bash
# Установка UFW
sudo apt install ufw
# Базовые правила
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Разрешение SSH
sudo ufw allow ssh
# Разрешение HTTPS
sudo ufw allow 443/tcp
# Разрешение LogBoard+ только для локальной сети
sudo ufw allow from 192.168.1.0/24 to any port 9001
# Включение файрвола
sudo ufw enable
# Проверка статуса
sudo ufw status verbose
```
### iptables правила
```bash
# Очистка правил
sudo iptables -F
sudo iptables -X
# Установка политик по умолчанию
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
# Разрешение локального трафика
sudo iptables -A INPUT -i lo -j ACCEPT
# Разрешение установленных соединений
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Разрешение SSH
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Разрешение HTTPS
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Разрешение LogBoard+ для локальной сети
sudo iptables -A INPUT -p tcp --dport 9001 -s 192.168.1.0/24 -j ACCEPT
# Сохранение правил
sudo iptables-save > /etc/iptables/rules.v4
```
### Настройка Docker сетей
```yaml
# В docker-compose.yml
networks:
logboard_network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
driver_opts:
com.docker.network.bridge.name: logboard_br0
services:
logboard:
networks:
- logboard_network
# Ограничение доступа к Docker socket
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
```
## Мониторинг безопасности
### Логирование событий безопасности
```bash
# Настройка логирования в .env
LOG_LEVEL=INFO
LOG_FORMAT=json
# Создание директории для логов
sudo mkdir -p /var/log/logboard
sudo chown $USER:$USER /var/log/logboard
# Настройка ротации логов
sudo tee /etc/logrotate.d/logboard <<EOF
/var/log/logboard/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 644 $USER $USER
postrotate
docker compose -f /path/to/logboard/docker-compose.yml restart logboard
endscript
}
EOF
```
### Мониторинг доступа
```bash
# Скрипт мониторинга доступа
cat > monitor_access.sh <<'EOF'
#!/bin/bash
# Мониторинг доступа к LogBoard+
# Автор: Сергей Антропов
LOG_FILE="/var/log/logboard/access.log"
ALERT_FILE="/var/log/logboard/security_alerts.log"
# Функция логирования
log_alert() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$ALERT_FILE"
}
# Мониторинг неудачных попыток входа
failed_logins=$(grep -c "authentication failed" "$LOG_FILE" 2>/dev/null || echo "0")
if [ "$failed_logins" -gt 10 ]; then
log_alert "Обнаружено $failed_logins неудачных попыток входа"
fi
# Мониторинг подозрительных IP
suspicious_ips=$(grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" "$LOG_FILE" | sort | uniq -c | awk '$1 > 100 {print $2}')
if [ -n "$suspicious_ips" ]; then
log_alert "Подозрительная активность с IP: $suspicious_ips"
fi
echo "Мониторинг завершен: $(date)"
EOF
chmod +x monitor_access.sh
# Добавление в cron
crontab -e
# Добавить строку:
# */5 * * * * /path/to/logboard/monitor_access.sh
```
### Алерты безопасности
```bash
# Скрипт отправки алертов
cat > security_alerts.sh <<'EOF'
#!/bin/bash
# Отправка алертов безопасности
# Автор: Сергей Антропов
ALERT_FILE="/var/log/logboard/security_alerts.log"
EMAIL="admin@company.com"
# Проверка новых алертов
if [ -f "$ALERT_FILE" ]; then
new_alerts=$(tail -n 10 "$ALERT_FILE")
if [ -n "$new_alerts" ]; then
echo "$new_alerts" | mail -s "LogBoard+ Security Alert" "$EMAIL"
fi
fi
EOF
chmod +x security_alerts.sh
# Добавление в cron
crontab -e
# Добавить строку:
# 0 */1 * * * /path/to/logboard/security_alerts.sh
```
## Рекомендации для продакшена
### Обязательные настройки
1. **Измените все пароли по умолчанию**
2. **Используйте сильные секретные ключи**
3. **Настройте HTTPS**
4. **Ограничьте доступ к Docker socket**
5. **Настройте файрвол**
6. **Включите мониторинг безопасности**
### Регулярные проверки
```bash
# Скрипт проверки безопасности
cat > security_check.sh <<'EOF'
#!/bin/bash
# Проверка безопасности LogBoard+
# Автор: Сергей Антропов
echo "=== Проверка безопасности LogBoard+ ==="
echo "Дата: $(date)"
echo ""
# Проверка паролей по умолчанию
if grep -q "LOGBOARD_PASS=admin" .env; then
echo "Пароль по умолчанию не изменен"
else
echo "Пароль изменен"
fi
# Проверка секретных ключей
if grep -q "SECRET_KEY=your-secret-key-here" .env; then
echo "SECRET_KEY не изменен"
else
echo "SECRET_KEY изменен"
fi
if grep -q "ENCRYPTION_KEY=your-encryption-key-here" .env; then
echo "ENCRYPTION_KEY не изменен"
else
echo "ENCRYPTION_KEY изменен"
fi
# Проверка HTTPS
if curl -s -I https://localhost:9001 > /dev/null 2>&1; then
echo "HTTPS доступен"
else
echo "HTTPS недоступен"
fi
# Проверка прав Docker
if ls -la /var/run/docker.sock | grep -q "srw-rw-rw-"; then
echo "Docker socket доступен"
else
echo "Проблемы с доступом к Docker socket"
fi
# Проверка файрвола
if command -v ufw > /dev/null && sudo ufw status | grep -q "Status: active"; then
echo "Файрвол активен"
else
echo "Файрвол не настроен"
fi
echo ""
echo "=== Рекомендации ==="
echo "1. Регулярно обновляйте ключи"
echo "2. Мониторьте логи доступа"
echo "3. Обновляйте зависимости"
echo "4. Проверяйте права доступа"
echo "5. Тестируйте резервные копии"
EOF
chmod +x security_check.sh
# Запуск проверки
./security_check.sh
```
### План реагирования на инциденты
1. **Немедленные действия**
- Отключение подозрительных IP
- Блокировка скомпрометированных учетных записей
- Анализ логов
2. **Расследование**
- Определение источника атаки
- Оценка ущерба
- Документирование инцидента
3. **Восстановление**
- Обновление ключей
- Патчинг уязвимостей
- Восстановление из резервных копий
4. **Профилактика**
- Усиление безопасности
- Обновление процедур
- Обучение персонала
### Контрольный список безопасности
- [ ] Изменены пароли по умолчанию
- [ ] Сгенерированы сильные секретные ключи
- [ ] Настроен HTTPS
- [ ] Ограничен доступ к Docker
- [ ] Настроен файрвол
- [ ] Включено логирование
- [ ] Настроен мониторинг
- [ ] Созданы резервные копии
- [ ] Документированы процедуры
- [ ] Проведено тестирование безопасности