# Ubuntu 24.04 — установка SAC (native, без Docker) Пошаговое руководство: **PostgreSQL + Python venv + systemd + nginx**. Рекомендуемый путь для production. --- ## 0. Исходные данные | Параметр | Пример | |----------|--------| | FQDN | `sac.kalinamall.ru` | | IP | `10.0.0.50` | | Каталог | `/opt/security-alert-center` | | Пользователь сервиса | `sac` | | API только на localhost | `127.0.0.1:8000` | | Снаружи | nginx → 443 → API | --- ## 1. Базовая настройка ОС ```bash sudo apt update sudo apt upgrade -y sudo timedatectl set-timezone Europe/Moscow ``` ### Firewall (ufw) ```bash sudo apt install -y ufw sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow OpenSSH sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable sudo ufw status verbose ``` --- ## 2. Пакеты ```bash sudo apt install -y \ git \ postgresql \ postgresql-contrib \ nginx \ python3.12 \ python3.12-venv \ python3-pip \ jq \ certbot \ python3-certbot-nginx ``` Проверка: ```bash python3.12 --version psql --version nginx -v ``` --- ## 3. Клонирование репозитория ```bash sudo mkdir -p /opt sudo git clone https://git.kalinamall.ru/PapaTramp/security-alert-center.git /opt/security-alert-center ``` --- ## 4. PostgreSQL Создать пользователя и БД (пароль сохраните для `.env`): ```bash sudo -u postgres psql <<'SQL' CREATE USER sac WITH PASSWORD 'ЗАМЕНИТЕ_НА_ДЛИННЫЙ_ПАРОЛЬ'; CREATE DATABASE sac OWNER sac; GRANT ALL PRIVILEGES ON DATABASE sac TO sac; SQL ``` PostgreSQL по умолчанию слушает `127.0.0.1` — для SAC этого достаточно. Проверка: ```bash psql "postgresql://sac@127.0.0.1/sac" -c 'SELECT 1' ``` Каталог бэкапов: ```bash sudo mkdir -p /var/backups/sac sudo chown postgres:postgres /var/backups/sac ``` --- ## 5. Пользователь `sac` и Python venv ```bash sudo useradd --system --home /opt/security-alert-center --shell /usr/sbin/nologin sac || true sudo chown -R sac:sac /opt/security-alert-center cd /opt/security-alert-center/backend sudo -u sac python3.12 -m venv .venv sudo -u sac .venv/bin/pip install --upgrade pip sudo -u sac .venv/bin/pip install -r requirements.txt ``` --- ## 6. Конфигурация Файл лежит **в каталоге приложения** (владелец `sac`) — так проще, чем права на `/etc/...`. ```bash sudo mkdir -p /opt/security-alert-center/config sudo cp /opt/security-alert-center/deploy/env.native.example \ /opt/security-alert-center/config/sac-api.env sudo nano /opt/security-alert-center/config/sac-api.env sudo chown sac:sac /opt/security-alert-center/config/sac-api.env sudo chmod 600 /opt/security-alert-center/config/sac-api.env ``` Если уже создавали `/etc/security-alert-center/sac-api.env` — перенесите: ```bash sudo mkdir -p /opt/security-alert-center/config sudo cp /etc/security-alert-center/sac-api.env /opt/security-alert-center/config/sac-api.env sudo chown sac:sac /opt/security-alert-center/config/sac-api.env sudo chmod 600 /opt/security-alert-center/config/sac-api.env ``` Обязательно задать: - `DATABASE_URL` — с паролем PostgreSQL из шага 4 (если в пароле есть `#`, `@`, `%` — возьмите значение в **кавычки**: `DATABASE_URL="postgresql+psycopg2://..."`) - `JWT_SECRET` — `openssl rand -hex 32` - `SAC_PUBLIC_URL` — `https://sac.kalinamall.ru` - `SAC_BOOTSTRAP_API_KEY` — `python3.12 -c "import secrets; print('sac_'+secrets.token_urlsafe(32))"` - `EVENT_SCHEMA_PATH=/opt/security-alert-center/schemas/event-schema-v1.json` --- ## 7. Миграции БД Проверка, что `sac` читает конфиг (должно быть без `Permission denied`): ```bash ls -la /opt/security-alert-center/config/sac-api.env # должно быть: -rw------- sac sac sudo -u sac test -r /opt/security-alert-center/config/sac-api.env && echo OK ``` Миграции: ```bash cd /opt/security-alert-center/backend sudo -u sac bash -c 'set -a; source /opt/security-alert-center/config/sac-api.env; set +a; .venv/bin/alembic upgrade head' ``` --- ## 8. systemd Приложение загружает `config/sac-api.env` **само** (не через `EnvironmentFile` systemd) — так же, как при `alembic` с `source`. ```bash cd /opt/security-alert-center && sudo git pull sudo cp /opt/security-alert-center/deploy/systemd/sac-api.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable sac-api sudo systemctl start sac-api sudo systemctl status sac-api --no-pager ``` Логи: ```bash journalctl -u sac-api -f ``` --- ## 9. nginx и TLS ```bash sudo cp /opt/security-alert-center/deploy/nginx/sac.conf.example /etc/nginx/sites-available/sac sudo ln -sf /etc/nginx/sites-available/sac /etc/nginx/sites-enabled/sac # убрать default при необходимости: sudo rm /etc/nginx/sites-enabled/default sudo nginx -t sudo systemctl reload nginx ``` В `sac.conf` замените `server_name` на ваш FQDN. Let's Encrypt: ```bash sudo certbot --nginx -d sac.kalinamall.ru ``` --- ## 10. Проверка Локально на сервере: ```bash curl -sS http://127.0.0.1:8000/health | jq . ``` Через nginx (после TLS): ```bash curl -sS https://sac.kalinamall.ru/health | jq . ``` Тест ingest (подставьте `SAC_BOOTSTRAP_API_KEY`): ```bash API_KEY="ваш_ключ_из_sac-api.env" curl -sS -X POST http://127.0.0.1:8000/api/v1/events \ -H "Authorization: Bearer ${API_KEY}" \ -H "Content-Type: application/json" \ -d '{ "schema_version": "1.0", "event_id": "00000000-0000-4000-8000-000000000002", "occurred_at": "2026-05-26T12:00:00+03:00", "source": {"product": "ssh-monitor", "product_version": "test"}, "host": {"hostname": "test-host", "os_family": "linux"}, "category": "agent", "type": "agent.test", "severity": "info", "title": "Test", "summary": "Native install check" }' ``` Ожидается HTTP **202** и `"status": "accepted"`. --- ## 11. Резервное копирование ```bash sudo tee /etc/cron.d/sac-backup <<'EOF' 0 3 * * * postgres pg_dump -Fc -U sac sac > /var/backups/sac/sac_$(date +\%Y\%m\%d).dump EOF ``` Для `pg_dump` без пароля в cron настройте `~postgres/.pgpass` (см. документацию PostgreSQL). --- ## 12. Обновление SAC ```bash cd /opt/security-alert-center sudo -u sac git pull sudo -u sac backend/.venv/bin/pip install -r backend/requirements.txt sudo -u sac bash -c 'set -a; source /opt/security-alert-center/config/sac-api.env; set +a; cd backend && .venv/bin/alembic upgrade head' sudo systemctl restart sac-api ``` --- ## 13. Чеклист - [ ] Ubuntu 24.04, timezone - [ ] ufw: 22, 80, 443 - [ ] PostgreSQL: БД `sac`, пользователь `sac` - [ ] venv, зависимости установлены - [ ] `/opt/security-alert-center/config/sac-api.env`, владелец `sac:sac`, chmod 600 - [ ] `alembic upgrade head` без ошибок - [ ] `sac-api` active (systemd) - [ ] nginx + TLS - [ ] `/health` ok, ingest 202 - [ ] cron backup --- ## 14. Устранение неполадок | Симптом | Действие | |---------|----------| | `sac-api.env: Permission denied` | Конфиг в `/opt/security-alert-center/config/`, `chown sac:sac`, `chmod 600`. Не используйте `/etc/...` с каталогом `root:root` | | `password authentication failed` в **sac-api**, но alembic OK | Старый unit с `EnvironmentFile=` — `git pull`, обновить `sac-api.service`, `daemon-reload`, `restart`. Либо пароль в `DATABASE_URL` ≠ PostgreSQL | | `password authentication failed` везде | Пароль в `DATABASE_URL` в кавычках; `ALTER USER sac WITH PASSWORD`; тот же пароль в URL | | `database: error` / SQLAlchemy connect | `systemctl status postgresql`; проверить `DATABASE_URL` после успешного `source` | | 401 ingest | ключ в `Authorization: Bearer`; проверить `SAC_BOOTSTRAP_API_KEY` | | 502 от nginx | API не слушает: `ss -lntp \| grep 8000`, `systemctl restart sac-api` | | Schema errors 422 | путь `EVENT_SCHEMA_PATH`, наличие файла schema | --- ## См. также - [install-ubuntu-24.04.md](install-ubuntu-24.04.md) — указатель - [install-ubuntu-24.04-docker.md](install-ubuntu-24.04-docker.md) — альтернатива (не prod) - [deployment.md](deployment.md)