Перейти к содержанию

agent-ssh-deploy — агент деплоит сам: SSH-доступ для ИИ-агента

Лайфхак: как настроить удалённую машину так, чтобы CLI-агент (Claude Code и подобные) мог сам заходить на неё по SSH, деплоить и проверять результат — а ты только смотрел и подтверждал.

Обычный путь: агент написал код → ты руками копируешь на сервер, запускаешь, смотришь логи. Скучно и легко ошибиться.

Правильный путь: дать агенту ключ от сервера, и тогда весь цикл «залей → запусти → проверь → почини» он делает сам, а ты видишь каждый шаг и подтверждаешь опасные.

Как это выглядит:

  1. На сервере заводится отдельный пользователь (у нас — agent).
  2. Для него делается SSH-ключ — файл-«отпечаток пальца» вместо пароля.
  3. Агенту в проекте говоришь: «сервер такой-то, пользователь такой-то» — и он сам делает ssh, scp, docker compose up.

Правила безопасности — те же, что для людей, только строже:

  • Ключ не кладём в git и не показываем в чатах.
  • Агент спрашивает подтверждение перед командами, которые меняют сервер.
  • Каждое изменение сервера записываем в журнал: что сделали, как откатить.

1. Пользователь и ключ

```bash

локально: отдельный ключ под этот сервер

ssh-keygen -t ed25519 -f ~/.ssh/vps_agent -C "agent@"

на сервере (один раз, под root):

useradd -m -s /bin/bash agent mkdir -p /home/agent/.ssh cat vps_agent.pub >> /home/agent/.ssh/authorized_keys chmod 700 /home/agent/.ssh && chmod 600 /home/agent/.ssh/authorized_keys chown -R agent:agent /home/agent/.ssh echo 'agent ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/agent # dev-сервер; для prod — allow-list конкретных команд ```

В sshd_config: PasswordAuthentication no, PermitRootLogin prohibit-password.

Приватный ключ живёт на твоей машине с правами 600 — в ~/.ssh/, не в папке проекта (а если очень надо рядом с проектом — строго под .gitignore). Главное — чтобы он физически не мог уехать в git.

2. Рассказать агенту про сервер

В инструкцию проекта (CLAUDE.md / AGENTS.md) — короткий блок:

```markdown

Деплой

Сервер: , пользователь agent, ключ ~/.ssh/vps_agent. Сервисы — в /srv//, каждый со своим docker-compose.yml. Деплой: rsync репо → docker compose up -d --build. После деплоя проверить curl -sSI http://<IP>/ и логи контейнера. Изменения сервера фиксировать в журнале. ```

Этого достаточно: дальше агент сам строит команды ssh agent@<IP> '...', rsync, docker compose ... и читает их вывод как обычный тул-результат.

3. Цикл деплоя руками агента

flowchart TB
    A["🤖 Агент на твоей машине"] -->|"rsync / scp"| S["Сервер"]
    A -->|"ssh: docker compose up -d --build"| S
    S -->|"вывод: логи, статусы"| A
    A -->|"curl http://server/ — проверка снаружи"| S
    A --> R["Отчёт: задеплоено, healthcheck зелёный"]

Такой «ручной» SSH-цикл — первый шаг. Следующий уровень — CI/CD: агент пушит в git, а сборку и выкладку делает пайплайн (так деплоится этот портал — в кластер через Gitea CI, см. site/README.md в репо). Но паттерн «агент сам заходит по SSH» остаётся нужным для отладки, серверов без CI и разовых задач.

4. Ограничители

  • Режим подтверждений. Деструктивные команды (rm, docker volume rm, правки sshd_config) — только с ручным подтверждением; ssh+read-only и rsync можно разрешить.
  • Журнал изменений. Агент после каждого изменения сервера дописывает запись: дата, что сделал, как откатить. Формат: YYYY-MM-DD — <что>: <детали> · откат: <как>.
  • Идемпотентный bootstrap. Настройку сервера держать одним скриптом, который можно гонять повторно — тогда «починить сервер» = «прогнать скрипт».

5. Если доступ сломали (агент тоже так умеет)

Классика: выключили PasswordAuthentication, а ключ не лёг. Спасение — VNC/Serial-консоль в панели хостера: это терминал мимо SSH. Заходишь под root с паролем хостера, временно включаешь PasswordAuthentication yes, кладёшь ключ, выключаешь обратно. Если консоли нет — тикет в саппорт хостера («включите password auth» / «rescue mode»).

Связанные страницы

  • why-server.md — зачем вообще сервер
  • install-agents.md — какие агенты бывают и как их поставить
  • agents.md — как агент устроен внутри