SSD Nodes Learn 🎉 VPS от $4.99/мес
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-08-07

Claude для системного администратора: 6 полезных задач

Узнайте, как использовать Claude для анализа логов, создания systemd юнитов и проверки конфигураций nginx. Разберем безопасные сценарии работы и данные, которые нельзя передавать.

Claude для системных администраторов: сначала совет, потом выполнение

Claude для системных администраторов эффективнее всего работает в роли рецензента. Вы вставляете фрагмент лога, конфигурационный файл, незнакомую команду или строку ошибки и получаете объяснение, которое можно проверить перед внесением изменений на сервере. Неверный ответ не несет рисков, пока вы не выполнили его, поэтому удержание модели в рамках консультативной роли является основой безопасности.

На арендованном Linux VPS (виртуальном выделенном сервере) еженедельно возникают шесть типичных задач. Для каждой из них ниже приведен шаблон промпта, команда для проверки ответа и возможный режим сбоя. Ни одна из этих задач не требует предоставления модели доступа к вашему серверу.

На продуктивном сервере важен порядок действий: прочитайте объяснение, выполните проверку самостоятельно, затем принимайте решение. Автономность допустима на тестовой виртуальной машине. На сервере, обслуживающем клиентов, приоритет за рецензированием, так как модель не видит состояние системы, о котором делает предположения.

Что никогда нельзя вставлять в запрос

Всё, что вы отправляете в запросе, покидает ваш сервер. Четыре категории данных должны оставаться на машине:

  • Приватные ключи: ~/.ssh/id_ed25519, /etc/ssh/ssh_host_*_key и любые ключи TLS (transport layer security) в /etc/letsencrypt/live/.
  • Файлы с учётными данными: .env, ~/.aws/credentials, /root/.docker/config.json, а также пароли от баз данных в любых файлах или строках логов.
  • Данные учётных записей: /etc/shadow и /etc/gshadow. Ни один вопрос по администрированию не требует передачи хеша пароля для получения ответа.
  • Любая информация, принадлежащая вашим пользователям: адреса электронной почты, строки заказов, логи запросов, содержащие сессионные cookie или PII (персонально идентифицируемую информацию).

Публичные ключи можно безопасно вставлять в запрос. Приватные ключи — нельзя. Эти два типа файлов визуально похожи, поэтому перед копированием проверяйте первую строку: файл, в первой строке которого содержится BEGIN OPENSSH PRIVATE KEY, никогда не должен попадать в запрос. Статья Как не запутаться в ключах SSH стоит того, чтобы потратить на неё десять минут.

Выполняйте очистку данных перед вставкой, вместо того чтобы надеяться заметить один секретный токен среди 200 строк:

sudo journalctl -u myapp -n 200 --no-pager | sed -E 's/(token|secret|password|api[_-]?key)[=:][^[:space:]]+/\1=REDACTED/gI'

Одна ловушка специфична для Docker. docker compose config подставляет значения ваших .env в выводимый текст, поэтому этот вывод становится секретным, даже если исходный файл на диске таковым не был. Используйте docker compose config -q, который выполняет проверку, но ничего не выводит. Общие правила о том, к чему агент имеет доступ, описаны в разделе Как защитить секреты от AI-агентов.

Задача 1: почему этот сервис завершился с ошибкой?

Начните с двух команд, которые содержат ответ:

systemctl status myapp.service --no-pager
sudo journalctl -u myapp.service -b -n 100 --no-pager -o short-iso

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

Ubuntu 24.04. myapp.service работал нормально, пока я не отредактировал юнит час назад. Вот systemctl status и последние 100 строк журнала. Какая строка является первой реальной ошибкой и что она означает? Исправлений пока не вносил.

Фраза "исправлений пока не вносил" выполняет важную работу в этом запросе. Журналы скрывают первоначальную ошибку под слоем повторных попыток запуска, которые она вызвала, поэтому модель, которую просят сразу дать решение, будет объяснять последнюю увиденную строку. Нужная строка обычно находится на двадцать строк выше этого шума.

Результатом будет строка вида Main PID: 1841 (code=exited, status=203/EXEC). Код завершения 203/EXEC означает, что ядро не смогло выполнить файл, указанный в ExecStart: либо путь не существует, либо файл существует, но не имеет прав на выполнение. Строка #!, указывающая на интерпретатор, который не установлен, дает такой же статус. Все это проверяется с помощью ls -l и head -1.

