Files

5.0 KiB

md2vk — Деплой

Топология

https://md2vk.nixg.ru (Caddy на vps02, basic auth)
   └─ reverse_proxy 10.8.0.2:8420   (WireGuard: vps02 .4 → bigbox .1)
        └─ docker-контейнер md2vk на bigbox, 127.0.0.1:8420
  • Порт приложения 8420 (8000 занят docker-search-api на bigbox).
  • Контейнер слушает на 127.0.0.1:8420 (снаружи bigbox не открыт).

bigbox (10.8.0.2) — приложение

cd /opt/md2vk
make docker-up          # docker compose up -d --build
docker ps | grep md2vk  # статус
curl -s http://127.0.0.1:8420/api/v1/health   # {"status":"ok"}
  • Данные: named volume md2vk_data → /data/md2vk.db (SQLite).
  • Секрет: ./secrets/token_encryption_key → /run/secrets/token_encryption_key.
  • Логи аудита: ./logs/ монтируется в /logs.
  • Health: /api/v1/health, проверяется Docker healthcheck.
  • Восстановление после перезагрузки: restart: unless-stopped.
  • Если надо пересоздать БД — удалить том (только по явной команде, данные!): docker compose down -v && make docker-up (НЕ делать без подтверждения).

Создание пользователя и API-ключа

cd /opt/md2vk
source venv/bin/activate
TOKEN_ENCRYPTION_KEY_FILE=/opt/md2vk/secrets/token_encryption_key ./scripts/create_user.py \
  --name estorozhenko --api-key-out secrets/estorozhenko_api_key.txt
# вывод: API key сохранён в secrets/estorozhenko_api_key.txt (md2vk_...)

Источник: scripts/create_user.py (добавляет User с сгенерированным ключом; ключ отображается один раз).

vps02 (87.242.100.206) — Caddy

Файл /opt/caddy/Caddyfile на vps02, секция:

md2vk.nixg.ru {
    basic_auth /* {
        estorozhenko $2a$14$T5gAji7gmg1t3Ifxw0CJy.jat9vpFfOiJIE8j5bnHynEVH1q.QTPS
    }
    reverse_proxy 10.8.0.2:8420
}

Применить (контейнер caddy, монтирует Caddyfile):

ssh vps02
docker exec caddy caddy validate --config /etc/caddy/Caddyfile   # проверить синтаксис
docker exec caddy caddy reload --config /etc/caddy/Caddyfile     # перезагрузить
# если нужно: docker restart caddy
  • TLS: Caddy автоматически выпускает Let's Encrypt сертификат для md2vk.nixg.ru (acme в Caddyfile: email kpa39l@yandex.ru).
  • Сертификат на caddy_data (volume), переживает рестарты.

vps02 — fail2ban (блокировка после 5 попыток)

Пакет ставится на vps02 (Debian/Ubuntu):

ssh vps02
sudo apt-get update && sudo apt-get install -y fail2ban

Конфиг jail (/etc/fail2ban/jail.local) и фильтр (/etc/fail2ban/filter.d/md2vk.conf):

# /etc/fail2ban/filter.d/md2vk.conf
[Definition]
failregex = ^.*"status":401.*
ignoreregex =
# /etc/fail2ban/jail.local
[md2vk]
enabled  = true
port     = http,https
filter   = md2vk
logpath  = /var/log/caddy/access.log
maxretry = 5
findtime = 600
bantime  = -1
action   = iptables-allports
  • Лог Caddy в JSON: настроить в Caddyfile log { output file /var/log/caddy/access.log format json } (глобальный блок).
  • Перезапуск: sudo systemctl restart fail2ban.
  • Проверка: sudo fail2ban-client status md2vk.
  • Ручной unban: sudo fail2ban-client -c /etc/fail2ban unban <ip>.

Сквозная проверка

# 1. health через Caddy (без auth → 401)
curl -s -o /dev/null -w "%{http_code}\n" https://md2vk.nixg.ru/api/v1/health          # 401
# 2. health c auth → 200
curl -s -u 'estorozhenko:<пароль>' https://md2vk.nixg.ru/api/v1/health                # {"status":"ok"}
# 3. публикация не требует VK-токена? нет — конвертация:
curl -s -u 'estorozhenko:<пароль>' -H 'Authorization: Bearer <api_key>' \
  -X POST https://md2vk.nixg.ru/api/v1/convert \
  -H 'Content-Type: application/json' \
  -d '{"message_md":"**test** *curl*"}'                                                # format_data
# 4. баним проверкой: 5 раз неверный пароль → fail2ban ban IP
for i in 1 2 3 4 5 6; do curl -s -o /dev/null -w "%{http_code}\n" -u 'estorozhenko:wrong' https://md2vk.nixg.ru/api/v1/health; done
# → 401 ×6, затем соединение DROP (curl timeout)
sudo fail2ban-client status md2vk    # IP в banned
sudo fail2ban-client unban <ваш-ip>

Восстановление после аварии

  • Приложение: docker compose up -d --force-recreate на bigbox.
  • Caddy: docker restart caddy на vps02 (volume caddy_data хранит сертификаты).
  • БД: том md2vk_data; бэкап = копия /opt/md2vk/data/md2vk.db (вне контейнера) — включена в homelab-backup (/opt/backup).