Sistem yöneticileri için Claude kullanımı ve ipuçları
Sistem yöneticileri için Claude ile günlük analizi, systemd birimi oluşturma ve Nginx yapılandırma incelemesi gibi altı temel görevi güvenli şekilde yönetmeyi öğrenin.
Sistem yöneticileri için Claude: önce tavsiye, sonra uygulama
Sistem yöneticileri için Claude, en iyi bir gözden geçirme aracı olarak çalışır. Bir günlük kaydı kesiti, yapılandırma dosyası, tanımadığınız bir komut veya hata dizisi paylaştığınızda, sunucuda herhangi bir değişiklik yapmadan önce doğrulayabileceğiniz bir açıklama alırsınız. Yanlış bir yanıt, siz onu çalıştırmadığınız sürece size bir maliyet çıkarmaz; bu nedenle modeli bu güvenlik çizgisinin tavsiye tarafında tutmak, tüm güvenlik modelini oluşturur.
Kiralık bir Linux VPS (sanal özel sunucu) üzerinde her hafta altı tür iş ortaya çıkar. Aşağıdakilerin her biri, çalışan bir istem kalıbına, yanıtı kanıtlayan komuta ve beklemeniz gereken hata moduna sahiptir. Bunların hiçbiri, modelin sunucunuza erişmesini gerektirmez.
Üretim ortamındaki bir sunucuda sıra önemlidir: açıklamayı okuyun, kontrolü kendiniz yapın ve ardından karar verin. Deneme amaçlı bir sanal makinede özerklik sorun yaratmaz. Müşterilerinize hizmet veren bir sunucuda ise gözden geçirme önceliklidir; çünkü model, hakkında tahminde bulunduğu sunucu durumunu göremez.
Asla yapıştırmamanız gerekenler
İstemciye gönderdiğiniz her şey sunucunuzdan çıkar. Dört kategorideki veriler sunucuda kalmalıdır:
- Özel anahtarlar:
~/.ssh/id_ed25519,/etc/ssh/ssh_host_*_keyve/etc/letsencrypt/live/altındaki tüm TLS (transport layer security) anahtarları. - Kimlik bilgisi dosyaları:
.env,~/.aws/credentials,/root/.docker/config.jsonve herhangi bir dosya veya günlük satırındaki veritabanı parolaları. - Hesap verileri:
/etc/shadowve/etc/gshadow. Hiçbir sistem yöneticisi sorusu, yanıtlanmak için parola özeti (hash) gerektirmez. - Kullanıcılarınıza ait her şey: e-posta adresleri, sipariş satırları, oturum çerezleri veya PII (kişisel olarak tanımlanabilir bilgiler) içeren istek günlükleri.
Açık anahtarların yapıştırılmasında bir sakınca yoktur. Özel anahtarlar ise paylaşılmamalıdır; iki dosya türü ilk bakışta birbirine benzer, bu yüzden kopyalamadan önce ilk satırı okuyun: ilk satırı BEGIN OPENSSH PRIVATE KEY içeren bir dosya asla bir isteme yapıştırılmamalıdır. SSH anahtar materyalinizi düzenli tutmak başlı başına on dakikanızı ayırmaya değer bir konudur.
200 satırlık bir metin içinde tek bir belirteci fark etmeye çalışmak yerine, yapıştırmadan önce sansürleme yapın:
sudo journalctl -u myapp -n 200 --no-pager | sed -E 's/(token|secret|password|api[_-]?key)[=:][^[:space:]]+/\1=REDACTED/gI'Docker ile ilgili özel bir tuzak mevcuttur. docker compose config, .env değerlerinizi yazdırdığı çıktıya dahil eder; bu nedenle diskteki dosya gizli olmasa bile çıktı gizli hale gelir. Doğrulama yapan ve hiçbir şey yazdırmayan docker compose config -q komutunu kullanın. Bir yapay zeka aracının neleri görmesine izin verildiğine dair daha geniş kapsamlı politika için sırları yapay zeka araçlarından uzak tutmak bölümü ortam tarafındaki gereksinimleri ele almaktadır.
İş 1: Bu servis neden başarısız oldu?
Cevabı barındıran iki komutla başlayın:
systemctl status myapp.service --no-pager
sudo journalctl -u myapp.service -b -n 100 --no-pager -o short-isoHer ikisini de, modelin tahmin edemeyeceği bağlamla birlikte yapıştırın: dağıtım ve sürüm, en son neyi değiştirdiğiniz, daha önce çalışıp çalışmadığı ve ne kadar süre önce bozulduğu. Önce mekanizmayı sorun.
Ubuntu 24.04.myapp.service, bir saat önce unit dosyasını düzenleyene kadar sorunsuz çalışıyordu. İştesystemctl statusve son 100 günlük kaydı satırı. İlk gerçek hata satırı hangisi ve ne anlama geliyor? Henüz bir düzeltme yapmadım.
"Henüz bir düzeltme yapmadım" ifadesi, bu komutta kritik bir işlev görür. Günlük kayıtları, ilk hatayı kendi tetiklediği yeniden denemelerin altında gizler; bu nedenle bir düzeltme istenen model, gördüğü son satırı açıklamaya çalışacaktır. Önemli olan satır, genellikle gürültünün yirmi satır üzerindedir.
Bunun karşılığı, Main PID: 1841 (code=exited, status=203/EXEC) gibi bir satırdır. 203/EXEC çıkış durumu, çekirdeğin ExecStart içinde belirtilen dosyayı çalıştıramadığı anlamına gelir: ya yol mevcut değildir ya da dosya mevcuttur ancak çalıştırılabilir değildir. Yüklü olmayan bir yorumlayıcıyı işaret eden bir #! satırı da aynı durumu üretir. Bunların tamamı ls -l ve head -1 ile test edilebilir.
Hata modu: uydurma bir neden. Çok az bilgi yapıştırırsanız model boşluğu "port zaten kullanımda" gibi genel bir ifadeyle doldurur. Bunun çözümü, bir soru geri gitmektir: "Verdiğim metnin hangi satırı bunu destekliyor?" Metinde kimsenin işaret edemediği bir neden, sadece bir tahmindir.
Görev 2: Bir systemd birimi veya cron girdisi tasarlayın
Bir birim dosyasının ihtiyaç duyduğu gerçekleri belirtin: tam komut, çalıştırılacağı kullanıcı, çalışma dizini, ağın beklenip beklenmeyeceği ve sıfır olmayan bir çıkış kodunda ne yapılması gerektiği. Herhangi bir şeyi etkinleştirmeden önce dönen sonucu doğrulayın.
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, dosyayı systemd'nin yaptığı gibi ayrıştırır; bu sayede insan gözünün kaçırdığı hataları yakalar. Yanlış yazılmış bir direktif /etc/systemd/system/myapp.service:7: Unknown key name 'Enviroment' in section 'Service', ignoring. çıktısı verir. Eksik bir binary dosyası Command /usr/local/bin/myapp is not executable: No such file or directory çıktısı verir. Her ikisi de daemon-reload sırasında sessiz kalır; bu yüzden bir birim sorunsuz yüklenebilir ancak çalıştırıldığı anda başarısız olabilir.
İki taslak hatası sürekli olarak tekrarlanır. Birincisi After=network.target kullanımıdır; bu sadece ağ yığınının yapılandırıldığı anlamına gelir, henüz bir adresin var olduğu anlamına gelmez. Belirli bir IP adresine bağlanan bir servis, önyükleme sırasında bind: Cannot assign requested address hatasıyla başarısız olur; çözüm ise Wants=network-online.target ile birlikte After=network-online.target kullanmaktır. İkincisi, daemon haline gelen bir program için Type=simple kullanılmasıdır: systemd ilk süreci servis olarak kabul eder, ana süreç hemen sonlanır ve gerçek süreç yönetilmeksizin çalışmaya devam ederken birim ölü olarak işaretlenir.
Bir zamanlama için, okumak yerine kontrol edin:
systemd-analyze calendar 'Mon *-*-* 04:00:00'Bu komut, normalleştirilmiş biçimi ve ifadenin bir sonraki çalışma zamanını yazdırır; bu da ifadenin ne anlama geldiği konusundaki tüm tartışmaları sonlandırır. Bir timer ile crontab arasında seçim yapıyorsanız, VPS üzerinde systemd servisleri ve timer'lar bu konudaki farkları açıklar.
Cron, siz sormadığınız sürece hiçbir modelin sizi uyarmayacağı bir tuzağa sahiptir. Cron işleri minimal bir ortamla çalıştırır, bu nedenle PATH kabaca /usr/bin:/bin değerindedir ve shell profiliniz asla okunmaz. Terminalinize yapıştırdığınızda çalışan bir iş, cron altında /bin/sh: 1: docker: not found hatasıyla başarısız olur; çünkü o binary dosyası /usr/local/bin içinde yer alır. Crontab dosyalarında mutlak yollar kullanın.
İş 3: Yayına almadan önce bir Nginx veya Compose dosyasını gözden geçirin
Bu iş en yüksek getiriyi sağlar. Dosyayı yapıştırın, ne yapması gerektiğini belirtin ve satır satır gerçekte ne yaptığının açıklanmasını isteyin.
Bu vhost,example.comüzerinden HTTPS sunmalı ve/apitrafiğini 8080 numaralı porttaki yerel bir servise yönlendirmelidir. Bunu bana geri okuyun ve bu tanıma uymayan her şeyi belirtin.
Ardından dilbilgisini bilen aracı çalıştırın:
sudo nginx -t
docker compose config -qnginx -t, nginx: configuration file /etc/nginx/nginx.conf test is successful çıktısını verir veya nginx: [emerg] unknown directive "proxy_pas" in /etc/nginx/conf.d/app.conf:12 örneğinde olduğu gibi dosya adını ve satır numarasını belirtir. docker compose config -q, dosya ayrıştırıldığında hiçbir şey yazdırmaz; girintileme hatası gibi durumlarda ise yaml: line 7: did not find expected key gibi net bir hata verir.
Hiçbir araç amacı kontrol etmez. nginx -t testinden geçen bir yapılandırma, yanlış porta yönlendirme yapabilir veya 127.0.0.1 yerine 0.0.0.0 portunu dinleyebilir. Modelin değerini kanıtladığı yer bu boşluktur; ancak başarısız olduğu yer de burasıdır: tek bir direktifi düzeltmesi istendiğinde, genellikle tüm dosyayı yeniden yazar ve bu sırada iki direktifinizi sessizce kaybedebilir. Değiştirilen satırları ve her birinin nedenini isteyin, ardından düzenlemeyi manuel olarak yapın.
Gerçekte neyi dışarıya açtığınızı doğrulayın:
sudo ss -tulpnsudo olmadan dinleme yapan soketleri görürsünüz ancak bunlara sahip olan süreçleri göremezsiniz. Eğer bu çıktı sizi şaşırtırsa, portların ne olduğu ve Linux'un bunları nasıl bağladığı hakkındaki yazı daha kısa bir okumadır.
İş 4: Bilinmeyen bir komutu çalıştırmadan önce açıklayın
Komutu yapıştırın ve hakkında dört soru sorun: her bir bayrak (flag) ne işe yarar, ne yazar, neyi siler ve iki kez çalıştırırsam ne olur? Son soru, diğerlerinden daha fazla hasarı önler.
find /var/log -name '*.gz' -mtime +7 -delete komutunu ele alalım. İyi bir yanıt, -mtime +7 ifadesinin tam 24 saatlik periyotları saydığını ve kesirli kısımları attığını, dolayısıyla yedi günden ziyade en az sekiz günlük dosyalarla eşleştiğini belirtir. Ayrıca find ifadesinin kendi ifadesini soldan sağa değerlendirdiğini, bu yüzden -delete ifadesini -name ifadesinin önüne almanın başlangıç yolunun altındaki her şeyi sileceğini söyler. Bu ikinci nokta, find kılavuz sayfasında bir uyarı olarak yer alır ve insanların /var/log verilerine mal olmuştur.
Veya rsync -a --delete /srv/app/ /backup/app/ komutunu ele alalım. Kaynak dizinin sonundaki eğik çizgi, "bu dizinin içeriği" anlamına gelir. Çizgiyi kaldırırsanız /backup/app/app/ sonucunu alırsınız. --delete eklerseniz, hedefte olup kaynakta olmayan her şey silinir; bu bir yansıtma (mirror) işlemi için doğrudur ancak kaynak yolu yanlış olduğunda bir felakettir.
Model ile değil, araç ile doğrulayın:
rsync -a --delete --dry-run /srv/app/ /backup/app/ | head -20
find /var/log -name '*.gz' -mtime +7find komutunu -delete olmadan çalıştırırsanız, veri kaybı yerine bir liste elde edersiniz.
Hata modu: bayrak halüsinasyonu. Model, otuz yıllık dokümantasyona sahip araçlarda güvenilirdir; ancak satıcıya özel CLI (komut satırı arayüzleri) ve yeni alt komutlarda çok daha zayıftır; burada kulağa mükemmel gelen ancak var olmayan bir bayrak üretebilir. --help bunu bir saniyede netleştirir. Tırnak işaretleri diğer zayıf noktadır, bu nedenle bir komut bir $(...) ifadesini sarmaladığında, açıklamaya güvenmek yerine komut değiştirmenin komut çalışmadan önce nasıl genişlediği konusunu okuyun.
İş 5: Shell geçmişinizi bir runbook'a dönüştürün
Bir şeyi çalışır hale getirmek için iki saatinizi harcadınız. Bu bilgi terminal geçmişinizde kalır ve gelecek ay silinmiş olacaktır.
history 200 > /tmp/session.txtBu dosyayı okuyun ve herhangi bir yere taşımadan önce parola, token veya müşteri tanımlayıcı içeren her satırı silin. Shell geçmişi, bir Linux sunucusunda gizli bilgileri bulmak için en güvenilir yerlerden biridir; çünkü herkes en az bir kez satır içinde bir parola yazar. ~/.bashrc dosyanızda HISTCONTROL=ignorespace ayarını yapın; böylece başında boşluk olan bir komut geçmişe asla yazılmaz.
Kullanılabilir bir runbook üreten istem, sadece adımları değil, kontrolleri de talep eder:
Bu, temiz bir Debian 13 sunucusunu çalışan bir Postgres kurulumuna getiren bir shell oturumudur. Bunu numaralandırılmış bir runbook olarak yazın. Her adımda tek bir komut olsun. Her adımdan sonra, çalıştığını kanıtlayan komutu verin ve sağlıklı çıktının nasıl göründüğünü açıklayın. Benim özel sunucuma bağlı olan adımları işaretleyin.
Hata modu: düzenli bir hikaye. Oturumunuzda düzeltmeden önce iki kez yanlış yaptığınız bir adım vardı ve model, transkript daha temiz göründüğü için bu adımı yok sayar. Runbook'u geçmişinizle karşılaştırın ve düzeltmeyi geri ekleyin. Ayrıca makul doğrulama komutları da uydurur, bu yüzden dosyayı kaydetmeden önce yazdığı her kontrolü çalıştırın. Eğer runbook ilk kurulumu kapsıyorsa, yeni bir VPS'teki ilk on dakika ile karşılaştırarak okuyun; böylece çözülmüş bir problemin daha kötü bir versiyonunu yazmamış olursunuz.
Görev 6: bir hata mesajını çözüme dönüştürme
Tam hata dizisini, hatayı üreten komutu ve bu hata ortaya çıkmadan önce değiştirdiğiniz tek bir öğeyi yapıştırın. Olası nedenleri sıralamalarını isteyin ve her biri için test edilebilir bir doğrulama komutu talep edin.
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use). Olası nedenleri sıralayın ve her neden için durumu doğrulayan veya eleyen bir komut verin.
Bu hata için mekanizma belirsiz değildir: başka bir süreç halihazırda 80 numaralı portu kullanıyordur ve sudo ss -tulpn | grep ':80 ' bu süreci tanımlar. Genellikle bu durum, başarısız bir yeniden yükleme sonrası arkada kalan ikinci bir nginx ana süreci veya bağımlılık olarak yüklenip kendi kendine başlayan Apache servisinden kaynaklanır.
Hata modu: nedeni gizleyerek çalışan bir düzeltme. chmod 777, --privileged, SELinux'u devre dışı bırakmak ve servisi root yetkileriyle çalıştırmak hatayı görünmez kılar. Model, dar kapsamlı izinlerin neden başarısız olduğunu açıklayana kadar izinleri genişleten hiçbir düzeltmeyi kabul etmeyin. Bu açıklama asıl cevaptır. Geçici bir çözüm (workaround) hatayı yalnızca sessizleştirir.
Neleri hatalı yapar, güvenilir biçimde
- Sunucunuzu göremez. Her yanıt, yapıştırdığınız içeriğin bir fonksiyonudur; alıntının çok kısa olduğunu size söylemeyecektir.
- Sürümler konusunda sapmalar yaşar. Paket isimleri ve varsayılan flag değerleri dağıtımlar ve sürümler arasında değişir; model ise bunların hepsinin ortalamasını alır.
- Hatalı olduğunda bile akıcıdır. Halüsinasyon ürünü bir mekanizma, doğru bir mekanizma ile aynı tonda okunur; yukarıdaki her nedenin bir test komutuyla birlikte sunulmasının sebebi budur.
- Uzun oturumlarda konuyu kaybeder. İki saatlik bir konuşmanın başındaki bilgiler, sonundaki yanıtları şekillendirmeyi bırakır.
Son madde, bir model sorunundan ziyade bir çalışma sorunudur ve uzun bir Claude Code oturumunda bağlam yönetimi, bunun pratik çözümüdür: daha kısa oturumlar, her biri için tek bir görev.
Ajanı doğrudan sunucuya yerleştirme
Yukarıdaki her şey kopyala-yapıştır yöntemine dayalıdır, bu nedenle model makinenize hiçbir şekilde erişmez. Ajan sunucu üzerinde çalışmaya başladığında, dosyaları okuyup komutları yürüttüğünde riskin boyutu değişir: hatalı bir komut artık bir servisin durmasına neden olabilir. Ajanı root yerine yetkisiz (unprivileged) bir kullanıcı ile çalıştırın, alışkanlıklarını öğrenene kadar üretim (production) sunucusundan uzak tutun ve öncesinde bir snapshot alın. Claude Code'u bir VPS üzerinde güvenli çalıştırma rehberi, sandbox ve izin modelini ele almaktadır. Claude Code'u tmux içinde kullanma, SSH (secure shell) oturumunun kopması durumunda ön planda çalışan ajanın işinin yarım kalması sorununu çözdüğü için denklemin diğer yarısını tamamlar. Hesap yapılandırmasını, VPS üzerinde en az yetkili kullanıcılar rehberinde belirtildiği gibi, herhangi bir servis hesabı oluşturur gibi yapın.
FAQ
Claude sunucu günlüklerimi doğrudan okuyabilir mi?
Hayır, doğrudan okuyamaz. Sohbet arayüzü yalnızca içine yapıştırdığınız metni görür. Sunucuda bir komut satırı aracı olarak çalıştırılan Claude Code, dosyaları okuyabilir ve başlatıldığı kullanıcının izinleriyle komutlar çalıştırabilir; bu daha büyük bir güven kararı gerektirir. Sıradan bir destek sorusu için, sansürlenmiş 100 satırlık bir alıntıyı yapıştırmak, bir araca kabuk erişimi vermekten daha hızlı ve güvenlidir.
Bir sunucudan asla neyi yapıştırmamalıyım?
Özel anahtarlar, .env dosyaları ve diğer kimlik bilgisi depoları, /etc/shadow ve kullanıcılarınıza ait her türlü veri. Günlük alıntılarındaki belirteçleri (token) isteme ulaşmadan önce sansürleyin. Belirgin olmayan bir durum: docker compose config çıktısı, .env değerlerinizi içine yerleştirilmiş olarak içerir; bu nedenle dosyayı doğrulayan ve hiçbir şey yazdırmayan docker compose config -q komutunu kullanın.
Claude'un bir üretim (production) VPS'inde komut çalıştırmasına izin vermek güvenli mi?
Buna bağlamı olmayan yeni bir yönetici gibi davranın: okuma işlemleri için uygundur, yazma işlemleri için inceleme gerekir. Üretim ortamında, açıklamayı isteyin ve komutu kendiniz çalıştırın. Eğer bir aracın komut yürütmesini istiyorsanız, ona sınırsız sudo yetkisi olmayan özel ve düşük ayrıcalıklı bir hesap verin; ayrıca bir hatanın kesinti yerine yeniden kurulum gerektireceği bir hazırlık (staging) ortamında başlayın.
Claude neden var olmayan bir bayrak (flag) öneriyor?
Çünkü makul görünen metinleri tahmin eder ve makul bir bayrak, gerçek bir bayrakla aynı görünür. Bu durum en çok, modelin arkasındaki dokümantasyonun zayıf olduğu veya o zamandan beri değiştiği satıcı CLI araçlarında ve yeni alt komutlarda gerçekleşir. --help ve man nihai karar vericidir; silme veya üzerine yazma yapan her komut önce bir deneme çalışmasını (dry run) hak eder.
Bir systemd birimini etkinleştirmeden önce nasıl kontrol ederim?
sudo systemd-analyze verify /etc/systemd/system/myapp.service komutunu çalıştırın. Bu komut, dosyayı systemd'nin kendi ayrıştırıcısı ile inceler, bilinmeyen yönergeleri satır numaralarıyla bildirir ve eksik veya çalıştırılabilir olmayan bir ExecStart ikili dosyasını işaretler. Ardından daemon-reload ve start komutlarını çalıştırın ve enable yapmadan önce systemctl status içeriğini okuyun; çünkü sorunsuz yüklenen bir birim, ilk çalıştırılmasında yine de başarısız olabilir.