Режим сбоя: выдуманная причина. Если вставить слишком мало данных, модель заполнит пробел чем-то общим, например: "порт уже занят". Лекарство — один встречный вопрос: "какая строка в предоставленном мной тексте подтверждает это?". Причина, на которую никто не может указать в тексте, — это догадка.

Задача 2: создание unit-файла systemd или записи cron

Укажите параметры, необходимые для unit-файла: точную команду, пользователя, от имени которого выполняется процесс, рабочую директорию, необходимость ожидания сети и действия при завершении процесса с ненулевым кодом. Затем проверьте результат перед тем, как активировать что-либо.

sudo systemd-analyze verify /etc/systemd/system/myapp.service
sudo systemctl daemon-reload
sudo systemctl start myapp.service
systemctl status myapp.service --no-pager

systemd-analyze verify анализирует файл так же, как это делает systemd, поэтому он обнаруживает ошибки, которые можно пропустить при визуальном осмотре. Опечатка в директиве выводит /etc/systemd/system/myapp.service:7: Unknown key name 'Enviroment' in section 'Service', ignoring.. Отсутствующий исполняемый файл выводит Command /usr/local/bin/myapp is not executable: No such file or directory. Оба случая остаются незамеченными при daemon-reload, из-за чего unit может успешно загрузиться, но завершиться с ошибкой в момент запуска.

Две ошибки при составлении встречаются постоянно. Первая — After=network.target, что означает лишь готовность сетевого стека, но не наличие IP-адреса. Сервис, который привязывается к конкретному IP, при загрузке выдает ошибку bind: Cannot assign requested address; решение заключается в использовании Wants=network-online.target совместно с After=network-online.target. Вторая ошибка — Type=simple для программы, которая сама переходит в режим демона: systemd считает первый процесс основным, родительский процесс сразу завершается, и unit помечается как неактивный, хотя реальный процесс продолжает работать без управления.

Для планировщика проверьте задачу, вместо того чтобы просто читать её:

systemd-analyze calendar 'Mon *-*-* 04:00:00'

Эта команда выводит нормализованный вид и время следующего запуска, что исключает любые споры о трактовке выражения. Если вы выбираете между таймером и crontab, systemd services and timers on a VPS поможет оценить преимущества и недостатки.

У Cron есть ловушка, о которой не предупредит ни одна модель, если вы не спросите. Cron выполняет задачи в минимальном окружении, поэтому PATH примерно соответствует /usr/bin:/bin, а ваш профиль оболочки не считывается. Задача, которая работает при вставке в терминал, завершается в cron с ошибкой /bin/sh: 1: docker: not found, так как исполняемый файл находится в /usr/local/bin. Используйте абсолютные пути в crontab.

Задача 3: проверка файла nginx или Compose перед запуском в эксплуатацию

Эта задача дает наибольшую отдачу. Вставьте содержимое файла, опишите, что он должен делать, и попросите построчный разбор того, что он делает на самом деле.

Этот vhost должен обслуживать example.com по HTTPS и проксировать /api на локальный сервис на порту 8080. Прочитайте его и укажите на всё, что не соответствует этому описанию.

Затем запустите инструмент, который проверяет синтаксис:

sudo nginx -t
docker compose config -q

nginx -t выводит nginx: configuration file /etc/nginx/nginx.conf test is successful или указывает имя файла и строку, как в nginx: [emerg] unknown directive "proxy_pas" in /etc/nginx/conf.d/app.conf:12. docker compose config -q ничего не выводит, если файл прошел проверку, и выдает краткое сообщение вроде yaml: line 7: did not find expected key, если у вас нарушены отступы.

Ни один из инструментов не проверяет логику. Конфигурация, прошедшая nginx -t, всё равно может проксировать трафик не на тот порт или слушать 0.0.0.0, когда вы имели в виду 127.0.0.1. Именно здесь модель оправдывает свое применение, но здесь же она и ошибается: при просьбе исправить одну директиву она часто возвращает весь файл целиком, в котором незаметно пропадают две ваши директивы. Просите только измененные строки и обоснование для каждой из них, а затем вносите правки вручную.

Подтвердите, что именно вы открыли для доступа:

sudo ss -tulpn

Без sudo вы увидите слушающие сокеты, но не процессы, которым они принадлежат. Если этот вывод вас удивил, что такое порты и как Linux их привязывает — это материал для быстрого чтения.

