İçeriğe geç
KubeAtlas
Linux DevOps SRE CLI Cheat Sheet

En Sık Kullanılan Linux Komutları

Onur Ömer Tunç 17 dk okuma

🔵 Temel Dosya İşlemleri

Temel Dosya İşlemleri

ls -lah — Dizin içeriğini ayrıntılı listele

bash — 80×24
$ ls -lah /var/log/nginx/
total 1.4G
drwxr-xr-x  2 www-data adm       4.0K Jun 29 09:15 .
drwxrwxr-x 16 root     syslog    4.0K Jun 28 00:00 ..
-rw-r--r--  1 www-data adm       1.1G Jun 29 09:15 access.log
-rw-r--r--  1 www-data adm       312M Jun 29 09:15 error.log
-rw-r--r--  1 www-data adm       2.4K Jun 28 23:59 access.log.1

Dizindeki dosyaları izinler, sahip, grup, boyut ve zaman damgasıyla listeler. -l uzun format, -a nokta ile başlayan gizli dosyaları dahil eder, -h boyutları K/M/G olarak gösterir.

Örnek: Production Nginx sunucusunda disk dolmadan önce hangi log dosyasının şiştiğini tespit etmek. access.log 1 GB'ı geçmişse logrotate konfigürasyonunu gözden geçirin.

find — Koşula göre dosya ara

bash — 80×24
$ find /var/log -name "*.log" -mtime -7 -size +100M
/var/log/nginx/access.log
/var/log/postgresql/postgresql-2026-06-29_0000.log

