Graylog ile Merkezi Log Yönetimi: Kurulum ve Yapılandırma Rehberi

Onlarca sunucu varken hangisinde ne olduğunu takip etmeye çalışmak, gece 2’de açılan bir ticket’a yanıt verirken 10 farklı sunucuya SSH açıp grep koşturmak… Bu tabloyu yaşadıysan, merkezi log yönetiminin neden hayat kurtarıcı olduğunu zaten biliyorsundur. Graylog, bu sorunu çözmek için üretilmiş, open-source, güçlü ve production ortamlarında ciddi ölçekte kullanılabilen bir çözüm. Bu yazıda sıfırdan bir Graylog kurulumu yapacak, log kaynaklarını bağlayacak ve gerçek senaryolarda nasıl kullanacağını göreceğiz.

Graylog Nedir ve Neden Kullanmalısın?

Graylog, merkezi log toplama, depolama, arama ve analiz platformudur. Arka planda Elasticsearch (ya da OpenSearch) ile MongoDB kullanır. Elasticsearch logları depolar ve arama motorunu sağlarken, MongoDB Graylog’un kendi metadata’sını, stream konfigürasyonlarını ve kullanıcı verilerini tutar.

Alternatifleriyle kısaca karşılaştıralım:

  • ELK Stack (Elasticsearch + Logstash + Kibana): Çok güçlü ama konfigürasyonu karmaşık, kaynak tüketimi yüksek
  • Loki + Grafana: Hafif, label bazlı, ama full-text search zayıf
  • Splunk: Enterprise düzeyi ama lisans maliyeti ciddi
  • Graylog: Orta yol. Kolay kurulum, güçlü arama, makul kaynak tüketimi, ücretsiz Open Source Edition

Graylog’u öne çıkaran birkaç özellik var. GELF (Graylog Extended Log Format) desteği, yapılandırılmış log gönderimini kolaylaştırır. Stream ve Pipeline sistemi ile logları gerçek zamanlı olarak sınıflandırabilir ve dönüştürebilirsin. Alert mekanizması ile belirli koşullarda mail, Slack veya webhook bildirimi gönderebilirsin.

Kurulum Mimarisi

Küçük/orta ölçekli bir ortam için şu yapıyı öneririm:

  • Graylog sunucusu: 4 CPU, 8 GB RAM (minimum)
  • Elasticsearch/OpenSearch: Ayrı sunucu veya aynı sunucuda (dev için)
  • MongoDB: Graylog ile aynı sunucuda olabilir

Bu yazıda tek sunucu üzerinde Docker Compose ile kurulum yapacağız. Sonra production için önerileri de vereceğim.

Docker Compose ile Kurulum

Önce bir proje dizini oluşturalım:

mkdir /opt/graylog && cd /opt/graylog

Şimdi docker-compose.yml dosyasını oluşturuyoruz:

cat > docker-compose.yml << 'EOF'
version: '3'
services:
  mongodb:
    image: mongo:6.0
    container_name: graylog-mongodb
    volumes:
      - mongodb_data:/data/db
    restart: unless-stopped
    networks:
      - graylog

  opensearch:
    image: opensearchproject/opensearch:2.11.0
    container_name: graylog-opensearch
    environment:
      - "OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g"
      - "bootstrap.memory_lock=true"
      - "discovery.type=single-node"
      - "action.auto_create_index=false"
      - "plugins.security.disabled=true"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - opensearch_data:/usr/share/opensearch/data
    restart: unless-stopped
    networks:
      - graylog

  graylog:
    image: graylog/graylog:5.2
    container_name: graylog
    environment:
      - GRAYLOG_PASSWORD_SECRET=uzunbirsecretyazburaya32karakterdenfazla
      - GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
      - GRAYLOG_HTTP_EXTERNAL_URI=http://YOUR_SERVER_IP:9000/
      - GRAYLOG_ELASTICSEARCH_HOSTS=http://opensearch:9200
      - GRAYLOG_MONGODB_URI=mongodb://mongodb:27017/graylog
    ports:
      - "9000:9000"      # Web arayüzü
      - "12201:12201/udp" # GELF UDP
      - "12201:12201/tcp" # GELF TCP
      - "1514:1514/udp"  # Syslog UDP
      - "1514:1514/tcp"  # Syslog TCP
      - "5555:5555/tcp"  # Raw/Plaintext
    volumes:
      - graylog_data:/usr/share/graylog/data
    restart: unless-stopped
    depends_on:
      - mongodb
      - opensearch
    networks:
      - graylog

volumes:
  mongodb_data:
  opensearch_data:
  graylog_data:

networks:
  graylog:
    driver: bridge
EOF

