- servers/rpi.md: новая домашняя Raspberry Pi 4 (Trixie, cloud-init), HDD 4 ТБ,
грабли с питанием двух HDD от USB
- stacks/rpi-backup: rclone sync с вечным архивом версий, еженедельная сверка
хэшей, smartd, пуш SMART и статуса бэкапов
- fr1: pushgateway (127.0.0.1:9091), приём по SSH через forced command
~/bin/pushgw-ingest, алерты группы rpi
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
После apt-get из установки WEB-прокси needrestart перезапустил
systemd-networkd, тот удалил ip rule fwmark 0x64 -> vpn: ~45 мин
зарубежный трафик клиентов OpenVPN #1 шёл через RU IP. Правило
возвращено, networkd запрещено трогать чужие правила и маршруты.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
На ru.ruzzy.dev:443 поднят официальный tproxy-server (relay, carrier
websocket) перед официальным MTProxy на loopback. Фронт — nginx в
~/gost, сертификат только на ru.ruzzy.dev.
- MTProxy: --nat-info 10.8.1.4:161.97.93.252 вручную — трафик к
Telegram выходит через wg0 с IP fr1, автоопределение install.sh
ошиблось бы и прокси молча не отвечал бы.
- relay на 8090/8091: 8080 занят cadvisor.
- telemt удалён окончательно (контейнер, образ, конфиг, том).
- certbot до этого не работал вовсе: сертификат был просрочен с
2026-07-01, продлён и запущен.
stacks/tproxy/: compose и nginx.conf стека ~/gost, setup-ru1.sh —
однократная root-установка relay и MTProxy.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Контракт в репозитории достаёт только агентов, у которых этот репозиторий
есть. Astra работает на fr1 как tgclaude и infra у неё не склонирован, так
что до неё не дошло бы ничего.
Заведено на сервере:
~rus/CLAUDE.md и ~tgclaude/CLAUDE.md — указатель на репо, правило и пять
граблей, стоивших больше всего; AGENTS.md рядом симлинком, для агентов с
другой конвенцией. Claude Code читает CLAUDE.md вверх по дереву, поэтому
файл в хоме работает и при работе в ~tgclaude/imgbot.
~rus/MyVault/TOOLS.md, раздел SSH — то же для Astra. Файл смонтирован в
claude-channels как /vault, изменение видно агенту сразу, в Gitea уезжает
кроном каждые 5 минут.
MOTD и .bashrc сознательно не использованы: .bashrc выходит на строке 6 для
неинтерактивных шеллов, MOTD показывается только при интерактивном входе, а
агенты обычно дёргают `ssh host 'команда'` и не увидят ни того, ни другого.
Ограничения механизма и причина, по которой детектор дрейфа не заведён,
описаны в servers/fr1.md.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Сверка fr1 показала, что дока расходится с фактом по десятку пунктов —
значит нужен не разовый проход, а контракт и инструмент.
CLAUDE.md — правило «тронул сервер, обнови servers/<хост>.md в том же
прогоне» плюс стиль: факт + причина + что сломается молча. Лежит именно
в CLAUDE.md, потому что AGENTS.md автоматически агенту не подгружается.
.claude/skills/server-audit/ — метод сверки и накопленные грабли: где
дока врёт чаще всего, почему ufw не отвечает на вопрос об открытых
портах, почему нужен up -d --dry-run, почему «executed successfully»
не доказывает работу задания.
scripts/snapshot.sh — инвентаризация живого состояния за один проход:
только чтение, без sudo, секретов не печатает, недоступное под root
помечает и подсказывает команду.
Первый же прогон скрипта нашёл две вещи, обе описаны:
- IPv6 не «починился», а мигает: за один день FAILED -> REACHABLE ->
FAILED без единой правки конфига. Описан как мигающий, с выводом
ничего на него не завязывать.
- В основном sshd_config стоит PermitRootLogin yes (правка шаблона
Contabo). Root-вход закрыт только потому, что Include дроп-инов
стоит выше, а sshd берёт первое значение. Уберёшь дроп-ин —
включится.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Дока расходилась с фактом по десятку пунктов. Что исправлено по
результатам обхода сервера:
- ядро 6.8.0-137 (было 134); IPv6 заработал — шлюз отвечает на NDP,
хотя конфиг не менялся, так что может отвалиться обратно
- Gitea 1.27.3, 1.9 ГБ, 20 репо (было 1.25.4 / 4.3 ГБ / 16)
- апекс ruzzy.dev уже на fr1; появились vhost'ы share и www
- мониторинг шире описанного: таргеты ru1 и job gitea, дашборды
OpenVPN и Gitea; убраны устаревшие упоминания выведенного de1
- vault-синк claude-channels работает (дока говорила обратное), том
claude-home раздулся заново до 2.8 ГБ
Добавлены разделы, которых не было вовсе:
- tgclaude — общий вход для агентов; цепочка Telegram-бот → агент в
контейнере → SSH → группа docker → root на хосте
- imgbot и его переезд в контейнеры
- расписания: полная инвентаризация cron и таймеров
- открытые хвосты, включая непогашенные токены в Gitea
Разобрано и описано попутно: ufw не управляет docker-портами (ipcam
месяцами держал 2221 и 30000-30010 наружу без единого правила);
sysstat хранил историю 7 дней при HISTORY=7 — поднято до 365 (при >28
sa1 сам переключает имена на saYYYYMMDD, иначе смысла нет); /etc/cron.
hourly/free час за часом выбрасывал страничный кэш (до -3.89 ГиБ,
подтверждено по Prometheus) — удалён.
Уборка диска: 104 → 52 ГБ занято. Ушли ipcam, sc2-parser, booty,
booty-collector, vacuum-scraper, ollama (8.1 ГБ), легаси-архив
картинок, docker build cache (43.4 ГБ).
В AGENTS.md поправлены две неверные строки: de1 значился действующей
прод-нодой, хотя выведен, а туннель ru1 — идущим до de1. Сами
servers/de1.md и servers/ru1.md не сверялись.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Проект агента (~tgclaude/imgbot) работал тремя голыми python-процессами,
запущенными руками из SSH-сессии: без юнита, без restart-политики, при
Linger=no. Держались только на KillUserProcesses=no и не пережили бы
перезагрузку, причём молча.
Один образ на базе playwright/python:v1.62.0-noble (версия пакета
playwright обязана совпадать с тегом, иначе разъезжается ревизия
chromium), два сервиса:
- imgbot-daemon — APScheduler: refresh 30 мин, analyze 5 мин
- imgbot-http — объединил прежние mcp-http (8765) и file-server
(8766): MCP как под-приложение Starlette плюс маршрут /photo/<id>
Неочевидное, из-за чего это ломается молча (в compose есть комментарии):
- данные монтируются в тот же путь, что на хосте: images.file_path в
SQLite абсолютный, и его читают обе стороны
- корней хранения может быть больше одного — проверять все префиксы
file_path, а не только data_dir
- HOME обязателен: collector.py вызывает Path.home(), а uid 1001 не
имеет записи в /etc/passwd образа
- у MCP своя защита от DNS-rebinding: без IMGBOT_ALLOWED_HOSTS отдаёт
421 на любой Host кроме localhost
Порт не публикуется на хост, сервис доступен из общей docker-сети с
claude-channels — агент наконец ходит по MCP, а не по SSH.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ipcam/FTPS-приёмник удалён с fr1 целиком: контейнер, образ, том, сеть,
каталоги /srv/ipcam и /srv/ftps, deploy-хук certbot и сертификат
cam.ruzzy.dev. Видео так и не начали складываться — на момент удаления
в /srv/ipcam было 0 файлов.
Пин образа Gitea в стеке держал 1.25.4, тогда как работает 1.27.3
(обновлён 2026-08-31). Любой `docker compose up -d` откатил бы сервис
на две минорные версии назад.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
housekeeping 30s, docker_only, отключены дорогие метрики,
init:true для reaping healthcheck-wget. На fr1 дало 231%→14% CPU.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>