ELK Stack ile Windows Event Log Analizi

Windows ortamlarında log yönetimi, çoğu sysadmin’in “sonra hallederim” listesinin başında gelir. Ta ki bir güvenlik olayı yaşanana veya bir müşteri “geçen hafta ne olmuştu?” diye sorana kadar. Ben de yıllarca Windows Event Log’larını sadece Event Viewer üzerinden takip ettim, sonra bir gün 50 sunucunun loglarını tek tek açmak zorunda kaldım ve o gece ELK Stack kurulumuna başladım. Bu yazıda sıfırdan çalışan bir Windows Event Log analiz altyapısını nasıl kuracağınızı, hangi hataları yapmamanız gerektiğini ve gerçek dünyada bu sistemin nasıl işe yaradığını anlatacağım.

Mimariyi Anlamak

ELK Stack üç bileşenden oluşur: Elasticsearch (veri depolama ve arama), Logstash (veri işleme ve dönüştürme), Kibana (görselleştirme). Windows Event Log’ları için bu üçlüye bir de Winlogbeat ekleniyor. Windows sunucularına Winlogbeat agent’ı kuruyorsunuz, bu agent logları Logstash veya direkt Elasticsearch’e gönderiyor.

Genel mimari şöyle işliyor:

  • Windows Sunucuları (Winlogbeat) -> Logstash -> Elasticsearch -> Kibana

Neden direkt Elasticsearch’e değil de Logstash üzerinden gönderiyoruz? Çünkü Logstash’te veri zenginleştirme, filtreleme ve dönüştürme yapabiliyorsunuz. Örneğin Event ID 4625 (başarısız login) geldiğinde bunu otomatik olarak “Failed Login Attempt” etiketiyle işaretleyebiliyorsunuz.

Elasticsearch Kurulumu

Üretim ortamı için single-node kurulum önerilmez ama başlangıç için işe yarar. Ben genellikle minimum 3 node’lu cluster kuruyorum. Şimdilik tek node ile başlayalım:

# Elasticsearch GPG key ve repo ekle
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list

sudo apt-get update && sudo apt-get install elasticsearch -y

# Servis başlat
sudo systemctl daemon-reload
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch

Kurulum sonrası /etc/elasticsearch/elasticsearch.yml dosyasını düzenlemeniz gerekiyor:

# /etc/elasticsearch/elasticsearch.yml temel ayarlar
cluster.name: windows-log-cluster
node.name: elk-node-01
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.type: single-node
xpack.security.enabled: true
xpack.security.enrollment.enabled: true

xpack.security.enabled: true ile güvenliği açık tutun. Production ortamında TLS olmadan çalıştırmak ciddi bir güvenlik açığıdır.

Logstash Kurulumu ve Pipeline Konfigürasyonu

Logstash kurulumu Elasticsearch’ten sonra gelir çünkü Java bağımlılıklarını paylaşıyorlar:

sudo apt-get install logstash -y

Şimdi kritik kısma geliyoruz: Logstash pipeline konfigürasyonu. Bu dosyayı yanlış yazarsanız loglar ya hiç gelmez ya da anlamsız bir şekilde gelir. /etc/logstash/conf.d/winlogbeat.conf dosyasını oluşturun:

input {
  beats {
    port => 5044
    ssl => true
    ssl_certificate => "/etc/logstash/certs/logstash.crt"
    ssl_key => "/etc/logstash/certs/logstash.key"
  }
}

filter {
  if [agent][type] == "winlogbeat" {
    
    # Security logları için özel işleme
    if [winlog][channel] == "Security" {
      
      # Başarısız login denemelerini işaretle
      if [winlog][event_id] == 4625 {
        mutate {
          add_tag => ["failed_login"]
          add_field => { "event_category" => "authentication_failure" }
        }
      }
      
      # Başarılı loginleri işaretle
      if [winlog][event_id] == 4624 {
        mutate {
          add_tag => ["successful_login"]
          add_field => { "event_category" => "authentication_success" }
        }
      }
      
      # Hesap kilitleme
      if [winlog][event_id] == 4740 {
        mutate {
          add_tag => ["account_lockout"]
          add_field => { "alert_level" => "high" }
        }
      }
      
      # Yeni servis kurulumu
      if [winlog][event_id] == 7045 {
        mutate {
          add_tag => ["new_service"]
          add_field => { "alert_level" => "medium" }
        }
      }
    }
    
    # GeoIP zenginleştirme - kaynak IP varsa
    if [winlog][event_data][IpAddress] and [winlog][event_data][IpAddress] != "-" {
      geoip {
        source => "[winlog][event_data][IpAddress]"
        target => "source_geo"
      }
    }
  }
}