Yukarıdaki konfigürasyonda dikkat etmen gereken birkaç şey var. GRAYLOG_ROOT_PASSWORD_SHA2 alanındaki hash, admin parolasının SHA256 hashidir. Kendi parolanı hashlemek için:

echo -n "senimsifren" | sha256sum | cut -d' ' -f1

GRAYLOG_PASSWORD_SECRET en az 32 karakter olmalı. Şöyle üretebilirsin:

pwgen -N 1 -s 96
# veya
openssl rand -hex 48

Şimdi stack’i başlatalım:

docker compose up -d

# Logları izlemek için
docker compose logs -f graylog

Birkaç dakika sonra http://YOUR_SERVER_IP:9000 adresine girip admin kullanıcısıyla giriş yapabilirsin.

İlk Input Yapılandırması

Graylog’a log gönderebilmek için önce bir Input tanımlamalısın. Web arayüzünden System > Inputs menüsüne git.

En sık kullanılan input tipleri:

  • GELF UDP: Uygulama logları için, hafif ve hızlı
  • GELF TCP: Güvenilir iletim gereken durumlar için
  • Syslog UDP/TCP: Linux sistem logları için
  • Beats: Filebeat kullanıyorsan bu tip

Syslog UDP Input için Launch new input tıkla, Syslog UDP seç, port olarak 1514 gir ve kaydet. Artık bu porta gelen syslog trafiğini dinliyorsun.

Linux Sunuculardan Log Gönderme

rsyslog ile Gönderim

Çoğu Linux dağıtımında varsayılan olarak gelen rsyslog, Graylog’a log iletmek için idealdir:

# /etc/rsyslog.d/90-graylog.conf dosyası oluştur
cat > /etc/rsyslog.d/90-graylog.conf << 'EOF'
# GELF formatında UDP ile gönder
$template GRAYLOGRFC5424,"<%PRI%>%PROTOCOL-VERSION% %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%n"

*.* @GRAYLOG_SERVER_IP:1514;GRAYLOGRFC5424
EOF

systemctl restart rsyslog

TCP ile göndermek istersen @ yerine @@ kullan. UDP için @, TCP için @@ kuralını aklında tut.

Filebeat ile Daha Gelişmiş Log Toplama

Özellikle uygulama log dosyalarını toplamak için Filebeat çok daha uygun. Kurulum:

curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | gpg --dearmor -o /usr/share/keyrings/elastic.gpg
echo "deb [signed-by=/usr/share/keyrings/elastic.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | tee /etc/apt/sources.list.d/elastic-8.x.list
apt update && apt install filebeat -y

/etc/filebeat/filebeat.yml konfigürasyonu:

cat > /etc/filebeat/filebeat.yml << 'EOF'
filebeat.inputs:
  - type: log
    enabled: true
    paths:
      - /var/log/nginx/access.log
      - /var/log/nginx/error.log
    fields:
      source: nginx
      environment: production
    fields_under_root: true
    multiline.pattern: '^d{4}-d{2}-d{2}'
    multiline.negate: true
    multiline.match: after

  - type: log
    enabled: true
    paths:
      - /var/log/syslog
    fields:
      source: syslog
      environment: production
    fields_under_root: true

output.logstash:
  hosts: ["GRAYLOG_SERVER_IP:5044"]

processors:
  - add_host_metadata: ~
  - add_cloud_metadata: ~
EOF

systemctl enable filebeat && systemctl start filebeat

Beats input için Graylog web arayüzünden Beats tipinde yeni bir input eklemen gerekiyor, port olarak 5044 kullan.

Pipeline ile Log Zenginleştirme

Graylog’un en güçlü özelliklerinden biri Processing Pipelines. Gelen logları parse edebilir, alan ekleyebilir, değiştirebilir veya reddedebilirsin.

System > Pipelines > Manage Pipelines menüsünden yeni pipeline oluştur. Örnek bir kural:

# Nginx access log parse kuralı
rule "parse nginx access log"
when
  has_field("source") AND to_string($message.source) == "nginx"
then
  let matches = grok(
    pattern: "%{COMBINEDAPACHELOG}",
    value: to_string($message.message)
  );
  set_field("client_ip", matches["clientip"]);
  set_field("http_method", matches["verb"]);
  set_field("request_path", matches["request"]);
  set_field("response_code", to_long(matches["response"]));
  set_field("response_size", to_long(matches["bytes"]));
end

Bu sayede nginx loglarındaki IP adresi, HTTP metodu, response kodu gibi alanlar otomatik parse edilir ve arama yaparken bu alanlara göre filtreleme yapabilirsin.

Bir başka pratik örnek, yüksek response kodlarına göre ciddiyet seviyesi belirleme:

rule "set http error level"
when
  has_field("response_code") AND to_long($message.response_code) >= 500
then
  set_field("alert_level", "critical");
  set_field("needs_attention", true);
end

Stream Yönetimi

Streams, gelen logları gerçek zamanlı olarak kategorize etmene yarar. Örneğin tüm nginx loglarını ayrı bir stream’e, tüm authentication loglarını başka bir stream’e yönlendirebilirsin.

Web arayüzünden Streams > Create Stream ile yeni stream oluştur. Sonra stream rules ekle. Örneğin:

  • Field: source | Type: match exactly | Value: nginx

Bu şekilde source alanı nginx olan tüm mesajlar bu stream’e düşer. Stream’e bir index set bağlayarak bu logları ayrı Elasticsearch index’inde saklayabilir, farklı retention politikası uygulayabilirsin.

Gerçek Dünya Senaryosu: SSH Brute Force Tespiti

Merkezi log yönetiminin en güzel use case’lerinden biri güvenlik olaylarını tespit etmek. Şöyle bir senaryo düşün: 10 sunucun var ve birinde brute force saldırısı var. Klasik yöntemle her sunucuda /var/log/auth.log grep’lemek yerine Graylog’da şunu yapabilirsin.

Önce Searches ekranında şu sorguyu çalıştır:

message:"Failed password" AND source:* 

Sonra Quick Values ile hangi IP adreslerinin en çok başarısız giriş denemesi yaptığını saniyeler içinde görebilirsin. Daha da ileriye gidip bir Alert tanımlayalım.

Alerts > Conditions > Create Condition menüsünden:

  • Condition type: Message Count
  • Stream: Auth loglarının olduğu stream
  • Search query: message:"Failed password"
  • Threshold: 10 (mesaj sayısı)
  • Time range: 5 dakika

Bu koşul tetiklendiğinde bir Notification ile Slack’e veya e-posta ile bildirim gönderebilirsin.

Gerçek Dünya Senaryosu: Uygulama Hata Takibi

Geliştiriciler Java ya da Python uygulamaları için GELF entegrasyonu yapabilir. Python örneği:

pip install graypy
# Python uygulama log konfigürasyonu
import logging
import graypy

logger = logging.getLogger('myapp')
logger.setLevel(logging.DEBUG)

handler = graypy.GELFUDPHandler('GRAYLOG_SERVER_IP', 12201)
logger.addHandler(handler)

# Kullanım
logger.error('Veritabanı bağlantısı başarısız', 
             extra={'db_host': 'db01', 'retry_count': 3, 'user': 'appuser'})

Bu şekilde gönderilen loglar Graylog’a yapılandırılmış olarak gelir. db_host, retry_count gibi alanlar ayrı field olarak saklanır ve bunlara göre arama yapabilirsin.

Log Retention ve Index Yönetimi

Uzun vadede en önemli konulardan biri disk yönetimi. System > Indices menüsünden index set oluşturabilirsin.

Dikkat etmen gereken parametreler:

  • Index Shards: Single node için 1 yeterli, cluster için sunucu sayısına göre artır
  • Index Replicas: Dev için 0, production için minimum 1
  • Max number of indices: Kaç index tutacağını belirler
  • Rotation strategy: Index boyutu veya zaman bazlı rotasyon
  • Retention strategy: Eski index’leri sil veya arşivle

Örnek bir konfigürasyon için şu değerleri öneririm: rotation için max index size 10 GB veya 30 gün (hangisi önce doluyorsa), retention olarak max 12 index tut. Bu sayede yaklaşık 1 yıllık log tutmuş olursun.

Disk kullanımını komut satırından da izleyebilirsin:

# OpenSearch index durumunu kontrol et
curl -s http://localhost:9200/_cat/indices?v | sort -k9 -h

# Toplam disk kullanımı
curl -s http://localhost:9200/_cat/allocation?v

Graylog API Kullanımı

Graylog REST API’si ile birçok işlemi otomatize edebilirsin. Örneğin belirli bir arama sonucunu script ile çekmek:

#!/bin/bash
GRAYLOG_HOST="http://localhost:9000"
API_USER="admin"
API_PASS="sifren"

# Son 1 saatteki hata sayısını çek
RESULT=$(curl -s -u "${API_USER}:${API_PASS}" 
  -H "Accept: application/json" 
  "${GRAYLOG_HOST}/api/search/universal/relative?query=level%3Aerror&range=3600&limit=1&fields=timestamp")

ERROR_COUNT=$(echo $RESULT | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['total_results'])")

echo "Son 1 saatte ${ERROR_COUNT} hata logu"

# Threshold aşıldıysa alert gönder
if [ "$ERROR_COUNT" -gt 100 ]; then
  echo "UYARI: Hata sayısı eşiği aştı!" | mail -s "Graylog Alert" [email protected]
