Реагування на інциденти безпеки¶
Систематичний процес — від виявлення інциденту до post-mortem та покращень. Написано під інфраструктуру UMTC (WireGuard-only доступ, Matrix для комунікації, Docker для сервісів).
Класифікація інцидентів¶
Різні типи інцидентів — різні пріоритети реагування.
| Тип | Приклад | Перший крок |
|---|---|---|
| Compromise | Несанкціонований доступ, виконання команд зловмисником | Ізоляція + forensics |
| Unauthorized access | Спроби входу, перебір паролів, 0-day сканер | Моніторинг + блок |
| DoS / DDoS | Сервіс недоступний через flood трафік | Rate limit + upstream filter |
| Data leak | Витік ключів, паролів, логів у публіку | Ротація секретів + аудит |
| Malware | Майнер, ботнет, шкідливе ПО в контейнері | Ізоляція + відновлення з clean backup |
| Insider threat | Зловмисна дія від легітимного юзера | Відкликання доступу + юридичний процес |
Пріоритети (SLA реагування)¶
flowchart LR
P1[P1: Critical<br/>Active compromise<br/>15 хв] --> Isolate
P2[P2: High<br/>Потенційна компрометація<br/>1 год] --> Investigate
P3[P3: Medium<br/>Підозріла активність<br/>4 год] --> Monitor
P4[P4: Low<br/>False positive<br/>24 год] --> Document
style P1 fill:#dc2626,color:#fff
style P2 fill:#f59e0b,color:#000
style P3 fill:#fbbf24,color:#000
style P4 fill:#10b981,color:#fffФаза 1 — Виявлення та тріаж¶
Типові сигнали¶
- Алерт від Prometheus/Grafana: аномальний CPU, мережа, кількість процесів
fail2banнотифікація про бан- Увага користувача: "Matrix поводиться дивно", "не пускає в VPN"
- Щоденний огляд логів
journalctl --since yesterday | grep -iE 'fail|error|unauthorized' - Cron з
rkhunter,chkrootkit,aide
Перевірка — це справді інцидент?¶
# Підозрілі процеси
ps auxf | less # дерево процесів
ps aux --sort=-%cpu | head -20 # top CPU
ps aux --sort=-%mem | head -20
lsof -nP -iTCP -sTCP:LISTEN # хто слухає порти
# Невідомі автентифікації
last -20 # останні логіни
lastb -20 # невдалі спроби
w # хто онлайн зараз
# Підозрілі з'єднання
ss -tuanp | grep ESTAB # всі встановлені з'єднання
ss -tuanp | awk '{print $5}' | sort -u # унікальні remote endpoints
Якщо щось підозріле — переходимо в режим інциденту.
Фаза 2 — Ізоляція (НЕ перезавантажуй!)¶
Якщо це VPS хаб¶
# 1. Заблокувати новий зовнішній трафік, але зберегти активні сесії admin
iptables -I INPUT 1 -i eth0 -m conntrack --ctstate NEW -j DROP
iptables -I INPUT 1 -i eth0 -m conntrack --ctstate ESTABLISHED,RELATED \
-s <YOUR_ADMIN_IP> -j ACCEPT
# АБО: від'єднати від інтернету з console VPS-провайдера
# (shutdown мережі через network-manager — залишиться WireGuard тільки)
Якщо це сервіс у Docker¶
# Зупинити контейнер БЕЗ видалення (щоб volume та процеси залишились для аналізу)
docker stop <container>
# Заморозити процеси замість зупинки (PID, пам'ять залишаються)
docker pause <container>
# Зняти snapshot файлової системи контейнера для forensics
docker commit <container> forensic-snapshot-2026-04-23
docker save forensic-snapshot-2026-04-23 | gzip > /evidence/snapshot.tar.gz
Якщо це WireGuard peer¶
# Видалити скомпрометованого peer з хабу
wg set wg0 peer <COMPROMISED_PUBKEY> remove
wg-quick save wg0 # зафіксувати в конфіг
# Скомпрометований ключ у blacklist (не допустити повторний додавання)
echo "<COMPROMISED_PUBKEY>" >> /etc/wireguard/banned-peers.txt
Фаза 3 — Збір доказів¶
Що збирати¶
# Створити директорію для доказів (поза компрометованим хостом бажано!)
mkdir -p /evidence/$(hostname)-$(date +%Y%m%d-%H%M%S)
cd /evidence/*
# 1. Дамп системних логів (ДО будь-яких дій, що їх можуть перезаписати)
journalctl --since "7 days ago" > journalctl.log
cp -a /var/log/ ./var-log/
cp /var/log/wtmp /var/log/btmp ./
# 2. Стан системи
ps auxfww > ps.txt
ss -tuanp > ss.txt
netstat -an > netstat.txt
lsof -nP > lsof.txt
iptables-save > iptables.txt
nft list ruleset > nft.txt
w; last -50 > sessions.txt
# 3. Файли з unexpected mtime (новіше за останній deploy)
find / -xdev -newer /var/log/dpkg.log -type f 2>/dev/null > recent-files.txt
# 4. SUID/SGID бінарі (можуть бути підкинуті)
find / -xdev \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null > suid.txt
# 5. Docker стан
docker ps -a > docker-ps.txt
docker images > docker-images.txt
docker network ls > docker-net.txt
docker inspect <susp> > docker-inspect.txt
# 6. Пам'ять (якщо є LiME або acquire tools)
# Потребує попередньо встановленого LiME
# insmod /opt/lime.ko "path=/evidence/memory.lime format=lime"
# 7. Хеші усього для integrity
find /evidence -type f -exec sha256sum {} \; > /evidence/hashes.txt
# 8. Копія на зовнішній носій — ОБОВ'ЯЗКОВО
rsync -a /evidence/ admin@forensic-vault:/incidents/
Ключові файли логів¶
| Файл | Що шукати |
|---|---|
/var/log/auth.log (Ubuntu) |
SSH login, sudo, PAM |
/var/log/syslog |
Системні події, kernel, firewall drops |
/var/log/wtmp (last) |
Успішні логіни — коли, звідки |
/var/log/btmp (lastb) |
Невдалі спроби — brute force |
journalctl -u sshd |
Деталі SSH connection attempts |
journalctl -u wg-quick@wg0 |
WireGuard handshakes |
/var/log/caddy/access.log |
HTTP requests — хто звертався |
docker logs <container> |
Логи скомпрометованого сервісу |
Аналітичні запити¶
# Хто логінився за останні 24 години
last --since yesterday
# SSH невдалі спроби — топ-10 IP
grep "Failed password" /var/log/auth.log | \
awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head
# Виконані sudo команди
grep "COMMAND=" /var/log/auth.log | tail -50
# Нові процеси, запущені як root за останні 6 годин (якщо auditd працює)
ausearch -ts today -ui 0 -m execve
# Відхилені WireGuard handshakes
journalctl -u wg-quick@wg0 --since "1 day ago" | grep -i "invalid\|fail"
Фаза 4 — Аналіз: хто, коли, що¶
Мета — зрозуміти timeline та scope.
Timeline reconstruction¶
# Об'єднати всі логи у timeline за ISO8601 timestamps
for f in auth.log syslog caddy.log; do
awk -v file="$f" '{print $0" ["file"]"}' /var/log/$f
done | sort > /evidence/timeline.txt
# або журнал з машинно-читабельним timestamp
journalctl --since "48 hours ago" -o short-iso | less
Скоуп — що ще зачепило¶
- Файли створені/модифіковані в період атаки:
find / -newermt "2026-04-23 10:00" ! -newermt "2026-04-23 14:00" - SSH ключі додані:
cat /root/.ssh/authorized_keys,cat /home/*/.ssh/authorized_keys - Cron-задачі модифіковані:
ls -la /var/spool/cron/,ls -la /etc/cron.*/ - Systemd unit-файли:
find /etc/systemd/ -newer /var/log/dpkg.log - Docker контейнери з незнайомими образами:
docker ps -a --format 'table {{.Names}}\t{{.Image}}\t{{.CreatedAt}}'
Індикатори компрометації (IoC)¶
- Невідомі IP у
authorized_keys(SSH),wg show(WireGuard) - Процеси з PID без запису в
/proc/<PID>/exe(виконуваний файл видалено) - Мережеві з'єднання до C2 (dynamic DNS домени, Tor, tor-bridges)
- Підвищене навантаження CPU від невідомих бінарників (крипто-майнер)
- Нові SUID binaries, особливо у
/tmp,/dev/shm,/var/tmp
Фаза 5 — Відновлення¶
План відновлення¶
- Ротація всіх секретів — припустити що ВСЕ скомпрометовано:
- wireguard ключі всіх peer-ів на ураженому хабі
- SSH host keys (/etc/ssh/ssh_host_*) та authorized_keys
- Паролі (MAS, Matrix, PostgreSQL, Redis, Grafana)
- API токени, TLS приватні ключі (mtls, Caddy account key)
- SIM карток (якщо LTE core скомпрометовано — K/OPc ключі) - Переінсталяція — чисте встановлення ОС з ISO, не "clean up" поточної
- Відновлення сервісів з backup, старіших за дату компрометації
- Аудит конфігів перед запуском — backup міг містити зворотні двері
- Новий firewall ruleset — default deny, явний allowlist
- Моніторинг посилений на 7-14 днів — зловмисник може спробувати повторно
Перевірка before go-live¶
# Базовий baseline
rkhunter --check --skip-keypress
chkrootkit
# File integrity baseline (після чистої інсталяції!)
aide --init
mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
# Далі щодня cron: aide --check
# Перевірка що nic не в promiscuous
ip link | grep PROMISC
Фаза 6 — Post-mortem¶
Документ для команди (не шукаємо винуватого, шукаємо причину).
Шаблон post-mortem¶
# Incident: <short title>
**Дата:** YYYY-MM-DD **Тривалість:** X год Y хв **Severity:** P1/P2/P3
## Timeline
- 10:15 — перший алерт X
- 10:23 — тріаж, підтверджено як інцидент
- 10:45 — ізоляція
- ...
## Impact
- Сервіси: які недоступні, скільки часу
- Дані: чи витекло, чи видозмінено
- Користувачі: скільки зачеплено
## Root cause
Що саме дозволило атаку (CVE, misconfig, weak password, etc.)
## What went well
- Що спрацювало — швидка ізоляція, робочий backup, тощо
## What went poorly
- Чого не вистачило — алерту не було, logging вимкнено, runbook застарілий
## Action items
- [ ] <конкретна дія> — <власник> — <термін>
- [ ] Патч CVE-2026-XXXX на всіх хостах — @admin — 2026-04-30
- [ ] Додати alert на >50 failed SSH/min — @monitoring — 2026-04-25
Особливості UMTC¶
WireGuard-only доступ — сильна й слабка сторона¶
Docker forensics специфіка¶
docker execвсередині контейнера — перегляд як root, але зміни в overlay FS шарі губляться приdocker rm. Для збереження —docker commitперед видаленням.- Скомпрометований контейнер може escape через
--privileged, mounted/var/run/docker.sock, capabilitySYS_ADMIN. Після escape — атакуючий root на host. Перевірка:docker inspect <container> | jq '.[] | .HostConfig.Privileged, .HostConfig.Binds'.
Matrix як канал повідомлень про інцидент¶
- Окрема кімната
#incidents:matrix.umtc.local(E2EE, обмежене членство) - Не використовувати сам Matrix як кризовий канал ЯКЩО Matrix-сервер постраждав. Fallback: signal/telephone, pre-agreed
- Зберігати номери/альтернативні канали у роздрукованому runbook, не лише в Matrix
SIM картки та LTE core¶
Якщо скомпрометовано HSS (Open5GS subscriber DB), атакуючий має Ki/OPc всіх SIM. Наслідок: можна клонувати будь-який SIM і підключатись до мережі від імені легітимного абонента.
- Ротація всіх Ki/OPc — перезаписати SIM через pySim/OYEITIMES
- Нові IMSI (новий діапазон PLMN 255/33), старі "спалити" у blacklist
- Перевірити що HSS база не містить IMSI, яких ми не створювали
Troubleshooting процесу IR¶
Не можу отримати докази — хост недоступний навіть через console
- Симптом: атакуючий змінив firewall/SSH так, що console-доступ не дає shell.
- Причина: rootkit замінив bash/login, або зламаний LUKS ключ.
- Рішення: rescue режим з ISO/Live CD провайдера. Змонтувати / як read-only: mount -o ro /dev/sda1 /mnt. Зробити dd-копію диска: dd if=/dev/sda of=/external/image.dd bs=4M status=progress — аналізувати offline. НЕ бутитись у скомпрометовану систему.
Логи виглядають підчищеними — lastlog порожній, auth.log обірваний
- Симптом: перед точкою інциденту логи просто "нуль рядків" або явні розриви.
- Причина: атакуючий має root, >/var/log/auth.log стерло файл.
- Рішення: перевірити journalctl --no-pager — він у binary форматі, важче підчистити. Налаштувати централізоване логування (rsyslog → окремий log host у WG мережі, куди атакуючий не зміг залізти). Для майбутніх інцидентів — chattr +a /var/log/* (append-only) ускладнює стирання, але не захищає від root.
Post-mortem перетворюється у пошук винного — команда закривається
- Симптом: на post-mortem зустрічі всі оправдовуються, action items розмиті.
- Причина: культура "хто винен" замість "blameless post-mortem".
- Рішення: явне правило "blameless" — на першому слайді. Фокус на: як система дозволила цю помилку (а не чому N зробив помилку). Питання "що могло спрацювати замість людини?" (автоматизація, моніторинг, руdnebook). Action items — ТЕХНІЧНІ та процесні, не "Петро буде уважніший".
Пов'язані статті¶
- Hardening системи — профілактика > реагування
- Firewall в Linux — ізоляція на мережевому рівні
- TLS/SSL — ротація сертифікатів після інциденту
- iptables шпаргалка — швидкі команди для ізоляції
- SSH ключі — ротація після компрометації
- Matrix адміністрування — деактивація користувачів
- SIM programming — перепрошивка після компрометації HSS
- wireguard, ssh, mtls — термінологія
Шлях: security/incident-response.md