Claude для системного администратора: 6 полезных задач
Используйте Claude для анализа логов, написания systemd юнитов и проверки конфигураций nginx. Узнайте, какие данные нельзя передавать модели и как безопасно автоматизировать рутину.
Claude для системных администраторов: сначала совет, потом выполнение
Claude для системных администраторов лучше всего работает в роли рецензента. Вы вставляете фрагмент лога, конфигурационный файл, незнакомую команду или строку ошибки и получаете объяснение, которое можно проверить перед внесением изменений на сервере. Неверный ответ не несет рисков, пока вы его не выполнили, поэтому удержание модели в рамках консультативной роли является основой безопасности.
На арендованном Linux VPS (виртуальном выделенном сервере) еженедельно возникают шесть типов задач. Для каждой из них ниже приведен шаблон промпта, команда для проверки ответа и возможный сценарий сбоя. Ни одна из этих задач не требует предоставления модели доступа к вашему серверу. Вы можете копировать данные из вкладки браузера или окна на своем рабочем столе, так как Claude работает в Linux нативно как в виде настольного приложения, так и в виде CLI.
На продуктовом сервере важен порядок действий: прочитайте объяснение, выполните проверку самостоятельно, затем примите решение. Автономность допустима на тестовой виртуальной машине. На сервере, который обслуживает ваших клиентов, приоритет за рецензированием, так как модель не видит состояние системы, о котором делает предположения.
Что никогда нельзя вставлять в запрос
Всё, что вы вводите в запрос, покидает ваш сервер. Четыре категории данных должны оставаться на машине:
- Приватные ключи:
~/.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-pagersystemd-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 помечается как неактивный, хотя реальный процесс продолжает работать без контроля. Это ошибка, которую модель чаще всего предлагает пользователю, так как она не может определить по команде, делает ли бинарный файл fork. Поэтому стоит изучить что гарантирует каждое значение Type= для systemd, прежде чем принимать черновик.
Для расписания проверьте его, вместо того чтобы просто читать:
systemd-analyze calendar 'Mon *-*-* 04:00:00'Эта команда выводит нормализованную форму и время следующего запуска, что исключает споры о трактовке выражения. Если вы выбираете между таймером и crontab, systemd-сервисы и таймеры на VPS описывают различия.
В cron есть ловушка, о которой не предупредит ни одна модель, если вы не спросите. Cron выполняет задачи в минималистичном окружении, поэтому PATH примерно равно /usr/bin:/bin, а ваш профиль оболочки не считывается. Задача, которая работает при вставке в терминал, завершается в cron с /bin/sh: 1: docker: not found, так как бинарный файл находится в /usr/local/bin. Используйте абсолютные пути в crontab. Если требование unit-файла явно указывать пользователя, окружение и зависимости кажется избыточным по сравнению с одной строкой crontab, проблемы, для решения которых был создан systemd объясняют причины такой детализации.
Задача 3: проверка файла nginx или Compose перед запуском в эксплуатацию
Эта задача дает наибольшую отдачу. Вставьте файл, укажите, что он должен делать, и попросите построчный разбор того, что он делает на самом деле.
Этот vhost должен обслуживатьexample.comпо HTTPS и проксировать/apiна локальный сервис на порту 8080. Прочитайте его и укажите на всё, что не соответствует этому описанию.
Затем запустите инструмент, который знает грамматику:
sudo nginx -t
docker compose config -qnginx -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-сессии (secure shell) прерывает работу агента, запущенного в foreground. Создайте учетную запись так же, как вы создаете любую сервисную учетную запись, что подробно описано в Пользователи с минимальными привилегиями на VPS.
FAQ
Может ли Claude напрямую читать логи моего сервера?
Нет, самостоятельно — нет. Интерфейс чата видит только тот текст, который вы в него вставляете. Claude Code, запущенный на сервере как инструмент командной строки, может читать файлы и выполнять команды с правами пользователя, который его запустил, что требует более высокого уровня доверия. Для обычного вопроса по поддержке вставка отредактированного фрагмента на 100 строк быстрее и безопаснее, чем предоставление агенту доступа к оболочке.
Что никогда не следует копировать с сервера?
Приватные ключи, файлы .env и другие хранилища учетных данных, /etc/shadow, а также любые данные, принадлежащие вашим пользователям. Удаляйте токены из фрагментов логов перед тем, как они попадут в промпт. Один неочевидный случай: вывод docker compose config содержит интерполированные значения ваших .env, поэтому используйте docker compose config -q, который проверяет файл и ничего не выводит.
Безопасно ли позволять Claude выполнять команды на production VPS?
Относитесь к нему как к новому администратору без контекста: чтение допустимо, запись требует проверки. На production запрашивайте объяснение и выполняйте команду самостоятельно. Если вы хотите, чтобы агент выполнял действия, предоставьте ему выделенную непривилегированную учетную запись без полных прав sudo и начните со staging-сервера, где ошибка приведет к пересборке, а не к простою.
Почему Claude предлагает флаг, которого не существует?
Потому что он предсказывает правдоподобный текст, а правдоподобный флаг выглядит так же, как настоящий. Чаще всего это случается с CLI от поставщиков и новыми подкомандами, где документация, на которой обучалась модель, скудна или с тех пор изменилась. --help и man являются последней инстанцией, и любая команда, которая удаляет или перезаписывает данные, заслуживает предварительного тестового запуска.
Как проверить unit-файл systemd перед его включением?
Выполните sudo systemd-analyze verify /etc/systemd/system/myapp.service. Он анализирует файл с помощью собственного парсера systemd, сообщает о неизвестных директивах с указанием номеров строк и отмечает бинарный файл ExecStart, который отсутствует или не является исполняемым. Затем выполните daemon-reload, start и прочитайте systemctl status перед тем, как сделать enable, поскольку unit, который корректно загружается, всё равно может завершиться ошибкой при первом запуске.