372 lines
11 KiB
Markdown
372 lines
11 KiB
Markdown
# 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
|
||
|
||
Для KalinaMall: **корпоративный wildcard VeriSign** (или DigiCert), не Let's Encrypt.
|
||
Хост `sac.kalinamall.ru` должен попадать под `*.kalinamall.ru`.
|
||
|
||
**Подробно:** форматы, scp с Windows/Linux, `.pfx` → PEM, права — **[ssl-certificate.md](ssl-certificate.md)**.
|
||
|
||
### 9.1. Кратко: куда положить файлы
|
||
|
||
nginx ожидает **два PEM-файла**:
|
||
|
||
| Файл на сервере | Содержимое |
|
||
|-----------------|------------|
|
||
| `/etc/ssl/sac/fullchain.pem` | Wildcard-сертификат + промежуточные CA |
|
||
| `/etc/ssl/sac/privkey.pem` | Закрытый ключ |
|
||
|
||
```bash
|
||
sudo mkdir -p /etc/ssl/sac && sudo chmod 750 /etc/ssl/sac
|
||
```
|
||
|
||
Скопировать с рабочего ПК (пример):
|
||
|
||
```bash
|
||
# с вашего компьютера:
|
||
scp fullchain.pem privkey.pem papatramp@<IP_SAC>:/tmp/
|
||
|
||
# на сервере:
|
||
sudo mv /tmp/fullchain.pem /tmp/privkey.pem /etc/ssl/sac/
|
||
sudo chmod 644 /etc/ssl/sac/fullchain.pem
|
||
sudo chmod 640 /etc/ssl/sac/privkey.pem
|
||
sudo chown root:root /etc/ssl/sac/fullchain.pem
|
||
sudo chown root:ssl-cert /etc/ssl/sac/privkey.pem
|
||
sudo -u www-data test -r /etc/ssl/sac/privkey.pem && echo OK
|
||
```
|
||
|
||
Если пришёл только **`.pfx`** — см. [ssl-certificate.md §4.3](ssl-certificate.md#43-распаковка-pfx--p12-на-сервере).
|
||
|
||
### 9.2. Конфиг nginx (HTTPS)
|
||
|
||
```bash
|
||
cd /opt/security-alert-center
|
||
sudo git pull
|
||
sudo cp deploy/nginx/sac.conf.tls.example /etc/nginx/sites-available/sac
|
||
sudo nano /etc/nginx/sites-available/sac
|
||
# Проверьте пути ssl_certificate и ssl_certificate_key → /etc/ssl/sac/...
|
||
|
||
sudo ln -sf /etc/nginx/sites-available/sac /etc/nginx/sites-enabled/sac
|
||
sudo rm -f /etc/nginx/sites-enabled/default
|
||
sudo nginx -t
|
||
sudo systemctl reload nginx
|
||
```
|
||
|
||
Проверка:
|
||
|
||
```bash
|
||
curl -sS https://sac.kalinamall.ru/health | jq .
|
||
```
|
||
|
||
В `config/sac-api.env` должно быть: `SAC_PUBLIC_URL=https://sac.kalinamall.ru`
|
||
|
||
### 9.3. Агенты (ssh-monitor, RDP) и доверие к CA
|
||
|
||
- Агенты ходят на `https://sac.kalinamall.ru/api/v1/events`.
|
||
- Если используется **внутренний корневой CA**, а не публичный VeriSign/DigiCert в системном store — на Linux/Windows может понадобиться установка корневого сертификата в доверенные (или корпоративный прокси с подменой TLS).
|
||
- Для публичного коммерческого wildcard от известного УЦ обычно **дополнительных действий на агентах не нужно**.
|
||
|
||
### 9.4. Альтернатива: только HTTP (отладка)
|
||
|
||
Шаблон `deploy/nginx/sac.conf.example` — порт 80 без TLS. Не для production.
|
||
|
||
### 9.5. Альтернатива: Let's Encrypt
|
||
|
||
Если понадобится публичный бесплатный сертификат только на этот хост:
|
||
|
||
```bash
|
||
sudo cp deploy/nginx/sac.conf.example /etc/nginx/sites-available/sac
|
||
# ... nginx -t, reload, затем:
|
||
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)
|