output {
  elasticsearch {
    hosts => ["https://localhost:9200"]
    index => "winlogbeat-%{+YYYY.MM.dd}"
    user => "elastic"
    password => "${ELASTIC_PASSWORD}"
    ssl => true
    cacert => "/etc/elasticsearch/certs/http_ca.crt"
  }
  
  # Yüksek öncelikli alertler için ayrı index
  if "account_lockout" in [tags] {
    elasticsearch {
      hosts => ["https://localhost:9200"]
      index => "security-alerts-%{+YYYY.MM.dd}"
      user => "elastic"
      password => "${ELASTIC_PASSWORD}"
      ssl => true
      cacert => "/etc/elasticsearch/certs/http_ca.crt"
    }
  }
}

Logstash’in Elasticsearch şifresine güvenli erişimi için keystore kullanın:

# Logstash keystore oluştur ve şifre ekle
sudo -u logstash /usr/share/logstash/bin/logstash-keystore create
sudo -u logstash /usr/share/logstash/bin/logstash-keystore add ELASTIC_PASSWORD

Winlogbeat Kurulumu (Windows Tarafı)

Windows sunucularında PowerShell ile kurulum yapıyoruz:

# PowerShell ile Winlogbeat indir ve kur
$version = "8.11.0"
$url = "https://artifacts.elastic.co/downloads/beats/winlogbeat/winlogbeat-$version-windows-x86_64.zip"
Invoke-WebRequest -Uri $url -OutFile "C:winlogbeat.zip"
Expand-Archive -Path "C:winlogbeat.zip" -DestinationPath "C:Program Files"
Rename-Item "C:Program Fileswinlogbeat-$version-windows-x86_64" "C:Program FilesWinlogbeat"

# Servis olarak kur
cd "C:Program FilesWinlogbeat"
.install-service-winlogbeat.ps1

C:Program FilesWinlogbeatwinlogbeat.yml konfigürasyon dosyası:

winlogbeat.event_logs:
  - name: Application
    ignore_older: 72h
  - name: System
    ignore_older: 72h
  - name: Security
    ignore_older: 72h
    # Kritik event ID'leri filtrele - hepsini göndermek bant genişliği öldürür
    event_id: 4624, 4625, 4634, 4647, 4648, 4656, 4672, 4698, 4702, 4720, 4722, 4724, 4725, 4726, 4728, 4732, 4740, 4756, 4768, 4769, 4771, 4776
  - name: Microsoft-Windows-PowerShell/Operational
    ignore_older: 24h
  - name: Microsoft-Windows-Sysmon/Operational
    ignore_older: 24h
    tags: ["sysmon"]

output.logstash:
  hosts: ["elk-server.domain.com:5044"]
  ssl.certificate_authorities: ["C:/Program Files/Winlogbeat/certs/ca.crt"]

logging.level: warning
logging.to_files: true
logging.files:
  path: C:/ProgramData/winlogbeat/Logs
  name: winlogbeat
  keepfiles: 7

fields:
  environment: production
  datacenter: ist-dc01

fields_under_root: true

Dikkat edin, Security kanalı için belirli Event ID’leri filtreledim. Bunu yapmazsanız her oturum açma işleminin onlarca ilgili eventi gelir ve Elasticsearch’iniz gereksiz verilerle dolmaya başlar. 500 kullanıcılı bir AD ortamında günlük Security log trafiği filtresiz 2-3 GB’a ulaşabilir.

Kibana Kurulumu ve Temel Dashboard

sudo apt-get install kibana -y

# /etc/kibana/kibana.yml
server.port: 5601
server.host: "0.0.0.0"
elasticsearch.hosts: ["https://localhost:9200"]
elasticsearch.username: "kibana_system"
elasticsearch.password: "kibana_system_sifreniz"
elasticsearch.ssl.certificateAuthorities: ["/etc/elasticsearch/certs/http_ca.crt"]
elasticsearch.ssl.verificationMode: certificate

Kibana başladıktan sonra Winlogbeat’in hazır dashboard’larını yükleyin. Bu dashboard’lar gerçekten kullanışlı, sıfırdan başlamak zorunda değilsiniz:

