Claude w pracy administratora systemu Linux
Poznaj sześć zadań serwerowych, w których Claude wspiera administratora. Dowiedz się, jak analizować logi systemd, sprawdzać pliki nginx oraz czego nigdy nie wklejać do modelu.
Claude dla administratorów systemów: najpierw porada, potem wykonanie
Claude w pracy administratora systemu najlepiej sprawdza się jako recenzent. Wklejasz fragment dziennika, plik konfiguracyjny, nieznane polecenie lub ciąg znaków błędu, a w zamian otrzymujesz wyjaśnienie, które możesz zweryfikować przed wprowadzeniem jakichkolwiek zmian na serwerze. Błędna odpowiedź nie generuje kosztów, dopóki jej nie wykonasz, dlatego utrzymywanie modelu w roli doradczej stanowi fundament bezpieczeństwa.
Każdego tygodnia na wynajętym serwerze Linux VPS (virtual private server) pojawia się sześć typowych zadań. Poniżej przedstawiono wzorce promptów, które działają, polecenia weryfikujące odpowiedź oraz możliwe tryby awarii. Żadne z nich nie wymaga, aby model miał dostęp do Twojego serwera. Możesz wklejać dane z karty przeglądarki lub okna na własnym pulpicie, ponieważ Claude działa natywnie w systemie Linux zarówno jako aplikacja desktopowa, jak i CLI.
Kolejność działań na serwerze produkcyjnym ma znaczenie: przeczytaj wyjaśnienie, samodzielnie uruchom weryfikację, a następnie podejmij decyzję. Autonomia jest dopuszczalna na maszynie wirtualnej przeznaczonej do testów. Na serwerze obsługującym klientów priorytetem jest weryfikacja, ponieważ model nie widzi stanu, którego dotyczy jego analiza.
Czego nigdy nie należy wklejać
Wszystkie dane zawarte w zapytaniu opuszczają serwer. Cztery kategorie informacji muszą pozostać na maszynie:
- Klucze prywatne:
~/.ssh/id_ed25519,/etc/ssh/ssh_host_*_keyoraz każdy klucz TLS (transport layer security) znajdujący się w/etc/letsencrypt/live/. - Pliki z danymi uwierzytelniającymi:
.env,~/.aws/credentials,/root/.docker/config.jsonoraz hasła do baz danych w dowolnym pliku lub wierszu dziennika. - Dane kont:
/etc/shadoworaz/etc/gshadow. Żadne pytanie dotyczące administracji systemem nie wymaga podania skrótu hasła w celu uzyskania odpowiedzi. - Wszelkie dane należące do użytkowników: adresy e-mail, wiersze zamówień, dzienniki żądań zawierające pliki cookie sesji lub PII (dane osobowe umożliwiające identyfikację).
Klucze publiczne można bezpiecznie wklejać. Klucze prywatne nie są bezpieczne, a oba typy plików wyglądają podobnie, dlatego przed skopiowaniem należy sprawdzić pierwszy wiersz: plik, którego pierwszy wiersz zawiera BEGIN OPENSSH PRIVATE KEY, nigdy nie powinien trafić do zapytania. Utrzymywanie porządku w kluczach SSH to temat, któremu warto poświęcić dziesięć minut.
Przed wklejeniem należy zredagować dane, zamiast polegać na własnej zdolności do wyłapania jednego tokena w 200 wierszach:
sudo journalctl -u myapp -n 200 --no-pager | sed -E 's/(token|secret|password|api[_-]?key)[=:][^[:space:]]+/\1=REDACTED/gI'Jedna pułapka dotyczy konkretnie Docker. docker compose config interpoluje wartości .env w generowanym wyjściu, przez co dane wyjściowe stają się poufne, nawet jeśli plik na dysku nimi nie był. Należy używać docker compose config -q, który sprawdza poprawność i nie wyświetla żadnych danych. W kwestii szerszej polityki dotyczącej tego, co agent może zobaczyć, artykuł ochrona sekretów przed agentami AI omawia aspekty środowiskowe.
Zadanie 1: dlaczego ta usługa uległa awarii?
Należy rozpocząć od dwóch poleceń, które zawierają odpowiedź:
systemctl status myapp.service --no-pager
sudo journalctl -u myapp.service -b -n 100 --no-pager -o short-isoNależy wkleić oba polecenia wraz z kontekstem, którego model nie jest w stanie odgadnąć: dystrybucją i wersją, ostatnimi zmianami, informacją czy usługa kiedykolwiek działała oraz jak dawno wystąpiła awaria. W pierwszej kolejności należy zapytać o mechanizm.
Ubuntu 24.04.myapp.servicedziałało poprawnie do momentu edycji jednostki godzinę temu. Otosystemctl statusoraz ostatnie 100 linii dziennika. Która linia jest pierwszym rzeczywistym błędem i co oznacza? Brak poprawek.
Fraza "Brak poprawek" pełni istotną funkcję w tym zapytaniu. Dzienniki ukrywają pierwszą przyczynę awarii pod warstwą ponownych prób uruchomienia. Model poproszony o rozwiązanie problemu wyjaśni ostatnią linię, którą zobaczył. Istotna linia znajduje się zazwyczaj dwadzieścia linii powyżej szumu.
Rezultatem jest linia typu Main PID: 1841 (code=exited, status=203/EXEC). Kod wyjścia 203/EXEC oznacza, że jądro nie mogło wykonać pliku wskazanego w ExecStart: ścieżka nie istnieje lub plik istnieje, ale nie posiada uprawnień do wykonywania. Linia #! wskazująca na niezainstalowany interpreter wywołuje ten sam kod statusu. Wszystko to można zweryfikować za pomocą ls -l oraz head -1.
Tryb awarii: wymyślona przyczyna. Wklejenie zbyt małej ilości danych powoduje, że model uzupełnia lukę ogólnym stwierdzeniem, na przykład "port jest już zajęty". Rozwiązaniem jest pytanie zwrotne: "która linia w dostarczonych przeze mnie danych to potwierdza?". Przyczyna, której nie można wskazać w tekście, jest jedynie domysłem.
Zadanie 2: przygotowanie jednostki systemd lub wpisu cron
Należy określić parametry wymagane przez plik jednostki: dokładne polecenie, użytkownika, w imieniu którego uruchamiany jest proces, katalog roboczy, wymóg oczekiwania na sieć oraz zachowanie w przypadku zakończenia procesu z kodem błędu. Następnie należy zweryfikować poprawność konfiguracji przed jej aktywacją.
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 analizuje plik w sposób identyczny z systemd, dzięki czemu wykrywa błędy, które mogą zostać przeoczone przez człowieka. Błędnie wpisana dyrektywa skutkuje komunikatem /etc/systemd/system/myapp.service:7: Unknown key name 'Enviroment' in section 'Service', ignoring.. Brak pliku wykonywalnego powoduje wyświetlenie Command /usr/local/bin/myapp is not executable: No such file or directory. Oba te błędy nie są zgłaszane podczas daemon-reload, dlatego jednostka może załadować się poprawnie, a mimo to zawieść w momencie uruchomienia.
Dwa błędy podczas tworzenia konfiguracji powtarzają się szczególnie często. Pierwszym jest After=network.target, co oznacza jedynie, że stos sieciowy został skonfigurowany, a nie że adres IP jest już dostępny. Usługa, która wiąże się z konkretnym adresem IP, zawiedzie podczas startu systemu z błędem bind: Cannot assign requested address. Rozwiązaniem jest zastosowanie Wants=network-online.target wraz z After=network-online.target. Drugim błędem jest Type=simple w przypadku programu, który sam przechodzi w tryb demona: systemd traktuje pierwszy proces jako usługę, proces nadrzędny natychmiast kończy działanie, a jednostka zostaje oznaczona jako martwa, podczas gdy właściwy proces działa dalej bez nadzoru. Jest to błąd, który model językowy najprawdopodobniej popełni, ponieważ nie jest w stanie stwierdzić na podstawie samego polecenia, czy plik binarny tworzy procesy potomne (fork). Warto zatem wiedzieć, co każda wartość Type= gwarantuje systemd, zanim zaakceptuje się wygenerowany szkic.
W przypadku harmonogramu zadań należy sprawdzić go zamiast tylko czytać:
systemd-analyze calendar 'Mon *-*-* 04:00:00'Polecenie to wyświetla znormalizowaną formę oraz czas następnego uruchomienia zadania, co rozstrzyga wszelkie wątpliwości dotyczące interpretacji zapisu. Jeśli wybierasz między timerem a crontab, usługi i timery systemd na VPS opisują różnice między tymi rozwiązaniami.
Cron posiada pułapkę, o której żaden model nie ostrzeże, jeśli o to nie zapytasz. Cron uruchamia zadania w minimalnym środowisku, więc PATH to w przybliżeniu /usr/bin:/bin, a profil powłoki użytkownika nigdy nie jest wczytywany. Zadanie, które działa po wklejeniu do terminala, zawiedzie w cronie z błędem /bin/sh: 1: docker: not found, ponieważ dany plik binarny znajduje się w /usr/local/bin. W plikach crontab należy używać ścieżek bezwzględnych. Jeśli konieczność definiowania użytkownika, środowiska i zależności w pliku jednostki wydaje się zbędną formalnością w porównaniu z pojedynczą linią w crontab, problemy, które systemd miał rozwiązać wyjaśniają, skąd wynika ta szczegółowość.
Zadanie 3: weryfikacja pliku nginx lub Compose przed wdrożeniem
To zadanie przynosi najlepsze efekty. Wklej plik, określ jego przeznaczenie i poproś o analizę wiersz po wierszu tego, co faktycznie wykonuje.
Ten vhost powinien obsługiwaćexample.comprzez HTTPS i przekazywać/apido lokalnej usługi na porcie 8080. Przeanalizuj go i wskaż wszystko, co nie jest zgodne z tym opisem.
Następnie uruchom narzędzie sprawdzające składnię:
sudo nginx -t
docker compose config -qnginx -t wyświetla nginx: configuration file /etc/nginx/nginx.conf test is successful lub podaje nazwę pliku i numer linii, tak jak w nginx: [emerg] unknown directive "proxy_pas" in /etc/nginx/conf.d/app.conf:12. docker compose config -q nie wyświetla niczego, gdy plik jest poprawny, lub zwraca lakoniczny komunikat typu yaml: line 7: did not find expected key, gdy wystąpił błąd wcięć.
Żadne z tych narzędzi nie weryfikuje intencji. Konfiguracja, która przechodzi nginx -t, może nadal przekazywać ruch na niewłaściwy port lub nasłuchiwać na 0.0.0.0, podczas gdy zamierzano użyć 127.0.0.1. W tej luce model wykazuje swoją przydatność, ale w niej również zawodzi: poproszony o poprawienie jednej dyrektywy, często zwraca cały plik w nowej wersji, pomijając przy tym dwie inne dyrektywy. Poproś o wskazanie zmienionych linii wraz z uzasadnieniem dla każdej z nich, a następnie wprowadź zmiany ręcznie.
Potwierdź, co faktycznie zostało wystawione:
sudo ss -tulpnBez sudo widoczne są gniazda nasłuchujące, ale nie procesy, które je posiadają. Jeśli ten wynik jest zaskakujący, czym są porty i jak Linux je wiąże jest krótszą lekturą.
Zadanie 4: wyjaśnij nieznane polecenie przed jego uruchomieniem
Wklej polecenie i zadaj cztery pytania na jego temat: co robi każda flaga, co polecenie zapisuje, co usuwa oraz co się stanie, jeśli uruchomisz je dwukrotnie. Ostatnie pytanie pozwala uniknąć większych szkód niż pozostałe.
Weźmy find /var/log -name '*.gz' -mtime +7 -delete. Dobra odpowiedź wyjaśni, że -mtime +7 zlicza pełne okresy 24-godzinne i odrzuca ułamki, więc dopasowuje pliki mające co najmniej osiem dni, a nie siedem. Wyjaśni również, że find oblicza swoje wyrażenie od lewej do prawej, więc przeniesienie -delete przed -name spowoduje usunięcie wszystkiego w ścieżce początkowej. Ten drugi punkt znajduje się w stronie podręcznika systemowego find jako ostrzeżenie i kosztował już wielu użytkowników ich /var/log.
Albo weźmy rsync -a --delete /srv/app/ /backup/app/. Końcowy ukośnik w ścieżce źródłowej oznacza „zawartość tego katalogu”. Usuń go, a otrzymasz /backup/app/app/. Dodaj --delete, a wszystko w miejscu docelowym, czego brakuje w źródle, zostanie usunięte, co jest poprawne dla kopii lustrzanej, ale katastrofalne, gdy ścieżka źródłowa jest błędna.
Weryfikuj za pomocą narzędzia, a nie modelu:
rsync -a --delete --dry-run /srv/app/ /backup/app/ | head -20
find /var/log -name '*.gz' -mtime +7Uruchom find bez -delete, a otrzymasz listę zamiast utraty danych.
Tryb awarii: halucynacje flag. Model jest wiarygodny w przypadku narzędzi z trzydziestoletnią dokumentacją, ale znacznie słabszy w przypadku interfejsów CLI (command line interfaces) producentów i nowych podpoleceń, gdzie generuje flagę, która brzmi idealnie, ale nie istnieje. --help rozstrzyga to w sekundę. Cytowanie to kolejny słaby punkt, więc gdy polecenie zawiera wyrażenie $(...), przeczytaj jak podstawienie polecenia rozwija się przed uruchomieniem komendy, zamiast ufać wyjaśnieniu.
Zadanie 5: przekształć historię powłoki w podręcznik operacyjny
Właśnie poświęciłeś dwie godziny na uruchomienie danego rozwiązania. Ta wiedza znajduje się w buforze przewijania terminala i zniknie w przyszłym miesiącu.
history 200 > /tmp/session.txtOdczytaj ten plik i usuń każdą linię zawierającą hasło, token lub identyfikator klienta, zanim plik zostanie gdziekolwiek przeniesiony. Historia powłoki jest jednym z najbardziej niezawodnych miejsc do znalezienia sekretów na maszynie z systemem Linux, ponieważ każdy przynajmniej raz wpisał je w linii poleceń. Ustaw HISTCONTROL=ignorespace w swoim ~/.bashrc, a polecenie wpisane z poprzedzającą spacją nigdy nie zostanie zapisane w historii.
Prompt, który pozwala uzyskać użyteczny podręcznik operacyjny, wymaga uwzględnienia kontroli, a nie tylko kroków:
To jest sesja powłoki, która doprowadziła świeżą instalację Debian 13 do działającej instancji Postgres. Przygotuj to jako numerowany podręcznik operacyjny. Jedno polecenie na krok. Po każdym kroku podaj polecenie weryfikujące poprawność działania i opisz, jak wygląda prawidłowy wynik. Oznacz każdy krok, który zależał od specyficznych ustawień mojego hosta.
Tryb awarii: uporządkowana historia. Twoja sesja zawierała krok, który wykonałeś błędnie dwa razy przed naprawą, a jest to właśnie ten krok, który model wygładza, ponieważ zapis wygląda czyściej bez niego. Porównaj podręcznik z historią i przywróć poprawki. Model może również wymyślać wiarygodnie brzmiące polecenia weryfikacyjne, dlatego uruchom każdą kontrolę, którą wygeneruje, zanim zapiszesz plik. Jeśli podręcznik dotyczy pierwszego uruchomienia, skonfrontuj go z pierwszymi dziesięcioma minutami na nowym VPS, aby nie tworzyć gorszej wersji już rozwiązanego problemu.
Zadanie 6: przekształcenie komunikatu o błędzie w rozwiązanie
Wklej dokładny ciąg znaków, polecenie, które go wygenerowało, oraz jedną rzecz, którą zmieniłeś przed jego wystąpieniem. Poproś o uszeregowanie przyczyn wraz z poleceniem diagnostycznym dla każdej z nich, co wymusi uzyskanie odpowiedzi możliwej do przetestowania.
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use). Uszereguj prawdopodobne przyczyny i podaj jedno polecenie dla każdej z nich, które potwierdzi lub wykluczy dany scenariusz.
W przypadku tego błędu mechanizm jest jednoznaczny: inny proces już zajmuje port 80, a sudo ss -tulpn | grep ':80 ' wskazuje jego nazwę. Często jest to drugi proces nadrzędny nginx pozostawiony po nieudanym przeładowaniu lub Apache zainstalowany jako zależność i uruchomiony przez własny pakiet.
Tryb awarii: rozwiązanie, które działa poprzez ukrycie przyczyny. chmod 777, --privileged, wyłączenie SELinux oraz uruchamianie usługi jako root sprawiają, że błąd znika. Odrzuć każdą poprawkę, która rozszerza uprawnienia, dopóki model nie wyjaśni, dlaczego ograniczone uprawnienia zawiodły. To wyjaśnienie jest właściwą odpowiedzią. Obejście problemu jedynie wycisza komunikat o błędzie.
Co jest błędnie interpretowane w sposób przewidywalny
- Model nie ma wglądu w serwer. Każda odpowiedź wynika wyłącznie z wklejonych danych i model nie poinformuje, jeśli fragment był zbyt krótki.
- Występują rozbieżności w wersjach. Nazwy pakietów i domyślne flagi zmieniają się między dystrybucjami oraz wydaniami, a model uśrednia informacje z wielu źródeł.
- Model brzmi przekonująco nawet w błędzie. Zmyślony mechanizm brzmi tak samo wiarygodnie jak poprawny, dlatego każda powyższa przyczyna jest opatrzona poleceniem weryfikującym.
- W długich sesjach model traci wątek. Fakty z początku dwugodzinnej konwersacji przestają wpływać na odpowiedzi udzielane pod koniec.
Ostatni punkt jest bardziej problemem operacyjnym niż ograniczeniem modelu, a zarządzanie kontekstem w długiej sesji Claude Code stanowi praktyczne rozwiązanie: krótsze sesje, jedno zadanie na sesję.
Instalacja agenta bezpośrednio na serwerze
Powyższe operacje polegają na kopiowaniu i wklejaniu, dzięki czemu model nie uzyskuje bezpośredniego dostępu do maszyny. Uruchomienie agenta na serwerze, gdzie może on odczytywać pliki i wykonywać polecenia, zmienia profil ryzyka: błędne polecenie może spowodować awarię usługi. Należy utworzyć dla niego osobnego użytkownika bez uprawnień roota, unikać uruchamiania go na serwerach produkcyjnych w fazie testów oraz wykonać snapshot przed rozpoczęciem pracy. Bezpieczne uruchamianie Claude Code na VPS opisuje mechanizmy piaskownicy oraz model uprawnień. Obsługa Claude Code wewnątrz tmux rozwiązuje problem przerywania pracy agenta w przypadku zerwania sesji SSH (secure shell). Konto użytkownika należy skonfigurować zgodnie z zasadami tworzenia kont usługowych, co szczegółowo wyjaśnia artykuł użytkownicy z minimalnymi uprawnieniami na VPS.
FAQ
Czy Claude może bezpośrednio odczytywać logi serwera?
Nie samodzielnie. Interfejs czatu widzi tylko tekst, który zostanie do niego wklejony. Claude Code, uruchomiony na serwerze jako narzędzie wiersza poleceń, może odczytywać pliki i wykonywać polecenia z uprawnieniami użytkownika, który go uruchomił, co wiąże się z większym zakresem zaufania. W przypadku typowych pytań technicznych wklejenie zanonimizowanego fragmentu 100 linii jest szybsze i bezpieczniejsze niż przyznawanie agentowi dostępu do powłoki.
Czego nigdy nie należy wklejać z serwera?
Kluczy prywatnych, plików .env oraz innych magazynów poświadczeń, /etc/shadow, a także wszelkich danych należących do użytkowników. Przed wysłaniem fragmentów logów do promptu należy usunąć z nich tokeny. Jeden mniej oczywisty przypadek: wynik docker compose config zawiera podstawione wartości .env, dlatego należy używać docker compose config -q, które sprawdza poprawność pliku i nie wypisuje żadnych danych.
Czy bezpieczne jest zezwalanie Claude na uruchamianie poleceń na produkcyjnym VPS?
Należy traktować go jak nowego administratora bez kontekstu: odczyt jest bezpieczny, ale zapis wymaga weryfikacji. Na środowisku produkcyjnym należy poprosić o wyjaśnienie i samodzielnie wykonać polecenie. Jeśli wymagane jest wykonywanie poleceń przez agenta, należy przydzielić mu dedykowane konto bez uprawnień sudo i rozpocząć pracę na środowisku testowym (staging), gdzie błąd skutkuje koniecznością przebudowy, a nie awarią usługi.
Dlaczego Claude sugeruje flagę, która nie istnieje?
Ponieważ model przewiduje prawdopodobny tekst, a prawdopodobna flaga wygląda tak samo jak prawdziwa. Zdarza się to najczęściej w przypadku interfejsów CLI dostawców oraz nowszych podpoleceń, dla których dokumentacja modelu jest skąpa lub uległa zmianie. --help oraz man są ostatecznym źródłem prawdy, a każde polecenie usuwające lub nadpisujące dane wymaga wcześniejszego uruchomienia próbnego (dry run).
Jak sprawdzić jednostkę systemd przed jej włączeniem?
Należy wykonać sudo systemd-analyze verify /etc/systemd/system/myapp.service. Narzędzie to analizuje plik za pomocą własnego parsera systemd, zgłasza nieznane dyrektywy wraz z numerami linii oraz wskazuje plik binarny ExecStart, który nie istnieje lub nie posiada uprawnień do wykonywania. Następnie należy wykonać daemon-reload, start i przeczytać systemctl status przed wykonaniem enable, ponieważ jednostka, która ładuje się poprawnie, może mimo to zawieść przy pierwszym uruchomieniu.