Bash Script Örnekleri: Siber Güvenlik İçin 15 Betik
Bash script örnekleri arayanlara 15 savunma betiği: SSH deneme sayımı, log tarama, SUID envanteri, dosya bütünlüğü ve port denetimi. Kopyala, uyarla.
Bash script örnekleri, tekrarlayan güvenlik işlerini birkaç satırla otomatikleştirmenin en kısa yoludur. Bu sayfadaki 15 betik savunma amaçlıdır: SSH deneme sayımı, web günlüğü tarama, SUID envanteri, dosya bütünlüğü, port ve servis denetimi. Hepsi Debian ve Ubuntu gibi Linux sistemlerde çalışacak biçimde yazıldı. Her birini önce kendi sanal makinende dene, sonra yolları sistemine göre uyarla.
Bash script nasıl yazılır ve çalıştırılır?
Bash betiği, terminalde tek tek yazdığın komutları bir dosyada toplar. İlk satır hangi yorumlayıcının kullanılacağını söyler. Dosyaya çalıştırma izni verip yoluyla çağırırsın:
chmod u+x denetim.sh bash -n denetim.sh ./denetim.sh
bash -n betiği çalıştırmaz, yalnız sözdizimini denetler. İzinlerin ayrıntısı için Linux dosya izinleri yazısına bak.
1. Güvenli başlangıç şablonu. Her betiği bu dört satırla başlat:
#!/usr/bin/env bash set -euo pipefail umask 077
Bash kılavuzuna göre -e başarısız komutta betiği bitirir, -u tanımsız değişkeni hata sayar, pipefail ise boru hattının ortasındaki hatayı görünür kılar. umask 077 betiğin oluşturduğu dosyaları yalnız sana açık yapar. Bu ayarlar açıkken yarım kalan bir adım sessizce geçilmez.
Girdi ve döngü için güvenli bash script örnekleri
Betiklerdeki hataların çoğu girdiden gelir: eksik argüman, boşluklu dosya adı, ters bölü içeren metin. Aşağıdaki üç örnek bu durumları baştan karşılar.
2. Argüman kontrolü. Eksik argümanla çalışırsa kullanım mesajı verip çıkar:
if [ "$#" -lt 1 ]; then
echo "Kullanım: $0 <günlük_dosyası>" >&2
exit 1
fi
gunluk="$1"
[ -r "$gunluk" ] || { echo "Okunamıyor: $gunluk" >&2; exit 1; }
set -u açıkken $1 boşsa betik hata verir. $# ile argüman sayısını kontrol etmek bu sorunu önler.
3. Kullanıcıdan güvenli girdi. read -r ters bölü işaretini kaçış karakteri saymaz:
read -r -p "Denetlenecek dizin: " dizin
[ -d "$dizin" ] || { echo "Dizin yok: $dizin" >&2; exit 1; }
4. Boşluklu dosya adlarına dayanıklı döngü. for f in $(ls) kalıbı boşlukta bölünür. Bunun yerine find ile sıfır baytla ayrılmış liste kullan:
find /var/log -type f -name '*.log' -print0 | while IFS= read -r -d '' dosya; do printf '%s\n' "$dosya" done
ShellCheck'in en sık uyarısı SC2086'dır: tırnaksız değişken. "$dosya" yerine $dosya yazarsan bash değeri boşluklardan böler ve joker karakterleri genişletir.
Dosya bütünlüğü ve izin denetimi örnekleri
Bu dört betik, sistemde beklenmeyen bir değişiklik olup olmadığını gösterir. İlk çalıştırmada bir temel çizgi kaydedersin, sonraki çalıştırmalarda farkı ararsın.
5. SHA-256 temel çizgisi ve doğrulama. Önce özet listesini çıkar, sonra aynı listeyle doğrula:
find /usr/local/bin -type f -print0 | sort -z | xargs -0r sha256sum > bin-ozet.txt sha256sum --quiet -c bin-ozet.txt
--quiet yalnız değişen ya da okunamayan dosyaları yazar. Özetin neden bir bit değişince tümüyle değiştiğini hashing nedir yazısında okuyabilirsin.
6. Herkesin yazabildiği dosyalar. Diğer kullanıcıların değiştirebildiği dosyaları listeler:
sudo find / -xdev -type f -perm -0002 2>/dev/null
7. SUID envanterini dünle karşılaştırma. Yeni beliren bir SUID dosyası yetki yükseltme işareti olabilir:
sudo find / -xdev -type f -perm -4000 2>/dev/null | sort > suid-bugun.txt if diff -q suid-dun.txt suid-bugun.txt >/dev/null; then echo "SUID listesi değişmedi" else diff suid-dun.txt suid-bugun.txt fi mv suid-bugun.txt suid-dun.txt
İlk çalıştırmada suid-dun.txt henüz yoktur. Komutun ilk satırını bir kez çalıştırıp çıktıyı bu adla kaydet. Son satır, bugünkü listeyi yarının karşılaştırması için saklar.
Bu farkın neden önemli olduğunu yetki yükseltme yazısı anlatıyor.
8. Son 24 saatte değişen ayar dosyaları.
sudo find /etc -xdev -type f -mtime -1 -ls
Log tarama örnekleri: SSH ve web günlükleri
Günlükler, parola denemesini ve dizin taramasını ilk gösteren yerdir. Debian ve Ubuntu'da SSH kayıtları geleneksel olarak /var/log/auth.log dosyasına yazılır. Debian 12 ve sonrasında rsyslog varsayılan olarak kurulmadığı için bu dosya olmayabilir. O durumda aynı kayıtları journalctl ile okursun.
9. Başarısız SSH girişlerini IP'ye göre sayma.
grep 'Failed password' /var/log/auth.log |
grep -oE 'from [0-9.]+' | awk '{print $2}' |
sort | uniq -c | sort -rn | head -10
auth.log yoksa ilk satırın yerine şunu kullan. Servis adı Debian ve Ubuntu'da ssh, RHEL ailesinde sshd olur:
journalctl -u ssh --since today --no-pager | grep 'Failed password'
Bu sayımın arkasındaki saldırıyı ve savunmasını Hydra ve brute-force yazısında bulabilirsin.
10. Web sunucusuna en çok istek atan adresler.
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
11. En çok 404 üreten adresler. Nginx'in varsayılan biçiminde dokuzuncu alan durum kodudur. Tek bir adresten gelen yüzlerce 404 çoğu zaman dizin taramasıdır:
awk '$9 == 404 {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
Daha fazla süzme kalıbı için günlük analizi kopya kâğıdına bak.
Sistem durumu ve port izleme örnekleri
12. Disk doluluk uyarısı. Disk dolarsa günlük yazımı durur ve iz kaybolur:
kullanim=$(df --output=pcent / | tail -n 1 | tr -dc '0-9') if [ "$kullanim" -ge 90 ]; then echo "UYARI: kök bölüm yüzde $kullanim dolu" >&2 fi
13. Dinleyen portları izin listesiyle karşılaştırma. Listede olmayan her TCP portunu yazar:
izinli=" 22 443 "
ss -H -tln | awk '{print $4}' | awk -F: '{print $NF}' | sort -un |
while read -r port; do
case "$izinli" in
*" $port "*) ;;
*) echo "Beklenmeyen port: $port" ;;
esac
done
-H başlık satırını gizler. Portların anlamını 20 temel Linux komutu yazısındaki ss bölümünde görebilirsin.
14. Kritik servis çalışıyor mu?
for servis in ssh nginx; do
if ! systemctl is-active --quiet "$servis"; then
echo "$servis çalışmıyor" >&2
fi
done
Örnekleri tek bir günlük rapora nasıl dönüştürürsün?
15. Günlük güvenlik özeti. Önceki örnekleri tek dosyada toplar ve tarihli bir rapor yazar:
#!/usr/bin/env bash
set -euo pipefail
umask 077
rapor="/var/log/guvenlik-ozeti/$(date +%F).txt"
mkdir -p "$(dirname "$rapor")"
{
echo "== Disk"; df -h /
echo "== Herkesin yazabildiği dosyalar"
find / -xdev -type f -perm -0002 2>/dev/null || true
echo "== SUID dosyalar"
find / -xdev -type f -perm -4000 2>/dev/null || true
echo "== Dinleyen portlar"; ss -tln
} > "$rapor"
Betiği /usr/local/sbin/guvenlik-ozeti.sh olarak kaydet, sahibini root yap ve iznini 700 ver. Root olarak çalışan bir betiği başka biri değiştirebiliyorsa, o kişi kendi komutunu root yetkisiyle çalıştırır. Her sabah çalışması için /etc/cron.d/guvenlik-ozeti dosyasına şu satırı ekle:
30 6 * * * root /usr/local/sbin/guvenlik-ozeti.sh
Raporları birkaç hafta biriktirince sisteminin normalini tanırsın. Yeni bir SUID dosyası ya da yeni bir port, normal dışı satır olarak hemen göze çarpar.
Bash betiklerinde en sık yapılan güvenlik hataları nelerdir?
Aşağıdaki hatalar hem bozuk çıktıya hem gerçek açıklara yol açar:
| Hata | Sonucu | Doğrusu |
|---|---|---|
| Tırnaksız değişken (SC2086) | Boşluklu adlar bölünür, joker genişler | "$degisken" |
cd sonucunu denetlememek (SC2164) | Silme komutu yanlış dizinde çalışır | cd başarısızsa betikten çık |
read komutunu -r olmadan kullanmak | Ters bölü işaretleri kaybolur | read -r |
| Parolayı betiğe yazmak | Depoya ve yedeklere sızar | Ortam değişkeni ya da izni dar dosya |
| Root betiğine geniş yazma izni | Yetki yükseltme | Sahibi root, izni 700 |
Kullanıcı girdisini eval ile çalıştırmak | Komut enjeksiyonu | eval kullanma, case ile izin listesi |
Silme ve taşıma içeren her komutu önce yalnız listeleyerek çalıştır. Çıktı beklediğin gibiyse asıl işlemi yap. Betik yüz satırı geçip veri yapıları gerektirmeye başladıysa siber güvenlik için Python iyi bir sonraki adımdır.
Bu betiklerin gerçek bir olayda nasıl kullanıldığını görmek istersen saha görevlerinde auth.log içinde SSH denemelerini sayıp saldırgan adresi bulduğun ve engellediğin bir senaryo var.
Kaynaklar
Sık sorulan sorular
Bash script nasıl çalıştırılır?
Dosyanın ilk satırına bash'i yorumlayıcı olarak gösteren shebang satırını yaz ve dosyayı .sh uzantısıyla kaydet. Sonra chmod u+x betik.sh ile sahibine çalıştırma izni ver ve ./betik.sh ile başlat. Çalıştırma izni vermeden bash betik.sh yazarak da çalıştırabilirsin. Yazım hatalarını görmek için önce bash -n betik.sh ile yalnız sözdizimini denetle.
set -euo pipefail ne işe yarar?
Bu satır betiği hatada durmaya zorlar. -e, başarısız olan bir komuttan sonra betiği bitirir. -u, tanımlanmamış bir değişken kullanıldığında hata verir. pipefail ise bir boru hattında ortadaki komut başarısız olursa bunu gizlemez. Böylece yarım kalmış bir işlem fark edilmeden devam etmez. if ve || ile denetlenen komutlarda -e devreye girmez.
Siber güvenlik için bash mı Python mı öğrenmeliyim?
İkisi farklı işlere yarar. Bash, Linux komutlarını birbirine bağlayan kısa denetim ve otomasyon betikleri için en hızlı yoldur. Veri ayrıştırma, ağ istekleri ve büyüyen araçlar için Python daha düzenlidir. Önce bash ile sunucu üzerinde rahat çalışmayı öğren. Betiğin yüz satırı geçiyorsa Python'a taşımayı düşün.
İnternetten bulduğum bash script'ini çalıştırmak güvenli mi?
Okumadan çalıştırmak güvenli değildir. Özellikle bir adresten indirilip doğrudan bash'e aktarılan tek satırlık kurulum komutları, ne yaptığını görmeden sistemine yetki verir. Betiği önce dosyaya indir, satır satır oku, mümkünse ShellCheck ile tara. Sonra yönetici yetkisi vermeden bir sanal makinede dene. Resmî görünen bir kaynak da ele geçirilmiş olabilir.
Bash script'ini her gün otomatik nasıl çalıştırırım?
Linux'ta en yaygın yol cron'dur. crontab -e ile kendi zamanlamanı eklersin, sistem genelindeki işler için /etc/cron.d altına kullanıcı alanı içeren bir satır yazılır. systemd kullanan dağıtımlarda zamanlayıcı birimi de seçenektir. Hangisini seçersen seç, betiğin çıktısını bir dosyaya yönlendir ve dosyayı yalnız root'un yazabileceği izinle sakla.
- bash
- bash script
- otomasyon
- log analizi
- Linux