Files
infra/stacks/astra-marusia/README.md
T
gilfanovrandClaude Opus 5.5 e2bd908198 fr1: вебхук Маруси — vhost astra.ruzzy.dev и пользователь туннеля marusia-tunnel
- nginx: vhost astra.ruzzy.dev (LE), только POST /marusia/webhook/ → 127.0.0.1:18788,
  limit_req 1r/s, 64k, без access log, error_log crit (секрет в пути); ссылка zz-,
  чтобы не перехватить ответ на неизвестный SNI у git
- sshd: Match User marusia-tunnel — только remote forward 127.0.0.1:18788;
  добавлен в AllowUsers
- живые конфиги fr1 в stacks/astra-marusia/ вместо nginx-location.example
- fr1.md: эффективные настройки sshd проверены под root, отпечатки host-ключей
- туннель ещё не поднят, интеграция не завершена (хвост в fr1.md)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 18:22:56 +03:00

5.3 KiB
Raw Blame History

Разговор с Астрой через Марусю

Код: ruzzy/astra-bot, marusia/server.py, тесты test_marusia.py. Сервис на rpi слушает только 127.0.0.1:8788; наружу пока не опубликован. Webhook: POST /webhook/<секрет из /etc/astra-marusia.env>. Проверка: GET /health.

Отдельный разговор на идентификатор пользователя Маруси, до 16 реплик в памяти; при перезапуске история очищается, через сутки простоя удаляется. Беседа семейная, ответы подходят ребёнку 10 лет. Тексты не пишутся в access log. Голос распознаёт Маруся, Астра отвечает текстом, Маруся озвучивает response.tts.

Codex использует существующую авторизацию ChatGPT: файл auth.json привязан только для чтения в отдельный CODEX_HOME. Пользовательская конфигурация, правила, документы проекта и инструменты shell/apps/browser отключены. systemd скрывает домашние каталоги, запрещает повышение привилегий и запись за пределами своего StateDirectory. Не подключать этот сервис к административному треду Telegram. После обновления Codex повторно проверять список отключаемых feature flags.

Быстрый ответ ожидается до 2 секунд. Если ответ ещё готовится, колонка просит сказать «готово?»; новая реплика во время ожидания не запускает вторую задачу. Повтор webhook с теми же session_id/message_id получает кешированный ответ. Не более двух обращений к модели одновременно, не более 50 разговоров.

Публичный вход на fr1 (с 2026-10-11)

Цепочка: VK → https://astra.ruzzy.dev/marusia/webhook/<секрет> → nginx на fr1 → 127.0.0.1:18788 (обратный SSH-туннель, поднимает rpi) → rpi 127.0.0.1:8788/webhook/<секрет>. Домашние порты наружу не открыты, 18788 на fr1 слушает только loopback.

  • fr1-nginx-astra.ruzzy.dev.conf → /etc/nginx/sites-available/astra.ruzzy.dev.conf, ссылка sites-enabled/zz-astra.ruzzy.dev.conf. ⚠️ Префикс zz- нужен: на :443 у fr1 нет default_server, и первый по алфавиту vhost отвечает на неизвестный SNI (ruzzy.dev, fr1.ruzzy.dev) — без префикса им стал бы этот vhost вместо git.
  • fr1-nginx-conf.d-marusia-webhook.conf → /etc/nginx/conf.d/marusia-webhook.conf (зона limit_req 1 r/s, burst 5, отказ — 429).
  • fr1-sshd-70-marusia-tunnel.conf → /etc/ssh/sshd_config.d/70-marusia-tunnel.conf; плюс marusia-tunnel дописан в AllowUsers в 00-hardening.conf — ⚠️ без этого sshd пользователя молча не пустит («Permission denied» без причины на клиенте).
  • Пользователь fr1 marusia-tunnel: nologin, пароль заблокирован, групп нет; authorized_keys принадлежит root, ключ с restrict,port-forwarding,permitlisten="127.0.0.1:18788".
  • Отпечаток host-ключа fr1 (ED25519): SHA256:M5J9nH+svyA3+beD7ZllUn1tayMMO2cxw/t3Z/kj6KU.

⚠️ Секрет — часть пути, поэтому на fr1 для этого location access_log off, а error_log отдельный и только crit: на уровне error nginx пишет строку запроса (с секретом) при 502 от упавшего туннеля и при срабатывании limit_req. Не поднимать уровень этого лога «для отладки» — секрет окажется на диске. По HTTP /marusia/ отдаёт 404 без лога и без редиректа.

Ожидаемые ответы до заполнения skill_id: GET → 403 (nginx), POST с неверным секретом → 404, с верным → 403 (сервис), туннель лежит → 502.

Ключ Gitea — не ключ сервера; для туннеля отдельный ed25519 на rpi. Не открывать домашний порт в интернет напрямую. Регистрация/проверка: https://platform.vk.com/ и https://skill-tester.marusia.mail.ru/ (актуальность интерфейса проверить при входе). До заполнения skill_id все POST закрыты (403), знание случайного пути обязательно. skill_id не является криптографическим доказательством отправителя; секрет URL и приватный доступ навыка обеспечивают первичное ограничение доступа.