# Windows makinede Winlogbeat dashboard'larını yükle
cd "C:Program FilesWinlogbeat"
.winlogbeat.exe setup --dashboards `
  -E output.logstash.enabled=false `
  -E output.elasticsearch.enabled=true `
  -E output.elasticsearch.hosts=["https://elk-server:9200"] `
  -E output.elasticsearch.username=elastic `
  -E output.elasticsearch.password=SifrenizBurada `
  -E output.elasticsearch.ssl.certificate_authorities="C:Program FilesWinlogbeatcertsca.crt"

Gerçek Dünya Senaryosu: Brute Force Tespiti

Bir finans şirketinde çalışırken, RDP üzerinden gelen brute force saldırısını tespit etmemiz gerekiyordu. Logları ELK’e taşıdıktan sonra Kibana’da şu Lucene sorgusuyla anlık görüntü aldık:

# Kibana Discover'da kullanılacak KQL sorgusu
winlog.event_id: 4625 AND winlog.event_data.LogonType: "3" AND @timestamp >= "now-1h"

# Aynı IP'den gelen başarısız deneme sayısını bulmak için Lens aggregation:
# Bucket: winlog.event_data.IpAddress
# Metric: Count
# Filter: event_id = 4625, son 24 saat
# Sıralama: Count DESC

Bu sorgu bize son 1 saatte ağ üzerinden kaç başarısız login denemesi olduğunu gösterdi. 10 dakika içinde tek bir IP’den 847 başarısız deneme geldiğini gördük. Elasticsearch’te bu tip anomalileri yakalamak için şu index pattern’ı da kullanabilirsiniz:

# Elasticsearch API ile direkt sorgulama
curl -X GET "https://localhost:9200/winlogbeat-*/_search" 
  -H "Content-Type: application/json" 
  -u elastic:sifreniz 
  --cacert /etc/elasticsearch/certs/http_ca.crt 
  -d '{
    "size": 0,
    "query": {
      "bool": {
        "must": [
          {"term": {"winlog.event_id": 4625}},
          {"range": {"@timestamp": {"gte": "now-1h"}}}
        ]
      }
    },
    "aggs": {
      "failed_logins_by_ip": {
        "terms": {
          "field": "winlog.event_data.IpAddress",
          "size": 10,
          "order": {"_count": "desc"}
        }
      }
    }
  }'

Index Lifecycle Management ile Disk Yönetimi

Burası çok önemli ve genellikle atlanan kısım. ELK kuruyorsunuz, loglar geliyor, birkaç ay sonra diskler dolmuş ve Elasticsearch yavaşlamış oluyor. Index Lifecycle Management (ILM) bu sorunu çözüyor:

# ILM Policy oluştur - Elasticsearch API
curl -X PUT "https://localhost:9200/_ilm/policy/winlogbeat-policy" 
  -H "Content-Type: application/json" 
  -u elastic:sifreniz 
  --cacert /etc/elasticsearch/certs/http_ca.crt 
  -d '{
    "policy": {
      "phases": {
        "hot": {
          "min_age": "0ms",
          "actions": {
            "rollover": {
              "max_primary_shard_size": "50gb",
              "max_age": "7d"
            }
          }
        },
        "warm": {
          "min_age": "7d",
          "actions": {
            "shrink": {
              "number_of_shards": 1
            },
            "forcemerge": {
              "max_num_segments": 1
            }
          }
        },
        "cold": {
          "min_age": "30d",
          "actions": {
            "freeze": {}
          }
        },
        "delete": {
          "min_age": "90d",
          "actions": {
            "delete": {}
          }
        }
      }
    }
  }'

Bu policy ile: loglar 7 gün hot storage’da kalır, 7-30 gün arası warm’da sıkıştırılmış halde tutulur, 30-90 gün arası cold’da freeze edilir, 90 günden sonra silinir. Kendi ihtiyaçlarınıza göre bu süreleri ayarlayın. Yasal gerekliliklere göre bazı logları 1 yıl veya daha uzun saklamanız gerekebilir.

Güvenlik ve İzin Yönetimi

ELK Stack’te rol bazlı erişim kontrolü (RBAC) kritik öneme sahiptir. SOC analistlerinin Security loglarına erişimi olmalı ama System log’larını düzenleyememeli. Bunu Kibana üzerinden veya API ile yapabilirsiniz:

# SOC analistleri için readonly rol oluştur
curl -X POST "https://localhost:9200/_security/role/soc_analyst" 
  -H "Content-Type: application/json" 
  -u elastic:sifreniz 
  --cacert /etc/elasticsearch/certs/http_ca.crt 
  -d '{
    "indices": [
      {
        "names": ["winlogbeat-*", "security-alerts-*"],
        "privileges": ["read", "view_index_metadata"],
        "field_security": {
          "grant": ["*"]
        }
      }
    ],
    "applications": [
      {
        "application": "kibana-.kibana",
        "privileges": ["read"],
        "resources": ["*"]
      }
    ]
  }'

