255 lines
11 KiB
Markdown
255 lines
11 KiB
Markdown
# DIP-IDS — Система обнаружения вторжений на основе анализа сетевого трафика
|
|
|
|
Дипломная практическая работа. Сетевая IDS с веб-панелью управления и генерацией PDF-отчётов.
|
|
|
|
---
|
|
|
|
## Быстрый старт
|
|
|
|
### Требования
|
|
|
|
| Компонент | Версия |
|
|
|-----------|--------|
|
|
| Go | ≥ 1.22 |
|
|
| Bun | ≥ 1.1 |
|
|
| libpcap | любая |
|
|
| Linux | — |
|
|
|
|
```bash
|
|
# Debian/Ubuntu
|
|
sudo apt install libpcap-dev gcc
|
|
|
|
# Arch
|
|
sudo pacman -S libpcap gcc
|
|
```
|
|
|
|
### Бэкенд
|
|
|
|
```bash
|
|
cd /path/to/dip-ids
|
|
go mod tidy
|
|
go build -o nids ./cmd/ids
|
|
sudo ./nids # sudo нужен для live-захвата
|
|
```
|
|
|
|
По умолчанию API поднимается на `http://0.0.0.0:8080`.
|
|
|
|
### Фронтенд (dev)
|
|
|
|
```bash
|
|
cd frontend
|
|
bun install
|
|
bun run dev # http://localhost:3000
|
|
```
|
|
|
|
Nuxt автоматически проксирует `/api/*` → `localhost:8080`.
|
|
|
|
### Сборка для продакшена
|
|
|
|
```bash
|
|
cd frontend
|
|
bun run generate # статические файлы в frontend/.output/public/
|
|
```
|
|
|
|
Готовые файлы можно раздавать любым статическим сервером или встроить в Go-бинарник через `//go:embed`.
|
|
|
|
---
|
|
|
|
## Архитектура
|
|
|
|
```
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
│ Nuxt 3 Frontend │
|
|
│ Dashboard · Alerts · Capture · Stats │
|
|
│ Nuxt UI · Chart.js · vue-chartjs │
|
|
└─────────────────────────┬────────────────────────────────────┘
|
|
│ HTTP / REST API
|
|
┌─────────────────────────▼────────────────────────────────────┐
|
|
│ Go Backend │
|
|
│ │
|
|
│ ┌──────────┐ ┌──────────────┐ ┌──────────────────────┐ │
|
|
│ │ Capture │──▶│ Engine │──▶│ Storage │ │
|
|
│ │ │ │ │ │ SQLite (GORM) │ │
|
|
│ │ Live │ │ PortScan │ └──────────────────────┘ │
|
|
│ │ PCAP │ │ BruteForce │ │
|
|
│ └──────────┘ │ DoS │ ┌──────────────────────┐ │
|
|
│ │ ARPSpoof │──▶│ PDF Report │ │
|
|
│ │ DNSAnomaly │ │ (maroto v2) │ │
|
|
│ └──────────────┘ └──────────────────────┘ │
|
|
└──────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## REST API
|
|
|
|
### Алерты
|
|
|
|
| Метод | Путь | Описание |
|
|
|----------|--------------------|-------------------------------------|
|
|
| `GET` | `/api/alerts` | Список алертов (фильтрация, пагинация) |
|
|
| `DELETE` | `/api/alerts` | Удалить все алерты |
|
|
| `DELETE` | `/api/alerts/:id` | Удалить алерт по ID |
|
|
|
|
**Параметры GET `/api/alerts`:**
|
|
|
|
| Параметр | Тип | Описание |
|
|
|-------------|--------|---------------------------------------|
|
|
| `type` | string | Тип атаки (port_scan, brute_force...) |
|
|
| `severity` | string | Уровень (critical, high, medium, low) |
|
|
| `src_ip` | string | IP-адрес источника |
|
|
| `page` | int | Номер страницы (по умолч. 1) |
|
|
| `page_size` | int | Размер страницы (по умолч. 50) |
|
|
|
|
### Статистика
|
|
|
|
| Метод | Путь | Описание |
|
|
|-------|-------------------------|----------------------------------|
|
|
| `GET` | `/api/stats/summary` | Сводка: total, by_severity, by_type |
|
|
| `GET` | `/api/stats/timeline` | Алерты по часам (`?hours=24`) |
|
|
| `GET` | `/api/stats/top-ips` | Топ источников (`?limit=10`) |
|
|
|
|
### Захват
|
|
|
|
| Метод | Путь | Описание |
|
|
|--------|----------------------------|---------------------------------|
|
|
| `GET` | `/api/capture/interfaces` | Список сетевых интерфейсов |
|
|
| `GET` | `/api/capture/status` | Статус текущей сессии |
|
|
| `GET` | `/api/capture/sessions` | История сессий |
|
|
| `POST` | `/api/capture/start` | Начать live-захват |
|
|
| `POST` | `/api/capture/stop` | Остановить захват |
|
|
| `POST` | `/api/capture/upload` | Загрузить и анализировать PCAP |
|
|
|
|
**POST `/api/capture/start` body:**
|
|
```json
|
|
{ "interface": "eth0" }
|
|
```
|
|
|
|
### Отчёты
|
|
|
|
| Метод | Путь | Описание |
|
|
|-------|-------------------------|---------------------|
|
|
| `GET` | `/api/reports/generate` | Скачать PDF-отчёт |
|
|
|
|
---
|
|
|
|
## Конфигурация
|
|
|
|
Файл `configs/config.yaml`:
|
|
|
|
```yaml
|
|
server:
|
|
host: "0.0.0.0"
|
|
port: 8080
|
|
|
|
database:
|
|
path: "nids.db" # путь к SQLite файлу
|
|
|
|
capture:
|
|
default_interface: "eth0"
|
|
snaplen: 65535
|
|
promiscuous: true
|
|
|
|
detectors:
|
|
port_scan:
|
|
enabled: true
|
|
threshold: 15 # уникальных портов за window_seconds
|
|
window_seconds: 10
|
|
severity: "high"
|
|
|
|
brute_force:
|
|
enabled: true
|
|
threshold: 10 # попыток подключения за window_seconds
|
|
window_seconds: 30
|
|
severity: "critical"
|
|
ports: [22, 21, 23, 3389, 5900, 25, 110, 143]
|
|
|
|
dos:
|
|
enabled: true
|
|
pps_threshold: 1000 # пакетов в секунду
|
|
window_seconds: 1
|
|
severity: "critical"
|
|
|
|
arp_spoof:
|
|
enabled: true
|
|
severity: "critical"
|
|
|
|
dns_anomaly:
|
|
enabled: true
|
|
max_label_length: 50 # макс. длина DNS-метки
|
|
query_threshold: 200 # запросов за window_seconds
|
|
window_seconds: 60
|
|
severity: "medium"
|
|
```
|
|
|
|
---
|
|
|
|
## Алгоритмы обнаружения
|
|
|
|
### Port Scan (Сканирование портов)
|
|
|
|
Детектор ведёт таблицу `srcIP → {dstPort → []timestamp}`. Для каждого входящего TCP SYN-пакета регистрируется новое обращение к порту назначения. Устаревшие записи (старше `window_seconds`) удаляются (sliding window). Если количество уникальных портов назначения превышает `threshold` — генерируется алерт.
|
|
|
|
### Brute Force (Перебор паролей)
|
|
|
|
Мониторятся только соединения к портам из списка `ports` (SSH, FTP, RDP и др.). Счётчик SYN-пакетов от одного источника к одному порту назначения ведётся в скользящем окне. Превышение `threshold` за `window_seconds` — алерт.
|
|
|
|
### DoS/DDoS
|
|
|
|
Считается общий поток пакетов от каждого источника в окне `window_seconds`. При превышении `pps_threshold` пакетов в секунду генерируется алерт категории `critical`.
|
|
|
|
### ARP Spoofing
|
|
|
|
Ведётся таблица соответствия `IP → MAC`. При получении ARP Reply проверяется, не изменился ли MAC для уже известного IP-адреса. Изменение MAC — признак подмены ARP-записей (Man-in-the-Middle).
|
|
|
|
### DNS Anomaly
|
|
|
|
Два сценария:
|
|
1. **DNS-туннелирование** — проверяется длина каждой метки в имени запроса. Метка длиннее `max_label_length` символов — подозрение на туннелирование данных через DNS.
|
|
2. **Высокая частота** — если один хост генерирует более `query_threshold` DNS-запросов за `window_seconds` — алерт.
|
|
|
|
## Тестирование
|
|
|
|
Для тестирования можно использовать инструкции из документации /docs/testing.md
|
|
|
|
|
|
---
|
|
|
|
## Структура проекта
|
|
|
|
```
|
|
dip-ids/
|
|
├── cmd/ids/main.go # точка входа
|
|
├── internal/
|
|
│ ├── config/config.go # загрузка конфигурации
|
|
│ ├── storage/
|
|
│ │ ├── models.go # GORM модели
|
|
│ │ └── db.go # CRUD операции
|
|
│ ├── capture/capture.go # live и pcap захват
|
|
│ ├── analyzer/
|
|
│ │ ├── engine.go # основной движок
|
|
│ │ ├── detector.go # интерфейс детектора
|
|
│ │ ├── portscan.go
|
|
│ │ ├── bruteforce.go
|
|
│ │ ├── dos.go
|
|
│ │ ├── arp.go
|
|
│ │ └── dns.go
|
|
│ ├── api/
|
|
│ │ ├── server.go # Gin HTTP сервер
|
|
│ │ └── handlers/ # обработчики маршрутов
|
|
│ └── report/pdf.go # генерация PDF (maroto v2)
|
|
├── frontend/ # Nuxt 3 + Nuxt UI
|
|
│ ├── pages/
|
|
│ │ ├── index.vue # дашборд
|
|
│ │ ├── alerts.vue # журнал алертов
|
|
│ │ ├── capture.vue # управление захватом
|
|
│ │ └── stats.vue # статистика
|
|
│ ├── components/
|
|
│ ├── composables/
|
|
│ ├── layouts/default.vue
|
|
│ ├── nuxt.config.ts
|
|
│ └── package.json
|
|
├── configs/config.yaml
|
|
└── README.md
|
|
```
|