FAQ

Bu, Arcivéo Monitor kurulumu, yapılandırması ve bakımı için bir kılavuzdur. Bölümler gruplandırılmıştır: genel bakış, panelin dağıtımı, güvenlik araçlarının bağlanması, yerleşik modüller ve tanılama. Komutlar sağdaki düğmeyle kopyalanabilir.

Nereden başlamalı

01. Panel kurulumu — bir yöntem seçin

Panel kurulumu ayrı adım adım sayfalarda anlatılıyor. Bir yöntem seçin:

Emin değilseniz otomatiği seçin. Bu başvuru kılavuzu SSL, araçlar, cron ve tanılama için tek kaynak olmaya devam eder — kurulum sayfaları hiçbir şeyi tekrarlamadan onun bölümlerine bağlantı verir.

Genel bakış

02. Arcivéo Monitor nedir

Arcivéo Monitor, sunucu güvenliği panelidir. Kurulu araçlardan (Fail2ban, UFW, Lynis, ModSecurity, AIDE, ClamAV, Auditd, CrowdSec, Suricata, Falco vb.) verileri toplar ve bunları gösterge paneli, saldırı haritası ve her araç için ayrıntılı sayfalar içeren tek bir arayüzde gösterir.

Monitor aktif bir koruma aracı değildir; saldırıları kendisi engellemez. Görevi, halihazırda çalışan araçlardan gelen bilgileri toplayıp bunları anlaşılır bir biçimde sunmaktır.

03. Monitör sunucuda nasıl çalışır

Monitör yalnızca yerel olarak çalışır — izlediği sunucunun üzerine kurulması gerekir. Herhangi bir SSH veya uzak API yoktur.

Tüm komutlar (fail2ban-client, ufw status, ipset list vb.) panel tarafından web sunucusu kullanıcısı adına (genellikle www-data, hosting panellerinde site hesabı) çalıştırılır; bunlar dar kapsamlı sudo izinleridir — yalnızca belirli araçlara, genel root erişimi olmadan. Sonuçlar ayrıştırılıp tarayıcıda gösterilir.

Birden fazla sunucu için monitörü her birine ayrı ayrı, benzersiz bir alan adıyla kurun.

04. Güvenlik Puanı nasıl hesaplanır

Puan en yüksek değerden başlar ve tespit edilen her sorun için düşer:

  • UFW etkin değil — −30
  • Fail2ban çalışmıyor (etkin jail yok) — −25
  • WebAuthn anahtarı yok — −15
  • Lynis hardening index < 60 — −20; 60–79 — −10
  • IPset ipsum yüklenmedi — −10
  • ClamAV tehdit buldu — −20
  • AIDE dosya değişiklikleri — −15
  • SSL süresi doldu — −30, <14 gün içinde doluyor — −15, <30 gün — −5
  • CrowdSec kurulu ama çalışmıyor — −5
  • Suricata kurulu ama çalışmıyor — −5
  • Veritabanı/önbellek (MySQL, PostgreSQL, Redis…) dışarıdan erişilebilir — −10
  • SSH ile root girişine izin veriliyor (PermitRootLogin yes) — −20
  • Bekleyen güvenlik güncellemeleri var — −5

Sonuç: 80+ = Korumalı, 60–79 = Dikkat, <60 = Tehlikede.

ClamAV, AIDE, CrowdSec ve Suricata için düşüşler yalnızca araç kuruluysa uygulanır. Veritabanı başlatılmamış Lynis ve AIDE “veri yok” olarak gösterilir ve puanı düşürmez. Bugünkü saldırı sayısı panoda gösterilir ama Güvenlik Puanını etkilemez.

Ayarlar ve lisans

05. WebAuthn — iki adımlı kimlik doğrulama

WebAuthn — donanım anahtarı ile parolasız kimlik doğrulama standardıdır. YubiKey, Touch ID, Face ID, Windows Hello ve Passkey destekler.

Parolayla giriş yaptıktan sonra sistem, kayıtlı anahtar üzerinden onay ister. Parola sızsa bile fiziksel anahtar veya biyometri olmadan giriş yapılamaz.

Yapılandırmak için yan menüden WebAuthn Anahtarları bölümünü açın ve “Anahtar kaydet” düğmesine tıklayın. Hemen iki anahtar kaydedin: tek anahtarınız kaybolur veya bozulursa, panele o anahtarla giriş yapamazsınız.

WebAuthn yalnızca HTTPS üzerinden çalışır. HTTP bağlantısında anahtarla kayıt ve giriş kullanılamaz.

06. Bildirimler: Telegram ve E-posta

Panel, güvenlik raporunu Telegram'a ve e-postaya gönderebilir (düğmeyle veya zamanlanmış). “Ayarlar” bölümünden yapılandırılır.

Telegram. bot token ve chat id gerekir:

  1. Telegram'da @BotFather/newbot yazın → 123456:ABC... biçiminde bir token alın.
  2. Yeni botunuza herhangi bir mesaj yazın (size yanıt verebilmesi için).
  3. chat id öğrenin: @userinfobot botuna yazın veya https://api.telegram.org/bot<TOKEN>/getUpdates adresini açıp "chat":{"id":...} değerini bulun.
  4. Token ve chat id değerlerini “Ayarlar” → Telegram bölümüne girin, “Kaydet ve test gönder” düğmesine basın.

E-posta. “Ayarlar” → E-posta bölümünde iki yöntemden biri:

  • SMTP — sunucu, bağlantı noktası (465/SSL veya 587/TLS), e-posta kutunuzun kullanıcı adı ve parolası;
  • Resend — modern API: API anahtarını (re_...) ve doğrulanmış gönderen alan adını girin.
“Test gönder” düğmesi kanalı anında sınar. Otomatik raporun zamanlaması cron ile yapılır (“Tüm cron görevleri” bölümü): cron göndermeyi tetikler, kanallar ise ayarlardan alınır.

Rapor durumu: “DİKKAT” veya “OK”. Başlık yalnızca gerçek bir sorun ya da bekleyen bir eylem varsa “DİKKAT” olur: ClamAV tehdidi bulundu, AIDE'de dosya değişiklikleri, kritik Falco olayları (son 24 saatte Emergency/Alert/Critical), Monit'te çöken bir servis, yeniden başlatma gerekiyor, SSL süresi doluyor (≤14 gün) veya güvenlik güncellemeleri bekliyor. Arka plan gürültüsü — botların SSH deneme saldırıları, fail2ban tarafından yasaklanan IP'ler, Suricata uyarıları, Lynis uyarıları ve ModSecurity'nin zaten savuşturduğu istekler — durumu yükseltmez, bu yüzden rapordaki bu sayılar tek başına “DİKKAT” anlamına gelmez.

07. Lisans — girme ve etkinleştirme

Ayrıntılı izleme modülleri (Lynis, UFW, ModSecurity, saldırı haritası, AIDE, ClamAV vb.) yalnızca geçerli bir lisans varken açılır. Lisans olmadan da panel, ayarlar ve hesap çalışır, ancak modüller "Lisans gerekli" kartını gösterir.

Hesaptan satın aldıktan sonra ARCIVEO-XXXX-XXXX-XXXX-XXXX biçiminde bir etkinleştirme kodunuz olur. Bu kodu panelinizin alan adında "etkinleştirmeniz" gerekir — böylece kod, panele yapıştırdığınız imzalı bir lisans dosyasına ([license] bloğu) dönüşür.

Nasıl etkinleştirilir (3 adım):

  1. Etkinleştirme kodunu alın. my.arciveo.com hesabı → "Lisanslar" / "Lisans etkinleştirme" bölümü — ARCIVEO-… kodunu kopyalayın.
  2. Kodu kendi alan adınızda etkinleştirin. Yine hesapta "Lisans etkinleştirme" bölümünü açın ve şunları girin: etkinleştirme kodu, e-postanız ve panel alan adı (monitörün açıldığı adres, örn. monitor.example.com). Etkinleştir'e basın — sistem bu alan adına bağlı bir lisans dosyası oluşturur ve "Kopyala" düğmesiyle birlikte alanda gösterir.
  3. Anahtarı panele yapıştırın. Lisansın tüm metnini kopyalayın → panelde "Ayarlar" → "Lisans" bloğunu açın, yapıştırın ve "Kaydet"e basın. Modüller anında açılır.

Panel anahtarı kriptografik olarak doğrular: imza, alan adı bağlantısı ve geçerlilik süresi.

Etkinleştirme sırasındaki alan adı, panelin adresiyle tam olarak aynı olmalıdır. Onu config.php içindeki APP_URL sabitinden alın ve yalnızca ana bilgisayar adını girin — https:// ve www öneki olmadan. Etkinleştirme tek seferliktir: kod, girilen alan adı için bir lisansa dönüşür ve yeniden etkinleştirilemez — alan adında hata olursa anahtar panelinize uymaz ve kod harcanmış olur. Bu nedenle alan adını dikkatle girin.
Süre dolduysa veya alan adı değiştiyse panelin üst kısmında bir uyarı belirir. Lisans alan adına kalıcı olarak bağlıdır ve başka bir alan adına taşınmaz: yeni bir süre ya da yeni bir alan adı için yeni bir anahtar gerekir (hesaptan satın alınır ve tek seferlik etkinleştirilir).

08. config.php dosyası — tüm panel ayarları

Panelin tüm temel parametreleri, kök dizindeki (public/ klasörünün yanında) tek bir config.php dosyasında sıradan define() sabitleriyle tanımlanır. Dosya kurulum sırasında oluşturulur; elle düzenlemeniz nadiren gerekir — çoğunlukla domain değişikliği, taşıma ya da başka bir veritabanına bağlanma durumunda. Herhangi bir düzenlemeden sonra PHP-FPM'i yeniden başlatın (aksi hâlde OPcache nedeniyle değişiklikler uygulanmaz).

Kendi değerlerinizi vurgulanan yerlere yazın; geri kalanını olduğu gibi bırakın:

// --- Veritabanı --- define('DB_HOST', 'localhost'); // olduğu gibi bırakın define('DB_NAME', 'db_name'); // veritabanını oluştururken belirlediğiniz ad define('DB_USER', 'user'); // veritabanını oluştururken belirlediğiniz kullanıcı define('DB_PASS', 'db_password'); // veritabanını oluştururken belirlediğiniz parola define('DB_CHARSET', 'utf8mb4'); // olduğu gibi bırakın // --- Uygulama --- define('APP_URL', 'https://monitor.example.com'); // panel adresi, sonunda eğik çizgi olmadan define('TIMEZONE', 'Europe/Istanbul'); // saat diliminiz // --- Oturum süresi --- define('SESSION_LIFETIME', 28800); // yeniden girişe kadar boşta kalma, sn (28800 = 8 sa)

Veritabanı. MySQL/MariaDB bağlantı bilgileri:

  • DB_HOST — veritabanı sunucusu, neredeyse her zaman localhost;
  • DB_NAME — panelin veritabanı adı;
  • DB_USER — veritabanı kullanıcısı (yalnızca kendi veritabanına erişim);
  • DB_PASS — bu kullanıcının parolası;
  • DB_CHARSET — bağlantı kodlaması, utf8mb4 olarak bırakın.

