diff --git a/README.md b/README.md new file mode 100644 index 0000000..75f96fe --- /dev/null +++ b/README.md @@ -0,0 +1,196 @@ +# GuardDog Nexus + +Интеграция [GuardDog](https://github.com/DataDog GuardDog) (сканер уязвимостей пакетов PyPI) с [Sonatype Nexus Repository Manager]. Автоматически сканирует Python-пакеты, хранящиеся в Nexus, на наличие уязвимостей, вредоносного кода и подозрительных паттернов при каждом обновлении или добавлении пакета. + +## Возможности + +- **Автоматическое сканирование** по вебхукам Nexus при создании/обновлении пакетов +- **Поддержка нескольких экосистем** — PyPI, Gem, и другие форматы через Nexus +- **REST API** для просмотра результатов сканирования, уязвимостей и статистики +- **Веб-интерфейс** с дашбордом, таблицами сканирований и фильтрацией по уязвимостям +- **Дедупликация** по URL и SHA256 — один и тот же пакет сканируется один раз +- **Структурированное логирование** в формате JSON с опциональной отправкой в syslog +- **Docker Compose** для развёртывания приложения, Nexus и настройки в одном стеке + +## Архитектура + +``` +Nexus ──(webhook)──> GuardDog Nexus ──(REST API)──> Веб-интерфейс + │ + ├──> GuardDog CLI (сканирование) + ├──> SQLite (хранилище результатов) + └──> REST API (данные для UI) +``` + +## Быстрый старт + +### Требования + +- Docker и Docker Compose +- Python 3.10+ (для локальной разработки) + +### Развёртывание в Docker + +```bash +# Скопируйте файл конфигурации +cp .env.example .env + +# Отредактируйте .env при необходимости +# NEXUS_PASSWORD=<ваш_пароль_администратора_Nexus> + +# Запустите стек +make docker-up +``` + +После запуска доступны: + +| Сервис | URL | Порт | +|--------|-----|------| +| GuardDog Nexus | http://localhost:8080 | 8080 | +| Sonatype Nexus | http://localhost:8081 | 8081 | + +### Локальная разработка + +```bash +# Установите зависимости +make install dev + +# Настройте переменные окружения +cp .env.example .env +export $(cat .env | xargs) + +# Запустите приложение +python -m guarddog_nexus.main +``` + +## Переменные окружения + +| Переменная | По умолчанию | Описание | +|------------|-------------|----------| +| `NEXUS_URL` | `http://localhost:8081` | URL Sonatype Nexus | +| `NEXUS_USERNAME` | `admin` | Имя пользователя Nexus | +| `NEXUS_PASSWORD` | _(обязательно)_ | Пароль пользователя Nexus | +| `NEXUS_REPOSITORIES` | _(пусто)_ | Список репозиториев через запятую | +| `DATABASE_PATH` | `data/guarddog.db` | Путь к SQLite-базе данных | +| `HOST` | `0.0.0.0` | Хост для прослушивания | +| `PORT` | `8080` | Порт для прослушивания | +| `LOG_LEVEL` | `INFO` | Уровень логирования | +| `LOG_SYSLOG_HOST` | _(пусто)_ | Хост syslog для отправки логов | +| `LOG_SYSLOG_PORT` | `514` | Порт syslog | +| `WEBHOOK_SECRET` | _(пусто)_ | Секрет для HMAC-подписи вебхуков | +| `SCAN_TIMEOUT_SECONDS` | `300` | Таймаут сканирования одного пакета | +| `TEMP_DIR` | `/tmp/guarddog-nexus` | Временная директория для загрузки пакетов | + +## Настройка Nexus + +### Создание репозитория + +1. Убедитесь, что в Nexus создан репозиторий `pypi-proxy` (прокси на `https://pypi.org`) +2. Настройте вебхук Nexus для отправки событий на `http://:8080/webhooks/nexus` +3. Используйте `scripts/setup-nexus.sh` для автоматической настройки (требует `curl`) + +### Вебхуки + +Nexus отправляет вебхуки при событиях `ASSET` и `COMPONENT`. GuardDog Nexus поддерживает: + +- **CREATED** — новое событие при создании пакета +- **UPDATED** — событие при обновлении пакета + +Для валидации вебхуков установите `WEBHOOK_SECRET` — подпись проверяется через HMAC-SHA256. + +> **Примечание:** Вебхуки доступны в Nexus Pro. В Nexus Repository Manager 3 Community Edition настройка вебхуков может потребовать дополнительных плагинов. + +## REST API + +### Сканирования + +| Метод | Путь | Описание | +|-------|------|----------| +| GET | `/api/v1/scans` | Список сканирований (пагинация, фильтр `flagged`) | +| GET | `/api/v1/scans/stats` | Статистика: общее количество, уязвимые пакеты, топ правил | +| GET | `/api/v1/scans/{id}` | Детали конкретного сканирования с результатами | + +### Пакеты + +| Метод | Путь | Описание | +|-------|------|----------| +| GET | `/api/v1/packages` | Список уникальных пакетов (пагинация, фильтр по экосистеме) | +| GET | `/api/v1/packages/{name}/{version}` | Все сканирования и уязвимости для пакета | + +### Уязвимости + +| Метод | Путь | Описание | +|-------|------|----------| +| GET | `/api/v1/findings` | Список уязвимостей (фильтр по правилу, severity, scan_id) | + +### Здоровье + +| Метод | Путь | Описание | +|-------|------|----------| +| GET | `/health` | Проверка работоспособности | + +## Веб-интерфейс + +| Страница | URL | Описание | +|----------|-----|----------| +| Дашборд | `/` | Статистика, графики, топ уязвимых пакетов | +| Сканирования | `/scans` | Таблица всех сканирований с фильтрацией | +| Детали сканирования | `/scans/{id}` | Результаты одного сканирования | +| Пакеты | `/packages` | Таблица уникальных пакетов | +| Детали пакета | `/packages/{name}/{version}` | История сканирований и уязвимости пакета | + +## Структура проекта + +``` +guarddog-nexus/ +├── guarddog_nexus/ # Основной пакет +│ ├── main.py # Точка входа FastAPI +│ ├── config.py # Конфигурация из переменных окружения +│ ├── database.py # Async SQLAlchemy + aiosqlite +│ ├── models.py # ORM-модели (Scan, Finding) +│ ├── logging_setup.py # JSON-логирование + syslog +│ ├── harvester.py # Пайплайн: загрузка → сканирование → сохранение +│ ├── scanner.py # Интеграция с GuardDog CLI +│ ├── nexus_client.py # HTTP-клиент для Nexus REST API +│ ├── webhooks.py # Приём вебхуков Nexus +│ ├── api/ # REST API (JSON) +│ │ ├── scans.py +│ │ ├── packages.py +│ │ └── findings.py +│ └── web/ # Веб-интерфейс +│ ├── routes.py +│ ├── templates/ # Jinja2-шаблоны +│ └── static/ # CSS, JS +├── tests/ # Тесты pytest +├── scripts/ # Вспомогательные скрипты +├── docker-compose.yml # Стек Docker Compose +├── Dockerfile # Образ приложения +└── pyproject.toml # Зависимости и настройки +``` + +## Команды Makefile + +| Команда | Описание | +|---------|----------| +| `make install` | Установка зависимостей проекта | +| `make dev` | Установка зависимостей для разработки | +| `make test` | Запуск тестов | +| `make lint` | Проверка кода через Ruff | +| `make format` | Форматирование кода через Ruff | +| `make typecheck` | Проверка типов через mypy | +| `make docker-build` | Сборка Docker-образа | +| `make docker-up` | Запуск стека Docker Compose | +| `make docker-down` | Остановка стека с удалением данных | +| `make docker-logs` | Просмотр логов стека | +| `make clean` | Очистка артефактов сборки | + +## Безопасность + +- Вебхуки поддерживают HMAC-SHA256 подпись через `WEBHOOK_SECRET` +- Nexus-клиент использует BasicAuth для аутентификации +- Результаты сканирования хранятся в локальной SQLite-базе +- Временные файлы пакетов удаляются после сканирования + +## Лицензия + +MIT diff --git a/guarddog_nexus/api/packages.py b/guarddog_nexus/api/packages.py index 1cff4dc..8af9281 100644 --- a/guarddog_nexus/api/packages.py +++ b/guarddog_nexus/api/packages.py @@ -4,7 +4,7 @@ import csv import io from fastapi import APIRouter, Depends, Query, Response -from sqlalchemy import func, select, text +from sqlalchemy import func, select from sqlalchemy.ext.asyncio import AsyncSession from guarddog_nexus.database import get_session