mirror of
https://gitverse.ru/kpa39l/md2vk.git
synced 2026-09-29 18:05:04 +00:00
4.7 KiB
4.7 KiB
md2vk — Безопасность
Два уровня доступа
1. Внешний — Caddy basic_auth (на vps02)
- Весь https://md2vk.nixg.ru закрыт HTTP Basic Auth.
- Пользователь: estorozhenko; пароль — у пользователя, в конфиге только bcrypt-хэш.
- Хэш в Caddyfile:
estorozhenko $2a$14$uzlQxJdcRZJ5gDpGG5B26OXnudIme1IYe7xh0WtDwFtbB6XiiDYTS(сгенерирован 2026-09-18docker exec caddy caddy hash-password --plaintext '<пароль>'). - Без basic auth сервис наружу не отдаётся.
2. Внутренний — API-ключ (FastAPI)
- Все эндпоинты
/api/v1/*(кроме/health) требуют API-ключmd2vk_...:- в заголовке
Authorization: Bearer <api_key>(GET) или в теле{"api_key": ...}(POST);
- в заголовке
- API-ключ даёт право публиковать, но не позволяет прочитать VK-токен (raw токен не возвращается ни одним эндпоинтом).
- Хранится только SHA-256 хэш (
api_key_hash), сравнение constant-time (hmac.compare_digest). - Пользователь estorozhenko + API-ключ: создаётся скриптом, ключ кладётся в
secrets/estorozhenko_api_key.txt(не в git).
Блокировка после 5 неудачных попыток (fail2ban на vps02)
- На vps02 установлен fail2ban (v1.0.2), jail
md2vk:- следит за site-логом Caddy:
/opt/caddy/caddy_data/logs/md2vk.access.log(JSON, все запросы включая 401), - фильтр
filter.d/caddy-md2vk.conf:^.*"request":\{"remote_ip":"<HOST>"[^}]*"host":"md2vk\.nixg\.ru"[^}]*\}.*"status":401, - правило: ban IP после 5 неудачных попыток (
maxretry=5,findtime=600; на 6-й срабатывает), - наказание: ban до ручного снятия (
bantime = -1), - действие:
iptables-allports(цепочкаf2b-md2vk, REJECT; на Debian 12 транслируется в nftables), - ignoreip:
127.0.0.1/8 ::1 10.8.0.0/24(не баним bigbox/vps02).
- следит за site-логом Caddy:
- Ручная разблокировка (на vps02, sudo):
fail2ban-client -c /etc/fail2ban unban <ip> fail2ban-client -c /etc/fail2ban status md2vk # проверить - Логи fail2ban:
journalctl -u fail2ban -eили/var/log/fail2ban.log.
Шифрование VK-токенов
- VK OAuth-токены в БД только в шифрованном виде: Fernet (AES-128-CBC + HMAC-SHA256).
- Ключ — Docker secret
/run/secrets/token_encryption_key(файл на bigbox:secrets/token_encryption_key, не в git). - Расшифровка только в памяти при публикации.
Rate limiting
- В конфиге
RATE_LIMIT_PER_MINUTE=10(запросов/мин на VK-аккаунт). - In-memory bucket — НЕ реализован (открытая задача).
Аудит-лог
- Пишется JSONL в
/opt/md2vk/logs/access.{YYYY-MM-DD}.log(вне контейнера —logs/на bigbox). - Событие на каждый запрос
/api/v1/*:ts, ip, method, path, api_key_prefix, user_id, status, success, latency_ms, error. - Используется для мониторинга (доступность, успешность, активная сессия) и расследований.
- Caddy на vps02 пишет свой access-лог (используется fail2ban).
Матрица рисков
| Сценарий | Последствия | Защита |
|---|---|---|
| Утечка .db | Токены зашифрованы | Fernet + Docker secret |
| Утечка API-ключа | Можно постить, но не украсть токен | API-ключ ≠ VK-токен |
| Брутфорс basic auth | Полный доступ к веб-интерфейсу API | fail2ban ban после 5 попыток, ручной unban |
| Перехват HTTP | — | HTTPS (Caddy/Let's Encrypt) |
| Компрометация контейнера | Полный доступ к токенам | read-only rootfs, audit log |
| Отзыв токена VK | Пост не выйдет | VK вернёт ошибку → error_message |
Правило пользователя
Никогда не удалять файлы пользователя без явного подтверждения. Пароли и токены не сохранять в коде — только через переменные окружения, Docker secrets или файлы, исключённые из git (.gitignore).