Задача 4: разберите незнакомую команду перед запуском

Вставьте команду и задайте четыре вопроса: за что отвечает каждый флаг, что именно она записывает, что она удаляет и что произойдет при повторном запуске. Последний вопрос помогает предотвратить больше повреждений, чем остальные.

Возьмем find /var/log -name '*.gz' -mtime +7 -delete. Хороший ответ пояснит, что -mtime +7 учитывает полные 24-часовые периоды и отбрасывает дробную часть, поэтому команда найдет файлы возрастом не менее восьми дней, а не семи. Также он укажет, что find вычисляет выражение слева направо, поэтому перемещение -delete перед -name приведет к удалению всего содержимого в начальном пути. Этот нюанс описан в man-странице find как предупреждение, и он уже стоил многим пользователям их /var/log.

Или возьмем rsync -a --delete /srv/app/ /backup/app/. Завершающий слэш в пути источника означает «содержимое этой директории». Уберите его, и вы получите /backup/app/app/. Добавьте --delete, и всё, чего нет в источнике, будет удалено в месте назначения — это правильно для зеркалирования, но катастрофично, если путь источника указан неверно.

Проверяйте информацию с помощью инструмента, а не модели:

rsync -a --delete --dry-run /srv/app/ /backup/app/ | head -20
find /var/log -name '*.gz' -mtime +7

Запустите find без -delete, и вы получите список вместо потери данных.

Режим отказа: галлюцинации с флагами. Модель надежна в работе с инструментами, имеющими тридцатилетнюю документацию, но значительно слабее в работе с CLI (интерфейсами командной строки) вендоров и новыми подкомандами, где она может сгенерировать флаг, который звучит логично, но не существует. --help проясняет ситуацию за секунду. Экранирование — еще одно слабое место, поэтому, когда команда оборачивает выражение $(...), ознакомьтесь с тем, как подстановка команд раскрывается до запуска команды, вместо того чтобы доверять объяснению.

Задача 5: превратите историю команд оболочки в руководство по эксплуатации

Вы только что потратили два часа на то, чтобы заставить систему работать. Эти знания остались в буфере прокрутки терминала и будут забыты уже через месяц.

history 200 > /tmp/session.txt

Прочитайте этот файл и удалите каждую строку, содержащую пароль, токен или идентификатор клиента, прежде чем куда-либо его передавать. История команд оболочки — одно из самых надежных мест для поиска секретов на сервере Linux, так как каждый хотя бы раз вводил их прямо в командной строке. Установите HISTCONTROL=ignorespace в вашем ~/.bashrc, и команда, введенная с пробелом в начале, не будет записана в историю вовсе.

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

Это сессия оболочки, в ходе которой чистая система Debian 13 была подготовлена к работе с установленным Postgres. Составь на ее основе нумерованное руководство по эксплуатации. Один шаг — одна команда. После каждого шага укажи команду, которая подтверждает успех выполнения, и опиши, как выглядит корректный вывод. Отметь любой шаг, который зависел от особенностей моего хоста.

Типичная ошибка: создание «причесанного» повествования. В вашей сессии наверняка был шаг, который вы выполнили неверно дважды, прежде чем исправить, — именно этот шаг модель может сгладить, так как транскрипт выглядит чище без него. Сравните руководство с вашей историей команд и верните исправление на место. Модель также может выдумать правдоподобные команды для проверки, поэтому запускайте каждую из них, прежде чем сохранять файл. Если руководство описывает первичную настройку системы, сверьте его с первыми десятью минутами на новом VPS, чтобы не создавать худшую версию уже решенной задачи.

Задача 6: превращение сообщения об ошибке в решение

Вставьте точную строку ошибки, команду, которая её вызвала, и одно изменение, которое вы внесли перед её появлением. Запросите ранжирование причин с проверочной командой для каждой из них, чтобы ответ был проверяемым.

nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use). Проранжируйте вероятные причины и предоставьте по одной команде для каждой причины, которая подтверждает или опровергает её.

Для этой ошибки механизм однозначен: другой процесс уже занимает порт 80, и sudo ss -tulpn | grep ':80 ' указывает на него. Часто это второй мастер-процесс nginx, оставшийся после неудачной перезагрузки, или Apache, установленный как зависимость и запущенный собственным пакетом.