$ find /opt/app -name “.conf” -not -path “/node_modules/*” /opt/app/config/app.conf /opt/app/config/db.conf

Belirtilen dizinden itibaren koşula uyan dosyaları özyinelemeli olarak bulur. -mtime -7 son 7 günde değiştirilenleri, -size +100M 100 MB üzerini, -not -path ise belirli alt dizinleri taramadan atlar.

Örnek: Bir Kubernetes node'unda disk baskısı (DiskPressure) oluştuğunda son 7 günde değiştirilmiş 100 MB üzerindeki log dosyalarını tespit etmek. Ardından truncate -s 0 /path/to/file.log ile servisi yeniden başlatmadan temizleyebilirsiniz.

tail -f — Log akışını gerçek zamanlı takip et

bash — 80×24
$ tail -f /var/log/nginx/access.log | grep -v "health\|readiness"
10.0.1.45 - - [29/Jun/2026:09:22:14 +0000] "POST /api/deploy HTTP/1.1" 200 348
10.0.1.12 - - [29/Jun/2026:09:22:15 +0000] "GET /api/status HTTP/1.1" 503 27
10.0.1.45 - - [29/Jun/2026:09:22:16 +0000] "GET /metrics HTTP/1.1" 200 1842

-f (follow) ile dosyaya yeni satır eklendikçe ekrana yansıtır. grep -v ile health check ve readiness probe satırlarını filtreler — aksi halde Kubernetes’in her 10 saniyede bir probe’u akışı gürültüye boğar.

Örnek: Deployment sonrasında 503 hatalarını anlık izlemek. grep " 503 " ekleyerek yalnızca hata satırlarını, grep -c " 503 " ile saniye başı sayısını görebilirsiniz.

rsync — Dosya ve dizin senkronizasyonu

bash — 80×24
$ rsync -avz --progress --exclude="*.tmp" \
    /opt/app/data/ backup@10.0.0.5:/backups/app-$(date +%Y%m%d)/
sending incremental file list
config/app.conf
         1,024 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=0/3)
sent 1,234 bytes  received 35 bytes  1,381.07 bytes/sec
total size is 1,024  speedup is 0.80

Delta transfer ile yalnızca değişen blokları aktarır; cp -r’den çok daha hızlıdır. -a arşiv modu (izinler + zaman damgası korunur), -z sıkıştırma, --progress transfer durumunu gösterir.

Örnek: Nightly backup script'inde PostgreSQL dump dosyalarını uzak backup sunucusuna aktarmak. --delete ekleyerek kaynakta silinmiş dosyaları hedefte de temizleyebilirsiniz.

grep -rn — Dosya içinde metin ara özyinelemeli

bash — 80×24
$ grep -rn "DB_PASSWORD" /etc/app/ --include="*.conf"
/etc/app/config/db.conf:7:DB_PASSWORD=s3cr3t!

$ grep -rn “error|critical” /var/log/ —include=“*.log” -l /var/log/nginx/error.log /var/log/app/app.log

-r alt dizinleri özyinelemeli tarar, -n satır numarasını gösterir, --include taranacak dosya uzantısını filtreler, -l yalnızca eşleşen dosya adlarını listeler. -i büyük/küçük harf duyarsız arama için eklenir.

Örnek: Konfigürasyon dosyalarında düz metin credential aramak. grep -rn "password\|secret\|token" /etc/ --include="*.conf" 2>/dev/null güvenlik denetimi öncesi standart taramadır.

tar — Dosya ve dizinleri arşivle veya aç

bash — 80×24
$ tar -czf config-backup-$(date +%Y%m%d).tar.gz /opt/app/config/
tar: Removing leading '/' from member names

$ tar -tzf config-backup-20260629.tar.gz | head -4 opt/app/config/ opt/app/config/app.conf opt/app/config/db.conf

$ tar -xzf config-backup-20260629.tar.gz -C /tmp/restore/

-c yeni arşiv oluştur, -x arşivi aç, -t içeriği listele (açmadan), -z gzip sıkıştırma, -f dosya adı. Açmadan önce -t ile içeriği doğrulamak standart güvenli uygulama pratiğidir.

Örnek: Deploy öncesinde konfigürasyon dizinini tarihli arşiv olarak yedeklemek. Deployment hata verirse tar -xzf config-backup-YYYYMMDD.tar.gz -C /opt/app/ ile önceki duruma saniyeler içinde dönün.

🟡 Disk Yönetimi

Disk Yönetimi

df -hT — Disk kullanımını dosya sistemi tipiyle göster

bash — 80×24
$ df -hT
Filesystem       Type      Size  Used Avail Use% Mounted on
/dev/sda1        ext4       40G   31G  6.8G  82% /
/dev/sdb1        xfs       500G  423G   77G  85% /data
tmpfs            tmpfs     7.8G  1.2G  6.6G  16% /dev/shm
overlay          overlay    40G   31G  6.8G  82% /var/lib/docker/overlay2/a1b2c3

-h insan okunabilir boyutlar, -T dosya sistemi tipini (ext4, xfs, tmpfs, overlay) gösterir. Overlay filesystem satırları Docker container layer’larıdır — çok sayıda overlay birikiyor ise docker system prune zamanı gelmiş demektir.

Örnek: Kubernetes node'u DiskPressure durumuna geçtiğinde ilk bakılacak komut. /data %85 üzerindeyse kubelet eviction'dan önce müdahale edin.

du -sh * | sort -rh — Dizin boyutlarını büyükten küçüğe sırala

bash — 80×24
$ du -sh /var/log/* | sort -rh | head -8
1.1G    /var/log/nginx
423M    /var/log/postgresql
188M    /var/log/journal
 42M    /var/log/audit
 18M    /var/log/syslog
3.2M    /var/log/kern.log

Her dizinin toplam boyutunu gösterir. -s özet (alt dizinleri tekrar tekrar listeleme), -h okunabilir format. sort -rh insan okunabilir boyuta göre büyükten küçüğe sıralar.

Örnek: Disk dolmadan önce hangi servisin log dizininin şiştiğini tespit etmek. Ardından journalctl --vacuum-size=500M ile systemd journal'ı, logrotate -f /etc/logrotate.conf ile diğer logları kırpabilirsiniz.

lsblk — Blok aygıtlarını ve bağlama noktalarını listele

bash — 80×24
$ lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,FSTYPE
NAME    SIZE TYPE MOUNTPOINT   FSTYPE
sda     100G disk
├─sda1   50G part /            ext4
└─sda2   50G part /data        xfs
sdb     500G disk
└─sdb1  500G part /backups     ext4
sr0    1024M rom

fdisk -l’den farklı olarak root yetkisi gerektirmez ve ağaç yapısında bağlama noktalarını gösterir. Yeni eklenen disk partition’larını veya EBS volume’larını tanımlamak için ilk komut.

Örnek: AWS EC2 üzerine yeni bir EBS volume bağladıktan sonra hangi blok aygıtı olarak göründüğünü tespit etmek (/dev/xvdf gibi). Ardından mkfs.xfs /dev/xvdf ile formatlayıp mount ile kullanıma alabilirsiniz.

ncdu — İnteraktif disk kullanımı analizi

bash — 80×24
$ ncdu /var --exclude=/var/lib/docker -x
ncdu 1.19 ~ Use the arrow keys to navigate, press ? for help
--- /var -----------------------------------------------------------------------
  423.1 MiB [##########] /log
   88.4 MiB [##       ] /cache
   12.3 MiB [         ] /spool
    1.2 MiB [         ] /tmp

du çıktısının interaktif, gezinebilir versiyonu. Ok tuşlarıyla alt dizinlere inip d tuşuyla doğrudan silebilirsiniz. -x farklı dosya sistemi sınırlarını geçmez (NFS veya Docker overlay’e dallanmaz), --exclude belirtilen dizini atlar.

Örnek: Production sunucusunda disk dolduğunda Docker overlay dışındaki gerçek disk tüketicilerini bulmak. sudo ncdu / -x --exclude=/proc --exclude=/sys kombinasyonu güvenlidir.

iotop -o — Disk I/O tüketen süreçleri izle

bash — 80×24
$ sudo iotop -o -d 2
Total DISK READ:  84.23 M/s | Total DISK WRITE:  12.44 M/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
 4821 be/4  postgres  82.11 M/s   0.00 B/s   0.00 %  98.12 %  postgres: autovacuum
  723 be/3  root       1.44 M/s  12.44 M/s   0.00 %   4.21 %  jbd2/sda1-8

-o yalnızca aktif I/O yapan süreçleri gösterir (ekranı sade tutar), -d 2 her 2 saniyede bir günceller. top’un disk I/O versiyonu — CPU’da değil, storage’da baskı yaratan süreci anında ortaya çıkarır.

Örnek: iostat yüksek I/O wait gösterdiğinde hangi sürecin sorumlu olduğunu tespit etmek. PostgreSQL autovacuum 80 MB/s okuyorsa autovacuum_vacuum_cost_delay parametresini artırarak I/O yükünü yayın.

🟢 Ağ & Sorun Giderme

Ağ & Sorun Giderme

ss -tulpn — Dinleyen portları ve süreçleri listele

bash — 80×24
$ ss -tulpn | grep LISTEN
tcp  LISTEN 0  128  0.0.0.0:22     0.0.0.0:*   users:(("sshd",pid=1234))
tcp  LISTEN 0  511  0.0.0.0:80     0.0.0.0:*   users:(("nginx",pid=4521))
tcp  LISTEN 0  511  0.0.0.0:443    0.0.0.0:*   users:(("nginx",pid=4521))
tcp  LISTEN 0  128  127.0.0.1:5432 0.0.0.0:*   users:(("postgres",pid=7823))

netstat’ın modern halefi. -t TCP, -u UDP, -l yalnızca LISTEN, -p süreç adı/PID, -n DNS çözümlemesini atla (hız). PostgreSQL’in yalnızca localhost’u dinlediğini, Nginx’in her arayüzü dinlediğini görürsünüz.

Örnek: Yeni deploy sonrasında uygulamanın beklenen portu dinleyip dinlemediğini doğrulamak. ss -tulpn | grep 8080 boş döndürüyorsa process başlamamış veya başka bir porta bind olmuş demektir.

curl — HTTP isteği gönder ve zamanla

bash — 80×24
$ curl -sI -o /dev/null \
    -w "HTTP %{http_code}  DNS %{time_namelookup}s  Connect %{time_connect}s  Total %{time_total}s\n" \
    https://api.kubeatlas.com/health
HTTP 200  DNS 0.003s  Connect 0.021s  Total 0.143s

-s sessiz mod, -I HEAD isteği (body almaz), -o /dev/null body’yi at, -w özel format. DNS çözümleme, TCP bağlantı ve toplam süreyi ayrı ayrı raporlar — latency kaynağını tam olarak gösterir.

Örnek: Monitoring script'inde her dakika API health endpoint'ini kontrol etmek. Total süresi 500ms üzerindeyse Prometheus alert'ine bağlayın. -k ekleyerek staging ortamında self-signed sertifikayla çalışabilirsiniz.

tcpdump — Ağ paketlerini yakala

bash — 80×24
$ tcpdump -i eth0 -n -s 0 'port 5432 and host 10.0.1.20' -w /tmp/pg-capture.pcap
tcpdump: listening on eth0, link-type EN10MB (Ethernet)
^C 847 packets captured
847 packets received by filter
0 packets dropped by kernel

-i arayüz, -n DNS çözümleme yok (hız), -s 0 tam paket boyutu yakala, -w dosyaya yaz (Wireshark ile analiz için). BPF filtresi 'port 5432 and host IP' gereksiz trafiği keser.

Örnek: Uygulama ile veritabanı arasındaki yavaş sorguları tespit etmek. Yakalanan pcap'i Wireshark'ta pgsql display filtresiyle açın ve yanıt sürelerine bakın.

dig — DNS çözümlemesini sorgula

bash — 80×24
$ dig +short @8.8.8.8 kubeatlas.com A
93.184.216.34

$ dig +trace kubeatlas.com | tail -4 kubeatlas.com. 300 IN A 93.184.216.34 ;; Received 56 bytes from 205.251.196.1#53(ns-1.awsdns-00.com) in 8 ms

+short yalnızca IP adresini döndürür. +trace root nameserver’dan başlayarak tam çözümleme zincirini gösterir. @8.8.8.8 ile ISP cache’ini devre dışı bırakarak Google DNS üzerinden doğrularsınız.

Örnek: DNS kayıt güncellemesinden sonra propagasyonun tamamlanıp tamamlanmadığını @1.1.1.1, @8.8.8.8 ve @208.67.222.222 (OpenDNS) ile ayrı ayrı test etmek. Farklı sonuçlar TTL'nin henüz dolmadığına işaret eder.

mtr — Ağ yolunu gerçek zamanlı analiz et

bash — 80×24
$ mtr --report --report-cycles 20 8.8.8.8
HOST: prod-node1                Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 10.0.0.1                 0.0%    20    0.4   0.5   0.3   0.8   0.1
  2.|-- 203.0.113.1              0.0%    20    1.2   1.4   1.1   2.1   0.3
  3.|-- 198.51.100.45            5.0%    20   11.3  12.1  10.8  18.4   2.1
  4.|-- 8.8.8.8                  0.0%    20   12.8  13.2  12.4  15.1   0.7

traceroute ve ping’i tek araçta birleştirir; her hop için paket kaybı yüzdesi ve gecikme istatistiklerini gösterir. --report anlık tek seferlik rapor, --report-cycles 20 örnekleme sayısı. Standart traceroute’tan üstün — yalnızca rota değil, kalite verir.

Örnek: Belirli bir dış servise bağlantı yavaşlıyorsa hangi hop'ta paket kaybı olduğunu tespit etmek. 3. hop'ta %5 kayıp varsa sorun ISP transit'inde; kendi altyapınızda değil.

nc -zv — Port erişilebilirliğini test et

bash — 80×24
$ nc -zv 10.0.1.20 5432
Connection to 10.0.1.20 5432 port [tcp/postgresql] succeeded!

$ nc -zv 10.0.1.20 6379 nc: connect to 10.0.1.20 port 6379 (tcp) failed: Connection refused

$ nc -zvw 3 10.0.1.20 443 Connection to 10.0.1.20 443 port [tcp/https] succeeded!

-z bağlantı kurar ve anında kapatır (veri göndermez), -v verbose çıktı, -w 3 3 saniye zaman aşımı. telnet ve nmap gerektirmeden port erişilebilirliğini test etmenin en hızlı yolu; container içinde bile genellikle mevcuttur.

Örnek: Kubernetes pod'u PostgreSQL'e bağlanamıyorsa: pod içinden nc -zv postgres-svc 5432 ile servis DNS çözümlemesini, node üzerinden nc -zv <pod-ip> 5432 ile network policy'yi ayrı ayrı test edin.

🟣 Süreç & Sistem İzleme

Süreç & Sistem İzleme

ps aux --sort=-%mem — Bellek tüketicilerini sırala

bash — 80×24
$ ps aux --sort=-%mem | head -8
USER       PID %CPU %MEM    VSZ    RSS  STAT COMMAND
postgres  4821  1.2 18.4 2145236 752184  Sl  postgres: autovacuum worker
node      7342  0.4  8.7  982340 356472  Sl  /usr/bin/node server.js
java      3201  2.1  7.2 4256789 294120  Sl  java -jar app.jar
root      1234  0.0  0.1   72348   4096  Ss  /usr/sbin/sshd -D

a tüm kullanıcılar, u kullanıcı formatlı çıktı, x terminal olmayan süreçler dahil. --sort=-%mem belleğe göre büyükten küçüğe sıralar. RSS gerçek fiziksel bellek, VSZ sanal bellek kullanımıdır.

Örnek: OOMKiller tarafından öldürülen bir pod'dan sonra hangi sürecin belleği tükettiğini anlamak. autovacuum 750 MB alıyorsa PostgreSQL'de autovacuum_work_mem parametresini düşürün.

journalctl — systemd servis loglarını sorgula

bash — 80×24
$ journalctl -u nginx.service -f --since "30 minutes ago" -p err
Jun 29 09:14:22 prod-node1 nginx[4521]: [error] upstream timed out (110: Connection timed out)
Jun 29 09:14:23 prod-node1 nginx[4521]: [error] connect() failed (111: Connection refused)
Jun 29 09:14:25 prod-node1 nginx[4521]: [error] no live upstreams while connecting to upstream

-u belirli servis, -f canlı takip, --since zaman filtresi, -p err sadece hata ve üstü (warning, err, crit, alert, emerg). --output=json-pretty ile log satırlarını yapısal olarak inceleyebilirsiniz.

Örnek: Nginx upstream bağlantı hatası verdiğinde backend pod'larının hazır olup olmadığını kontrol etmek. Aynı terminal penceresinde kubectl get endpoints çalıştırarak endpoint'lerin kayıtlı olduğunu doğrulayın.

lsof -i — Belirli bir portu hangi süreç kullanıyor

bash — 80×24
$ lsof -i :8080 -n -P
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
node     7342   deploy   22u  IPv4 123456      0t0  TCP *:8080 (LISTEN)
node     7342   deploy   24u  IPv4 123457      0t0  TCP 10.0.1.5:8080->10.0.1.20:54321 (ESTABLISHED)

-i :PORT belirtilen port, -n hostname çözümleme yok, -P port numarasını servis adına çevirme. Hem LISTEN hem ESTABLISHED bağlantıları gösterir; kaç aktif bağlantı olduğunu da buradan anlarsınız.

Örnek: Yeni uygulama deploy'u "address already in use" hatası veriyorsa: lsof -i :8080 ile eski süreci bulun ve PID ile kill -15 PID ile temiz kapatın; grace period için 5 saniye bekleyin.

strace -p — Çalışan sürecin sistem çağrılarını izle

bash — 80×24
$ strace -p 7342 -e trace=network,file -T 2>&1 | head -10
strace: Process 7342 attached
read(28, "", 4096)                      = 0 <0.000012>
connect(29, {sa_family=AF_INET, sin_port=htons(5432)}, 16) = 0 <0.021453>
read(29, "\x00\x00\x00...", 4096)       = 256 <0.143211>
write(29, "SELECT ...", 512)            = 512 <0.000089>

Çalışan bir sürece eklenerek sistem çağrılarını gerçek zamanlı raporlar. -e trace=network,file yalnızca ağ ve dosya çağrılarını filtreler, -T her çağrının süresini <sn> olarak ekler. Production’da dikkatli kullanın — küçük bir overhead ekler.

Örnek: Node.js uygulaması belirli bir endpoint'te yavaşlıyorsa, PID'ini bulup strace -p PID -e trace=network -T ile PostgreSQL bağlantısının tam olarak ne kadar sürdüğünü ölçün. 143ms'lik read() çağrısı yavaş sorgunun işaretidir.

free -h — Bellek kullanımını anlık göster

bash — 80×24
$ free -h
               total        used        free      shared  buff/cache   available
Mem:            15Gi       8.2Gi       1.1Gi       312Mi       5.9Gi       6.8Gi
Swap:          2.0Gi       0.0Gi       2.0Gi

$ watch -n 2 free -h

used aktif süreçlerin tüketimi, buff/cache kernel disk cache’i — bu alan gerektiğinde OS tarafından serbest bırakılır. Gerçek kullanılabilir bellek available sütununda; free’ye değil, ona bakın. Swap kullanımı sıfırdan büyükse bellek baskısı kritik seviyede.

Örnek: OOM durumu yaklaşıyorsa watch -n 2 free -h ile 2 saniyede bir izleyin. available toplam RAM'in %10'unun altına düştüğünde JVM heap veya PostgreSQL shared_buffers değerini düşürün.

vmstat 1 — CPU, bellek ve I/O bütünsel görünüm

bash — 80×24
$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 1124352 204288 6029312    0    0   182   124 1842 3241 18  4 72  6  0
 1  0      0 1123840 204288 6029312    0    0     0   856 2103 3891 22  5 71  2  0

r run queue (çalışmayı bekleyen süreç sayısı), b I/O bekleyenler, wa CPU’nun I/O’da boşa harcadığı yüzde. si/so swap in/out — sıfırdan büyükse ciddi bellek sorunu. Argümanlar: saniye cinsinden aralık, ardından örnek sayısı.

Örnek: CPU yükü yüksek ama neden belirsizse: r yüksekse CPU doymuş, wa yüksekse disk I/O darboğazı var, si/so sıfır değilse bellek yetersiz. Her durum için farklı aksiyon alın.

systemctl — Servis durumu ve yönetimi

bash — 80×24
$ systemctl status nginx.service
● nginx.service - A high performance web server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
   Active: active (running) since Mon 2026-06-29 08:00:01 UTC; 1h 22min ago
 Main PID: 4521 (nginx)

$ systemctl list-units —state=failed UNIT LOAD ACTIVE SUB DESCRIPTION app.service loaded failed failed Application Service

status servis durumu, son log satırları ve PID’i gösterir. list-units --state=failed tüm başarısız servisleri bir bakışta listeler. is-active nginx ve is-enabled nginx komutları script içinde koşullu kontrol için idealdir.

Örnek: Sunucu yeniden başladıktan sonra hangi servislerin başlamadığını anında görmek. Başarısız servisin log detayı için journalctl -u SERVICE_NAME --since boot -p err komutunu ardından çalıştırın.

🔴 Dosya İzinleri & Sahiplik

Dosya İzinleri & Sahiplik

chmod — Dosya izinlerini ayarla

bash — 80×24
$ chmod 640 /etc/app/secrets/db.conf
$ ls -la /etc/app/secrets/db.conf
-rw-r----- 1 app app 512 Jun 29 09:00 /etc/app/secrets/db.conf

$ chmod 755 /opt/app/bin/start.sh $ chmod 444 /etc/nginx/nginx.conf

Sekizlik sayıyla: owner / group / others için r=4, w=2, x=1. 640 → owner okur/yazar, group okur, others erişemez. Secret dosyalar için 640 veya 600; executable script’ler için 755; konfigürasyon için 644.

Örnek: Kubernetes Secret'dan volume olarak mount edilen bir credential dosyasını yalnızca uygulama kullanıcısının okuyabileceği şekilde kısıtlamak. CIS Benchmark denetimleri bu kontrolü otomatik yapar.

chown -R — Dosya sahipliğini değiştir

bash — 80×24
$ chown -R app:app /opt/myapp/
$ ls -la /opt/myapp/
total 16
drwxr-xr-x 4 app app 4096 Jun 29 09:00 .
drwxr-xr-x 8 root root 4096 Jun 28 00:00 ..
drwxr-xr-x 2 app app 4096 Jun 29 09:00 config
drwxr-xr-x 2 app app 4096 Jun 29 09:00 logs

-R tüm alt dizinleri ve dosyaları özyinelemeli değiştirir. user:group formatı hem kullanıcıyı hem grubu aynı anda değiştirir. Uygulama dizinleri hiçbir zaman root’a ait olmamalı; kendi service account’ına devredilmeli.

Örnek: Yeni bir sunucuya uygulama dosyalarını root ile rsync ettikten sonra sahipliği uygulama kullanıcısına devretmek. Ardından systemctl restart myapp ile servisi başlatın.

find ile güvenlik taraması — Dünyaya açık yazılabilir dosyaları bul

bash — 80×24
$ find /opt/app -type f -perm /o+w
/opt/app/config/app.conf
/opt/app/tmp/upload-cache

$ find /etc -name “*.conf” -perm -0002 2>/dev/null (no output = clean)

-perm /o+w (veya -perm /002) others için yazma izni olan dosyaları bulur. /etc altında böyle bir dosya varsa güvenlik açığı var demektir. Bu kontrolü CI pipeline’ına entegre ederek her deploy’da otomatik çalıştırın.

Örnek: PCI-DSS veya SOC 2 denetimi öncesinde sunucudaki tüm world-writable dosyaları tespit etmek. Ardından chmod o-w ile düzeltin ve konfigürasyon yönetim aracınıza (Ansible/Chef) ekleyin.

stat — Dosya meta verisini detaylı göster

bash — 80×24
$ stat /etc/nginx/nginx.conf
  File: /etc/nginx/nginx.conf
  Size: 1742      Blocks: 8    IO Block: 4096   regular file
Device: 8,1     Inode: 131074  Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2026-06-29 08:14:33.000000000 +0000
Modify: 2026-06-15 11:22:07.000000000 +0000
Change: 2026-06-15 11:22:07.000000000 +0000

ls -l’den farklı olarak inode numarası, erişim/değiştirilme/metadata değişim zamanlarını (atime/mtime/ctime) ayrı ayrı gösterir. -c "%n %a %U:%G" ile yalnızca ad, izin ve sahipliği script’te kullanılabilir formatta alabilirsiniz.

Örnek: Bir konfigürasyon dosyasının son ne zaman değiştirildiğini kesin olarak tespit etmek. mtime ile ctime farklıysa yalnızca metadata (izin/sahiplik) güncellenmiş, içerik değişmemiş demektir.

getfacl / setfacl — Gelişmiş erişim kontrol listeleri

bash — 80×24
$ getfacl /opt/app/logs/
# file: opt/app/logs/
# owner: app
# group: app
user::rwx
group::r-x
other::---
user:monitoring:r-x

$ setfacl -m u:monitoring:rx /opt/app/logs/ $ setfacl -Rm d:u:monitoring:rx /opt/app/logs/

Standart Unix izinlerinin ötesinde belirli kullanıcılara ayrı ayrı izin atar. d: (default) ACL yeni oluşturulan dosya ve alt dizinlere otomatik uygulanır. Sahiplik değişikliği gerektirmeden ek okuma/yazma erişimi vermek bu araçla mümkündür.

Örnek: Prometheus node_exporter'ın uygulama log dizinini okuyabilmesi için app kullanıcısının sahipliğini değiştirmeden ek okuma izni vermek. setfacl -Rm u:prometheus:rx /opt/app/logs/ tüm mevcut ve yeni dosyalara uygulanır.
Etiketler Linux DevOps SRE CLI Cheat Sheet