Пакет B — задачи через SSH-доступ¶
Составлено 06.08.2026 · Требует ручного выполнения пользователем через
ssh oswold@...Агент готовит команды и промпты, ты выполняешь и присылаешь вывод для верификации.Правила: - По одной задаче за раз — не параллелим - Каждая команда с
sudoвыполняется тобой (я не могу через API) - После каждой задачи — вывод в чат, я обновлю KB и TODO - Секреты (новые ключи, токены) никогда в чат — только в Vaultwarden, в чате только "готово"
📋 Порядок выполнения¶
Задачи отсортированы: сначала быстрые + без риска простоя, потом сложные + требующие downtime.
| Порядок | # | Задача | Хост | Downtime | Риск | Время |
|---|---|---|---|---|---|---|
| B1 | 27 | Пароли роутера/Reg.ru/Hostkey → Vaultwarden | локально | нет | нет | 5 мин |
| B2 | 3 | Продублировать OPENWEBUI_API_TOKEN в Vaultwarden |
ragserver | нет | нет | 5 мин |
| B3 | 4 | Диагностика DPI (какой SNI ловит Инетком) | локально | нет | нет | 10 мин |
| B4 | 5 | AmneziaWG auto-connect дома | локально | нет | нет | 5 мин |
| B5 | 21 | Security headers в nginx на ragserver | ragserver | reload | низкий | 10 мин |
| B6 | 6 | Cron для sync-to-openwebui.sh | ragserver | нет | низкий | 15 мин |
| B7 | 23 | Зафиксировать версию образа Vaultwarden | VPS | 30 сек | низкий | 15 мин |
| B8 | 26 | Убрать дубликат MASQUERADE в amnezia-awg2 | VPS | нет | низкий | 10 мин |
| B9 | 25 | Аудит клиентов AmneziaWG | VPS | нет | нет | 20 мин |
| B10 | 24 | Переоформить awg-rag через Amnezia GUI | VPS | несколько сек | средний | 20 мин |
| B11 | 1 | Ротировать QDRANT_API_KEY |
ragserver | 30 сек | средний | 20 мин |
| B12 | 2 | Ротировать POSTGRES_PASSWORD |
ragserver | 1-2 мин | высокий | 30 мин |
| B13 | 17 | Off-site бэкап Vaultwarden (VPS → ragserver) | VPS + ragserver | нет | низкий | 30 мин |
| B14 | 19 | Расширить бэкапы на AmneziaWG | VPS | нет | низкий | 20 мин |
| B15 | 20 | Бэкап /opt/rag-platform/data/ |
ragserver | зависит | низкий | 30 мин |
| B16 | 22 | SMTP для Vaultwarden | VPS + Yandex 360 | нет | низкий | 30 мин |
| B17 | 18 | Test restore Vaultwarden | ragserver | нет | нет | 30 мин |
| B18 | 28 | Мониторинг (Uptime Kuma) | ragserver | нет | нет | 30 мин |
| B19 | 36 | Open WebUI API наружу для Perplexity | VPS + ragserver | reload | средний | 45 мин |
Итого: ~7-8 часов работы, разбито на подходы по 30-60 минут.
🎯 Рекомендованные группировки¶
Если делать в один заход — группируй по хосту:
- Только локально (B1, B3, B4) — 20 минут, полностью без SSH
- Ragserver, лёгкое (B2, B5, B6) — 30 минут
- VPS, лёгкое (B7, B8, B9, B10) — 60 минут
- Ротация секретов (B11, B12) — 50 минут, требует внимания
- Бэкапы (B13, B14, B15, B17) — 2 часа
- Мониторинг + SMTP + API (B16, B18, B19) — 1.5 часа
B1. Пароли роутера/Reg.ru/Hostkey → Vaultwarden¶
Задача 27 в TODO. Хост: локально (Vaultwarden UI).
Проще всего сделать сейчас пока не забыли. Открой https://vault.alatyr-service.ru (или через VPN если DPI режет), заведи три записи:
| Название | Логин | URL |
|---|---|---|
Router ASUS RT-N12E (192.168.1.1) |
admin | http://192.168.1.1 |
Reg.ru — DNS панель |
(твой email/логин) | https://www.reg.ru/ |
Hostkey — панель управления VPS |
(твой логин) | https://hostkey.com/ |
После завершения: напиши "B1 done" — я обновлю TODO.
B2. Продублировать OPENWEBUI_API_TOKEN в Vaultwarden¶
Задача 3 в TODO. Хост: ragserver 192.168.1.200 (SSH).
ssh oswold@192.168.1.200
# Извлекаем токен из .env (в чат НЕ копируй!)
sudo grep OPENWEBUI_API_TOKEN /opt/rag-sync/.env
Открываешь Vaultwarden в браузере → создаёшь запись:
- Название: RAG sync — OpenWebUI API token
- Логин: perplexity-agent (или чей токен)
- Пароль: вставляешь значение из вывода
- URL: https://192.168.1.200:3000/
После завершения: "B2 done", я поставлю ✅ в TODO.
B3. Диагностика DPI (SNI-паттерн Инетком)¶
Задача 4 в TODO. Хост: локально с домашнего Wi-Fi (без VPN!).
Отключи AmneziaWG перед тестом. Выполни:
# 1. Основной домен — должен упасть на ERR_CONNECTION_RESET
curl -v https://vault.alatyr-service.ru 2>&1 | head -30
# 2. Тот же IP, другой SNI — работает?
curl -v --resolve vw.alatyr-service.ru:443:176.99.153.164 https://vw.alatyr-service.ru 2>&1 | head -20
curl -v --resolve pw.alatyr-service.ru:443:176.99.153.164 https://pw.alatyr-service.ru 2>&1 | head -20
curl -v --resolve test.alatyr-service.ru:443:176.99.153.164 https://test.alatyr-service.ru 2>&1 | head -20
# 3. Прямо по IP без SNI — работает?
curl -vk https://176.99.153.164:8443/alive 2>&1 | head -30
# 4. Bonus — что режется по слову "vault":
curl -v https://vault.example.com 2>&1 | head -5 # если такого домена нет, ошибка DNS — норм
После завершения: пришли выводы (без BODY, только заголовки/ошибки), я разберу и запишу в vaultwarden.md § Повторная диагностика.
B4. AmneziaWG auto-connect дома¶
Задача 5 в TODO. Хост: локально.
Windows/Amnezia GUI: - Открой Amnezia app → Настройки → Общие - Включи "Auto-connect at startup" / "Запускать при старте системы" - Проверь что после ребута туннель поднимается сам
Android (если используешь): - Настройки телефона → VPN → AmneziaWG → Always-on VPN: ON - Block connections without VPN: рекомендую тоже ON (кроме LAN)
После завершения: "B4 done".
B5. Security headers в nginx на ragserver¶
Задача 21 в TODO. Хост: ragserver 192.168.1.200.
ssh oswold@192.168.1.200
# Бэкап перед правкой
sudo cp /etc/nginx/sites-enabled/rag.alatyr-service.ru /etc/nginx/sites-enabled/rag.alatyr-service.ru.bak.$(date +%Y%m%d)
# Правка (открой в редакторе)
sudo nano /etc/nginx/sites-enabled/rag.alatyr-service.ru
Добавь внутри server { ... } блока (после listen 443 или рядом с другими add_header):
# Security headers (2026-08-06)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
Проверка + reload:
sudo nginx -t
sudo systemctl reload nginx
# Проверка снаружи (через VPN если ты не дома)
curl -sI https://rag.alatyr-service.ru | grep -iE "strict-transport|x-frame|x-content|referrer|permissions"
После завершения: пришли последний curl -sI — я запишу в nginx-ragserver-config.md.
B6. Cron для sync-to-openwebui.sh¶
Задача 6 в TODO. Хост: ragserver 192.168.1.200.
Рекомендую вариант A (user cron) — проще и достаточно надёжно для не-критичной задачи.
ssh oswold@192.168.1.200
# Проверить что скрипт есть и исполняем
ls -la /opt/rag-sync/sync-to-openwebui.sh
# Ожидаем -rwx------ 1 oswold oswold
# Создать директорию под лог
mkdir -p /opt/rag-sync/logs
# Открыть user crontab
crontab -e
Добавь строку:
# RAG KB sync каждые 15 минут (при первом прогоне 10 мин на 10 файлов, потом секунды)
*/15 * * * * /opt/rag-sync/sync-to-openwebui.sh >> /opt/rag-sync/logs/sync.log 2>&1
Сохрани, проверь:
После завершения: пришли crontab -l и первые строки нового прогона из sync.log.
Альтернатива (systemd user timer) — если хочешь надёжнее с ретраем: скажи, дам конфиг.
B7. Зафиксировать версию образа Vaultwarden¶
Задача 23 в TODO. Хост: VPS 46.17.99.183.
ssh oswold@46.17.99.183
# Проверить какая сейчас версия
sudo docker inspect vaultwarden --format '{{.Config.Image}}'
sudo docker exec vaultwarden /vaultwarden --version
# Посмотреть актуальные стабильные теги
curl -s https://hub.docker.com/v2/repositories/vaultwarden/server/tags/?page_size=20 | \
grep -oE '"name":"[^"]+"' | head -20
Открой docker-compose.yml:
Замени image: vaultwarden/server:latest → image: vaultwarden/server:1.35.0 (или актуальную стабильную из вывода выше — на 06.08.2026 самая свежая была 1.35.x, уточни).
Перезапуск:
sudo docker compose pull
sudo docker compose up -d
sudo docker logs vaultwarden --tail 30
# Проверить снаружи
curl -sI https://vault.alatyr-service.ru
После завершения: пришли версию, я обновлю vaultwarden.md.
B8. Проверить MASQUERADE в amnezia-awg2 ✅¶
Задача 26 закрыта 24.08.2026. Хост: VPS 46.17.99.183.
ssh oswold@46.17.99.183
# Проверить полные условия каждого правила
sudo docker exec amnezia-awg2 iptables -t nat -S POSTROUTING
Проверка показала, что похожие правила для 10.8.1.0/24 имеют разные
выходные интерфейсы: eth0 и eth1. Они не являются дубликатами. Отдельное
правило через awg0 нужно для маршрута rag-api к 10.8.1.12.
⚠ Не удалять правила по line number. Подробности: fix-masquerade-duplicate.md.
B9. Аудит клиентов AmneziaWG¶
Задача 25 в TODO. Хост: VPS 46.17.99.183.
ssh oswold@46.17.99.183
# Список всех клиентов из clientsTable
sudo cat /opt/amnezia/awg/clientsTable 2>/dev/null | \
python3 -c "import json,sys; d=json.load(sys.stdin); [print(f'{c.get(\"clientName\",\"—\")}\t{c.get(\"clientId\",\"\")[:16]}') for c in d]"
# Кто когда последний раз подключался
sudo docker exec amnezia-awg2 wg show awg0 latest-handshakes
Открой Amnezia GUI на VPS (или через SSH-туннель на порт GUI):
- Каждый клиент из clientsTable — есть в GUI?
- В GUI есть, а latest-handshakes показывает 0 — никогда не подключались
- Названия New client (X) от 04.08.2026 → определи по IP кого и переименуй, либо удали
После завершения: пришли список "оставить"/"удалить"/"переименовать", я запишу в amneziawg-tunnels.md.
B10. Переоформить awg-rag через Amnezia GUI¶
Задача 24 в TODO. Хост: VPS 46.17.99.183 + ragserver.
⚠ Есть риск на 30-60 секунд оставить ragserver без туннеля. Делаем аккуратно.
Шаг 1. В Amnezia GUI на VPS создать нового клиента awg-rag-new. Скачать конфиг.
Шаг 2. На ragserver:
ssh oswold@192.168.1.200
# Бэкап старого конфига
sudo cp /etc/amnezia/awg-rag.conf /etc/amnezia/awg-rag.conf.bak.$(date +%Y%m%d)
# Загрузить новый конфиг с VPS (или через scp с локальной машины)
# ... вставить новый содержание awg-rag-new.conf в /etc/amnezia/awg-rag.conf
sudo -e /etc/amnezia/awg-rag.conf
# Рестарт туннеля
sudo systemctl restart amneziawg-awg-rag # или awg-quick@awg-rag
sudo wg show awg-rag # или awg show awg-rag
Шаг 3. На VPS удалить старого клиента через GUI. Проверить что новый handshake активен:
После завершения: пришли wg show awg-rag с ragserver.
B11. Ротировать QDRANT_API_KEY¶
RAG-02 в TODO. Хост: ragserver 192.168.1.200.
⚠ Downtime OpenWebUI ~30 сек.
ssh oswold@192.168.1.200
cd /opt/rag-platform
# Сгенерировать новый ключ (в чат НЕ вставляй!)
NEW_KEY=$(openssl rand -hex 32)
echo "$NEW_KEY" | wc -c # должно быть 65 (64 символа + \n)
# Прямо в этом же терминале — сохранить в клипборд через файл
echo "$NEW_KEY" > /tmp/newkey.txt
chmod 600 /tmp/newkey.txt
Открой .env:
Замени QDRANT_API_KEY=... на QDRANT_API_KEY=<новый>. Сохрани.
Рестарт:
cd /opt/rag-platform
sudo docker compose down qdrant openwebui
sudo docker compose up -d qdrant openwebui
# Проверить логи
sudo docker logs rag-openwebui --tail 30 | grep -iE "qdrant|error"
sudo docker logs rag-qdrant --tail 20
Открой Vaultwarden → запись Qdrant API key (ragserver) → обнови значение из /tmp/newkey.txt. Затем удали временный файл:
После завершения: пришли последние строки логов OpenWebUI (проверяем что коннект к Qdrant есть).
B12. Ротировать POSTGRES_PASSWORD¶
RAG-03 в TODO. Хост: ragserver 192.168.1.200.
⚠ Downtime OpenWebUI 1-2 мин. Требует внимания к DATABASE_URL.
ssh oswold@192.168.1.200
cd /opt/rag-platform
# 1. Сгенерировать новый пароль (в чат НЕ вставляй!)
NEW_PW=$(openssl rand -hex 24)
echo "$NEW_PW" > /tmp/newpw.txt && chmod 600 /tmp/newpw.txt
# 2. Обновить пароль в самом Postgres
sudo docker exec -it rag-postgres psql -U postgres -c "ALTER USER postgres WITH PASSWORD '$NEW_PW';"
# ⚠ пароль ушёл в bash history! Затрём:
history -d $(history 1 | awk '{print $1}')
# 3. Проверить что можем зайти с новым паролем
sudo docker exec -e PGPASSWORD="$NEW_PW" rag-postgres psql -U postgres -c "SELECT current_user;"
Открой .env:
Обнови два места:
- POSTGRES_PASSWORD=<новый>
- DATABASE_URL=postgresql://postgres:<новый>@postgres:5432/openwebui (если он там)
Рестарт:
sudo docker compose down openwebui
sudo docker compose up -d openwebui
# Проверка (даём 30 сек на старт)
sleep 30
sudo docker logs rag-openwebui --tail 50 | grep -iE "postgres|database|error"
curl -sI http://192.168.1.200:3000/ # 200 OK ожидаем
Обнови в Vaultwarden запись Postgres — RAG platform. Затри временный файл:
После завершения: пришли последние строки логов + curl ответ.
Если что-то сломалось: откати .env из бэкапа .env.bak.<дата> (если делал) и обратно ALTER USER postgres WITH PASSWORD 'старый';.
B13. Off-site бэкап Vaultwarden (VPS → ragserver)¶
Задача 17 в TODO. Хост: VPS + ragserver.
Шаг 1. Подготовить приёмник на ragserver:
ssh oswold@192.168.1.200
sudo mkdir -p /opt/backups/vaultwarden
sudo chown oswold:oswold /opt/backups/vaultwarden
chmod 750 /opt/backups/vaultwarden
# SSH-ключ для приёма (генерим на VPS позже)
mkdir -p ~/.ssh && chmod 700 ~/.ssh
Шаг 2. Сгенерировать SSH-ключ на VPS (только для бэкапа):
ssh oswold@46.17.99.183
sudo -u root ssh-keygen -t ed25519 -f /root/.ssh/backup-to-ragserver -N ""
sudo cat /root/.ssh/backup-to-ragserver.pub
# Скопируй публичную часть
Шаг 3. На ragserver добавить ключ:
# На ragserver
echo "команда=rsync --server -vlogDtprze.iLsfxCIvu . /opt/backups/vaultwarden/ ssh-ed25519 AAAA... backup@vps" \
>> ~/.ssh/authorized_keys
# ⚠ Ограничим ключ только rsync с force_command — безопаснее чем полный доступ
Шаг 4. Настроить туннель AmneziaWG (если VPS → ragserver не работает напрямую):
Ragserver из VPN должен быть доступен на IP 10.8.1.12 (если это тот awg-rag). Проверь с VPS:
ssh oswold@46.17.99.183
ping -c 3 10.8.1.12
ssh -i /root/.ssh/backup-to-ragserver oswold@10.8.1.12 "hostname"
Шаг 5. Крон на VPS после ежедневного бэкапа (03:15):
sudo crontab -e
# Добавить:
# 20 3 * * * rsync -az -e "ssh -i /root/.ssh/backup-to-ragserver" /opt/vaultwarden/backups/*.gpg oswold@10.8.1.12:/opt/backups/vaultwarden/ >> /var/log/vw-offsite.log 2>&1
После завершения: пришли вывод первого прогона sudo rsync -avn ... (dry-run) — я проверю пути.
B14. Расширить бэкапы на AmneziaWG¶
Задача 19 в TODO. Хост: VPS.
ssh oswold@46.17.99.183
# Найти текущий backup-скрипт
sudo find /opt -name "backup*.sh" 2>/dev/null
sudo find /root -name "backup*.sh" 2>/dev/null
sudo crontab -l | grep -i backup
Добавь в существующий скрипт (или создай новый) блок:
# AmneziaWG config backup
BACKUP_TMP=$(mktemp -d)
sudo docker cp amnezia-awg2:/opt/amnezia/awg "$BACKUP_TMP/"
tar czf "$BACKUP_TMP/awg-$(date +%Y%m%d).tar.gz" -C "$BACKUP_TMP" awg
gpg --batch --yes --passphrase-file /root/.backup-pass \
-c --cipher-algo AES256 "$BACKUP_TMP/awg-$(date +%Y%m%d).tar.gz"
mv "$BACKUP_TMP/awg-$(date +%Y%m%d).tar.gz.gpg" /opt/backups/awg/
rm -rf "$BACKUP_TMP"
После завершения: покажи ls -la /opt/backups/awg/ и что бэкап-крон включает.
B15. Бэкап /opt/rag-platform/data/¶
Задача 20 в TODO. Хост: ragserver.
Есть два подхода:
Вариант A — offline снапшот (простой, есть downtime):
ssh oswold@192.168.1.200
cd /opt/rag-platform
sudo docker compose down
sudo tar czf /opt/backups/rag-platform-$(date +%Y%m%d).tar.gz -C /opt/rag-platform data
sudo docker compose up -d
Вариант B — online (сложнее, без downtime):
- Postgres: sudo docker exec rag-postgres pg_dumpall -U postgres > /opt/backups/pg-$(date +%Y%m%d).sql
- Qdrant: snapshot API curl -X POST http://localhost:6333/collections/open-webui_knowledge/snapshots
- OpenWebUI: копия data/webui.db (SQLite) на живой системе — риск повреждения, но обычно ок
Рекомендую A для еженедельного бэкапа + B ежедневно. Скажи какой вариант — дам полный скрипт + крон.
B16. SMTP для Vaultwarden¶
Задача 22 в TODO. Хост: VPS + Yandex 360.
Шаг 1 (Yandex 360, локально):
- Создай ящик vault@alatyr-service.ru (или noreply@) в Y360
- Настройки → Пароли приложений → Создать → сохрани в Vaultwarden как Y360 — vault@ app password
Шаг 2 (VPS):
Добавь:
SMTP_HOST=smtp.yandex.ru
SMTP_FROM=vault@alatyr-service.ru
SMTP_FROM_NAME="Vaultwarden Alatyr"
SMTP_SECURITY=starttls
SMTP_PORT=587
SMTP_USERNAME=vault@alatyr-service.ru
SMTP_PASSWORD=<application password>
SMTP_TIMEOUT=15
Рестарт + тест:
sudo docker compose restart vaultwarden
sudo docker logs vaultwarden --tail 30
# В /admin панели → Send test email → на свой ящик
После завершения: "B16 done" + подтверди что тестовое письмо пришло.
B17. Test restore Vaultwarden¶
Задача 18 в TODO. Хост: ragserver или VPS в отдельном контейнере.
ssh oswold@192.168.1.200
mkdir -p /tmp/vw-restore-test
cd /tmp/vw-restore-test
# Скопировать последний бэкап
scp oswold@46.17.99.183:/opt/vaultwarden/backups/$(ssh oswold@46.17.99.183 'ls -1t /opt/vaultwarden/backups/*.gpg | head -1') .
# Расшифровать
gpg -d $(ls *.gpg) > backup.tar.gz
tar xzf backup.tar.gz
# Запустить временный Vaultwarden с этими данными на другом порту
docker run -d --name vw-test \
-v $(pwd):/data \
-p 8080:80 \
vaultwarden/server:1.35.0
# Открыть http://192.168.1.200:8080 → залогиниться своим паролем
# Проверить что вижу свои записи
Уборка:
Задокументируй процедуру в vaultwarden.md § План восстановления.
После завершения: "B17 done" + сколько записей увидел.
B18. Мониторинг (Uptime Kuma)¶
Задача 28 в TODO. Хост: ragserver.
ssh oswold@192.168.1.200
sudo mkdir -p /opt/uptime-kuma/data
cd /opt/uptime-kuma
cat > docker-compose.yml <<'YAML'
services:
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
restart: unless-stopped
ports:
- "3001:3001"
volumes:
- ./data:/app/data
YAML
sudo docker compose up -d
sudo docker logs uptime-kuma --tail 20
Через nginx на VPS (или напрямую 192.168.1.200:3001 из LAN): - Добавь мониторы: - HTTPS https://vault.alatyr-service.ru — 200 OK - HTTPS https://rag.alatyr-service.ru — 200 OK - HTTPS https://alatyr-service.ru — 200 OK - HTTPS https://alatyr-taverna.ru — 200 OK - Ping 46.17.99.183 - Уведомления: Telegram-бот или email
После завершения: пришли скриншот дашборда или список мониторов.
B19. Open WebUI API наружу для Perplexity¶
Задача 36 в TODO. Хост: VPS + ragserver + локально.
Большая задача, разбита на подшаги:
B19.1 — проверить что rag.alatyr-service.ru отдаёт Open WebUI:
B19.2 — создать пользователя perplexity-agent в Open WebUI:
- Открой https://rag.alatyr-service.ru → Settings → Users → Add
- Сгенерируй API key в его профиле
B19.3 — тест API:
TOKEN="<новый ключ, в чат не вставлять>"
curl -s -H "Authorization: Bearer $TOKEN" https://rag.alatyr-service.ru/api/v1/chats/ | head -20
B19.4 — fail2ban jail для этого endpoint (нужно защитить ключ от brute-force):
- Добавь в nginx access_log паттерн запросов /api/
- Создай jail в /etc/fail2ban/jail.local (проксируем через VPS)
B19.5 — сохранить ключ:
- В Vaultwarden как OPEN_WEBUI_PERPLEXITY_TOKEN
- В Perplexity через custom-credentials (skill custom-credentials)
B19.6 — тест из Perplexity: - В новой сессии попроси: "через RAG rag.alatyr-service.ru найди что было про DPI Инетком" - Должен ответить содержимым vaultwarden.md
После завершения: "B19 done" + скажи какой сессии этот доступ уже пригодился.
Что делать когда всё выполнено¶
- Обновить TODO — все закрытые задачи помечены ✅
- Обновить changelog в конце TODO
- Обновить прогресс-счётчик (было 9/43, станет ~28/43)
- Финальный коммит
Пакет B выполнен через SSH: <список задач>
Что мне присылать после каждой задачи¶
- Формат:
B<N> done+ вывод команд без секретов - Секреты (новые ключи, пароли): только "готово, положил в Vaultwarden запись
<название>" - Ошибки: полный текст ошибки — я разберу и дам исправление
Составлено агентом 06.08.2026 для сессии по Alatyr Infrastructure.