fi

Production Ortamı için Öneriler

Tek sunucu kurulumu dev ve küçük ortamlar için yeterli, ama production için dikkat etmen gereken birkaç nokta var.

Kaynak boyutlandırması için:

  • Günlük 10 GB log altı: 4 CPU, 8 GB RAM, 500 GB SSD
  • Günlük 10-50 GB log: 8 CPU, 16 GB RAM, 2 TB SSD
  • Günlük 50 GB üzeri: Cluster kurulumu, ayrı Elasticsearch node’ları

JVM heap ayarları: OpenSearch için heap, RAM’in yarısını geçmemeli ve 32 GB’ı aşmamalı. 8 GB RAM’li bir sunucuda:

# OpenSearch JVM ayarı
OPENSEARCH_JAVA_OPTS=-Xms4g -Xmx4g

Güvenlik için mutlaka:

  • Graylog web arayüzü önüne Nginx reverse proxy ve SSL koy
  • API erişimini firewall ile kısıtla
  • Graylog input portlarını sadece log kaynaklarına aç
  • MongoDB ve OpenSearch’i external erişime kapatıp sadece Graylog’a izin ver
  • Admin parolasını güçlü tut, LDAP/AD entegrasyonu değerlendir

Nginx reverse proxy konfigürasyonu:

server {
    listen 443 ssl;
    server_name graylog.sirketiniz.com;

    ssl_certificate /etc/letsencrypt/live/graylog.sirketiniz.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/graylog.sirketiniz.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:9000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {
    listen 80;
    server_name graylog.sirketiniz.com;
    return 301 https://$server_name$request_uri;
}

Dashboard Oluşturma

Graylog’un dashboard özelliği ile tek ekranda tüm ortamın durumunu görebilirsin. Dashboards > Create Dashboard ile başla.

Pratik widget önerileri:

  • Message Count: Son 24 saatte toplam log sayısı
  • Quick Values (source): Hangi sunucu en çok log üretiyor
  • Quick Values (level): Error/Warning/Info dağılımı
  • Field Chart (response_code): HTTP response code trendi
  • Message Table: Son hata logları listesi

Dashboard’u ekiple paylaşmak için URL’yi kopyalaman yeterli, ayrıca public paylaşım da ayarlayabilirsin.

Sık Yapılan Hatalar ve Çözümleri

Log gelmiyor: İlk kontrol noktası Input’un çalışıp çalışmadığı. System > Inputs ekranında ilgili input’un durumuna bak. RUNNING değilse log gelmiyor demektir.

OpenSearch sarı/kırmızı durumda: Tek node kurulumda replica sayısı 0 olmalı. Eğer yellow durumundaysa muhtemelen replica bekleniyordur:

curl -X PUT "localhost:9200/_settings" 
  -H 'Content-Type: application/json' 
  -d '{"index": {"number_of_replicas": 0}}'

Graylog yavaş: Büyük olasılıkla OpenSearch heap yetersiz ya da disk I/O darboğazı var. docker stats ile kaynak kullanımını kontrol et.

Timestamp yanlış: rsyslog veya Filebeat tarafında timezone konfigürasyonunu kontrol et. Graylog kendi içinde UTC kullanır, web arayüzünde timezone ayarını düzeltebilirsin.

Sonuç

Graylog, doğru kurulduğunda bir sysadmin’in günlük hayatını ciddi ölçüde kolaylaştırır. SSH açıp grep koşturmak yerine tek bir arayüzden tüm ortamını görmek, saniyeler içinde hata analizini tamamlamak, gece yarısı bildirimleri otomatize etmek… Bunların hepsi mümkün ve bu yazıda anlattıklarımla bunu yapmak için gereken temeli attın.

Küçük bir ortam için başlangıç olarak tek node Docker Compose kurulumu yeterli. Ortam büyüdükçe OpenSearch’ü ayrı bir sunucuya ya da cluster’a taşı, Graylog’u da ayrı node’larla büyüt. Stream’leri ve pipeline’ları doğru konfigüre etmek biraz zaman alıyor ama bir kez oturtunca, ne kadar değerli olduğunu ilk production incident’ında anlayacaksın.

Son bir tavsiye: Log yönetimi sadece arıza anında işe yarar bir şey değil. Trend analizi, kapasite planlaması ve güvenlik denetimleri için de vazgeçilmez. Graylog’u kurduktan sonra dashboard’ları düzenli incele, anomali gördüğünde araştır. Zamanla ortamının “normal” davranışını öğrenirsin ve sorunları kullanıcılar şikayet etmeden önce yakalarsın.

Similar Posts

Bir yanıt yazın

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