Windows Event Viewer ile Sistem Olaylarını İzleme
Yıllar önce bir müşterimizdeki sunucu, her gece saat 03:00’da çöküyordu. Sabah geldiğimizde sistem yeniden ayağa kalkmış oluyordu ama kimse neyin ne zaman olduğunu bilmiyordu. İki hafta boyunca bu sorunu takip ettim ve sonunda Event Viewer’daki o küçük sarı uyarı işaretleri beni doğru yere götürdü. O günden bu yana Windows Event Viewer benim için sıradan bir araç değil, gerçek bir dedektiflik aleti.
Windows sunucu yönetiminde Event Viewer’ı sadece bir şeyler ters gittiğinde açıp kapatan bir araç olarak görmek büyük bir hata. Düzgün kullanıldığında bu araç size sistemin geçmişini, şimdisini ve olası geleceğini anlatır. Ama doğru okumayı bilmek gerekir.
Event Viewer’ın Temel Yapısı
Event Viewer’ı açtığınızda sol tarafta bir ağaç yapısı görürsünüz. Bu yapının mantığını anlamadan içinde kaybolmak kaçınılmaz.
Windows Logs altında beş temel kategori var:
- Application: Uygulamaların yazdığı olaylar. SQL Server, IIS, .NET uygulamaları buraya yazar.
- Security: Oturum açma girişimleri, kaynak erişimleri, politika değişiklikleri. Adli incelemede altın madeni.
- Setup: Windows kurulum ve güncelleme olayları.
- System: İşletim sistemi bileşenlerinin, sürücülerin ve servislerin olayları.
- Forwarded Events: Başka sunuculardan yönlendirilen olaylar. Merkezi izleme yapıyorsanız burası dolup taşar.
Applications and Services Logs altında ise Microsoft’un kendi ürünleri ve üçüncü taraf yazılımlar için ayrı log kanalları bulunuyor. Active Directory, DNS, DHCP gibi rol bazlı loglar burada.
Her olay dört önem seviyesine sahip:
- Information: Rutin işlemler, servis başlatma/durdurma
- Warning: Henüz hata değil ama dikkat etmezsen olacak
- Error: Bir şeyler yanlış gitti ama sistem çalışmaya devam ediyor
- Critical: Sistem düzeyinde büyük sorun
PowerShell ile Event Log Sorgulama
Arayüzden tıklayarak log aramak küçük sistemlerde idare eder, ama onlarca sunucu yönetiyorsanız PowerShell şart. Get-WinEvent cmdlet’i bu işin kalbi.
Temel kullanım:
Get-WinEvent -LogName System -MaxEvents 50
Son 24 saatteki hata ve kritik olayları çekmek için:
$zaman = (Get-Date).AddHours(-24)
Get-WinEvent -FilterHashtable @{
LogName = 'System'
Level = 1,2
StartTime = $zaman
} | Select-Object TimeCreated, Id, LevelDisplayName, Message | Format-List
Burada Level değerleri şu anlama geliyor:
- 1: Critical
- 2: Error
- 3: Warning
- 4: Information
- 5: Verbose
Birden fazla log kanalını aynı anda sorgulamak mümkün:
Get-WinEvent -FilterHashtable @{
LogName = 'System','Application'
Level = 1,2
StartTime = (Get-Date).AddDays(-7)
} | Sort-Object TimeCreated -Descending | Select-Object TimeCreated, LogName, Id, Message
Bu sorgu size geçen haftanın tüm hata ve kritik olaylarını kronolojik sırayla verir. Özellikle bir olay sonrasında “tam o sırada ne oluyordu” sorusunu yanıtlamak için çok kullanışlı.
Event ID’leri Tanımak
Event Viewer’ı gerçekten verimli kullananlar Event ID’leri ezberden bilir. Tabii hepsini bilmek mümkün değil, ama kritik olanları tanımak işin yarısı.
Güvenlik logunda bilmeniz gerekenler:
- 4624: Başarılı oturum açma. Logon Type alanına dikkat edin. Type 3 network üzerinden giriş demek.
- 4625: Başarısız oturum açma girişimi. Brute force tespiti için temel olay.
- 4648: Açık kimlik bilgileriyle oturum açma girişimi. Pass-the-hash saldırılarında görürsünüz.
- 4720: Yeni kullanıcı hesabı oluşturuldu. Yetkisiz hesap açılmasını takip edin.
- 4728: Güvenlik grubuna üye eklendi. Domain Admins grubuna kim eklenmiş?
- 4776: Domain Controller kimlik doğrulama girişimi.
System logunda önemliler:
- 41: Kernel-Power, beklenmeyen kapatma. Sunucu düştü mü anlamak için.
- 6008: Beklenmeyen sistem kapatması. 41 ile birlikte görülür.
- 7034: Servis beklenmedik şekilde sonlandı. Hangi servis olduğuna bakın.
- 7036: Servis durumu değişti. Başladı mı, durdu mu.
- 1074: Sistem düzenli olarak kapatıldı veya yeniden başlatıldı. Kim yaptı, neden?
Belirli bir Event ID’yi aramak:
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4625
StartTime = (Get-Date).AddHours(-1)
} | Select-Object TimeCreated, Message | Format-List
Son bir saatte kaç tane başarısız giriş denemesi olmuş, bir bakışta görürsünüz. Eğer bu sayı anormal derecede yüksekse alarm çalmalı.
Özel Görünümler Oluşturmak
Event Viewer arayüzünde “Custom Views” bölümü çoğu zaman görmezden geliniyor. Bu bölümde bir kez oluşturduğunuz filtreler kalıcı olarak kaydediliyor. Her seferinde aynı filtreyi tekrar yazmak yerine tek tıkla aynı görünüme geliyorsunuz.
Yeni bir Custom View oluştururken XML filtresi kullanmak çok daha güçlü sonuçlar veriyor. Örneğin sadece kritik güvenlik olaylarını gösteren bir görünüm için:
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">
*[System[(EventID=4625 or EventID=4720 or EventID=4728)
and TimeCreated[timediff(@SystemTime) <= 86400000]]]
</Select>
</Query>
</QueryList>
Bu XML’i Event Viewer’daki “Edit Filter” ekranındaki XML sekmesine yapıştırırsanız son 24 saatin kritik güvenlik olaylarını anlık izleyebilirsiniz.
Uzak Sunuculara Bağlanmak
Tek sunucuya Event Viewer açmak kolay. Ama 20 sunucuyu tek yerden izlemek gerekince ne yaparsınız?
Get-WinEvent -ComputerName sunucu01,sunucu02,sunucu03 -FilterHashtable @{
LogName = 'System'
Level = 1,2
StartTime = (Get-Date).AddHours(-4)
} | Select-Object MachineName, TimeCreated, Id, LevelDisplayName, Message
Bu komutla birden fazla sunucunun son 4 saatlik hata loglarını tek çıktıda görebilirsiniz. Büyük ortamlarda tüm sunucu listesini bir değişkene alıp döngüyle çalıştırmak daha pratik:
$sunucular = Get-Content "C:sunucu-listesi.txt"
$sonuclar = foreach ($sunucu in $sunucular) {
Get-WinEvent -ComputerName $sunucu -FilterHashtable @{
LogName = 'System','Application'
Level = 1,2
StartTime = (Get-Date).AddHours(-8)
} -ErrorAction SilentlyContinue
}
$sonuclar | Sort-Object TimeCreated -Descending |
Select-Object MachineName, TimeCreated, LogName, Id, Message |
Export-Csv "C:raporlargeceyarisi-kontrol-$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation -Encoding UTF8
Bu scripti görev zamanlayıcıya ekleyin, her sabah masanızda bir CSV raporu hazır olsun. Ben bunu yıllardır sabah 06:00’da çalışacak şekilde ayarlı tutuyorum, işe geldiğimde geceye ait tüm anormallikleri görmüş oluyorum.
Olay Tabanlı Uyarılar Oluşturmak
Event Viewer’ın en az kullanılan ama en güçlü özelliklerinden biri “Attach Task to This Event” seçeneği. Bir olay gerçekleştiğinde otomatik olarak bir şey yapmasını sağlayabilirsiniz: e-posta gönder, script çalıştır, program başlat.
Örneğin Domain Admins grubuna yeni birisi eklendiğinde (Event ID 4728) anında bildirim almak için:
Event Viewer’da Security logunda 4728 ID’li bir olayı bulun, sağ tıklayın, “Attach Task to This Event” deyin. Açılan sihirbazda “Start a program” seçin ve şu scripti çalıştıracak şekilde ayarlayın:
$konu = "UYARI: Domain Admins grubuna yeni uye eklendi"
$icerik = "Tarih: $(Get-Date)`nSunucu: $env:COMPUTERNAME`nDetaylar icin Security logunu kontrol edin."
Send-MailMessage -To "[email protected]" -From "[email protected]" `
-Subject $konu -Body $icerik -SmtpServer "10.0.0.10"
Tabii Send-MailMessage artık deprecated sayılıyor, ama küçük ortamlarda hala çalışıyor. Daha güvenilir bir yöntem için MailKit veya üçüncü parti SMTP wrapper kullanmak daha mantıklı.
Log Boyutu ve Saklama Politikası
Bu konu çoğunlukla es geçilir ve felaket olduğunda “ama loglar yoktu” diye yas tutulur. Windows’un varsayılan log boyutları yoğun ortamlar için gerçekten yetersiz.
Varsayılan değerler:
- Application: 20 MB
- Security: 20 MB
- System: 20 MB
Orta ölçekli bir ortamda Security logu saatte yüzlerce binlerce olay yazabilir. 20 MB dolduğunda eski olaylar üzerine yazılır. Saldırı olduğunu iki gün sonra fark ettiğinizde loglar çoktan silinmiş olabilir.
Log boyutunu ve saklama politikasını PowerShell ile ayarlamak:
# Security logunun boyutunu 512 MB'a cıkar ve eski olayları koru
$log = Get-WinEvent -ListLog Security
$log.MaximumSizeInBytes = 512MB
$log.LogMode = [System.Diagnostics.Eventing.Reader.LogMode]::Retain
$log.SaveChanges()
# System logu için
$log = Get-WinEvent -ListLog System
$log.MaximumSizeInBytes = 128MB
$log.LogMode = [System.Diagnostics.Eventing.Reader.LogMode]::Retain
$log.SaveChanges()
LogMode için üç seçenek var:
- Retain: Log dolu olduğunda yeni olayları yazar, eski olayları korur. Kritik sistemler için tercih edin.
- Circular: Dolunca en eski olayların üzerine yaz. Varsayılan davranış.
- AutoBackup: Dolunca arşivle ve yenisine başla.
Group Policy ile bunu tüm domaine uygulamak daha verimli: Computer Configuration > Administrative Templates > Windows Components > Event Log Service yolunu takip edin.
Performans Sorunlarını Event Log ile Tespit Etmek
Event Viewer sadece güvenlik değil, performans sorunlarını takip etmek için de kullanılabilir. Windows, belirli eşikler aşıldığında Event Log’a yazıyor.
Disk sorunları için Disk kategorisini, servis çöküşleri için Windows Error Reporting’i takip etmek gerekiyor. Ama pratik olarak en çok işe yarayan yöntem, düzenli interval’lerle performans verilerini korele etmek.
Örneğin servis çöküşlerini analiz edelim:
# Son 7 gunde coken servisleri grupla ve say
Get-WinEvent -FilterHashtable @{
LogName = 'System'
Id = 7034
StartTime = (Get-Date).AddDays(-7)
} | ForEach-Object {
$_.Message
} | Group-Object | Sort-Object Count -Descending |
Select-Object Count, Name | Format-Table -AutoSize
Bu sorgu hangi servisin ne kadar sıklıkla çöktüğünü gösterir. Bir servis haftada 3-4 kez çöküyorsa ve siz fark etmemişseniz, bu çıktı gözünüzü açacaktır.
Windows Event Forwarding ile Merkezi Toplama
Küçük ortamlarda her sunucuya ayrı ayrı bağlanmak idare eder. Ama 50’den fazla sunucunuz varsa Windows Event Forwarding (WEF) kurmak zorundasınız.
WEF’in mantığı basit: Kaynak sunucular (source) olayları bir kolektör sunucuya (collector) gönderir. Kolektörde tüm olayları tek noktadan izlersiniz.
Kolektör sunucuda:
# Windows Remote Management servisini etkinlestir
winrm quickconfig
# Event Collector servisini baslat
wecutil qc
Kaynak sunucularda:
# WinRM'i yapılandır
winrm quickconfig
# Network Service'in Security loguna erisim vermesi icin
wevtutil sl Security /ca:O:BAG:SYD:(A;;0xf0005;;;SY)(A;;0x5;;;BA)(A;;0x1;;;S-1-5-32-573)(A;;0x1;;;NS)
Subscription oluşturmak için kolektörde:
wecutil cs subscription.xml
subscription.xml içeriği temel bir yapı için:
<Subscription xmlns="http://schemas.microsoft.com/2006/03/windows/events/subscription">
<SubscriptionId>CriticalEvents</SubscriptionId>
<SubscriptionType>SourceInitiated</SubscriptionType>
<Description>Tum sunuculardan kritik olaylar</Description>
<Enabled>true</Enabled>
<Uri>http://schemas.microsoft.com/wbem/wsman/1/windows/EventLog</Uri>
<ConfigurationMode>MinLatency</ConfigurationMode>
<Query><![CDATA[
<QueryList>
<Query Path="System">
<Select>*[System[Level=1 or Level=2]]</Select>
</Query>
<Query Path="Security">
<Select>*[System[(EventID=4625 or EventID=4720 or EventID=4728)]]</Select>
</Query>
</QueryList>
]]></Query>
<EventSources>
<EventSource>
<Address>sunucu01.domain.local</Address>
</EventSource>
</EventSources>
</Subscription>
WEF kurulumu biraz meşakkatli görünebilir ama kurulduktan sonra hayat çok kolaylaşıyor. Tüm ortamın loglarını tek pencereden görmek, olayları korele etmek çok daha kolay hale geliyor.
Gerçek Bir Senaryo: Brute Force Tespiti
Giriş paragrafında bahsettiğim o gece senaryosuna döneyim. Aslında çözüm şuydu: Her gece 03:00’da birisi RDP üzerinden sisteme girmeye çalışıyordu. Onlarca başarısız deneme sonunda hesabı kilitliyordu, kilitli hesabın oturum açma girişimleri sistem üzerinde yük yaratıyordu ve bu yük servis çöküşlerine neden oluyordu.
Bunu tespit eden sorgu şuydu:
$baslangic = (Get-Date).AddDays(-1)
$sonuc = Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4625
StartTime = $baslangic
} | ForEach-Object {
$xml = [xml]$_.ToXml()
[PSCustomObject]@{
Zaman = $_.TimeCreated
Kullanici = $xml.Event.EventData.Data |
Where-Object { $_.Name -eq 'TargetUserName' } |
Select-Object -ExpandProperty '#text'
KaynakIP = $xml.Event.EventData.Data |
Where-Object { $_.Name -eq 'IpAddress' } |
Select-Object -ExpandProperty '#text'
LogonTipi = $xml.Event.EventData.Data |
Where-Object { $_.Name -eq 'LogonType' } |
Select-Object -ExpandProperty '#text'
}
}
$sonuc | Group-Object KaynakIP | Sort-Object Count -Descending |
Select-Object Count, Name | Format-Table -AutoSize
Bu sorgu size hangi IP adresinden kaç başarısız giriş denemesi yapıldığını gösterir. O geceki vakada Rusya’ya ait bir IP adresinden gece yarısı 2.000’den fazla deneme geliyordu. Firewall kuralına bir satır ekleyip bitirdik.
Sonuç
Event Viewer, adı “basit bir log okuyucu” gibi görünse de aslında Windows ekosisteminde güvenlik, kararlılık ve performans izlemenin temel taşı. Onu sadece “bir şeyler patladığında açılan araç” olarak görmek, elimizdeki en değerli bilgi kaynağını görmezden gelmek demek.
Pratikte önerim şu: Bugün üretim ortamınızda bir PowerShell scripti yazın, son 24 saatin kritik ve hata olaylarını toplayın, bir CSV’ye atın ve bakın. Büyük ihtimalle şu ana kadar fark etmediğiniz birkaç şeyle karşılaşacaksınız. Bu “keşif” sizi hem şaşırtacak hem de doğru yönde ilerlemek için bir başlangıç noktası verecek.
Log boyutlarını artırmayı ihmal etmeyin, WEF’i kurmayı ertelemeyin ve önemli Event ID’leri için uyarı mekanizmaları oluşturun. Bu üç adım bile sizi ortalama sysadminin çok önüne geçirir.