Режим сбоя: решение, которое работает, скрывая причину. chmod 777, --privileged, отключение SELinux и запуск службы от имени root — всё это заставляет ошибку исчезнуть. Отклоняйте любое решение, расширяющее права доступа, пока модель не объяснит, почему ограниченные права привели к сбою. Это объяснение и есть настоящий ответ. Обходное решение лишь делает ошибку невидимой.

Типичные ошибки и ограничения

  • Модель не имеет доступа к вашему серверу. Ответ зависит исключительно от предоставленного вами фрагмента текста, и модель не сообщит, если этого фрагмента было недостаточно.
  • Модель может ошибаться в версиях. Имена пакетов и стандартные флаги меняются в зависимости от дистрибутива и релиза, а модель выдает усредненные данные по всем версиям.
  • Модель звучит убедительно, даже когда ошибается. Выдуманный механизм работы выглядит так же достоверно, как и настоящий, поэтому каждая причина выше сопровождается командой для проверки.
  • В длинных сессиях модель теряет нить обсуждения. Факты, упомянутые в начале двухчасового разговора, перестают влиять на ответы в конце.

Последний пункт — это скорее проблема организации работы, чем самой модели. Управление контекстом в долгой сессии Claude Code — практическое решение: разбивайте работу на короткие сессии, по одной задаче на каждую.

Размещение агента непосредственно на сервере

Все описанное выше выполняется методом копирования и вставки, поэтому модель не имеет прямого доступа к вашей машине. Как только агент начинает работать на сервере, читая файлы и выполняя команды, характер рисков меняется: ошибочная команда может привести к сбою сервиса. Создайте для него отдельного непривилегированного пользователя вместо root, не запускайте его на продуктивном сервере, пока не изучите его поведение, и сначала сделайте снимок системы (snapshot). В Безопасный запуск Claude Code на VPS рассматриваются вопросы песочницы и модели прав доступа. Использование Claude Code внутри tmux решает вторую часть проблемы, так как разрыв SSH-сессии прерывает работу агента, запущенного в foreground. Создайте учетную запись так же, как вы создаете любую сервисную учетную запись, что подробно описано в Пользователи с минимальными привилегиями на VPS.

FAQ

Может ли Claude читать логи моего сервера напрямую?

Нет, самостоятельно не может. Интерфейс чата видит только тот текст, который вы в него вставили. Claude Code, запущенный на сервере как инструмент командной строки, может читать файлы и выполнять команды с правами пользователя, который его запустил, что требует более высокого уровня доверия. Для обычного вопроса по поддержке вставка отредактированного фрагмента на 100 строк быстрее и безопаснее, чем предоставление агенту доступа к оболочке.

Что никогда не следует копировать с сервера?

Приватные ключи, файлы .env и другие хранилища учетных данных, /etc/shadow, а также любые данные, принадлежащие вашим пользователям. Удаляйте токены из фрагментов логов перед тем, как они попадут в запрос. Один неочевидный случай: вывод docker compose config содержит интерполированные значения ваших .env, поэтому используйте docker compose config -q, который проверяет файл и ничего не выводит.

Безопасно ли позволять Claude выполнять команды на рабочем VPS?

Относитесь к нему как к новому администратору без контекста: чтение допустимо, запись требует проверки. На рабочем сервере запросите объяснение и выполните команду самостоятельно. Если вы хотите, чтобы агент выполнял действия, предоставьте ему отдельную учетную запись с ограниченными правами без полного доступа sudo и начните со стенда для тестирования, где ошибка приведет к пересборке, а не к простою.

Почему Claude предлагает флаг, которого не существует?

Потому что он предсказывает правдоподобный текст, а правдоподобный флаг выглядит так же, как настоящий. Это чаще всего случается с CLI от поставщиков и новыми подкомандами, где документация, на которой обучалась модель, скудна или с тех пор изменилась. --help и man являются окончательными источниками истины, и любая команда, которая удаляет или перезаписывает данные, заслуживает предварительного тестового запуска.

Как проверить юнит systemd перед тем, как его включить?

Выполните sudo systemd-analyze verify /etc/systemd/system/myapp.service. Он анализирует файл с помощью собственного парсера systemd, сообщает о неизвестных директивах с указанием номеров строк и отмечает бинарный файл ExecStart, который отсутствует или не является исполняемым. Затем выполните daemon-reload, start и прочитайте systemctl status перед тем, как выполнить enable, так как юнит, который корректно загружается, всё равно может завершиться ошибкой при первом запуске.