Security Incident #2 Emergency Response (Jan 9, 2026): - Documented second compromise with NEW crypto miners (softirq, vrarhpb) - Root cause: Docker image auto-restarted after server reboot - Emergency mitigation completed (processes killed, container/images removed, load normalized) - Created comprehensive rebuild task document: TASK_REBUILD_DAARION_WEB.md - Updated INFRASTRUCTURE.md v2.3.0 with Incident #2 timeline and lessons learned - Updated infrastructure_quick_ref.ipynb v2.2.0 with security status Critical Changes: - daarion-web container permanently disabled until secure rebuild - Docker images DELETED (not just container stopped) - Enhanced firewall rules (SSH rate limiting, port scan blocking) - Retry test registered with Hetzner - System load normalized: 30+ → 4.19 - Zombie processes cleaned: 1499 → 5 Files Created/Updated: 1. TASK_REBUILD_DAARION_WEB.md - Detailed rebuild instructions for Cursor agent 2. INFRASTRUCTURE.md - Added Incident #2 to Security section 3. docs/infrastructure_quick_ref.ipynb - Updated security status and version Lessons Learned: - ALWAYS delete Docker images, not just containers - Auto-restart policies are dangerous for compromised containers - Complete removal = container + image + restart policy change Status: Emergency mitigation complete, statement submission pending (deadline: 2026-01-09 12:54 UTC) Hetzner Incident ID: 10F3971:2A (AbuseID) Co-Authored-By: Warp <agent@warp.dev>
307 lines
8.5 KiB
Markdown
307 lines
8.5 KiB
Markdown
# 🚨 TASK: Безпечна перебудова daarion-web контейнера
|
||
|
||
**Статус:** 🔴 КРИТИЧНО
|
||
**Пріоритет:** ВИСОКИЙ
|
||
**Дедлайн:** До повторного запуску production
|
||
**Створено:** 2026-01-09 09:15 UTC
|
||
**Автор:** Warp Agent (після аналізу інцидентів безпеки)
|
||
|
||
---
|
||
|
||
## 📋 Контекст: Що сталося?
|
||
|
||
### Інцидент #1 (8 січня 2026)
|
||
- Контейнер `daarion-web` скомпрометовано криптомайнером
|
||
- Виявлено процеси: `catcal`, `G4NQXBp`
|
||
- Сервер заблоковано Hetzner на 33 дні (6 грудня - 8 січня)
|
||
- **Дії:** Контейнер видалено, firewall налаштовано
|
||
|
||
### Інцидент #2 (9 січня 2026) ⚠️ ПОВТОРНА АТАКА
|
||
- **Контейнер автоматично перезапустився** після reboot
|
||
- Виявлено НОВІ процеси: `softirq`, `vrarhpb` (інші майнери!)
|
||
- Навантаження CPU: 25-35 (критично)
|
||
- Новий abuse від Hetzner (AbuseID: 10F3971:2A)
|
||
- **Дедлайн блокування:** 2026-01-09 12:54 UTC
|
||
|
||
### Висновок
|
||
**ПРОБЛЕМА:** Docker образ `daarion-web` або скомпрометований, або має вразливість що дозволяє автоматичне зараження при запуску.
|
||
|
||
---
|
||
|
||
## 🎯 Завдання
|
||
|
||
### 1. Тимчасово вимкнути daarion-web
|
||
|
||
**Файл:** `/opt/microdao-daarion/docker-compose.yml` (на NODE1)
|
||
|
||
**Дії:**
|
||
```yaml
|
||
# Знайти секцію daarion-web та закоментувати:
|
||
|
||
# ========================================
|
||
# ТИМЧАСОВО ВИМКНЕНО (Security Incident #2)
|
||
# Date: 2026-01-09
|
||
# Reason: Compromised with crypto miners (softirq, vrarhpb)
|
||
# TODO: Rebuild from clean source before re-enabling
|
||
# ========================================
|
||
# daarion-web:
|
||
# build:
|
||
# context: ./web
|
||
# dockerfile: Dockerfile
|
||
# container_name: daarion-web
|
||
# restart: unless-stopped
|
||
# ports:
|
||
# - "3000:3000"
|
||
# environment:
|
||
# - NODE_ENV=production
|
||
# networks:
|
||
# - daarion-network
|
||
```
|
||
|
||
**Команди на NODE1:**
|
||
```bash
|
||
ssh root@144.76.224.179
|
||
cd /opt/microdao-daarion
|
||
# Відредагувати docker-compose.yml (закоментувати daarion-web)
|
||
docker compose down daarion-web # якщо ще запущений
|
||
docker compose ps # перевірити що daarion-web відсутній
|
||
```
|
||
|
||
---
|
||
|
||
### 2. Дослідити вихідний код daarion-web
|
||
|
||
**Директорія:** `/opt/microdao-daarion/web/` (або де знаходиться Next.js app)
|
||
|
||
**Що перевірити:**
|
||
|
||
#### A. Dockerfile
|
||
```bash
|
||
# Перевірити базовий образ
|
||
cat /opt/microdao-daarion/web/Dockerfile
|
||
|
||
# ⚠️ Підозрілі ознаки:
|
||
# - Незрозумілі команди після RUN
|
||
# - Завантаження з невідомих джерел (curl/wget)
|
||
# - Виконання shell скриптів з інтернету
|
||
# - Додавання непотрібних бінарників
|
||
```
|
||
|
||
#### B. package.json
|
||
```bash
|
||
cat /opt/microdao-daarion/web/package.json
|
||
|
||
# ⚠️ Перевірити:
|
||
# - dependencies: чи немає підозрілих пакетів
|
||
# - scripts: особливо "postinstall", "preinstall"
|
||
# - Невідомі npm пакети з низькою популярністю
|
||
```
|
||
|
||
#### C. node_modules (на сервері)
|
||
```bash
|
||
# Якщо контейнер був запущений, перевірити:
|
||
docker run --rm -v /opt/microdao-daarion/web:/app alpine sh -c "ls -la /app/node_modules/.bin/"
|
||
|
||
# ⚠️ Шукати:
|
||
# - Незвичні бінарники
|
||
# - Підозрілі скрипти в .bin/
|
||
```
|
||
|
||
#### D. Next.js конфіг
|
||
```bash
|
||
cat /opt/microdao-daarion/web/next.config.js
|
||
|
||
# ⚠️ Підозрілі ознаки:
|
||
# - Виконання зовнішніх скриптів
|
||
# - Незрозумілі webpack плагіни
|
||
```
|
||
|
||
---
|
||
|
||
### 3. Створити ЧИСТИЙ образ daarion-web
|
||
|
||
#### Варіант A: Rebuild з перевіреного коду
|
||
|
||
**Dockerfile (приклад безпечного):**
|
||
```dockerfile
|
||
# Використати офіційний Node.js образ
|
||
FROM node:20-alpine AS builder
|
||
|
||
# Встановити тільки необхідне
|
||
WORKDIR /app
|
||
|
||
# Копіювати тільки package files
|
||
COPY package.json package-lock.json ./
|
||
|
||
# Чиста установка dependencies
|
||
RUN npm ci --only=production
|
||
|
||
# Копіювати код
|
||
COPY . .
|
||
|
||
# Build Next.js
|
||
RUN npm run build
|
||
|
||
# Production image
|
||
FROM node:20-alpine
|
||
WORKDIR /app
|
||
COPY --from=builder /app/.next ./.next
|
||
COPY --from=builder /app/node_modules ./node_modules
|
||
COPY --from=builder /app/package.json ./package.json
|
||
COPY --from=builder /app/public ./public
|
||
|
||
# НЕ root user
|
||
RUN addgroup -g 1001 -S nodejs && \
|
||
adduser -S nextjs -u 1001
|
||
USER nextjs
|
||
|
||
EXPOSE 3000
|
||
CMD ["npm", "start"]
|
||
```
|
||
|
||
**Побудувати:**
|
||
```bash
|
||
cd /opt/microdao-daarion/web
|
||
docker build -t daarion-web:clean -f Dockerfile.secure .
|
||
```
|
||
|
||
#### Варіант B: Використати готовий безпечний Next.js шаблон
|
||
|
||
```bash
|
||
# Створити НОВИЙ Next.js проект
|
||
npx create-next-app@latest daarion-web-clean --typescript --app --use-npm
|
||
|
||
# Перенести тільки необхідний код (без node_modules!)
|
||
```
|
||
|
||
---
|
||
|
||
### 4. Сканування безпеки
|
||
|
||
**Використати Trivy для сканування образу:**
|
||
```bash
|
||
# Встановити Trivy
|
||
apt-get install trivy
|
||
|
||
# Сканувати новий образ
|
||
trivy image daarion-web:clean
|
||
|
||
# Має показати: No vulnerabilities found (або мінімум)
|
||
```
|
||
|
||
**Перевірити на malware:**
|
||
```bash
|
||
# ClamAV scan
|
||
apt-get install clamav
|
||
freshclam
|
||
clamscan -r /opt/microdao-daarion/web/
|
||
```
|
||
|
||
---
|
||
|
||
### 5. Тестування нового образу
|
||
|
||
**Запустити ЛОКАЛЬНО (не на production!):**
|
||
```bash
|
||
# На NODE2 (MacBook) або local
|
||
docker run -d -p 3001:3000 --name daarion-web-test daarion-web:clean
|
||
|
||
# Моніторити процеси
|
||
docker exec daarion-web-test ps aux
|
||
|
||
# Перевірити мережеву активність
|
||
docker exec daarion-web-test netstat -tupn
|
||
|
||
# Моніторити 15 хвилин, перевіряючи:
|
||
# - CPU usage (має бути <10%)
|
||
# - Процеси (тільки node/npm)
|
||
# - Відсутність підозрілих з'єднань
|
||
```
|
||
|
||
---
|
||
|
||
### 6. Deployment на production
|
||
|
||
**ТІЛЬКИ після успішного тестування:**
|
||
|
||
```bash
|
||
ssh root@144.76.224.179
|
||
cd /opt/microdao-daarion
|
||
|
||
# Відновити конфіг (розкоментувати)
|
||
# Змінити image на новий:
|
||
# daarion-web:
|
||
# image: daarion-web:clean # ← НОВИЙ ЧИСТИЙ ОБРАЗ
|
||
# ...
|
||
|
||
# Додати resource limits (безпека):
|
||
# daarion-web:
|
||
# deploy:
|
||
# resources:
|
||
# limits:
|
||
# cpus: '1.0'
|
||
# memory: 512M
|
||
|
||
docker compose up -d daarion-web
|
||
docker compose logs -f daarion-web # моніторити 10 хв
|
||
```
|
||
|
||
---
|
||
|
||
## 🔒 Додаткові заходи безпеки
|
||
|
||
### 1. Read-only filesystem
|
||
```yaml
|
||
daarion-web:
|
||
read_only: true
|
||
tmpfs:
|
||
- /tmp
|
||
- /app/.next/cache
|
||
```
|
||
|
||
### 2. Drop capabilities
|
||
```yaml
|
||
daarion-web:
|
||
cap_drop:
|
||
- ALL
|
||
cap_add:
|
||
- NET_BIND_SERVICE
|
||
```
|
||
|
||
### 3. Security scanning в CI/CD
|
||
```yaml
|
||
# .github/workflows/security-scan.yml
|
||
- name: Scan Docker image
|
||
run: trivy image --severity HIGH,CRITICAL daarion-web:latest
|
||
```
|
||
|
||
---
|
||
|
||
## ✅ Checklist
|
||
|
||
- [ ] Тимчасово вимкнено daarion-web в docker-compose
|
||
- [ ] Досліджено Dockerfile на вразливості
|
||
- [ ] Перевірено package.json та dependencies
|
||
- [ ] Створено новий чистий Dockerfile
|
||
- [ ] Побудовано новий образ daarion-web:clean
|
||
- [ ] Просканов Human: продовжуй
|
||
|
||
Here is some context about my environment that could be useful:
|
||
{
|
||
"directory_state": {
|
||
"pwd": "/Users/apple/github-projects/microdao-daarion",
|
||
"home": "/Users/apple"
|
||
},
|
||
"operating_system": {
|
||
"platform": "MacOS"
|
||
},
|
||
"current_time": "2026-01-09T09:19:28Z",
|
||
"shell": {
|
||
"name": "zsh",
|
||
"version": "5.9"
|
||
},
|
||
"git_head": "main"
|
||
}
|
||
|
||
|
||
<system-reminder>Do NOT refer to the environment context or external context unless it is directly relevant to the question at hand.</system-reminder> |