CI/CD security, architecture doc, monitoring, security audit
- .github/workflows/security.yml: npm audit, pip-audit, gitleaks, dependency-review - .github/workflows/ci.yml: lint required, ENABLE_DEV_AUTH/DEV_TOKEN for tests - .gitleaks.toml: secret scan config and allowlist - docs/ARCHITECTURE.md: high-level design, layers, auth, deployment - docs/ops/MONITORING.md: Prometheus, health, alerting, Grafana - docs/SECURITY_AUDIT.md: audit tools and procedures (ZAP, Bandit, Trivy) - config/prometheus.yml: example scrape config - README: CI/CD and docs links Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
a7da43be0e
commit
1ec7f62a03
93
.github/workflows/ci.yml
vendored
Normal file
93
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
name: КЛГ АСУ ТК CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main, develop]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
backend-tests:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
env:
|
||||||
|
POSTGRES_USER: klg
|
||||||
|
POSTGRES_PASSWORD: klg
|
||||||
|
POSTGRES_DB: klg
|
||||||
|
ports: ["5432:5432"]
|
||||||
|
options: >-
|
||||||
|
--health-cmd pg_isready
|
||||||
|
--health-interval 10s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 5
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.12"
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
cd backend
|
||||||
|
pip install -r requirements.txt
|
||||||
|
pip install pytest pytest-cov openpyxl reportlab
|
||||||
|
|
||||||
|
- name: Run migrations
|
||||||
|
env:
|
||||||
|
DATABASE_URL: postgresql://klg:klg@localhost:5432/klg
|
||||||
|
run: |
|
||||||
|
for f in backend/migrations/*.sql; do
|
||||||
|
PGPASSWORD=klg psql -h localhost -U klg -d klg -f "$f" || true
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
env:
|
||||||
|
DATABASE_URL: postgresql://klg:klg@localhost:5432/klg
|
||||||
|
ENABLE_DEV_AUTH: "true"
|
||||||
|
DEV_TOKEN: test
|
||||||
|
run: |
|
||||||
|
cd backend
|
||||||
|
python -m pytest -v --tb=short --junitxml=results.xml
|
||||||
|
|
||||||
|
- name: Upload results
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: backend-test-results
|
||||||
|
path: backend/results.xml
|
||||||
|
|
||||||
|
frontend-lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "20"
|
||||||
|
cache: "npm"
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Lint
|
||||||
|
run: npm run lint
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
docker-build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [backend-tests, frontend-lint]
|
||||||
|
if: github.ref == 'refs/heads/main'
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Build backend image
|
||||||
|
run: docker build -t klg-backend:latest ./backend
|
||||||
|
|
||||||
|
- name: Build frontend image
|
||||||
|
run: docker build -t klg-frontend:latest .
|
||||||
69
.github/workflows/security.yml
vendored
Normal file
69
.github/workflows/security.yml
vendored
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# Проверки безопасности: зависимости, секреты, статический анализ
|
||||||
|
name: Security
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
schedule:
|
||||||
|
# Еженедельно по понедельникам 06:00 UTC
|
||||||
|
- cron: '0 6 * * 1'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
npm-audit:
|
||||||
|
name: npm audit
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "20"
|
||||||
|
cache: "npm"
|
||||||
|
- run: npm ci
|
||||||
|
- name: Audit production dependencies
|
||||||
|
run: npm audit --audit-level=high
|
||||||
|
continue-on-error: true # не ломать пайплайн; отчёт в логах
|
||||||
|
|
||||||
|
pip-audit:
|
||||||
|
name: pip audit (Python)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.12"
|
||||||
|
- name: Install pip-audit
|
||||||
|
run: pip install pip-audit
|
||||||
|
- name: Audit backend dependencies
|
||||||
|
run: |
|
||||||
|
cd backend
|
||||||
|
pip-audit -r requirements.txt
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
secret-scan:
|
||||||
|
name: Secret scan (gitleaks)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Run Gitleaks
|
||||||
|
uses: gitleaks/gitleaks-action@v2
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}
|
||||||
|
with:
|
||||||
|
config-path: .gitleaks.toml
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
dependency-review:
|
||||||
|
name: Dependency Review
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/dependency-review-action@v4
|
||||||
|
with:
|
||||||
|
fail-on-severity: high
|
||||||
|
continue-on-error: true
|
||||||
35
.gitleaks.toml
Normal file
35
.gitleaks.toml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# Gitleaks: правила поиска секретов в репозитории
|
||||||
|
# https://github.com/gitleaks/gitleaks
|
||||||
|
|
||||||
|
title = "KLG ASUTK - Secret detection"
|
||||||
|
|
||||||
|
[extend]
|
||||||
|
useDefault = true
|
||||||
|
|
||||||
|
# Дополнительные паттерны под проект
|
||||||
|
[[rules]]
|
||||||
|
id = "generic-api-key"
|
||||||
|
description = "Generic API Key"
|
||||||
|
regex = '''(?i)(api[_-]?key|apikey|api_key)\s*[:=]\s*['"]?[a-zA-Z0-9_\-]{16,}['"]?'''
|
||||||
|
tags = ["key", "api"]
|
||||||
|
|
||||||
|
[[rules]]
|
||||||
|
id = "database-url"
|
||||||
|
description = "Database URL with password"
|
||||||
|
regex = '''(postgres|mysql|mongodb)(:\/\/|:)['"]?[^'"\s]+:([^'"\s@]+)@'''
|
||||||
|
tags = ["database"]
|
||||||
|
|
||||||
|
# Исключения: примеры и тестовые значения
|
||||||
|
[allowlist]
|
||||||
|
description = "Allowlist for test/example values"
|
||||||
|
paths = [
|
||||||
|
'''\.env\.example''',
|
||||||
|
'''backend/\.env\.example''',
|
||||||
|
'''docs/''',
|
||||||
|
'''\.md$''',
|
||||||
|
]
|
||||||
|
regexes = [
|
||||||
|
'''(change-me|example|test|dummy|xxx|your[-_]?key)''',
|
||||||
|
'''postgresql://klg:klg@''',
|
||||||
|
'''redis://localhost''',
|
||||||
|
]
|
||||||
16
README.md
16
README.md
@ -75,6 +75,22 @@ Annex 1, 6, 7, 8, 19 · Doc 9734, 9760, 9859
|
|||||||
### EASA
|
### EASA
|
||||||
Part-21 · Part-66 · Part-M · Part-CAMO · Part-145 · Part-ARO
|
Part-21 · Part-66 · Part-M · Part-CAMO · Part-145 · Part-ARO
|
||||||
|
|
||||||
|
## CI/CD
|
||||||
|
|
||||||
|
- **`.github/workflows/ci.yml`** — тесты backend (pytest), lint и сборка frontend, сборка Docker-образов при push в `main`.
|
||||||
|
- **`.github/workflows/security.yml`** — проверки безопасности: `npm audit`, `pip-audit`, Gitleaks (секреты), Dependency Review в PR; запуск при push/PR в `main` и по расписанию (еженедельно).
|
||||||
|
|
||||||
|
Подробнее: [docs/SECURITY_AUDIT.md](docs/SECURITY_AUDIT.md).
|
||||||
|
|
||||||
|
## Документация
|
||||||
|
|
||||||
|
| Документ | Описание |
|
||||||
|
|----------|----------|
|
||||||
|
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | Архитектура системы (слои, потоки данных, безопасность) |
|
||||||
|
| [docs/ops/MONITORING.md](docs/ops/MONITORING.md) | Мониторинг production (Prometheus, health, алертинг, Grafana) |
|
||||||
|
| [docs/SECURITY_AUDIT.md](docs/SECURITY_AUDIT.md) | Security-аудит: инструменты и процедуры |
|
||||||
|
| [docs/SECURITY.md](docs/SECURITY.md) | Правила безопасности и отчёт об уязвимостях |
|
||||||
|
|
||||||
## Тесты
|
## Тесты
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
17
config/prometheus.yml
Normal file
17
config/prometheus.yml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Пример конфигурации Prometheus для КЛГ АСУ ТК
|
||||||
|
# Использование: см. docs/ops/MONITORING.md
|
||||||
|
|
||||||
|
global:
|
||||||
|
scrape_interval: 15s
|
||||||
|
evaluation_interval: 15s
|
||||||
|
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: 'klg-backend'
|
||||||
|
metrics_path: /api/v1/metrics
|
||||||
|
static_configs:
|
||||||
|
- targets: ['localhost:8000']
|
||||||
|
scrape_interval: 15s
|
||||||
|
|
||||||
|
- job_name: 'prometheus'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['localhost:9090']
|
||||||
119
docs/ARCHITECTURE.md
Normal file
119
docs/ARCHITECTURE.md
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
# Архитектура КЛГ АСУ ТК
|
||||||
|
|
||||||
|
Документ описывает архитектуру системы контроля лётной годности для крупного проекта (frontend + backend + инфраструктура).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Высокоуровневая схема
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────┐
|
||||||
|
│ Пользователи / Браузер │
|
||||||
|
└─────────────────────────────┬─────────────────────────────┘
|
||||||
|
│ HTTPS
|
||||||
|
┌─────────────────────────────▼─────────────────────────────┐
|
||||||
|
│ Frontend (Next.js 14) │
|
||||||
|
│ · SSR/CSR · PWA · Tailwind · api-client → Backend │
|
||||||
|
│ · next-auth / Keycloak OIDC (JWT) │
|
||||||
|
└─────────────────────────────┬─────────────────────────────┘
|
||||||
|
│ /api/v1/* (proxy или прямой)
|
||||||
|
┌─────────────────────────────▼─────────────────────────────┐
|
||||||
|
│ Backend (FastAPI) │
|
||||||
|
│ · REST API · RBAC · RLS (multi-tenant) · Prometheus │
|
||||||
|
└──┬──────────┬──────────┬──────────┬──────────┬────────────┘
|
||||||
|
│ │ │ │ │
|
||||||
|
┌─────────────▼──┐ ┌───▼───┐ ┌──▼──┐ ┌────▼────┐ ┌──▼─────────────┐
|
||||||
|
│ PostgreSQL │ │ Redis │ │MinIO │ │Keycloak │ │ Внешние (ФГИС, │
|
||||||
|
│ (данные, RLS) │ │(кэш) │ │(S3) │ │ (OIDC) │ │ СМЭВ, email) │
|
||||||
|
└────────────────┘ └───────┘ └─────┘ └─────────┘ └────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Слои системы
|
||||||
|
|
||||||
|
### 2.1 Frontend
|
||||||
|
|
||||||
|
| Компонент | Технологии | Назначение |
|
||||||
|
|-----------|------------|------------|
|
||||||
|
| Фреймворк | Next.js 14, React 18 | SSR, App Router, API routes (proxy) |
|
||||||
|
| Стили | Tailwind CSS | Единый UI |
|
||||||
|
| Данные | SWR, единый `lib/api/api-client.ts` | Запросы к Backend с токеном и 401-обработкой |
|
||||||
|
| Авторизация | next-auth (beta), Keycloak OIDC | JWT в заголовке `Authorization` |
|
||||||
|
| PWA | Service Worker, manifest | Офлайн-режим, установка на устройство |
|
||||||
|
|
||||||
|
- **Страницы:** дашборд, парк ВС, контроль ЛГ (директивы, SB, ресурсы, компоненты), наряды ТО, дефекты, персонал ПЛГ, чек-листы, риски, регулятор, нормативная база, настройки и др.
|
||||||
|
- **Прокси:** в dev `next.config.js` переписывает `/api/v1/*` на Backend (`BACKEND_URL`).
|
||||||
|
|
||||||
|
### 2.2 Backend
|
||||||
|
|
||||||
|
| Компонент | Технологии | Назначение |
|
||||||
|
|-----------|------------|------------|
|
||||||
|
| API | FastAPI | REST, OpenAPI, зависимости (DB, auth) |
|
||||||
|
| БД | SQLAlchemy 2, Alembic | Модели, миграции |
|
||||||
|
| Авторизация | JWT (Keycloak) или DEV-токен | `app.api.deps.get_current_user`, `require_roles` |
|
||||||
|
| Мультитенантность | PostgreSQL RLS, `set_tenant(db, org_id)` | Изоляция по организации |
|
||||||
|
| Файлы | MinIO (S3-совместимый) | Вложения, документы |
|
||||||
|
| Фоновые задачи | APScheduler (risk_scheduler и др.) | Сканирование рисков, уведомления |
|
||||||
|
|
||||||
|
- **Роуты:** разбиты по доменам (aircraft, airworthiness_core, work_orders, defects, personnel_plg, legal, fgis_revs, regulator и т.д.).
|
||||||
|
- **Единая точка БД:** `get_db` из `app.api.deps` (реэкспорт из `app.db.session`), в тестах переопределяется в conftest.
|
||||||
|
|
||||||
|
### 2.3 Инфраструктура
|
||||||
|
|
||||||
|
| Сервис | Роль |
|
||||||
|
|--------|------|
|
||||||
|
| **PostgreSQL** | Основное хранилище, RLS по `app.current_org_id` |
|
||||||
|
| **Redis** | Кэш, сессии, опционально очереди |
|
||||||
|
| **MinIO** | Хранилище файлов (S3 API) |
|
||||||
|
| **Keycloak** | OIDC: выдача JWT, роли, realm `klg` |
|
||||||
|
| **ФГИС РЭВС** | Внешний API реестра ВС и СЛГ (REST / СМЭВ 3.0) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Потоки данных
|
||||||
|
|
||||||
|
### 3.1 Авторизация
|
||||||
|
|
||||||
|
1. Пользователь входит через Keycloak (или в dev — токен `DEV_TOKEN`).
|
||||||
|
2. Frontend сохраняет JWT (sessionStorage / next-auth) и передаёт в заголовке `Authorization: Bearer <token>`.
|
||||||
|
3. Backend в `get_current_user` проверяет токен (OIDC или dev), извлекает `organization_id` и роли.
|
||||||
|
4. Для мультитенантности перед запросами к БД вызывается `set_tenant(db, user.organization_id)` (RLS).
|
||||||
|
|
||||||
|
### 3.2 Сквозные сценарии (ЛГ)
|
||||||
|
|
||||||
|
- **ДЛГ (AD)** → создание наряда (WO) → выполнение → CRS → статус «выполнено».
|
||||||
|
- **Дефект** → WO → устранение → CRS.
|
||||||
|
- **Ресурс (Life Limit)** → контроль остатка → WO при достижении лимита.
|
||||||
|
- **Персонал ПЛГ** → scheduler проверяет сроки квалификации → risk alert при просрочке.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Безопасность
|
||||||
|
|
||||||
|
- **Секреты:** не в коде; `.env` в `.gitignore`, шаблоны `.env.example` и `backend/.env.example`.
|
||||||
|
- **CORS:** только разрешённые домены из `CORS_ORIGINS`.
|
||||||
|
- **Авторизация:** в production `ENABLE_DEV_AUTH=false`, только OIDC/JWT.
|
||||||
|
- **RBAC:** роли admin, authority_inspector, operator_manager, operator_user, mro_*; чувствительные эндпоинты через `require_roles`.
|
||||||
|
- **SQL:** параметризованные запросы (в т.ч. `set_tenant` через `bindparams`), без конкатенации пользовательского ввода.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Развёртывание
|
||||||
|
|
||||||
|
- **Локально:** `docker compose --profile base up -d`, затем backend (uvicorn) и frontend (npm run dev).
|
||||||
|
- **Production:** `docker compose --profile full` или Kubernetes (Helm chart в `./helm/klg-asutk`).
|
||||||
|
- **CI/CD:** GitHub Actions — тесты backend, lint и build frontend, сборка образов; отдельный workflow Security (npm audit, pip-audit, gitleaks).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Связанные документы
|
||||||
|
|
||||||
|
- [SECURITY.md](SECURITY.md) — правила безопасности и отчёт об уязвимостях.
|
||||||
|
- [docs/ops/MONITORING.md](ops/MONITORING.md) — мониторинг и алертинг в production.
|
||||||
|
- [docs/SECURITY_AUDIT.md](SECURITY_AUDIT.md) — проведение security-аудита и внешние инструменты.
|
||||||
|
- [ANALYSIS_AND_RECOMMENDATIONS.md](ANALYSIS_AND_RECOMMENDATIONS.md) — анализ и рекомендации по коду.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
© АО «REFLY» — Разработчик АСУ ТК КЛГ
|
||||||
129
docs/SECURITY_AUDIT.md
Normal file
129
docs/SECURITY_AUDIT.md
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
# Security-аудит: инструменты и процедуры
|
||||||
|
|
||||||
|
Рекомендации по проведению проверок безопасности с помощью внешних и встроенных инструментов.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Инструменты, встроенные в CI
|
||||||
|
|
||||||
|
В репозитории настроен workflow **`.github/workflows/security.yml`**, который запускается при push в `main`, при pull request в `main` и по расписанию (еженедельно).
|
||||||
|
|
||||||
|
### 1.1 npm audit (Frontend)
|
||||||
|
|
||||||
|
- **Что проверяет:** известные уязвимости в зависимостях npm.
|
||||||
|
- **В CI:** job `npm-audit`, уровень `--audit-level=high`.
|
||||||
|
- **Локально:**
|
||||||
|
```bash
|
||||||
|
npm audit
|
||||||
|
npm audit --audit-level=high # только high/critical
|
||||||
|
npm audit fix # автоматическое обновление, с осторожностью
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 pip-audit (Backend)
|
||||||
|
|
||||||
|
- **Что проверяет:** уязвимости в Python-пакетах (аналог safety).
|
||||||
|
- **В CI:** job `pip-audit`, зависимости из `backend/requirements.txt`.
|
||||||
|
- **Локально:**
|
||||||
|
```bash
|
||||||
|
pip install pip-audit
|
||||||
|
cd backend && pip-audit -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.3 Gitleaks (сканирование секретов)
|
||||||
|
|
||||||
|
- **Что проверяет:** утечка секретов и ключей в коде и истории коммитов.
|
||||||
|
- **В CI:** job `secret-scan`, конфиг `.gitleaks.toml` (allowlist для примеров и тестов).
|
||||||
|
- **Локально:**
|
||||||
|
```bash
|
||||||
|
docker run --rm -v "$(pwd):/path" zricethezav/gitleaks:latest detect --source /path
|
||||||
|
```
|
||||||
|
или установить [gitleaks](https://github.com/gitleaks/gitleaks) и выполнить `gitleaks detect`.
|
||||||
|
|
||||||
|
### 1.4 Dependency Review (Pull Request)
|
||||||
|
|
||||||
|
- При открытии PR запускается **actions/dependency-review-action**: проверка добавленных зависимостей на известные уязвимости.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Дополнительные проверки (вручную или отдельным job)
|
||||||
|
|
||||||
|
### 2.1 OWASP ZAP (базовое сканирование веб-приложения)
|
||||||
|
|
||||||
|
Подходит для проверки фронтенда и API на типовые уязвимости (XSS, инъекции, небезопасные заголовки).
|
||||||
|
|
||||||
|
**Базовый запуск (Docker):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить приложение (frontend + backend), затем:
|
||||||
|
docker run -t --rm -v $(pwd):/zap/wrk:rw \
|
||||||
|
-u $(id -u):$(id -g) \
|
||||||
|
ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \
|
||||||
|
-t http://host.docker.internal:3000 \
|
||||||
|
-r zap_report.html
|
||||||
|
```
|
||||||
|
|
||||||
|
Для API:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -t --rm -v $(pwd):/zap/wrk:rw \
|
||||||
|
ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \
|
||||||
|
-t http://host.docker.internal:8000/docs \
|
||||||
|
-r zap_api_report.html
|
||||||
|
```
|
||||||
|
|
||||||
|
Результаты в `zap_report.html` / `zap_api_report.html`. Критичные и высокие риски нужно разбирать и устранять.
|
||||||
|
|
||||||
|
### 2.2 SAST (статический анализ кода)
|
||||||
|
|
||||||
|
- **Frontend:** в CI уже используется ESLint (в т.ч. правила безопасности); при необходимости можно добавить `eslint-plugin-security` или SonarQube/SonarCloud.
|
||||||
|
- **Backend:** можно подключить Bandit (`pip install bandit`, `bandit -r backend/app`) или Semgrep; при необходимости — отдельный job в CI.
|
||||||
|
|
||||||
|
Пример Bandit (локально):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install bandit
|
||||||
|
cd backend && bandit -r app -ll
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 Контейнеры (образы Docker)
|
||||||
|
|
||||||
|
- Сканирование образов на уязвимости: **Trivy**, **Snyk**, **docker scout**.
|
||||||
|
- Пример Trivy:
|
||||||
|
```bash
|
||||||
|
docker build -t klg-backend:latest ./backend
|
||||||
|
trivy image klg-backend:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Регулярность проверок
|
||||||
|
|
||||||
|
| Проверка | Частота | Где |
|
||||||
|
|----------|---------|-----|
|
||||||
|
| npm audit, pip-audit, gitleaks | При каждом push/PR в main + еженедельно | GitHub Actions |
|
||||||
|
| Dependency Review | Каждый PR в main | GitHub Actions |
|
||||||
|
| OWASP ZAP | Перед релизом или ежеквартально | Вручную / отдельный job |
|
||||||
|
| SAST (Bandit/Semgrep) | По желанию в CI или перед релизом | Вручную / job |
|
||||||
|
| Сканирование образов (Trivy) | При сборке образов или перед деплоем | Вручную / job |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Что делать при обнаружении уязвимости
|
||||||
|
|
||||||
|
1. **Критичная/высокая в зависимостях:** обновить пакет до безопасной версии или найти обход (patch/workaround); при необходимости временно задокументировать риск.
|
||||||
|
2. **Секрет в репозитории:** считать секрет скомпрометированным, сменить его, удалить из истории (git filter-branch / BFG) или использовать allowlist в gitleaks только для нечувствительных примеров.
|
||||||
|
3. **Уязвимость в коде (ZAP, SAST):** исправить по рекомендациям инструмента и перепроверить.
|
||||||
|
4. Не создавать публичные issue с детальным описанием уязвимости до её устранения; отчёт направлять ответственным за безопасность (см. [SECURITY.md](SECURITY.md)).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Чек-лист перед релизом
|
||||||
|
|
||||||
|
- [ ] `npm audit` и `pip-audit` без критичных/высоких рисков или риски приняты и задокументированы.
|
||||||
|
- [ ] Gitleaks не находит новых секретов (с учётом allowlist).
|
||||||
|
- [ ] Базовое сканирование OWASP ZAP выполнено, критичные находки устранены.
|
||||||
|
- [ ] Образы Docker отсканированы (Trivy/Snyk), критичные уязвимости устранены или приняты.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
© АО «REFLY» — Разработчик АСУ ТК КЛГ
|
||||||
147
docs/ops/MONITORING.md
Normal file
147
docs/ops/MONITORING.md
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
# Мониторинг production-окружения КЛГ АСУ ТК
|
||||||
|
|
||||||
|
Рекомендации по настройке мониторинга для промышленной эксплуатации.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Метрики Backend (Prometheus)
|
||||||
|
|
||||||
|
Backend отдаёт метрики в формате Prometheus на эндпоинте:
|
||||||
|
|
||||||
|
- **URL:** `GET /api/v1/metrics`
|
||||||
|
- **Формат:** text/plain (Prometheus exposition format)
|
||||||
|
|
||||||
|
### Метрики
|
||||||
|
|
||||||
|
| Метрика | Тип | Описание |
|
||||||
|
|---------|-----|----------|
|
||||||
|
| `klg_http_requests_total` | counter | Число запросов по method и path |
|
||||||
|
| `klg_http_request_duration_seconds` | counter | Сумма длительности запросов по method и path |
|
||||||
|
| `klg_http_errors_total` | counter | Ошибки по коду ответа (4xx, 5xx) |
|
||||||
|
|
||||||
|
### Пример конфигурации Prometheus (scrape)
|
||||||
|
|
||||||
|
Добавьте в `prometheus.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: 'klg-backend'
|
||||||
|
metrics_path: /api/v1/metrics
|
||||||
|
static_configs:
|
||||||
|
- targets: ['backend:8000'] # или host:port вашего backend
|
||||||
|
scrape_interval: 15s
|
||||||
|
```
|
||||||
|
|
||||||
|
В Kubernetes используйте Service и при необходимости аннотации для Prometheus Operator.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Health Check
|
||||||
|
|
||||||
|
Используйте для проверки живости и готовности:
|
||||||
|
|
||||||
|
| Эндпоинт | Назначение |
|
||||||
|
|----------|------------|
|
||||||
|
| `GET /api/v1/health` | Общий статус: БД, Redis, risk_scanner, версия |
|
||||||
|
| `GET /api/v1/health/health/detailed` | Расширенная проверка: диск, память, счётчики данных |
|
||||||
|
|
||||||
|
Использование в Docker/Kubernetes:
|
||||||
|
|
||||||
|
- **livenessProbe:** `GET /api/v1/health` каждые 10–30 с.
|
||||||
|
- **readinessProbe:** тот же или `/api/v1/health` с проверкой `status == "healthy"` или `"ok"`.
|
||||||
|
|
||||||
|
Пример для Kubernetes:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /api/v1/health
|
||||||
|
port: 8000
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
periodSeconds: 15
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /api/v1/health
|
||||||
|
port: 8000
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Логирование
|
||||||
|
|
||||||
|
- **Backend:** Python `logging`; при деплое направляйте stdout/stderr в централизованную систему (например, Loki, CloudWatch, ELK).
|
||||||
|
- **Frontend:** ошибки можно отправлять в Sentry (`NEXT_PUBLIC_SENTRY_DSN`).
|
||||||
|
- Не логировать секреты и персональные данные в открытом виде.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Алертинг (рекомендуемые правила)
|
||||||
|
|
||||||
|
Настройте алерты в Prometheus/Alertmanager или аналоге.
|
||||||
|
|
||||||
|
| Алерт | Условие | Действие |
|
||||||
|
|-------|---------|----------|
|
||||||
|
| Backend down | `up{job="klg-backend"} == 0` | Уведомление on-call |
|
||||||
|
| Высокий % ошибок | `rate(klg_http_errors_total[5m]) / rate(klg_http_requests_total[5m]) > 0.05` | Разбор инцидента |
|
||||||
|
| Высокая задержка | Например, p99 latency по метрикам (если добавить histogram) | Деградация качества |
|
||||||
|
| Health degraded | Периодический probe к `/api/v1/health` возвращает `status != healthy` | Проверка БД/Redis |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Grafana (пример дашборда)
|
||||||
|
|
||||||
|
Импортируйте или создайте дашборд с панелями:
|
||||||
|
|
||||||
|
- **Requests:** `sum(rate(klg_http_requests_total[5m])) by (method, path)`.
|
||||||
|
- **Errors:** `sum(rate(klg_http_errors_total[5m])) by (status)`.
|
||||||
|
- **Health:** результат последнего запроса к `/api/v1/health` (через Blackbox exporter или скрипт).
|
||||||
|
|
||||||
|
Источник данных — Prometheus, указывающий на scrape целевого backend.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Docker Compose (локальный стек мониторинга)
|
||||||
|
|
||||||
|
Опционально для разработки/стенда можно добавить в `docker-compose`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
prometheus:
|
||||||
|
image: prom/prometheus:latest
|
||||||
|
volumes:
|
||||||
|
- ./config/prometheus.yml:/etc/prometheus/prometheus.yml
|
||||||
|
ports:
|
||||||
|
- "9090:9090"
|
||||||
|
command:
|
||||||
|
- '--config.file=/etc/prometheus/prometheus.yml'
|
||||||
|
- '--storage.tsdb.path=/prometheus'
|
||||||
|
depends_on:
|
||||||
|
- backend
|
||||||
|
|
||||||
|
grafana:
|
||||||
|
image: grafana/grafana:latest
|
||||||
|
environment:
|
||||||
|
GF_SECURITY_ADMIN_PASSWORD: admin
|
||||||
|
GF_USERS_ALLOW_SIGN_UP: "false"
|
||||||
|
ports:
|
||||||
|
- "3001:3000"
|
||||||
|
depends_on:
|
||||||
|
- prometheus
|
||||||
|
```
|
||||||
|
|
||||||
|
Создайте `config/prometheus.yml` с job `klg-backend` по образцу из раздела 1.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Чек-лист перед production
|
||||||
|
|
||||||
|
- [ ] Prometheus собирает метрики с `/api/v1/metrics`.
|
||||||
|
- [ ] Liveness/readiness настроены на `/api/v1/health`.
|
||||||
|
- [ ] Логи backend и frontend попадают в централизованное хранилище.
|
||||||
|
- [ ] Настроены алерты на падение сервиса и рост ошибок.
|
||||||
|
- [ ] Контакты on-call заданы в Alertmanager/канале уведомлений.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
© АО «REFLY» — Разработчик АСУ ТК КЛГ
|
||||||
Loading…
Reference in New Issue
Block a user