Uygulama.

  • APP_URL — panelin tam adresi (örn. https://monitor.example.com). Lisansın etkinleştirildiği domain ile aynı olmalı — aksi hâlde anahtar reddedilir (bkz. “Lisans” bölümü);
  • TIMEZONEPHP saat dilimi: yalnızca panelin tarih ve saati nasıl gösterdiğini etkiler. Cron görevlerinin çalışma zamanını etkilemez — orada sistemin saat dilimi geçerlidir (bkz. “Tüm cron görevleri”).

Oturum süresi. SESSION_LIFETIME — saniye cinsinden oturum boşta kalma zaman aşımı (kayan: her etkinlikte yenilenir). Varsayılan olarak 28800 = 8 saat; bu boşta kalma süresinden sonra panel yeniden giriş yapmanızı ister. Örneğin, 3600 = 1 saat, 86400 = bir gün.

Hata günlükleme. Hatalar ziyaretçilere asla gösterilmez, logs/php_errors.log dosyasına yazılır — bunları “Uygulama günlükleri” sayfasında görebilirsiniz. Bu satırları (display_errors=0, log_errors=1, error_log yolu) genellikle değiştirmenize gerek yoktur — ayarlar doğrudan dosyada tanımlıdır ve php.ini'ye bağlı değildir.

config.php — gizli bir dosyadır. İçinde veritabanı parolası vardır. Panel kök dizininde (public/ yanında) bulunur, bu panelin web kökü (DocumentRoot) ise tam olarak panel köküdür, public/ değil. Dosyanın kendisi “sızmaz”: kök .htaccess içinde onun için açık bir yasak vardır (Require all denied) — sunucu 403 döndürür. Bu kural olmadan bile kaynak sızmazdı: bu PHP'dir — sunucu onu çalıştırır, metin olarak vermez. Her ihtimale karşı: bunu herkese açık depolara koymayın ve gerçek parolayla destek ekibine göndermeyin. Dosya izinleri — 640.
Taşıma ya da erişimi geri kazanma sırasında bu dosya, bilgilerin ana kaynağıdır: veritabanı adı, kullanıcı ve parola tam olarak buradan alınır (bkz. “Panelin güncellenmesi ve taşınması” ile “Erişimi geri kazanma” bölümleri).

Güvenlik araçları

09. UFW Güvenlik Duvarı

UFW (Uncomplicated Firewall), nftables/iptables için basit bir arayüzdür. Açıkça izin verilenler dışındaki tüm gelen bağlantı noktalarını kapatır. “UFW Güvenlik Duvarı” sayfası durumu ve kuralları gösterir.

sudo apt install ufw # SSH (etkinleştirmeden ÖNCE zorunlu!) ve web erişimine izin ver sudo ufw allow OpenSSH sudo ufw allow 80,443/tcp # Veritabanını dışarıya kapat (yalnızca yerel erişim) sudo ufw deny 3306 # Etkinleştir ve kontrol et sudo ufw enable sudo ufw status verbose
ufw enable öncesinde mutlaka SSH'a izin verin (ufw allow OpenSSH), aksi halde sunucuya erişimi kaybedersiniz.
Panodaki “Dış maruziyet” UFW'yi dikkate alır: deny kuralıyla kapatılan bir bağlantı noktası dışarıdan erişilebilir sayılmaz.
Skipping adding existing rule bir hata değildir. UFW bu şekilde aynı kuralın zaten var olduğunu ve tekrar eklemediğini bildirir. Otomatik yapılandırma yeniden çalıştırıldığında (idempotenttir) bu normal bir mesajdır — tepki vermenize gerek yoktur.

10. Fail2ban Kurulumu

Başarısız giriş denemesi sayısı aşıldığında IP adresini otomatik engeller. SSH, nginx, Apache ve diğer servislerin günlüklerini analiz eder.

sudo apt install fail2ban sudo systemctl enable --now fail2ban # Durumu kontrol et: sudo fail2ban-client status
Çalışan yapılandırma (onlarca jail içeren ve ipsum ile otomatik ban yapan jail.local) bir sonraki bölümde.

11. Fail2ban + ipsum çalışan yapılandırması

Temel kurulum yukarıda. Burada, onlarca etkin jail ve binlerce yasak sağlayan çalışan yapılandırma var: genel ayarlar, temel jail'lar ve ipsum listesinden zararlı IP'lerin otomatik yasaklanması.

/etc/fail2ban/jail.local dosyası — genel ayarlar ve en önemli jail'lar:

[DEFAULT] bantime = 1w findtime = 900 maxretry = 3 backend = systemd banaction = nftables-multiport ignoreip = 127.0.0.1/8 ::1 <YOUR_IP> <TRUSTED_NETS> # Kademeli yasak: her tekrar daha uzun sürer bantime.increment = true bantime.factor = 2 bantime.maxtime = 5w bantime.rndtime = 300 [sshd] enabled = true maxretry = 5 bantime = -1 # SSH kaba kuvvet için kalıcı yasak findtime = 3600 # Tekrar edenler: birkaç kez yasak yiyen kalıcı olarak yasaklanır [recidive] enabled = true logpath = /var/log/fail2ban.log banaction = %(banaction_allports)s bantime = -1 findtime = 86400 maxretry = 2 [http-get-dos] enabled = true maxretry = 100 findtime = 300 bantime = 1w # Web hizmetleri (apache-*, nginx-*, php-url-fopen, phpmyadmin-syslog): [nginx-http-auth] enabled = true port = http,https [apache-badbots] enabled = true port = http,https # … ve hizmetlere göre diğer jail'lar (dovecot, exim, postfix-sasl, # mysqld-auth, vsftpd, portscan, pam-generic) — enabled = true
ignoreip içine kendi IP'nizi ve güvenilir ağları mutlaka ekleyin, aksi halde kendinizi yasaklayabilirsiniz. Değişikliklerden sonra: sudo fail2ban-client reload.

ipsum engel listesinin otomatik yüklenmesi — root cron içine (sudo crontab -e): level 1 (100+ bin IP), güvenlik duvarında engellenen ipsum kümesine yüklenir (ayrıntılar için “IPset engel listesi” bölümüne bakın):

# 04:00 — ipset ipsum güncellemesi (level 1, maksimum kapsam): 0 4 * * * /usr/local/bin/load-ipsum.sh >> /path/to/monitor/logs/cron.log 2>&1
Kümenin adı ipsum olmalıdır — panoyu bu okur (“IPset ipsum” kartı). Seviyeler: levels/1.txt — maksimum kapsam, levels/3.txt — daha kesin (3+ kaynak).

“Güvenlik Monitörü” neden iki bölgeye ayrılmıştır. Koruma iki düzeyde çalışır ve pano bunları karıştırmaz:

  • Gerçek saldırılar (reaktif) — fail2ban'ın yakaladığı her şey: canlı sızma denemeleri (sshd, apache-*, nginx-* vb. jail'lar) ve ısrarlı tekrar edenler (recidive jail'ı — daha önce birkaç kez yasaklananlar). Bunlar size gerçekten saldıran IP'lerdir; saldırı haritasında ve “Zaman çizelgesi”nde yer alırlar.
  • Önleyici engelleme (proaktif) — bilinen zararlı IP'lerin genel engel listesi ipset ipsum, güvenlik duvarında DROP kuralıyla engellenir. Bu adresler çoğunlukla sunucunuza hiç dokunmamıştır — önceden kesilirler; “IPset ipsum” sayacı, önleyici olarak ne kadarının kesildiğini gösterir.

Fark basit: reaktif — “bunlar saldırdı ve yasak yedi”, önleyici — “bunlar denemeden önce engellendi”. Önceden recidive'e yapay olarak ipsum list-3 yükleniyordu (eski “listeli recidive” ayrımı buradan geliyor); artık recidive yalnızca gerçek tekrar edenlerdir, önleme ise tamamen güvenlik duvarındadır.

12. IPset engelleme listesi (ipsum)

ipsum — günlük olarak güncellenen, kötü amaçlı IP'lerin herkese açık listesidir. Monitor, yüklenen adres sayısını panoda ve saldırı haritasında gösterir ve Güvenlik Puanı'nda hesaba katar (küme yüklü değilse −10).

fail2ban olmadan en basit yöntem — iptables ile engelleme yapan ayrı bir ipsum kümesidir:

# Kümeyi oluştur (bir kez): sudo ipset create ipsum hash:ip # Güncelleme betiği /usr/local/bin/update-ipsum.sh: #!/bin/bash ipset flush ipsum for ip in $(curl -s https://raw.githubusercontent.com/stamparm/ipsum/master/levels/3.txt); do ipset add ipsum "$ip" 2>/dev/null done iptables -C INPUT -m set --match-set ipsum src -j DROP 2>/dev/null \ || iptables -I INPUT -m set --match-set ipsum src -j DROP # Cron (sudo crontab -e, her gün 4:00'te): 0 4 * * * /usr/local/bin/update-ipsum.sh
fail2ban-recidive ile gelişmiş yöntem “Çalışan Fail2ban + ipsum yapılandırması” bölümündedir.
ipset bellekte tutulur ve yeniden başlatmada kaybolur. Yalnızca günlük cron kullanırsanız, yeniden başlatmadan sonraki çalıştırmaya kadar küme boş kalır (pano 0 gösterir). Kümeyi açılışta da yükleyin — yüklemeyi bir betiğe taşıyıp @reboot'a bağlayın. Ayrıca create … -exist komutu maxelem 300000 limitini belirler (varsayılan 65536 — level 1 sığmaz, “Hash is full” hatası verir):
# /usr/local/bin/load-ipsum.sh #!/bin/bash curl -s https://raw.githubusercontent.com/stamparm/ipsum/master/levels/1.txt \ | grep -v '^#' | sed 's/^/add ipsum /' \ | (echo "create ipsum hash:ip hashsize 131072 maxelem 300000 -exist"; echo "flush ipsum"; cat) \ | ipset restore -exist # sudo crontab -e — her gün 04:00'te VE her açılışta: 0 4 * * * /usr/local/bin/load-ipsum.sh @reboot sleep 60 && /usr/local/bin/load-ipsum.sh
Otomatik kurulumda nasıl çalışır. Betik, tam level 1 listesini (100 binden fazla IP) ipsum kümesine yükler ve güvenlik duvarını yükleyici yönetiyorsa (yeni VPS — “Tam”/“Hafif” profiller), kümeyi bir DROP kuralıyla UFW'ye bağlar — bu IP'lerden gelen trafik gerçekten engellenir. Kural ESTABLISHED,RELATED kuralından sonra gelir, bu yüzden mevcut bağlantılar (SSH'niz dahil) kopmaz — yalnızca listeden gelen yeni bağlantılar kesilir. Küme, ipsum-load.service servisi yüklenirken güvenlik duvarından önce geri yüklenir (yoksa UFW başlamazdı) ve 04:00'teki cron ile güncellenir. Zaten yapılandırılmış bir sunucuda (panel, kendi güvenlik duvarı) yükleyici güvenlik duvarına dokunmaz — orada ipsum pano ve saldırı haritası için bir liste olarak kalır, istenirse DROP kuralı elle eklenir (en basit yöntem iptables … --match-set ipsum … -j DROP ile — yukarıda). Otomatik kurulumda elle bir şey yapmanıza gerek yoktur.

13. CrowdSec kurulumu

Fail2ban'ın kolektif tehdit istihbaratına sahip modern alternatifi: topluluk kaynaklı engellemelerin yanı sıra kendi kurallarınız. Engellemeleri güvenlik duvarına uygulamak için ayrı bir bouncer gerektirir.

curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash sudo apt install crowdsec sudo systemctl enable --now crowdsec # iptables/nftables için bouncer: sudo apt install crowdsec-firewall-bouncer-iptables # Durumu denetle: sudo systemctl status crowdsec sudo cscli decisions list sudo cscli bouncers list
Panelde “Çalışmıyor” durumu = servis kuruludur ama hizmet etkin değildir (monitör bunu systemctl is-active crowdsec ile denetler). Başlatmak için: sudo systemctl enable --now crowdsec; çökerse sudo journalctl -u crowdsec -n 30 çıktısına bakın. “Çalışmıyor” durumundaki her servis için aynı kural geçerlidir (Suricata, Falco, Monit, MySQL).
Panoda “0 senaryo” veya “0 bouncer”. CrowdSec kutudan neredeyse boş gelir — koleksiyonlar olmadan hiçbir şey tespit etmez, kayıtlı bir bouncer olmadan da engellemeler güvenlik duvarına uygulanmaz. Temel koleksiyonları kurun ve bouncer'ın listede olduğundan emin olun:
# Temel koleksiyonlar (Linux + SSH + web sunucusu): sudo cscli collections install crowdsecurity/linux crowdsecurity/sshd crowdsecurity/base-http-scenarios sudo systemctl reload crowdsec # Bouncer listede ve etkin bağlantı durumunda olmalı: sudo cscli bouncers list
Bouncer günlüğünde stream halted / engellemeler uygulanmıyor. Bu, sahipsiz bir api anahtarıdır: bouncer cscli bouncers list içinden silinmiş ama eski anahtarı /etc/crowdsec/bouncers/*.yaml içinde kalmıştır. Bouncer'ı yeniden kaydedin ve yeni anahtarı girin:
sudo cscli bouncers add fw-bouncer # yeni bir api_key üretir # bu anahtarı /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml dosyasındaki api_key: alanına girin sudo systemctl restart crowdsec-firewall-bouncer
Otomatik kurulum (“Tam koruma” profili) koleksiyonları kendisi kurar ve firewall-bouncer'ı kaydeder — bunu elle yapmak yalnızca manuel kurulumda veya CrowdSec'e elle müdahaleden sonra gerekir.

14. AIDE Kurulumu

AIDE (Advanced Intrusion Detection Environment) dosya sisteminin anlık görüntüsünü alır ve her kontrolde /etc, /bin, /usr içindeki değişiklikleri bildirir. Kurulumdan sonra veritabanının başlatılması (aideinit) zorunludur.

sudo apt install aide # Veritabanı başlatma (5–15 dakika): sudo aideinit sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db # Ubuntu 24.04: /var/lib/aide dizini 700 modunda oluşturulur (sahibi _aide), # ve panel (www-data) veritabanını göremez → “Başlatılmadı” gösterir. # Dizine geçiş izni verin (veritabanı dosyaları 600 kalır): sudo chmod 755 /var/lib/aide # İlk kontrol, monitörün okuduğu loga YAZARAK. # Ubuntu/Debian'da aide açık bir --config gerektirir (aksi halde “missing configuration”; # aide.wrapper ikili dosyası yeni sürümlerde gelmiyor): sudo bash -c 'aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1'
aideinit sırasında terminal 5–15 dakika Running aide --init... satırında bekler — bu normaldir (tüm dosya sisteminin hash'lenmesi, disk yükü). Ctrl+C ile kesmeyin. İşlem “takılı” görünüyor ama bir şey yazmıyorsa — muhtemelen gizli bir Overwrite existing aide.db.new [Yn]? sorusuna yanıt bekliyordur (Y tuşuna basın). Başka bir oturumdan etkinliği kontrol edin: pgrep -af aide.
aideinit hatası: “21_aide_spamassassin … printf: invalid number” (return code 20) — Ubuntu 22.04'te AIDE yapılandırma parçacığının bilinen bir hatası. Veritabanı oluşturulmaz. Bozuk parçacığı taşıyıp tekrar deneyin:
sudo mv /etc/aide/aide.conf.d/21_aide_spamassassin /etc/aide/21_aide_spamassassin.disabled sudo aideinit sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
Panodaki durumlar. “Başlatılmadı” = panel veritabanı dosyasını göremiyor: ya aideinit çalıştırılmadı, ya da (Ubuntu 24.04) /var/lib/aide dizini 700 modunda oluşturuldu ve www-data erişemiyor — sudo chmod 755 /var/lib/aide ile çözülür (yukarıdaki bloğa bakın). “Kontrol yapılmadı” = veritabanı var ama kontrol henüz çalıştırılmadı — bu bir hata değildir. Monitör sonuçları /var/log/aide/aide.log dosyasından okur.
Düzenli kontrol → panel için log. Standart /etc/cron.daily/aide, yeni Ubuntu/Debian'da /var/log/aide/aide.log dosyasını gerekli biçimde yazmayabilir (ve aide.wrapper onlarda artık yok). Daha güvenilir olanı, açık --config ile kendi cron görevinizi eklemektir — logu root altında 644 modunda yazar ve monitör onu ek grup olmadan okur:
# sudo crontab -e — her gün saat 02:00'de kontrol: 0 2 * * * /usr/bin/aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1 # Zamanlamayı beklemeden şimdi çalıştırın: sudo bash -c 'aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1'
Otomatik kurulum tüm bunları zaten yapar: chmod 755 /var/lib/aide ve saat 02:00'deki kontrol cron'u — elle bir şey yapmanıza gerek yok.
İlk başlatmayı temiz bir sunucuda yapın — web uygulamalarını kurmadan önce. Meşru değişikliklerden sonra veritabanını yeniden oluşturun: sudo aideinit && sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db.

15. ClamAV kurulumu

Linux için antivirüs tarayıcısı. Özellikle /var/www dizinini PHP kabuklarına ve zararlı koda karşı taramak için kullanışlıdır.

sudo apt install clamav clamav-daemon sudo systemctl enable --now clamav-daemon # İmza veritabanını güncelle: sudo freshclam # Klasörü elle tara: sudo clamscan -r /var/www --infected
clamd servisi enable --now sonrasında “Etkin değil” mi gösteriyor? Üç tipik neden:

1. Yapılandırmada Example satırı kalmış — bu satır durdukça clamd başlamayı reddeder:

sudo sed -i '/^Example/d' /etc/clamav/clamd.conf sudo systemctl restart clamav-daemon

2. İmza veritabanı indirilmemiş — clamd onsuz başlamaz:

sudo systemctl stop clamav-freshclam sudo freshclam sudo systemctl start clamav-freshclam sudo systemctl restart clamav-daemon

3. Sadece yükleniyordur — clamd ~8 milyon imzayı 30–60 saniyede belleğe yükler. Bekleyin ve kontrol edin: systemctl is-active clamav-daemon (activating durumu → hâlâ yükleniyor).

Tanılama: sudo journalctl -u clamav-daemon -n 30 --no-pager.
Panoda “Taranan dosya: 0” / “Son tarama: —” mi görünüyor? clamd servisi yalnızca imzaları bellekte tutar, kendisi zamanlanmış hiçbir tarama yapmaz. Panel planlı tarama sonuçlarını gösterir, bu yüzden tarayıp günlüğe yazan bir cron gerekir. Otomatik kurulum /usr/local/bin/clamav-scan.sh sarmalayıcısını ve 01:30 için bir cron kurar — ilk çalıştırmadan sonra “Taranan dosya” ve “Son tarama” dolar. Zamanlamayı beklemeden hemen çalıştırmak için: sudo /usr/local/bin/clamav-scan.sh.

16. Linux Malware Detect (maldet) Kurulumu

Linux Malware Detect (LMD) — web tehditlerine yönelik kötü amaçlı yazılım tarayıcısı: PHP shell'leri, web arka kapıları, yükleyiciler. ClamAV motorunu kullanır ve onu kendi imzalarıyla tamamlar.

wget https://www.rfxn.com/downloads/maldetect-current.tar.gz tar -xzf maldetect-current.tar.gz dir=$(ls -d maldetect-*/ | head -1) && cd "$dir" && sudo bash install.sh && cd ~ rm -rf maldetect-* maldetect-current.tar.gz # İmzaları güncelle: sudo maldet -u # /var/www dizinini tara: sudo maldet -a /var/www
LMD ve ClamAV birlikte iyi çalışır. Son rapor: maldet --report.
Kurulum sırasında update-rc.d: error: unable to read /etc/init.d/maldet satırı görülebilir — bu zararsızdır. maldet init.d kullanmaz; imza güncellemeleri ve taramalar /etc/cron.daily/maldet üzerinden çalıştırılır. Aşağıda installation completed görüyorsanız her şey kurulmuş demektir.
Kurulu olduğu halde sayfada LMD için “Kurulu değil” mi yazıyor? maldet apt ile değil /usr/local/maldetect içine kurulur ve open_basedir etkinken varlığı shell üzerinden kontrol edilir — “Veriler sunucuda olduğu halde sayfa boş” bölümüne bakın.

17. Suricata Kurulumu

Ağ tabanlı saldırı tespit sistemi: trafiği paket düzeyinde analiz eder ve binlerce saldırı imzasını tanır. ModSecurity'yi tamamlar (o HTTP düzeyinde, Suricata ise TCP/IP düzeyinde çalışır).

sudo add-apt-repository ppa:oisf/suricata-stable sudo apt update && sudo apt install suricata # Güncel kuralları indir: sudo suricata-update sudo systemctl enable --now suricata
Suricata “Etkin” görünüyor ama panel uyarı göstermiyor / olay sayısı 0 mı? Suricata /var/log/suricata/eve.json dosyasını root altında, dizinde 750 modunda yazıyor ve web sunucusu (www-data) bunu okuyamıyor. Dizini geçişe açın — içindeki dosyalar korunmuş kalır:
sudo chmod o+rx /var/log/suricata
Otomatik kurulum bunu kendisi yapar — elle yapmaya gerek yok.

18. Falco Kurulumu

eBPF/kernel module aracılığıyla sistem çağrılarını yakalar ve anormallikleri gerçek zamanlı olarak tespit eder: nginx'ten shell, web sürecinin /etc/passwd dosyasını okuması, /bin dizinine yazma vb.

curl -fsSL https://falco.org/repo/falcosecurity-packages.asc > /tmp/falco.asc gpg --dearmor < /tmp/falco.asc | sudo tee /usr/share/keyrings/falco-archive-keyring.gpg > /dev/null sudo chmod 644 /usr/share/keyrings/falco-archive-keyring.gpg && rm /tmp/falco.asc echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] https://download.falco.org/packages/deb stable main" \ | sudo tee /etc/apt/sources.list.d/falcosecurity.list sudo apt update && sudo apt install falco sudo systemctl enable --now falco
Monitör, Falco olaylarını journalctl -u falco üzerinden okur (sudo olmadan — systemd-journal grubu üzerinden). www-data'nın bu grupta olduğundan emin olun — bkz. manuel kurulum sayfasındaki “sudo Yapılandırması” (madde 2).
“24 saatte 0 olay” bir hata değil, normaldir. Falco olay tabanlıdır: her şey yolundayken sessiz kalır ve yalnızca bir anormallikte olay kaydeder (web sürecinden shell, /etc/passwd okuma, sistem dizinlerine yazma). Sakin bir sunucuda günde sıfır kritik olay sağlıklı bir durumdur.
Panel için dosya çıktısı daha güvenilirdir. journalctl üzerinden okuma, günlüğe erişim izni gerektirir; panelin olayları kararlı biçimde görebilmesi için otomatik kurulum Falco'da file_output/var/log/falco/falco.log özelliğini etkinleştirir ve hizmete UMask=0022 ayarını verir (günlük web sunucusu tarafından okunur). Yeni bir kurulumda bunu elle yapılandırmaya gerek yoktur.

19. ModSecurity (WAF) Kurulumu

ModSecurity — Apache veya Nginx için bir web güvenlik duvarı (WAF). Uygulama katmanındaki saldırıları engeller: SQL enjeksiyonları, XSS, dizin geçişi, tarayıcılar.

# Apache: sudo apt install libapache2-mod-security2 sudo a2enmod security2 # OWASP Core Rule Set kural seti: sudo apt install modsecurity-crs # ZORUNLU: bu dosya olmadan kural motoru kapalıdır sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf sudo sed -i 's/^SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/modsecurity/modsecurity.conf sudo apache2ctl configtest && sudo systemctl reload apache2 # Doğrulama: 403 döndürmeli curl -s -o /dev/null -w '%{http_code}\n' "https://monitor.example.com/?id=1%20UNION%20SELECT%201,2--"
Paketi kurmak tek başına hiçbir şeyi korumaz. Apache, yapılandırmaları IncludeOptional /etc/modsecurity/*.conf satırıyla dâhil eder, ancak paket yalnızca modsecurity.conf-recommended dosyasını koyar — bu da *.conf maskesine uymaz. Onu modsecurity.conf olarak kopyalamazsanız SecRuleEngine değeri Off kalır: modül yüklüdür, CRS kuralları yüklüdür, fakat trafik denetlenmez ve denetim günlüğü oluşturulmaz. Ara mod DetectionOnly istekleri engellemeden yalnızca olayları günlüğe yazar — panel bunu sarı renkte gösterir.

Panelin denetim günlüğüne erişimi. /var/log/apache2/modsec_audit.log günlüğü root'a aittir (640 izinleri) ve web kullanıcısı onu okuyamaz. Panel verileri bir sarmalayıcı üzerinden alır — bunu oluşturun:

sudo tee /usr/local/bin/monitor-modsec >/dev/null <<'EOF' #!/bin/sh echo "ENGINE=$(grep -hE '^SecRuleEngine[[:space:]]+' /etc/modsecurity/*.conf 2>/dev/null | tail -1 | awk '{print $2}')" echo "---LOG---" tail -n 3000 /var/log/apache2/modsec_audit.log 2>/dev/null echo "---RULES---" for f in /etc/modsecurity/crs/rules/*.conf /usr/share/modsecurity-crs/rules/*.conf /etc/modsecurity/custom-rules.conf; do [ -f "$f" ] && { echo "===FILE:$(basename "$f")==="; cat "$f"; } done EOF sudo chown root:root /usr/local/bin/monitor-modsec sudo chmod 755 /usr/local/bin/monitor-modsec # /etc/sudoers.d/monitor içinde (kullanıcı = PHP-FPM'in çalıştığı kullanıcı): # www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-modsec
Sarmalayıcı, girintisiz son SecRuleEngine yönergesini alır: girintili satırlar <LocationMatch>/<Directory> bloklarının içindedir (örneğin phpMyAdmin için WAF'ın devre dışı bırakılması) ve genel modu belirlemez.
sudoers'taki kullanıcı FPM havuzunun kullanıcısıyla aynı olmalıdır: normal Apache/Debian'da bu www-data, HestiaCP'de sitenin havuzu site sahibinin adına çalışır (örneğin admin) — grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf ile kontrol edin.
Site bir Nginx proxy'sinin arkasındaysa (HestiaCP), Apache istemci olarak proxy'nin kendisini görür — panel, saldırganın gerçek IP adresini X-Forwarded-For başlığından alır. İstatistiklere yalnızca bir kuralın tetiklendiği işlemler dahil olur: SecAuditLogRelevantStatus yönergesi denetim günlüğüne tüm 4xx/5xx yanıtlarını yazar, bu nedenle oraya sıradan 403/500'ler de dahil olur — panel bunları WAF olayı saymaz.
---RULES--- bloğu “Tüm etkin kurallar” bölümü için gereklidir — panel yalnızca tetiklenenleri değil, yüklenmiş tüm CRS + özel kuralları gösterir. for f in … döngüsündeki üç yol — CRS kuralları ve yerel eklemeler için tipik konumlardır; farklı bir düzeniniz varsa (paket dosyaları kendi dizinine koyuyorsa veya özel kurallar /etc/modsecurity/custom-rules.conf içinde değilse), gerçek yolları sudo grep -rl 'IncludeOptional\|^Include ' /etc/apache2/mods-enabled/security2.conf /etc/apache2/conf-enabled/*.conf 2>/dev/null komutuyla bulun ve listeye ekleyin. Sarmalayıcı eskiyse (bu bölüm yoksa) — bölüm yalnızca “kullanılamıyor” uyarısı gösterir, sayfanın geri kalanı eskisi gibi çalışır.

20. Auditd Kurulumu

Auditd (Linux Audit Daemon), sistem çağrılarını çekirdek düzeyinde kaydeder: oturum açma ve kapatma işlemleri, sudo komutları, başarısız kimlik doğrulama denemeleri, dosya değişiklikleri. Monitor, bugünkü oturum açmaları, başarısız denemeleri ve sudo komutlarını gösterir.

sudo apt install auditd audispd-plugins sudo systemctl enable --now auditd # Durumu ve olayları kontrol et: sudo systemctl status auditd sudo ausearch -m USER_LOGIN -ts today
Monitor, olayları ausearch (/usr/sbin/ausearch) aracılığıyla ve gerektiğinde /var/log/audit/audit.log dosyasından tail komutuyla okur. Her ikisi de sudoers içinde olmalıdır.

21. Monit Kurulumu

Servisleri (nginx, php-fpm, mysql vb.) izler ve çöktüklerinde yeniden başlatır. E-posta ile uyarı gönderebilir.

sudo apt install monit sudo systemctl enable --now monit # Yapılandırma dosyaları: sudo nano /etc/monit/monitrc ls /etc/monit/conf.d/
Monitör, servis listesini monit status üzerinden alır. /etc/monit/monitrc içinde HTTP arayüzü etkin olmalıdır (allow localhost içeren set httpd bloğu), aksi hâlde monit status hata döndürür.
Panoda “izlenen 0 servis” mi görünüyor? İki nedeni var. (1) HTTP arayüzü kapalı — monitrc içinde set httpd satırı yorum satırı hâlinde (varsayılan olarak # set httpd port 2812 … şeklinde gelir). Bloğun yorumunu kaldırın ve localhost'a izin verin. (2) Etkin bir httpd tek başına hiçbir şey izlemez — Monit yalnızca check stanzalarında tanımlananları sayar; bunlar olmadan arayüz çalışsa bile liste boş kalır. Asgari çalışan yapılandırma:
# /etc/monit/conf.d/00-httpd — localhost için HTTP arayüzü: set httpd port 2812 use address localhost allow localhost # check stanzaları örnekleri (neyin izleneceği): check process sshd with pidfile /run/sshd.pid start program = "/usr/bin/systemctl start ssh" stop program = "/usr/bin/systemctl stop ssh" check filesystem rootfs with path / if space usage > 90% then alert
sudo monit -t # söz dizimini denetle (Control file syntax OK) sudo systemctl reload monit sudo monit status
Otomatik kurulum, 2812 portunda httpd ve bir denetim setiyle hazır bir conf.d yerleştirir — yeni bir kurulumda elle ayarlamaya gerek yoktur.
Servis “Hatalı” durumunda mı? Monitör yalnızca durumu gösterir ve servisleri web panelinden bilinçli olarak yeniden başlatmaz (bu, güvenlik panelinde uzaktan root komutu yürütmek olurdu). Tanılama ve yeniden başlatma — SSH üzerinden Monit ile:
sudo monit status <service> # hatanın nedeni sudo monit restart <service> # Monit üzerinden yeniden başlat # Monit servisi başlatamıyorsa — kendi birimine bakın: sudo systemctl status <unit> --no-pager sudo journalctl -u <unit> -n 50 --no-pager

22. PSAD kurulumu (port taraması tespiti)

PSAD iptables günlüğünü analiz ederek port taramalarını ve ağ saldırılarını tespit eder ve her kaynağa bir tehdit seviyesi (1–5) atar. fail2ban ve Suricata'yı tamamlar.

sudo apt install psad # PSAD, iptables günlüğünü okur — günlük kaydını etkinleştirmeniz gerekir (UFW bunu kendisi yapar). # Salt iptables için INPUT/FORWARD zincirlerine LOG kuralları ekleyin. sudo psad --sig-update sudo systemctl enable --now psad
Monitor verileri psad --Status üzerinden okur (sudoers içinde gereklidir). iptables günlük kaydı olmadan sayfa boş görünür — herhangi bir tarama olana kadar bu normaldir.

23. AppArmor / SELinux (erişim denetimi)

Mandatory Access Control, bir programın hangi dosya ve kaynaklara erişebileceğini kısıtlar; program ele geçirilse bile bu kısıtlama geçerlidir. Ubuntu/Debian'da varsayılan olarak AppArmor kullanılır (genellikle kurulu ve etkin durumdadır).

# AppArmor (Ubuntu/Debian): sudo apt install apparmor apparmor-utils sudo systemctl enable --now apparmor sudo aa-status # profilleri denetle
Monitor durumu aa-status üzerinden okur (sudoers'ta olması gerekir). enforce/complain modundaki profil sayısını ve profilsiz süreçleri gösterir.

“Yüklenen profiller” sayısının enforce + complain toplamından fazla olması normaldir. AppArmor 4.x'te (Ubuntu 24.04 ve sonrası) unconfined modu geldi: profil çekirdeğe yüklenir ancak hiçbir şeyi kısıtlamaz. Ubuntu, user namespaces kullanan programlar için (tarayıcılar, torrent istemcileri ve benzerleri) onlarca profili böyle işaretler. Böyle profiller olduğunda “Yüklenen profiller” kartı kehribar rengine döner ve sayılarını gösterir — örneğin 120 yüklü ve 26 enforce içinde iken unconfined: 90. Gerçekte yalnızca enforce modundaki profiller koruma sağlar; Ubuntu 22.04'te (AppArmor 3.x) bu mod yoktur ve sayılar her zaman tutar.

sudo aa-status | grep -E "profiles are" # modlara göre dağılım sudo aa-enforce /etc/apparmor.d/profile-name # profili enforce moduna al
Ubuntu'nun bilerek unconfined bıraktığı profilleri enforce moduna almak yalnızca bilinçli yapılmalıdır: bunlar hata sonucu değil, aksi halde programların kendisi bozulacağı için kapatılmıştır. complain modundaki profiller ise farklıdır: orada kurallar zaten yazılmıştır, yalnızca uygulanmıyordur.

24. debsums kurulumu (paket bütünlüğü)

debsums, kurulu paketlerin dosyalarının depodaki sağlama toplamlarıyla eşleştiğini denetler — değiştirilmiş sistem ikili dosyalarını tespit eder (AIDE'yi tamamlar). Tam denetim 1–2 dakika sürer, bu yüzden cron ile çalıştırılır; panel sonucu data/debsums/debsums.log dosyasından okur ve kendisi kategorilere ayırır (yalnızca ikili dosyalar ve kütüphaneler önemlidir).

Görev root-cron'a eklenir (sudo crontab -e). Hazır debsums-scan.sh sarmalayıcısı /usr/local/bin/ içine konur (chmod +x; bkz. cron görevleri özeti) ve raporu kendisi panelin data/debsums/ dizinine yazar.

sudo apt install debsums # Cron satırı (her gün 4:30): 30 4 * * * /usr/local/bin/debsums-scan.sh >> /path/to/monitor/logs/cron.log 2>&1

debsums-scan.sh sarmalayıcısı panelin data/ dizinini kendisi bulur — yolu belirtmeye gerek yoktur.

Sunucuda /etc/ (yapılandırmalar) ve /usr/share/ (kaynaklar) içindeki değişiklikler genellikle normaldir — panel bunları ayrı bir renkle işaretler. İkili dosyalardaki ve kütüphanelerdeki değişiklikler (/bin, /sbin, /usr/lib vb.) endişe vericidir — “İkili dosyalar / kütüphaneler” kartı tam da bunları gösterir.

25. Lynis raporlarını yapılandırma

Lynis elle veya cron ile çalıştırılır. Rapor, projenin data/lynis/ klasörüne kaydedilmelidir — monitör lynis-report.dat dosyasını okur.

# Tek seferlik çalıştırma (kendi panel kök yolunuzu girin): sudo lynis audit system --report-file /path/to/monitor/data/lynis/lynis-report.dat # Günlük denetim — cron satırı (hazır lynis-scan.sh betiği /usr/local/bin/ içinde, özete bakın): 0 3 * * * /usr/local/bin/lynis-scan.sh >> /path/to/monitor/logs/cron.log 2>&1
İlk çalıştırmadan sonra “Lynis Denetimi” sayfası hardening index, uyarıları ve önerileri hemen gösterir.
Lynis sayfasındaki “Denetimi başlat” düğmesi. Bu düğme lynis-scan.sh betiğini doğrudan panelden arka planda çalıştırır (cron'u beklemeden): “Taranıyor…” gösterir ve tamamlanınca raporu kendisi günceller. Bunun için web kullanıcısının betiği çalıştıracak bir sudoers satırına ihtiyacı vardır — kurulumcu bunu otomatik olarak /etc/sudoers.d/monitor dosyasına ekler. Panel elle/daha önce kurulduysa, dosyada zaten belirtilen kullanıcıyla bu satırı ekleyin:
u=$(sudo awk '/NOPASSWD/ && !/lynis-scan/ {print $1; exit}' /etc/sudoers.d/monitor) [ -n "$u" ] && echo "$u ALL=(ALL) NOPASSWD: /usr/local/bin/lynis-scan.sh" | sudo tee -a /etc/sudoers.d/monitor sudo visudo -c && sudo chmod 440 /etc/sudoers.d/monitor

26. Logwatch raporlarının yapılandırılması

Logwatch, günlük raporları projenin data/logwatch/ klasörüne .txt biçiminde kaydetmelidir. Monitor son raporu ve arşivi gösterir.

# Günlük (6:00) — cron satırı (hazır logwatch_daily.sh sarmalayıcısı /usr/local/bin/ içinde, özete bakın): 0 6 * * * /usr/local/bin/logwatch_daily.sh >> /path/to/monitor/logs/cron.log 2>&1

Panel modülleri

27. Ağ monitörü (yerleşik)

Ağ monitörü kurulum gerektirmez — bu, panelin yerleşik bir sayfasıdır. Sunucunun ağ durumunu yerel kaynaklardan gösterir:

  • arayüzler ve trafik — /proc/net/dev üzerinden;
  • bağlantı durumları (UP/DOWN) ve IP — ip aracılığıyla;
  • bağlantılar ve dinlenen portlar — ss aracılığıyla;
  • son 24 saatin çekirdek ağ olayları — journalctl -k aracılığıyla.

İlk üç kaynak sudo olmadan çalışır, bu yüzden arayüzler, trafik, bağlantılar ve portlar anında görünür. “Çekirdek olayları” bloğu journalctl -k kullanır — bu, systemd-journal grubu üzerinden okunur (“sudo yapılandırması”, madde 2), sudo gerekmez. Her şeyin web kullanıcısına erişilebilir olduğunu doğrulamak için:

# www-data adına doğrulama (PHP bu kullanıcıyla çalışır): sudo -u www-data bash -c 'cat /proc/net/dev' sudo -u www-data bash -c 'ip -o link show' sudo -u www-data bash -c 'ss -s' sudo -u www-data journalctl -k --no-pager -n 5
“Çekirdek ağ olayları” bloğu, çekirdek ağ yığınının olaylarını gösterir (bağlantı up/down değişimi, taşıyıcı hataları, “network unreachable”). Güvenlik duvarının UFW BLOCK kayıtları buraya düşmez — bunlar “UFW güvenlik duvarı” ve “Saldırı haritası” sayfalarındadır. Yeşil onay işaretli boş blok = son 24 saatte ağ arızası olmadı.

28. Disk ve SMART

Yerleşik sayfa üç şey gösterir:

  • Dosya sistemleri — bölüm doluluğu (df); ≥%90'da çubuk kırmızıya döner;
  • Depolama aygıtları — disk listesi (lsblk), yalnızca gerçek olanlar (loop/snap gizlidir);
  • Sağlık (SMART) — disk durumu ve öznitelikleri (smartctl).

Alan ve aygıt listesi ayar gerektirmeden hemen çalışır. SMART için smartmontools paketi gerekir. Web süreci disk aygıtlarına doğrudan erişemediğinden, SMART cron ile data/disk/smart.txt dosyasına yazılır, panel de onu okur.

Görev root cron'a eklenir (sudo crontab -e). Hazır sarmalayıcı smart-scan.sh, /usr/local/bin/ dizinine konur (chmod +x; cron görevleri özetine bakın) ve panelin data/disk/ dizinine kendisi yazar.

sudo apt install smartmontools # Cron satırı (her 30 dakikada bir): */30 * * * * /usr/local/bin/smart-scan.sh >> /path/to/monitor/logs/cron.log 2>&1

Sarmalayıcı smart-scan.sh panelin data/ dizinini kendisi bulur — yol belirtmeniz gerekmez. İçeride lsblk -e7,11 loop/cdrom'u hariç tutar.

Sanal disklerde (QEMU/KVM ve benzerleri) genellikle yalnızca genel “sağlık: OK” durumu görünür; sıcaklık, çalışma saatleri ve yeniden atanan sektörler boş olabilir — bu normaldir. Fiziksel sunucuda tüm öznitelikler görüntülenir.

29. Performans (CPU/RAM/Ağ/Disk)

Bu sayfa sunucunun son 24 saatteki yük geçmişini gösterir — Load Average, CPU kullanımı ve I/O bekleme, RAM/Swap, ağ trafiği (alım/gönderim), disk I/O (okuma/yazma), disk ve inode doluluğu, açık dosya tanımlayıcıları ve MySQL bağlantıları, ayrıca güncel TCP bağlantı ve süreç sayısı.

Verileri cron/collect_metrics.php toplar — 5 dakikada bir sayaçların bir “ham” anlık görüntüsünü (/proc/loadavg, /proc/meminfo, /proc/stat, /proc/net/dev, /proc/diskstats, df/df -i, /proc/sys/fs/file-nr, SHOW GLOBAL STATUS LIKE 'Threads_connected') system_metrics veritabanı tablosuna yazar; yüzdeleri ve hızları sayfa, komşu anlık görüntüler arasındaki farka göre kendisi hesaplar (disk/inode/tanımlayıcı doluluğu ve MySQL bağlantıları anlık değerlerdir, yeniden hesaplanmaz). Sudo gerekmez — kaynaklar root yetkisi olmadan okunur. 24 saatten eski noktalar her yazma işleminde otomatik silinir.

# Cron satırı (her 5 dakikada bir): */5 * * * * /usr/local/bin/collect-metrics-all.sh >> /path/to/monitor/logs/cron.log 2>&1

Sarmalayıcı collect-metrics-all.sh (cron görevleri özetine bakın) sunucudaki tüm kurulu panel örneklerini kendisi bulur ve her birinin cron/collect_metrics.php dosyasını site sahibi adına çalıştırır.

Toplayıcı en az iki kez çalışana dek (kurulumdan sonraki ilk ~10 dakika) sayfa “veriler toplanıyor” gösterir — grafiklerin hızları ve yüzdeleri hesaplayabilmesi için en az bir komşu nokta çiftine ihtiyacı var.

Yük uyarıları (“Ayarlar” → “Yük uyarıları” bölümü) — CPU/RAM/disk/inode eşiği aşıldığında panel Telegram/E-posta üzerinden bildirim gönderir (günlük raporla aynı kanallar — uyarılar için ayrıca etkinleştirmeye gerek yok), metrik normale döndüğünde de bir bildirim daha. Eşik aşımı sürerken tekrar tekrar bildirim göndermez: bir sonraki bildirim ancak “normale döndü → yeniden aşıldı” döngüsünden sonra gelir.

Eşikler her çalışmada (5 dakikada bir) aynı collect_metrics.php tarafından kontrol edilir — ayrı bir cron gerekmez. “Zaten bildirildi / henüz bildirilmedi” durumu data/alerts_state.json içinde, eşikler ise panel ayarlarında tutulur.

30. Saldırı haritası (GeoIP)

“Saldırı haritası” sayfası, IP adresinin ülkesini geoiplookup komutuyla belirler. GeoIP paketi olmadan ülkeler belirlenmez ve haritada noktalar görünmez:

sudo apt install geoip-bin geoip-database # Kontrol: geoiplookup 8.8.8.8
Sudo gerekmez — /usr/share/GeoIP/GeoIP.dat veritabanı herkes tarafından okunabilir, sonuçlar tmp/geoip_cache.json içinde önbelleğe alınır. Haritanın kendisi (Leaflet + OpenStreetMap döşemeleri) tarayıcıda yüklenir — panelin açık olduğu bilgisayarda internet gerekir.

31. Dış maruz kalma, güncellemeler ve otomatik güncellemeler

Bir aracın “açık/kapalı” olmasını değil, sunucunun gerçek güvenlik durumunu gösteren iki yerleşik pano kartı. Kurulum gerektirmez, sudo olmadan yerel olarak okunur.

Dış maruz kalma — kaç servisin tüm arayüzleri (0.0.0.0/[::]) dinlediği ve dışarıdan erişilebilir olduğu. Dışarıya bir veritabanı veya önbellek açıksa (MySQL, PostgreSQL, Redis, MongoDB, Memcached, Elasticsearch) kırmızı işaretler — bu doğrudan bir açıktır (Güvenlik Puanına −10). Kaynak: ss -tuln.

Kart kırmızıysa veritabanını dış dünyaya kapatın: 127.0.0.1 adresine bağlayın (MySQL/PostgreSQL yapılandırmasında bind-address, Redis'te bind 127.0.0.1) veya UFW'de portu kapatın.
“Açık port” ≠ “dışarıdan erişilebilir”. 127.0.0.1 (loopback) dinleyen bir servis yalnızca sunucunun kendisine görünür — port “açık” olsa bile dışarıdan erişilemez. Bu yüzden loopback'e bağlı 25 portundaki Postfix güvenlidir: otomatik yapılandırma inet_interfaces = loopback-only ayarını yapar (ayrıca nötr bir smtpd_banner — sürüm ifşasına ilişkin Lynis MAIL-8818 uyarısını kapatır). “Dış maruz kalma” kartı, dışarıya yalnızca 0.0.0.0/[::] dinleyenleri sayar; loopback servisleri buna girmez.
Lynis MAIL-8818 manuel (postayı kendiniz kurduysanız): /etc/postfix/main.cf içinde smtpd_banner = $myhostname ESMTP (sürüm ve işletim sistemi olmadan) ve inet_interfaces = loopback-only ayarlayın, ardından sudo systemctl restart postfix.

Güvenlik güncellemeleri — kaç güvenlik yamasının kurulmayı beklediği ve çekirdek güncellemesi sonrası yeniden başlatma gerekip gerekmediği (yama varsa Güvenlik Puanına −5). Kaynak: /usr/lib/update-notifier/apt-check, /var/run/reboot-required dosyası. Ayrıntılı liste “Güvenlik güncellemeleri” sayfasında.

# Güncellemeleri kurmak için: sudo apt update && sudo apt upgrade # Dışarıya ne dinlendiğini kontrol et: ss -tuln | grep -E '0\.0\.0\.0|\[::\]'
Güncelleme kartı Ubuntu/Debian'da çalışır (update-notifier-common). apt-check yoksa monitör yamaları apt-get -s upgrade ile sayar.

Otomatik güvenlik güncellemeleri (unattended-upgrades) — “Güvenlik güncellemeleri” sayfasındaki ayrı bir kart, güvenlik yamalarının otomatik kurulumunun etkin olup olmadığını ve en son ne zaman çalıştığını gösterir. Sudo gerekmez — durum apt-config dump ile okunur.

sudo apt install unattended-upgrades sudo dpkg-reconfigure -plow unattended-upgrades # etkinleştir # Neyin etkin olduğunu kontrol et: apt-config dump | grep Unattended-Upgrade

Bakım

32. Yedekleme

Yedek en önemli güvencedir: veri kaybı her türlü saldırıdan daha kötüdür. İki şey gerekir — sunucu/site yedeği ve ayrıca panel veritabanı yedeği (orada kullanıcılar, WebAuthn anahtarları, ayarlar, lisans bulunur).

Seçenek A — HestiaCP: kullanıcının Backup sekmesi → yedek oluşturma düğmesi (veya sunucu ayarlarında zamanlanmış olarak). Yedek, siteleri ve veritabanlarını kapsar.

Seçenek B — elle (cron): veritabanı dökümü + panelin data/ dizininin arşivi:

# root cron (sudo crontab -e) — her gün 2:30'da yedek (kendi adlarınızı/yollarınızı girin): 30 2 * * * mysqldump -u root MY_DB | gzip > /var/backups/monitor-db-$(date +\%F).sql.gz 40 2 * * * tar czf /var/backups/monitor-data-$(date +\%F).tar.gz -C /path/to/monitor data # 14 günden eski arşivleri sil: 0 3 * * * find /var/backups -name 'monitor-*' -mtime +14 -delete
Aynı sunucudaki yedek hatalardan korur ama sunucu kaybından korumaz. Arşivleri harici bir depolamaya kopyalayın (başka sunucu, S3, rclone ile buluta). Geri yüklemenin gerçekten çalıştığını doğrulayın.

33. Panelin güncellenmesi ve taşınması

Yeni sürüme güncelleme. Önce yedek alın. Ardından kod dosyalarını verilerinizi koruyarak yeniden yükleyin:

  • üzerine yaz (kod): public/, includes/, assets/, cron/, database/, ayrıca kök dizindeki .htaccess (ön denetleyici — yönlendirme eski sürümden kalamaz), manifest.json, sw.js;
  • dokunma: config.php (veritabanı bilgileri), data/ (raporlar), logs/, tmp/ (oturumlar ve önbellek).
# Yükleme sonrası — PHP önbelleğini sıfırla (opcache açıksa): sudo systemctl reload php*-fpm
FileZilla SSH_FX_PERMISSION_DENIEDPermission denied diyor. Panel dosyaları www-data sahipliğindedir (kurulumda böyle ayarlandı), SFTP istemcisi ise yazma izni olmayan kendi kullanıcınızla bağlanır. Tüm paneli “çalışsın diye” www-data'ya vermek tam da bu hataya yol açan şeydir; aşağıda üç yol var, herhangi biri sorunu çözer.
# Seçenek A (önerilir) — sahipleri ayırın: kod sizin, çalışma klasörleri web sunucusunun. # Web sunucusu panel KODUNA yazma iznini hiç almaz: sudo chown -R deploy:www-data /path/to/monitor sudo chown -R www-data:www-data /path/to/monitor/data /path/to/monitor/tmp /path/to/monitor/logs sudo find /path/to/monitor -type d -exec chmod 755 {} \; sudo find /path/to/monitor -type f -exec chmod 644 {} \; sudo chmod 750 /path/to/monitor/data /path/to/monitor/tmp /path/to/monitor/logs sudo chmod 640 /path/to/monitor/config.php # Seçenek B — mevcut sahiplerin üzerine ACL (hiçbir şey taşımıyoruz): sudo apt install -y acl sudo setfacl -R -m u:deploy:rwX /path/to/monitor sudo setfacl -R -d -m u:deploy:rwX /path/to/monitor # Seçenek C — www-data grubu üzerinden. Daha basit, ama panel dosyalarına yazma # iznini web sunucusu da alır (PHP'de bir açıkta kod değiştirilebilir): sudo usermod -aG www-data deploy sudo find /path/to/monitor -type d -exec chmod 2775 {} \; sudo find /path/to/monitor -type f -exec chmod 664 {} \; sudo chmod 640 /path/to/monitor/config.php sudo chmod 2750 /path/to/monitor/data /path/to/monitor/tmp /path/to/monitor/logs
A seçeneği neden güvenli. Panel yalnızca üç dizine yazar — data/ (raporlar), tmp/ (oturumlar ve önbellek), logs/; bunlar www-data'da kalır. Geri kalanı koddur ve web sunucusunun ona yalnızca 644 izinleriyle www-data grubunun verdiği okuma erişimi gerekir. Yan fayda: PHP'de bir açıkta panel dosyaları artık yeniden yazılamaz. Barındırma panellerinde (HestiaCP ve benzerleri) A seçeneği gerekmez: orada site dosyaları zaten SFTP ile bağlandığınız hesaba aittir ve web sunucusu onları grup üzerinden okur.
B seçeneğinin tuzağı: dosyalar üzerinde sonradan yapılan herhangi bir chmod, ACL maskesini sıfırlar ve erişim sessizce kaybolur. “İzinleri düzene sokma” işleminden sonra yükleme yine Permission denied hatasına takılırsa — her iki setfacl komutunu tekrarlayın.
C seçeneğindeki 2 biti setgid'dir: SFTP ile yüklenen dosyalar www-data grubunda kalır, aksi hâlde panel onların üzerine yazamaz. C seçeneğinden sonra FileZilla'da yeniden bağlanın — yeni grup ancak yeni bir oturum açmada geçerli olur. Kontrol: id deploy (www-data grubu görünmelidir) ve ls -ld /path/to/monitor (drwxrwsr-xs harfi setgid'in ayarlandığı anlamına gelir).

Başka bir sunucuya taşıma:

  1. Yeni sunucuda siteyi + HTTPS ayağa kaldırın (bkz. manuel kurulum sayfası).
  2. Tüm panel dosyalarını config.php, data/ ile birlikte kopyalayın.
  3. Veritabanını taşıyın: eskide mysqldump → yenide içe aktarma; config.php içindeki veritabanı bilgilerini düzeltin.
  4. Yeni sunucuda tekrarlayın: sudoers, adm grubuna üyelik, cron görevleri.
  5. Lisans alan adına bağlıdır — alan adı aynıysa anahtar çalışmaya devam eder.

34. Erişimi kurtarma (kayıp anahtar, parola, IP engeli)

Giriş yapamıyorsanız her şey doğrudan sunucudaki veritabanından düzeltilebilir. Veritabanını açın (adı config.php içinde):

sudo mysql MY_DB

WebAuthn anahtarı kayboldu (ikinci faktör geçilemiyor) — 2FA'yı devre dışı bırakın, parolayla giriş yapın ve yeni bir anahtar kaydedin:

UPDATE users SET webauthn_enabled = 0;

Parolayı unuttunuz — yeni bir hash belirleyin (sunucuda oluşturup yerine koyun):

# Yeni parolanın hash'ini oluşturun: php -r "echo password_hash('NEW_PASSWORD', PASSWORD_BCRYPT), \"\n\";" # Veritabanında (oluşan hash'i yapıştırın): # UPDATE users SET password = '$2y$10$...' WHERE username = 'admin';

IP filtresiyle kendinizi engellediniz — kısıtlamayı devre dışı bırakın:

UPDATE settings SET value = '0' WHERE name = 'ip_restriction_enabled';
Veritabanına her zaman erişebilirsiniz: sunucuda sudo mysql, ya da phpMyAdmin / hosting panelindeki veritabanı bölümü. Kurtarmadan sonra WebAuthn ve IP filtresini yeniden etkinleştirin.

35. Tüm cron görevleri tek yerde

Görevlerin özeti — sunucunun root cron'unda (sudo crontab -e ile eklenir). Yalnızca kullandığınız araçlara ait satırları bırakın; yolları kendi sunucunuza göre düzenleyin.

# Monitörün sunucu cron'u (root) — şununla ekleyin: sudo crontab -e # 01:30 — tehlikeli yollarda ClamAV taraması (web, home, temp) → “Taranan dosyalar” ve “Son tarama” kartları 30 1 * * * /usr/local/bin/clamav-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 02:00 — AIDE dosya bütünlüğü denetimi (açık --config gerekir) 0 2 * * * /usr/bin/aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1 # başlangıçta — /var/lib/aide izinlerini geri yükle (paket tmpfiles dosyası # aide-common.conf onları 0700'e sıfırlar ve panel veritabanını göremez olur) @reboot chmod 755 /var/lib/aide # 03:00 — Lynis güvenlik denetimi 0 3 * * * /usr/local/bin/lynis-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 04:00 — ipsum engel listesi güncellemesi (level 1) 0 4 * * * /usr/local/bin/load-ipsum.sh >> /path/to/monitor/logs/cron.log 2>&1 # ipsum kümesini başlangıçta ipsum-load.service yükler (güvenlik duvarından ÖNCE, aksi halde # UFW kümeyi before.rules içinde görmez) — cron değil. Burada yalnızca yukarıdaki günlük yenileme var. # 06:00 — Logwatch raporu 0 6 * * * /usr/local/bin/logwatch_daily.sh >> /path/to/monitor/logs/cron.log 2>&1 # her 30 dakikada — SMART disk kontrolü */30 * * * * /usr/local/bin/smart-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 04:30 — debsums paket bütünlüğü 30 4 * * * /usr/local/bin/debsums-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 08:00 — E-posta ve Telegram için zamanlanmış rapor 0 8 * * * /usr/local/bin/daily-report-all.sh >> /path/to/monitor/logs/cron.log 2>&1 # her saat — paket listelerinin yenilenmesi (“Güvenlik güncellemeleri” kartı için) 0 * * * * /usr/bin/apt-get update -qq >/dev/null 2>&1 # her 5 dakikada — kaynak anlık görüntüsü (CPU/RAM/ağ/disk) “Performans” sayfası için */5 * * * * /usr/local/bin/collect-metrics-all.sh >> /path/to/monitor/logs/cron.log 2>&1
Her birine dair ayrıntılar ilgili bölümlerde. Yedekleme görevleri (önceki bölüm) aynı cron'a eklenir. Düzenlemelerden sonra kontrol edin: sudo crontab -l ve cron hizmetinin etkin olduğunu.
cron zamanı = sunucunun saat dilimi, config.php içindeki TIMEZONE değil. TIMEZONE sabiti yalnızca PHP'yi etkiler (panelin tarihleri nasıl gösterdiğini), ancak cron arka planı görevleri işletim sisteminin sistem saatine göre çalıştırır. Sunucunun dilimi sizinkiyle uyuşmuyorsa “08:00” raporu yanlış saatte gelir. Örnek: sunucu başka bir dilimde (Europe/Berlin, UTC+2), siz ise İstanbul'dasınız (UTC+3) → “08:00” raporu sizin saatinizle 09:00'da gelir. Kontrol edin ve gerekirse sistem dilimini kendinize göre ayarlayın:
# Sunucunun geçerli dilimini kontrol et: timedatectl # Kendi dilimini ayarla (örnek) ve cron'u yeniden başlat: sudo timedatectl set-timezone Europe/Istanbul sudo systemctl restart cron
Bundan sonra 0 8 * * * satırı yerel saatle 08:00'de çalışır. Aksi halde cron'un kendisini kaydırmak gerekirdi, ancak yaz/kış saatine geçişte kayma yine bozulur — bu nedenle sistem dilimini ayarlamak daha doğrudur.
Hazır sarmalayıcı betikler. Bunların çalışan kopyaları ve örnek crontab (crontab.txt) proje yanındaki system/ klasöründe, public_html dışında bulunur. Bu sitenin parçası değildir — web köküne yüklemeniz gerekmez; sunucuda sistem yollarına yerleştirin (yukarıdaki crontab'daki gibi):
  • lynis-scan.sh/usr/local/bin/ (chmod +x) — lynis audit system çalıştırır, tarama süresince /tmp/lynis-running bayrağını koyar ve lynis-report.dat dosyasını panelin data/lynis/ dizinine kopyalar;
  • logwatch_daily.sh/usr/local/bin/ (chmod +x) — günlük Logwatch raporunu (sshd, fail2ban, sudo, postfix) data/logwatch/ içine oluşturur;
  • smart-scan.sh/usr/local/bin/ (chmod +x) — disk durumunu (smartctl) data/disk/ içine alır;
  • debsums-scan.sh/usr/local/bin/ (chmod +x) — paket bütünlüğünü (debsums) data/debsums/ içinde kontrol eder;
  • clamav-scan.sh/usr/local/bin/ (chmod +x) — tehlikeli yollarda (web, home, temp) ClamAV virüs taraması; özeti /var/log/clamav/scan.log dosyasına yazar, ClamAV sayfası onu buradan okur (yukarıdaki crontab'da 01:30 satırı);
  • load-ipsum.sh/usr/local/bin/ (chmod +x) — ipsum ipset kümesini (level 1) yerinde günceller, etkin güvenlik duvarı kurallarını bozmadan (yukarıdaki crontab'daki 04:00 satırı);
  • daily-report-all.sh/usr/local/bin/ (chmod +x) — panelin cron/daily_report.php raporunu çalıştırır (yukarıdaki crontab'da 08:00 satırı);
  • daily_report.php — zaten panele dahildir (cron/daily_report.php), daily-report-all.sh aracılığıyla çalışır, ayrıca kurmaya gerek yoktur;
  • collect-metrics-all.sh/usr/local/bin/ (chmod +x) — panelin cron/collect_metrics.php betiğini çalıştırır (“Performans” sayfası, yukarıdaki crontab'da */5 satırı); collect_metrics.php zaten panele dahildir, ayrıca kurmaya gerek yoktur;
  • crontab.txt (system/cron/) — görev örneği; gereken satırları sudo crontab -e ile ekleyin.
crontab'daki betik yolu, betiği koyduğunuz yerle aynı olmalıdır.
Betiği /usr/local/bin/ dizinine nasıl koyarsınız. Doğrudan FileZilla'dan oraya yazılamaz — dizin root sahipliğindedir ve SFTP istemcisi SSH_FX_PERMISSION_DENIED alır. Sıra şudur: önce dosyayı /tmp dizinine yükleyin (oraya herkes yazabilir), sonra tek komutla yerine taşıyın:
# FileZilla'da: “Uzak site” alanına /tmp girip betiği oraya yükleyin, # ardından SSH ile (install sahibi ve izinleri hemen ayarlar, chown/chmod gerekmez): sudo install -o root -g root -m 755 /tmp/lynis-scan.sh /usr/local/bin/lynis-scan.sh rm -f /tmp/lynis-scan.sh # kontrol: dosya yerinde, izinler rwxr-xr-x, sözdizimi sağlam bash -n /usr/local/bin/lynis-scan.sh && ls -l /usr/local/bin/lynis-scan.sh
Dizinleri karıştırmayın: sunucunun kökündeki /tmp gerekir — /var/tmp değil, panelin kendi içindeki tmp/ de değil (sonuncusu www-data sahipliğindedir ve sizin kullanıcınıza kapalıdır). FileZilla ağacında /tmp, var'ın yanındaki üst düzey bir daldır, onun içinde değil.
Sunucuyu otomatik kurulumla mı kurdunuz? Bu sarmalayıcılar ve cron görevleri betik tarafından zaten kuruldu (/usr/local/bin/ içine, günlük — /var/log/arciveo-cron.log) — elle bir şey yapmanıza gerek yok.
Betikler paneli nerede arar. Sarmalayıcılar etki alanından bağımsızdır: /home/*/web/*/public_html ve /var/www/* yollarını tarayarak panel kurulumlarını bulur ve raporları onların data/ dizinine koyar. Panel başka bir yoldaysa — betiklerin içindeki for app in … satırına o yolu ekleyin, aksi halde Lynis/SMART/debsums/Logwatch raporları panele ulaşmaz.
cron.log ve erişim izinleri. logs/cron.log dosyasını ilk olarak root cron oluşturur — dosya root sahipliğinde olur ve paneldeki “cron Günlüğü” sekmesi onu ne okuyabilir ne de temizleyebilir. Dosyayı önceden web kullanıcısı adına oluşturun (site dizininin sahibi; HestiaCP'de bu, ör. admin hesabıdır) — böylece root cron sahibi değiştirmeden yalnızca ekleme yapar:
# web kullanıcısı adına önceden oluştur (cron satırlarını eklemeden önce): sudo -u OWNER touch /path/to/monitor/logs/cron.log # cron.log zaten root cron tarafından oluşturulduysa — web kullanıcısına ver: sudo chown OWNER:OWNER /path/to/monitor/logs/cron.log sudo chmod 644 /path/to/monitor/logs/cron.log
Dizin sahibini öğrenmek için: stat -c %U /path/to/monitor.
Panelden yönetim. “Sistem” bölümünde “Crontab” sayfası vardır — SSH olmadan görevleri görüntüleyip ekleyebilirsiniz. Panel yalnızca kendisi aracılığıyla eklenen görevleri düzenler (root-crontab içinde hizmet yorumlarıyla işaretlenmiş ayrı bir blok); crontab'da zaten bulunan her şey (yukarıdaki liste) orada “Diğer sunucu görevleri” adlı salt-okunur bir listede “Düzenleyiciye kopyala” düğmesiyle gösterilir — bu düğme yalnızca zamanlamayı/komutu ekleme formuna taşır, özgün satıra dokunmaz. Mevcut bir görevi panel yönetimine “geçirmek” için — onu düzenleyiciye kopyalayın, kaydedin, ardından eski satırı elle silin (sudo crontab -e), aksi halde iki kez çalışır.
Sunucuda tek seferlik ayar. Sayfanın ayrıcalıklı bir sarmalayıcı betiğe ihtiyacı vardır — çıplak sudo crontab değil (bu, panel oturumuna erişen herkes için root'a doğrudan yükseltme olurdu), yalnızca kendi bloğuna hizmet yorumları arasında dokunan, iki komutlu (list/set) dar bir betik. Bir kez kurun:
sudo install -m 0755 -o root -g root /dev/stdin /usr/local/sbin/arciveo-cron <<'ARCIVEO_CRON_EOF' #!/bin/bash set -euo pipefail BEGIN='# >>> ARCIVEO-CRON-MANAGED (edited from the panel; do not edit by hand) >>>' END='# <<< ARCIVEO-CRON-MANAGED <<<' cmd=${1:-} case "$cmd" in list) [ "$#" -eq 1 ] || { echo "usage: ${0##*/} list" >&2; exit 2; } crontab -l -u root 2>/dev/null || true ;; set) [ "$#" -eq 1 ] || { echo "usage: ${0##*/} set (body on stdin)" >&2; exit 2; } body=$(cat) if grep -qF "$BEGIN" <<<"$body" || grep -qF "$END" <<<"$body"; then echo "invalid body: markers not allowed" >&2; exit 2 fi current=$(crontab -l -u root 2>/dev/null || true) tmp=$(mktemp); trap 'rm -f "$tmp"' EXIT { if grep -qF "$BEGIN" <<<"$current"; then awk -v b="$BEGIN" '{print} $0==b{exit}' <<<"$current" else [ -n "$current" ] && printf '%s\n' "$current" echo "$BEGIN" fi printf '%s\n' "$body" echo "$END" if grep -qF "$END" <<<"$current"; then awk -v e="$END" 'f{print} $0==e{f=1}' <<<"$current" fi } > "$tmp" crontab -u root "$tmp" ;; *) echo "usage: ${0##*/} <list|set>" >&2; exit 2 ;; esac ARCIVEO_CRON_EOF echo "www-data ALL=(ALL) NOPASSWD: /usr/local/sbin/arciveo-cron" | sudo tee -a /etc/sudoers.d/monitor sudo visudo -c
Web kullanıcısı www-data'dan farklı olabilir — sitenin PHP-FPM havuzunun hangi kullanıcı altında çalıştığını kontrol edin (ps -o user= -C php-fpm) ve onu sudoers satırına koyun.
Yeni dosya yanlış sahiple yüklendi — sayfa “Access denied.” yanıtı veriyor. public/crontab_monitor.php dosyası FTP/SFTP ile diğer site dosyalarından farklı bir sistem kullanıcısıyla (örneğin root) yüklendiyse, web sunucusu onu okuyamaz. Sahibini ve izinleri komşu dosyayla karşılaştırıp eşitleyin:
ls -la public/crontab_monitor.php public/ssl_monitor.php sudo chown OWNER:OWNER public/crontab_monitor.php sudo chmod 644 public/crontab_monitor.php

Tanılama

36. Araç kurulu ama “Kurulu değil” yazıyor

Monitor, araçların varlığını dpkg-query — APT paket veritabanı üzerinden belirler. Araç apt ile kurulmadıysa (elle, snap ile ya da kaynaktan), dpkg onu görmez.

# dpkg ile kontrol et: dpkg -l fail2ban | grep '^ii' dpkg -l auditd | grep '^ii' # Binary dosyanın yolunu bul: which ufw fail2ban-client auditctl # www-data ile sudo testi: sudo -u www-data sudo fail2ban-client status sudo -u www-data sudo ufw status verbose

37. Sorun giderme (500, veri yok)

500 hatası — PHP, nginx ve monitörün kendi loglarını kontrol edin:

tail -50 /var/log/nginx/error.log tail -50 /var/log/php*-fpm.log # Monitör logları: tail -50 logs/monitor_$(date +%Y-%m-%d).log # Klasör izinleri: ls -la data/ tmp/ logs/
Panel bir hosting panelinde mi (HestiaCP, ISPmanager, cPanel)? Orada PHP, www-data altında değil, kullanıcı hesabı altında çalışır (örneğin admin — site dizininin sahibi). Tüm sudo kuralları ve grup üyelikleri (adm, systemd-journal) bu kullanıcı için tanımlanmalıdır, aksi halde servisler çalışırken modüller “Etkin değil / 0” gösterir. Gerçek PHP kullanıcısını öğrenmek için: ps -o user= -C php-fpm | sort -u veya site dizininin sahibi stat -c '%U' /path/to/monitor. Ardından aşağıdaki tüm komutlarda www-data yerine onu yazın. Otomatik kurulum web kullanıcısını kendisi belirler ve sudoers'ı ona göre tanımlar.

Veriler görüntülenmiyor — neredeyse her zaman tanımlanmamış sudo izinleri yüzündendir. İlgili komutu web kullanıcısı adına kontrol edin (www-data yerine kendi kullanıcınızı yazın). -n bayrağı = PHP'deki gibi parolasız — parola isterse, sudoers'ta kural yok demektir:

sudo -u www-data sudo -n fail2ban-client status sudo -u www-data sudo -n ufw status verbose sudo -u www-data sudo -n ipset list -t ipsum sudo -u www-data sudo -n /usr/sbin/ausearch -m USER_LOGIN -ts today sudo -u www-data sudo -n /usr/sbin/aa-status sudo -u www-data sudo -n /usr/sbin/psad --Status sudo -u www-data journalctl -u falco --no-pager -n 5
Araç çalıştığı halde modül “Etkin değil” / “0” yazıyor (örneğin terminalde sudo aa-status profilleri gösteriyor, ama “AppArmor” sayfası “Etkin değil” diyor). Nedeni: web kullanıcısının o modülün komutu için sudo izni yok. Onu yukarıdaki listeden kontrol edin: parola isterse — /etc/sudoers.d/monitor dosyasına eksik satırı ekleyin (“sudo ayarı”). Sık karşılaşılan “yeni” komutlar: /usr/sbin/aa-status (MAC), /usr/sbin/psad --Status (PSAD).
Belirli bir sayfa (Falco, ModSecurity, Auditd, açık UFW portları) boşsa — sudo bölümündeki listeyle karşılaştırın: muhtemelen apache2ctl, ausearch, aa-status ya da ss izinli değil, veya web kullanıcısı adm/systemd-journal gruplarında değil (fail2ban/auth/modsec logları ve journalctl — Falco ve çekirdek olayları buradan okunur).

38. Sunucuda veri olmasına rağmen sayfa boş

Belirti: sunucuda veri var (shell üzerinden görünüyor), ancak sayfa “veri yok” gösteriyor veya yanlış durum bildiriyor — örneğin veritabanı oluşturulmuş olmasına rağmen AIDE “Başlatılmadı” yazıyor.

Neden open_basedir: birçok panel ve barındırma sağlayıcısı PHP-FPM havuzunu domain dizinine kısıtlar, bu yüzden sistem yollarındaki (/var/lib/aide, /var/log, /proc…) file_exists(), file_get_contents(), filemtime() PHP fonksiyonları engellenir. Monitör bunu, söz konusu yolları standart sistem komutlarıyla (cat, test, stat) okuyarak aşar.

# Dosya shell üzerinden görünüyor mu (monitör böyle okur): sudo -u www-data bash -lc 'test -e /var/lib/aide/aide.db && echo VISIBLE || echo NO' # Domain havuzu için geçerli open_basedir değeri: grep -ri open_basedir /etc/php/*/fpm/pool.d/ 2>/dev/null
Shell dosyayı “görüyor” (VISIBLE) ama sayfa görmüyorsa, sorun open_basedir'dir. Doğru çözüm sistem komutlarıyla okumadır (AIDE ve Ağ monitörü için zaten yapıldı). open_basedir ayarını /var, /proc yollarına genişletmek gerekmez ve daha az güvenlidir.

39. SSL sayfası çalışmıyor

Monitör, sertifikaları alan adlarına 443 portu üzerinden doğrudan bağlanarak kontrol eder. Alan adı sunucunun kendisinden erişilemiyorsa veya port güvenlik duvarınca kapalıysa kontrol başarısız olur.

# Sertifikayı elle kontrol edin: echo | openssl s_client -connect monitor.example.com:443 2>/dev/null \ | openssl x509 -noout -dates # Erişilebilirliği kontrol edin: curl -I https://monitor.example.com
Monitör, alan adlarını otomatik olarak nginx (/etc/nginx/sites-enabled/, /etc/nginx/conf.d/) ve Apache (/etc/apache2/sites-enabled/) yapılandırmalarından, ayrıca HTTP_HOST üzerindeki geçerli ana bilgisayardan alır.
Alt alan adı otomatik algılama. Alt alan adları, herkese açık Certificate Transparency günlüklerinden otomatik olarak belirlenir ve ağ üzerinden kontrol edilir — başka sunucularda barındırılsalar bile. Elle bir şey eklemenize gerek yoktur.

40. Birden fazla veritabanından yalnızca biri görünüyor

Monitor, MySQL'e config.php içindeki, yalnızca kendi veritabanına erişimi olan kullanıcıyla bağlanır. MySQL, information_schema içinde yalnızca yetkisi olan veritabanlarını gösterir; bu yüzden diğerleri görünmez.

Monitorün tüm veritabanlarını görebilmesi için bu kullanıcıya yalnızca okuma yetkisi verin (root ile bir kez; config.php içindeki kullanıcı adını girin):

sudo mysql -u root GRANT SELECT, PROCESS, SHOW DATABASES ON *.* TO 'DB_USER'@'localhost'; FLUSH PRIVILEGES; EXIT;
SELECT ON *.* yalnızca okuma yetkisi verir; hiçbir şey değiştirilemez, silinemez veya oluşturulamaz, izleme için güvenlidir.
Bu GRANT olmadan panel yalnızca kendi veritabanını görür; bu bir hata değil, yetki kısıtlamasıdır. Panel hiçbir sudo mysql kullanmaz: veritabanı listesi kendi PDO bağlantısı üzerinden alınır.

41. PostgreSQL “Veritabanı” sayfasında görünmüyor

PostgreSQL, postgres kullanıcı düzeyinde erişim gerektirir; panelin web kullanıcısında ise bu erişim yoktur. PHP üzerinden geniş yetkili sudo psql açmak güvenli değildir — bunun yerine panel, yalnızca sürümü, bağlantı sayısını ve veritabanlarının boyutlarıyla listesini yazan, parametresiz dar bir sarmalayıcı çağırır. Bunu oluşturun:

sudo tee /usr/local/bin/monitor-pgstat >/dev/null <<'EOF' #!/bin/sh # Arciveo Monitor - read-only PostgreSQL version, connections and per-database size sudo -u postgres psql -tAc "SELECT version();" | grep -oE 'PostgreSQL [0-9.]+' echo "---" sudo -u postgres psql -tAc "SELECT count(*) FROM pg_stat_activity;" echo "---" sudo -u postgres psql -tAc "SELECT datname || '|' || pg_size_pretty(pg_database_size(datname)) FROM pg_database WHERE datistemplate = false;" EOF sudo chown root:root /usr/local/bin/monitor-pgstat sudo chmod 755 /usr/local/bin/monitor-pgstat # /etc/sudoers.d/monitor içinde (kullanıcı = PHP-FPM'nin çalıştığı kullanıcı): # www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-pgstat
PostgreSQL kullanmıyorsanız monitor-pgstat satırını sudoers'tan kaldırın (manuel kurulumun 13. adımı) ve betiği hiç oluşturmayın: PostgreSQL kartı yalnızca etkin olmayan durumda kalır.

42. Uyarı tetiklendi — ne yapmalı

Panel ne olduğunu gösterir; aşağıda ise tipik durumlarda ne yapılacağı var. Genel ilke: paniğe kapılmayın, meşru etkinlikle (kendi işlemleriniz, güncellemeler, yedekler) karşılaştırın ve ciddiyetine göre tepki verin.

  • Saldırı haritası / çok sayıda fail2ban banı — internetteki her sunucu için bu normaldir (botlar sürekli SSH/web dener). Önemli olan banların tetiklenmesi. SSH girişinin yalnızca anahtarla olduğundan (parola kapalı) ve IP adresinizin ignoreip içinde olduğundan emin olun.
  • ModSecurity istekleri engelledi — WAF, siteye yönelik saldırıları savuşturur, bu onun işidir. Meşru trafiğiniz engelleniyorsa (yanlış tetikleme) — ayrıntılarda rule id'yi bulup CRS yapılandırmasına bir istisna ekleyin.
  • AIDE: dosyalar değişti — listeyi yaptıklarınızla karşılaştırın (paket güncelleme, yapılandırma düzenleme — normaldir). Dokunmadığınız sistem ikili dosyalarındaki değişiklikler ise dikkat edilmesi gereken bir durumdur. Meşru değişikliklerden sonra AIDE veritabanını güncelleyin.
  • debsums: ikili dosyalar/kütüphaneler değişti (/etc ve /usr/share dışında) — olası bir değiştirme. Paketi karşılaştırın: debsums PACKAGE_NAME, şüphe halinde yeniden kurun (apt install --reinstall).
  • ClamAV / maldet: tehdit bulundu — karantinadaki dosyayı kontrol edin, açmayın. Bu, site dizininde bir web shell ise — sunucuyu izole edip giriş noktasını arayın (savunmasız eklenti, sızan erişim bilgileri).
  • Falco: kritik olaylar (kapsayıcıda shell çalıştırma, hassas dosyalara erişim) — olayı inceleyin: hangi işlem, neyi başlattı. Çoğu zaman bu meşru yönetici etkinliğidir.
  • Dış maruziyet: kırmızı işaretli VTYS/önbellek — hemen kapatın: hizmeti 127.0.0.1 adresine bağlayın veya UFW'de portu kapatın. Bu gerçek bir açıktır.
  • SSL süresi doluyor / doldu — sertifikayı yenileyin (Let's Encrypt kendi kendine yenilenir; yenilenmiyorsa certbot renew komutunu veya panel ayarlarını kontrol edin).
  • Güvenlik güncellemeleri bekliyor — kurun: sudo apt update && sudo apt upgrade; çekirdek güncellemesinden sonra sunucuyu yeniden başlatın.
Gerçek bir ihlalin belirtileri (bilinmeyen işlemler/kullanıcılar, değişmiş ikili dosyalar, giden spam, bilinmeyen cron görevleri): sunucuyu dış erişimden kesin, analiz için bir yedek alın ve veriler kritikse güvenilir bir yedekten temiz bir sunucu kurun — bir rootkit'i güvenilir şekilde temizlemek zordur.
Arcivéo - Security Monitor © 2026