SIEM — Системи Управління Подіями Безпеки¶
SIEM (Security Information and Event Management) — інструмент, який збирає логи з усього вашого серверу, аналізує їх у реальному часі та сповіщає адміністратора про підозрілу активність.
Аналогія: Уяви, що у твоєму будинку 100 відеокамер. SIEM — це охоронець, який дивиться всі екрани одночасно та натискає кнопку тривоги, коли помічає щось підозріле.
Що таке SIEM і навіщо він потрібен?¶
Системи управління інформацією та подіями безпеки (SIEM) призначені для: - Збору логів з різних джерел (Django, nginx, PostgreSQL, системні логи) - Зберігання та індексування великих обсягів даних - Аналізу та кореляції — пошук підозрілих патернів - Виявлення загроз у режимі реального часу
Популярні SIEM-платформи: - Splunk — найпопулярніший комерційний SIEM - ELK Stack (Elasticsearch + Logstash + Kibana) — безкоштовний open-source - IBM QRadar — корпоративний рівень - LogRhythm — для SOC-команд (Security Operations Center)
Чому просто зберігати логи локально недостатньо?¶
Проблема 1: Атакер зламав сервер → видалив лог-файли → немає доказів
Проблема 2: Лог-файл на 10 ГБ → неможливо читати вручну
Проблема 3: Docker-контейнер перезапустився → всі логи зникли
Проблема 4: Потрібно порівняти логи Django + nginx + PostgreSQL → різні файли
Рішення: SIEM збирає все в одному місці та аналізує автоматично
Архітектура передачі логів: Django → SIEM¶
[Django App]
↓ (Python logging → SysLogHandler)
[Syslog Daemon (rsyslog)] ← /dev/log socket
↓ (stunnel: шифрування SSL/TLS)
[SIEM Server (Splunk/ELK)]
↓
[Дашборди + Сповіщення]
Крок 1: Налаштування логування Django (settings.py)¶
Замість запису в локальний файл — відправляємо до системного syslog:
# settings.py
import logging
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'security': {
# Формат: [рівень] [час] [модуль] повідомлення
'format': '[%(levelname)s] %(asctime)s %(name)s: %(message)s',
},
},
'handlers': {
# Відправка в системний syslog (/dev/log)
'syslog': {
'class': 'logging.handlers.SysLogHandler',
'address': '/dev/log', # Linux syslog socket
'facility': 'local7', # категорія для SIEM-фільтрації
'formatter': 'security',
},
# Додатково — в консоль під час розробки
'console': {
'class': 'logging.StreamHandler',
'formatter': 'security',
},
},
'loggers': {
# Django вбудований security logger
'django.security': {
'handlers': ['syslog', 'console'],
'level': 'WARNING',
'propagate': False,
},
# Наш кастомний security logger
'security': {
'handlers': ['syslog', 'console'],
'level': 'INFO',
'propagate': False,
},
},
}
Крок 2: Які події треба логувати?¶
2.1. Невдалі спроби входу (Brute-Force Detection)¶
# views.py
import logging
security_log = logging.getLogger('security')
def login_view(request):
if request.method == 'POST':
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
user = form.get_user()
login(request, user)
security_log.info(
f"LOGIN_SUCCESS user_id={user.pk} username={user.username} "
f"ip={request.META.get('REMOTE_ADDR')}"
)
else:
security_log.warning(
f"LOGIN_FAILED username={request.POST.get('username', 'unknown')} "
f"ip={request.META.get('REMOTE_ADDR')}"
)
Правило в SIEM: Якщо LOGIN_FAILED > 5 разів за 1 хвилину з однієї IP → сповіщення!
2.2. Спроби несанкціонованого доступу (IDOR Detection)¶
from django.core.exceptions import PermissionDenied
@login_required
def note_edit(request, pk):
try:
note = Note.objects.get(pk=pk)
except Note.DoesNotExist:
raise Http404
# Фіксуємо спробу доступу до чужого ресурсу
if note.user != request.user:
security_log.warning(
f"UNAUTHORIZED_ACCESS user_id={request.user.pk} "
f"tried to access note_id={pk} owned_by={note.user_id} "
f"ip={request.META.get('REMOTE_ADDR')}"
)
raise PermissionDenied
# ... решта view
2.3. Привілейовані дії (Audit Trail)¶
# Логуємо видалення, зміну прав, групові операції
@login_required
def note_delete(request, pk):
note = get_object_or_404(Note, pk=pk, user=request.user)
if request.method == 'POST':
security_log.info(
f"NOTE_DELETED user_id={request.user.pk} note_id={pk} "
f"note_title={note.title[:50]!r}"
)
note.delete()
Крок 3: Налаштування Syslog Daemon¶
rsyslog — системний демон, що збирає логи від додатків.
# /etc/rsyslog.conf або /etc/rsyslog.d/django.conf
# Отримати логи від Django (через /dev/log)
local7.* /var/log/django-security.log
# Пересилати на SIEM-сервер (порт 514 UDP)
local7.* @log.mycompany.com:514
Крок 4: Шифрування передачі логів (stunnel)¶
Без шифрування логи летять через мережу у відкритому вигляді! Атакер всередині мережі може їх перехопити.
stunnel — створює SSL/TLS тунель для будь-якого TCP з'єднання:
# Встановлення:
sudo apt install stunnel4
# /etc/stunnel/siem.conf:
[siem-forward]
client = yes
accept = 127.0.0.1:514 # локальний порт (rsyslog пише сюди)
connect = siem.company.com:6514 # SIEM-сервер (TLS порт)
cert = /etc/ssl/certs/client.pem
Без stunnel: Django → rsyslog → [відкрита мережа] → SIEM ← НЕБЕЗПЕЧНО
З stunnel: Django → rsyslog → stunnel (SSL) → [зашифровано] → SIEM
Крок 5: Правила та Сповіщення в SIEM¶
Коли логи надходять до SIEM, налаштовуємо автоматичні правила:
| Правило | Умова | Дія |
|---|---|---|
| Brute-Force | LOGIN_FAILED > 5 за 60 сек з однієї IP | Email адміністратору |
| IDOR Attack | UNAUTHORIZED_ACCESS > 3 за 5 хв | Заблокувати IP (через SOAR) |
| Privilege Escalation | GROUP_ADDED для нового admin | Негайне сповіщення |
| After-Hours Access | Вхід між 2:00-6:00 | Підозріла активність |
| Mass Deletion | NOTE_DELETED > 10 за 1 хв | Можливий витік даних |
SOAR (Security Orchestration, Automation, and Response) — автоматизована відповідь на інциденти:
SIEM виявив brute-force
↓
SOAR автоматично:
1. Блокує IP на рівні nginx
2. Надсилає SMS адміністратору
3. Відкриває тікет в Jira
4. Зберігає IP в blacklist
ELK Stack — безкоштовна альтернатива для навчання¶
ELK = Elasticsearch + Logstash + Kibana
Kibana дозволяє будувати дашборди: - Графік спроб входу за часом - Карта IP-адрес атакерів - Топ-10 найчастіших помилок авторизації
Де це в нашому проєкті?¶
У crispy_notes_chat_app SIEM поки не підключений. Для навчального проєкту достатньо:
# settings.py — мінімальний security logging:
LOGGING = {
'version': 1,
'handlers': {
'console': {'class': 'logging.StreamHandler'},
},
'loggers': {
'django.security': {
'handlers': ['console'],
'level': 'WARNING',
},
},
}
Для production — підключай ELK або Splunk за схемою вище.