# SOC analist kullanıcısı oluştur
curl -X POST "https://localhost:9200/_security/user/soc_user1" 
  -H "Content-Type: application/json" 
  -u elastic:sifreniz 
  --cacert /etc/elasticsearch/certs/http_ca.crt 
  -d '{
    "password": "GucluBirSifre123!",
    "roles": ["soc_analyst"],
    "full_name": "SOC Analisti 1",
    "email": "[email protected]"
  }'

Performans Optimizasyonu

Winlogbeat tarafında queue.mem ayarları önemli:

# winlogbeat.yml içine ekleyin
queue.mem:
  events: 4096
  flush.min_events: 512
  flush.timeout: 5s

# Logstash pipeline worker sayısını CPU core'a göre ayarlayın
# /etc/logstash/logstash.yml
pipeline.workers: 4
pipeline.batch.size: 500
pipeline.batch.delay: 50

# Elasticsearch heap size - RAM'in yarısını ver, 32GB'ı geçme
# /etc/elasticsearch/jvm.options.d/heap.options
-Xms8g
-Xmx8g

Elasticsearch heap’ini 32GB’ın üzerine çıkarmayın. JVM’in pointer compression özelliği 32GB üzerinde devre dışı kalır ve performans düşer. 64GB RAM’iniz varsa iki node çalıştırın, her birine 16-20GB verin.

Uyarı Sistemi Kurulumu

Kibana Alerting ile kritik eventler için bildirim kuralları oluşturabilirsiniz. Örneğin 5 dakika içinde 10’dan fazla başarısız login olursa e-posta gönder:

Kibana arayüzünde Stack Management > Rules and Connectors yolunu izleyin. Elasticsearch Query rule tipini seçin:

  • Index: winlogbeat-*
  • KQL Filter: winlog.event_id: 4625
  • Time window: 5 dakika
  • Threshold: Count > 10
  • Action: E-posta veya Slack notification

Kibana’nın built-in alerting’i temel ihtiyaçlar için yeterli. Daha gelişmiş correlation rules için Elastic SIEM (Elastic Security) modülüne bakabilirsiniz.

Karşılaşılan Yaygın Sorunlar

Winlogbeat logları gelmiyor: İlk kontrol edeceğiniz yer Winlogbeat log dosyası. C:ProgramDatawinlogbeatLogswinlogbeat dosyasına bakın. SSL sertifika sorunları, firewall kuralları (5044 portu) ve Logstash servisinin çalışıp çalışmadığı sıklıkla sorun çıkarır.

Elasticsearch disk doldu: ILM policy yoksa veya yanlış yapılandırılmışsa bu olur. Acil durum için /_cat/indices?v&s=store.size:desc endpoint’iyle en büyük index’leri bulun ve eski olanları silin.

Logstash yavaş işliyor: Pipeline worker sayısını artırın ve batch size’ı optimize edin. Geoip filter CPU yoğun bir işlemdir, zorunlu değilse kapatın.

Kibana’da tarih/saat sorunu: Kibana’nın zaman dilimiyle Winlogbeat’in zaman diliminin uyuşmadığı durumlar olabiliyor. Tüm sistemlerde UTC kullanın, görüntüleme için Kibana’dan timezone ayarı yapın.

Sonuç

ELK Stack ile Windows Event Log analizi ilk kurulumda zahmetli görünüyor ama çalışır hale getirdiğinizde gerçekten vazgeçilmez bir araç oluyor. 50 sunucunun loglarını tek bir ekrandan görmek, brute force saldırılarını dakikalar içinde tespit etmek, hesap kilitlenmelerinin nedenini anında bulmak, bunların hepsi operasyonel verimliliği ciddi ölçüde artırıyor.

Başlarken şunlara dikkat edin: ILM policy’yi en baştan kurun, Event ID filtrelemesini doğru yapın yoksa gereksiz veri trafiğiyle boğulursunuz, güvenliği kapatmayın ve mutlaka TLS kullanın, heap size’ı doğru ayarlayın.

Bu altyapıyı bir kez kurduğunuzda “nasıl bu kadar süre Event Viewer ile idare ettim?” diye soracaksınız. Eski günlere dönmek mümkün olmuyor.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir