SSD Nodes Learn 🎉 VPS $5.50/aydan başlayan
Rehberler Matt ConnorYazan Matt Connor

Linux sunucuda kullanıcı komut geçmişi nasıl denetlenir

Shell geçmişi güvenli bir denetim izi değildir. Sudo günlükleri, oturum kaydı, shell kancaları ve auditd execve kurallarını karşılaştırarak komutları sunucu dışına aktarın.

Sunucunuzda kullanıcıların çalıştırdığı komutları gerçekte ne kaydeder

Sunucunuzda kullanıcıların çalıştırdığı komutları denetlemek için, kullanıcının düzenleyemeyeceği bir kayda ihtiyacınız vardır. Shell geçmişi bu kayıt değildir. Bu, onu yazan hesaba ait bir kolaylık dosyasıdır; o shell üzerinde yazma yetkisi olan herkes bu özelliği kapatabilir veya dosyayı silebilir.

Dört katman gerçek bir kayıt tutar ve her birinin bir maliyeti vardır. sudo, her komut için syslog dosyasına bir satır yazar. sudo I/O günlüğü, bir hesap için tüm oturumu yakalar. PROMPT_COMMAND gibi bir shell kancası, etkileşimli bir bash kullanıcısının ne yazdığını günlüğe kaydeder. Çekirdek denetim alt sistemi (kernel audit subsystem), execve sistem çağrısının kendisini kaydeder; bu nedenle her süreci gören tek katman budur. Bu kılavuz, bu merdiveni tırmanır, her katmanın nerede durduğunu belirtir ve denetlediğiniz kişi kayıtlara ulaşamadan önce onları makineden dışarı aktarma aşamasıyla, yani tüm bu çabanın bir anlam ifade edip etmeyeceğine karar veren kısımla sona erer.

Başlamadan önce bir uyarı: Denetim alt sistemi çekirdek seviyesinde bir işlemdir, bu nedenle hiçbir parçası ana makine çekirdeğini paylaşan bir container içinde test edilemez. Bu komutları, çekirdeğin size ait olduğu bir KVM VPS üzerinde çalıştırın.

Shell geçmişi neden bir denetim izi değildir

~/.bash_history dört basit nedenden ötürü kanıt olarak geçersizdir ve bunların hiçbiri zeki bir saldırgan gerektirmez.

Kullanıcıya aittir. Dosya 600 modundadır ve ilgili hesaba aittir; bu nedenle rm ~/.bash_history hiçbir ayrıcalık gerektirmez. Dosyayı bir düzenleyicide açıp önemli olan yirmi satırı silmek de aynı şekilde hiçbir ayrıcalık gerektirmez.

Shell kapandığında yazılır. kill -9 $$ ile biten veya bağlantısı kesilen bir oturum hiçbir şey yazmaz. exit öncesinde history -c kullanmak aynı etkiyi yaratır ve hiçbir şey olmamış gibi görünür.

Tek bir komutla kapatılabilir. unset HISTFILE, o oturum için dosyanın yazılmasını durdurur. set +o history, kaydı anında keser. HISTCONTROL=ignorespace, başına boşluk karakteri eklenerek yazılan tüm komutları gizler. Bunların tamamı man bash içinde yer alır çünkü bu özellik kullanıcının kontrolünde olması için tasarlanmıştır.

Çalışanı değil, yazılanı kaydeder. Bir alias veya shell fonksiyonu, dosyadaki metnin çekirdek tarafından yürütülen programla aynı olmadığı anlamına gelir.

Ayrıca, giriş yazıldığı sırada HISTTIMEFORMAT ayarlanmamışsa zaman damgaları da bulunmaz; çünkü bash, #1755043200 işaretçi satırlarını yalnızca bu değişken ayarlandığında yazar.

Paylaşımlı bir girişte, işlemin kime ait olduğunu da söyleyemez. Tek bir deploy hesabını kullanan üç kişi, tek bir uid altında iç içe geçmiş tek bir dosya üretir. İki insan aynı uid'yi paylaştığında hiçbir günlük katmanı bir eylemi bir insana atayamaz; bu durum, paylaşımlı giriş yerine kişi başına bir yetkisiz hesap kullanılması için pratik bir argümandır.

Shell geçmişi, gerçek işi olan dünkü komutu tekrar yazmanıza yardımcı olma konusunda başarılıdır. Onu bir ipucu olarak kullanın. Asla kanıt olarak sunmayın.

sudo neyi günlüğe kaydeder ve nerede durur

sudo, çalıştırdığı her komut için authpriv syslog tesisine bir satır gönderir.

sudo grep 'sudo:' /var/log/auth.log | tail -5
journalctl -t sudo -n 5

Her satır kullanıcıyı, terminali, çalışma dizinini, hedef kullanıcıyı ve komutu belirtir:

sudo:    alice : TTY=pts/0 ; PWD=/home/alice ; USER=root ; COMMAND=/usr/bin/apt update

Eğer /var/log/auth.log mevcut değilse, o imajda rsyslog yüklü değildir ve aynı kayıtlar yalnızca journal içinde bulunur. Ona güvenmeden önce journal'ın geçici (volatile) olmadığından emin olun:

journalctl --list-boots

Listelenen yalnızca mevcut önyükleme (boot) ise /var/log/journal mevcut değildir; bu durumda journal /run içinde yaşar ve her satır bir sonraki yeniden başlatmada silinir. Onu kalıcı hale getirin:

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald

Şimdi sınırlamaya gelelim. sudo, çalıştırılması istenen komutu günlüğe kaydeder. O komutun daha sonra ne yaptığını kaydetmez. Dolayısıyla tek bir satır izi sonlandırır:

sudo -i

Günlük, kabuk (shell) için tek bir kayıt alır. O root kabuğu içinde yazılan her komut sudo için görünmezdir, çünkü sudo artık yol üzerinde değildir. sudo su -, sudo bash ve sudo vim /etc/shadow ile ardından gelen :!bash, hepsi aynı yapıya sahiptir. vim veya find gibi kabuk kaçışına (shell escape) sahip herhangi bir programa izin veren bir sudoers kuralı, günlüğe kaydedilmeyen root yetkisi veren bir kuraldır. Bir hesabın günlük satırlarına güvenmeden önce o hesabın gerçekte nelere erişebileceğini inceleyin:

sudo -l -U alice

Tek bir hesap için tam oturum kaydı

Öncelikle hangi sudo sürümüne sahip olduğunuzu belirleyin, çünkü bu özellik Rust ile yeniden yazılan sürümde bulunmamaktadır:

sudo --version | head -1

Eğer çıktı sudo-rs ismini veriyorsa, bu bölümü atlayın ve audit altsistemini kullanın. Ubuntu'nun 25.10 ve 26.04 sürümlerine ait kendi belgeleri, I/O günlüğü tutma ve sudoreplay özelliklerinin desteklenmediğini belirtmektedir ve bu durum Ağustos 2026 itibarıyla geçerliliğini korumaktadır. Bu durum önemlidir çünkü sudo-rs, söz konusu sürümlerde varsayılan sudo paketidir; dolayısıyla bir yükseltme işlemi, sahip olduğunuzu düşündüğünüz bir denetim mekanizmasını kaldırabilir. sudo-rs davranış değişikliklerinin tam listesi, sudo tabanlı herhangi bir günlük kaydı planlamadan önce okunmalıdır.

Ubuntu 24.04 LTS sürümünde yüklü gelen orijinal sudo ile, tek bir hesap için I/O günlüğünü şu şekilde etkinleştirin:

sudo visudo -f /etc/sudoers.d/iolog
Defaults:deploy log_output
Defaults!/usr/bin/sudoreplay !log_output

Bir düzenleyici yerine visudo kullanın, çünkü bu araç ayrıştırılamayan bir dosyayı kaydetmeyi reddeder. Hatalı bir sudoers dosyası, herkesin sudo erişimini kısıtlar. Ardından bir oturumu yeniden oynatın:

sudo sudoreplay -l user=deploy
sudo sudoreplay 000001

sudoreplay -l, oturumları kimlikleriyle listeler; eğer log_output o kullanıcıya hiç uygulanmadıysa hiçbir çıktı vermez. Maliyeti şudur: terminalden geçen her bayt /var/log/sudo-io altında saklanır, bu nedenle ayrıntılı bir oturum oldukça büyük yer kaplar. İkinci sudoers satırı, bir yeniden oynatma işleminin kendisini kaydetmesini engeller. Asıl maliyet gizli verilerdir; çünkü bir I/O günlüğü, oturum içindeki bir isteme yazılan parola dahil olmak üzere yazılan ve ekrana basılan her şeyi tutar. Bu nedenle, bir parola deposuyla aynı korumaya ihtiyaç duyar. Kapsamı da dardır; yalnızca sudo üzerinden çalıştırılan komutları görür. Sisteme giriş yapıp tamamen kendi yetkileriyle çalışan birinin işlemleri hiç kaydedilmez.

Shell kancaları ve bunların nasıl atlatıldığı

"Her komutu günlüğe kaydetme" için dolaşımda olan tarif, /etc/profile.d/ içine yerleştirilen bir PROMPT_COMMAND kancasıdır:

# /etc/profile.d/00-cmdlog.sh
PROMPT_COMMAND='logger -p local6.info -t cmdlog "$(whoami) $$ $(history 1 | sed "s/^ *[0-9]* *//")"'

bash, her komut satırı istemini (prompt) çizmeden önce PROMPT_COMMAND dosyasını çalıştırır. Böylece bir satır, çıkış anında değil yazıldığı anda syslog'a ulaşır ve logger sistem günlük daemon'ı üzerinden yazma işlemi gerçekleştirdiği için kullanıcının kendi dosya izinleri sürece dahil olmaz. Yeni bir oturum kabuğu açın ve sudo tail -f /var/log/syslog ile veya rsyslog bulunmayan bir imajda journalctl -t cmdlog -f ile kontrol edin.

Ancak bu yöntem, her birini bir dakika içinde yeniden oluşturabileceğiniz beş farklı yolla çalışmayı durdurur.

  • Etkileşimli olmayan kabuklar asla bir istem çizmez. ssh you@server 'id' komutu çalıştırır ve döner; PROMPT_COMMAND hiçbir zaman değerlendirilmediği için hiçbir şey günlüğe kaydedilmez.
  • Bu bir değişkendir. unset PROMPT_COMMAND, oturumun geri kalanı için bunu devre dışı bırakır ve herhangi bir ayrıcalık gerektirmez.
  • Dosya, oturum açma kabukları tarafından okunur. bash --noprofile --norc, /etc/profile.d/ dosyasını hiçbir şekilde kaynak (source) olarak almaz.
  • Bu, bash'e özgüdür. vim içindeki zsh, sh, python3 -c 'import os; os.system("id")' ve :!id, hiçbir bash istem kancasının göremeyeceği programlar çalıştırır.
  • Satırı yazıldığı şekliyle günlüğe kaydeder; bu nedenle bir alias veya fonksiyon, gerçekte çalışan komutu gizlemeye devam eder.

Bir kabuk kancasını kolaylık sağlaması amacıyla kullanın. İş birliği yapan kullanıcılar için "geçen Salı ne çalıştırdım" sorusuna yanıt verir. Bir kontrol listesinin bunu bir denetim mekanizması olarak adlandırmasına izin vermeyin.

Çekirdek denetim altsistemi her execve işlemini görür

auditd arka plan süreci tarafından yönetilen Linux denetim altsistemi, kullanıcının etrafından dolaşamayacağı tek katmandır; çünkü kayıt, sistem çağrısı (syscall) gerçekleştiği anda çekirdek içinde oluşturulur. Bir süreç bir program çalıştırdığında bir olay meydana gelir. Kabuk, kullanılan dil veya bir terminalin varlığı sonucu değiştirmez.

sudo apt update && sudo apt install -y auditd audispd-plugins
sudo systemctl enable --now auditd
sudo auditctl -s

auditctl -s, arka plan sürecinin durumunu yazdırır. Sıfır olmayan bir pid değeri ile enabled 1, sürecin çalıştığı anlamına gelir; lost 0 ise henüz hiçbir kaydın düşürülmediğini gösterir. lost sayacını unutmayın, bu değer daha sonra tekrar karşımıza çıkacak.

auid, denetim sistemini değerli kılan alandır. PAM, bir oturum başladığında bir giriş kullanıcı kimliği (login uid) atar ve çekirdek, bu andan itibaren tüm alt süreçlerde bu kimliği taşır. Kendi değerinizi kontrol edin:

cat /proc/self/loginuid

Etkileşimli bir SSH oturumu, /etc/pam.d/sshd içinde pam_loginuid.so bulunduğu için kullanıcı kimliğinizi yazdırır. 4294967295 değeri, giriş kullanıcı kimliğinin hiç atanmadığı anlamına gelir; bu durum, önyükleme sırasında bir sistem arka plan süreci tarafından başlatılan süreçler için normaldir. Önemli olan nokta, sudo -i komutunun bu değeri değiştirmemesidir: alice tarafından açılan bir root kabuğu hala 1000 auid değerini taşır, bu nedenle içindeki her komut alice'e atfedilebilir. sudo komutunun açık bıraktığı boşluk tam olarak budur. Bir kez atandıktan sonra giriş kullanıcı kimliğini değiştirmek CAP_AUDIT_CONTROL yetkisi gerektirir; sıradan kullanıcılar bu yetkiye sahip değildir ve sudo auditctl --loginuid-immutable, bir sonraki yeniden başlatmaya kadar root için bile bu yolu kapatır.

/etc/pam.d/sshd, /etc/pam.d/login ve /etc/pam.d/cron dosyalarının her birinin pam_loginuid.so içerdiğinden emin olun; aksi takdirde olaylar, kendilerine bağlı bir kullanıcı olmadan ulaşacaktır. Bu, VPS üzerinde SSH erişimini sıkılaştırma işlemi sırasında düzenlediğiniz dosya listesiyle aynıdır, bu nedenle her iki işi birlikte yapın.

auditd için başlangıç kural seti

Kurallar /etc/audit/rules.d/*.rules dizininde bulunur. augenrules, bu kuralları dosya adı sırasına göre tek bir listede birleştirir. Çekirdek ilk eşleşen kuralda durduğu için kural sırası davranış üzerinde belirleyicidir. Yeni bir şey eklemeden önce mevcut kuralları inceleyin; çünkü sonraki bir dosyada yer alan -D, kendisinden önce yüklenmiş olan her şeyi siler.

ls /etc/audit/rules.d/
cat /etc/audit/rules.d/audit.rules

Ardından /etc/audit/rules.d/50-exec.rules dosyasını oluşturun:

## Suppressions first: the kernel takes the first matching rule.
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-deb
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-query
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-split
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-trigger

## Every program started by a logged-in human.
-a always,exit -F arch=b64 -S execve,execveat -F auid>=1000 -F auid!=unset -k exec
-a always,exit -F arch=b32 -S execve,execveat -F auid>=1000 -F auid!=unset -k exec

## Changes to who may become root.
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity

## Changes to the audit configuration itself.
-w /etc/audit/ -p wa -k auditconfig

Kuralları yükleyin ve doğrulayın:

sudo augenrules --load
sudo auditctl -l

auditctl -l komutunun kurallarınızı geri dökmesi, kuralların aktif olduğu anlamına gelir. No rules hatası yüklemenin başarısız olduğunu gösterir; journalctl -u auditd -n 20 ise ayrıştırıcının reddettiği dosya adını ve satır numarasını belirtir. Eski audit kullanıcı alanı araçları unset anahtar kelimesini tanımaz. Yükleyici bu alanla ilgili bir hata verirse, aynı değeri ifade eden -F auid!=4294967295 ifadesini kullanın.

Şimdi olayları inceleyin:

sudo ausearch -k exec -ts recent -i | tail -40
sudo ausearch -ul 1000 -ts today -i
sudo aureport -k --summary -i

-i, uid değerlerini ve sistem çağrısı numaralarını isimlere dönüştürür; pratikte bu seçenek zorunludur. -ts recent son on dakikayı kapsar. Her yürütme bir kayıt grubu olarak gelir: uid, auid, çıkış durumu ve anahtarı taşıyan bir SYSCALL kaydı, tam argüman listesini içeren bir EXECVE kaydı ve bağlam için CWD ile PATH kayıtları.

Önemli bir kısıtlama: audit sistem çağrılarını kaydeder, ancak shell yerleşik komutları kendi başına bir sistem çağrısı yapmaz. cd /root bir program çalıştırmaz. Bir bash isteminde yazılan echo evil >> /etc/passwd de bir program çalıştırmaz; çünkü hem echo hem de yönlendirme işlemi zaten çalışmakta olan shell süreci içinde gerçekleşir. Bu nedenle execve kuralları programları, -w kuralları ise yazma işlemlerini görür. Tek başına hiçbiri yeterli değildir.

Son olarak yapılandırmayı kilitleyin:

## /etc/audit/rules.d/99-finalize.rules
-e 2

-e 2, bir sonraki yeniden başlatmaya kadar kural setini değiştirilemez hale getirir. Yüklendikten sonra auditctl -s komutu enabled 2 değerini raporlar ve root dahil olmak üzere herhangi bir kural ekleme veya silme girişimi Operation not permitted hatasıyla başarısız olur. Bu dosyayı en son ekleyin ve bir kuralı değiştirmek istediğinizde sistemi yeniden başlatmanız gerekeceğini göz önünde bulundurun. Bu değiş tokuşun amacı şudur: herkesin sessizce devre dışı bırakabileceği bir kural seti kanıt niteliği taşımaz.

Kimsenin okumadığı bir denetim günlüğü yalnızca uyumluluk belgesidir

auditd sisteminin başarısızlık modu, olayları gözden kaçırması değildir. Sorun, o kadar çok kayıt tutmasıdır ki kimse dönüp bakmaz; sonuçta günlük, bir soruyu yanıtlamak yerine sadece bir kontrol listesini doldurmak için var olur.

Herhangi bir ayar yapmadan önce kendi sunucunuzda şu hesabı yapın:

sudo aureport -k --summary -i
sudo du -sh /var/log/audit

Tek bir sudo apt upgrade binlerce kısa ömürlü süreç çalıştırır ve her biri sizin auid değerinizi taşır; bu nedenle tek bir paket güncellemesi, bir haftalık insan etkileşiminden daha fazla veri üretebilir. Yukarıdaki hariç tutma kurallarının dpkg ve yardımcılarını hedeflemesinin nedeni budur. Hariç tutma işlemlerini kullanıcıya göre değil, çalıştırılabilir dosyaya göre yapın: /usr/bin/dpkg için yapılan bir istisna tek cümleyle açıklanabilecek bir güvenlik açığıdır; ancak bir hesap için yapılan istisna, tam olarak yakalamaya çalıştığınız tehdidin şeklini alan bir güvenlik açığıdır.

Her kuraldaki -k anahtarı, günlüğün bir ay sonra aranabilir olmasını sağlayan şeydir. ausearch -k sudoers cevabı olan bir sorudur. Filtresiz bir ausearch ise sizi okumayı bırakmaya şartlandıran bir metin yığınıdır. Eğer günlük toplayıcınız yerel format yerine JSON istiyorsa, laurel her olayı argümanları çözülmüş tek bir JSON nesnesi olarak yeniden yazan bir auditd eklentisidir. Diğer tüm eklentiler gibi /etc/audit/plugins.d/ içinde kayıtlıdır ve auditd, eklenti değişikliklerini sudo pkill -HUP auditd üzerinde algılar.

auditd maliyeti nedir, dürüstçe

Eşleşen her syscall, çekirdeğin biçimlendirip kullanıcı alanına (userspace) ilettiği bir kayda dönüşür. Maliyet iki noktada ortaya çıkar ve her ikisi de başkasının yayınladığı tahmini rakamlar yerine kendi iş yükünüz üzerinde ölçülebilir.

  • CPU ve gecikme. Sürekli fork işlemi yapan bir makine, bir derleme sunucusu veya bir CI çalıştırıcısı, her exec için bir kayıt üretir. Çekirdek birikim kuyruğu (backlog) dolduğunda, --backlog_wait_time çekirdeğin olayı üreten süreci yer açılana kadar duraklatmasına neden olur; bu nedenle audit, CPU yüzdesi yerine yavaş derleme süreleri olarak kendini gösterir. Gerçek yük altında sudo auditctl -s içerisindeki backlog ve lost değerlerini izleyin. Artan bir lost, kayıtların atıldığı anlamına gelir; sessiz boşluklar içeren bir günlük, hiç günlük olmamasından daha kötüdür çünkü ona güvenmeye devam edersiniz.
  • Disk. /etc/audit/auditd.conf dosyasını okuyun ve disk dolduğunda ne olacağına bilinçli olarak karar verin, çünkü varsayılan değerler sadece birer görüştür. max_log_file, num_logs ve max_log_file_action rotasyonu kontrol eder. space_left_action, admin_space_left_action ve disk_full_action acil durum davranışını kontrol eder; halt ve single dahil olmak üzere mevcut bazı eylemler, bir kaydı kaybetmek yerine makineyi kapatmayı tercih eder.

/etc/audit/rules.d/audit.rules dosyasındaki -f satırı, çekirdek seviyesindeki aynı kararı temsil eder: -f 1 bir audit hatasını syslog'a bildirir, -f 2 ise çekirdeği paniğe sürükler. 2 seçeneğini yalnızca bir kaydı kaybetmektense sunucuyu kaybetmeyi gerçekten tercih ediyorsanız seçin. İnsanların bağımlı olduğu bir VPS üzerinde çalışıyorsanız, bunun yerine rotasyon yapın ve depolama sorununu sunucunun dışına taşıyın.

Log kayıtlarını sunucu dışına, gerçek zamana yakın biçimde aktarın

Olay sonrası hazırlanan raporların sürekli kanıtladığı gerçek budur. Ele geçirilmiş bir sunucuda kalan log kayıtları, sunucuyu ele geçiren kişi tarafından değiştirilebilir. root kullanıcısı /var/log/auth.log dosyasını yeniden yazabilir, /var/log/audit/audit.log dosyasını silebilir ve servisi durdurabilir. -e 2, kuralların kaldırılmasını engeller. Ancak rm konusunda hiçbir etkisi yoktur. Yukarıdaki tüm katmanlar, yalnızca bir kopyanın makineden önce çıkması durumunda kanıt üretir.

Audit servisinin kendi taşıma mekanizması, audispd-plugins içindeki audisp-remote eklentisidir. Bunu /etc/audit/plugins.d/au-remote.conf içinde etkinleştirin:

active = yes
direction = out
path = /usr/sbin/audisp-remote
type = always
format = string

Yeniden yükleme yapmadan önce path dosyasını command -v audisp-remote ile kontrol edin; yanlış bir yol, günlük kayıtlarında tek bir satır dışında hiçbir sonuç üretmez. /etc/audit/audisp-remote.conf içinde remote_server ve port değerlerini ayarlayın; toplayıcı (collector) tarafında ise kendi auditd.conf dosyasında tcp_listen_port = 60 değerini yapılandırın. sudo pkill -HUP auditd ile yeniden yükleyin. Birçok imajda systemctl restart auditd komutu reddedilir, çünkü unit dosyası RefuseManualStop=yes ayarını içerir; bu nedenle sinyal göndermek en güvenilir yoldur.

Diğer seçenek, audit kayıtlarını zaten yönlendirmekte olduğunuz syslog akışına dahil etmektir. active = no ile birlikte /etc/audit/plugins.d/syslog.conf gelir. Bunu yes olarak ayarlayın ve yeniden yükleyin; böylece audit olayları, sudo satırları ve diğer tüm kayıtlarla birleşir. Ardından, rsyslog-gnutls paketini gerektiren rsyslog üzerinden TLS (transport layer security) ile tümünü yönlendirin:

# /etc/rsyslog.d/60-forward.conf
*.* action(type="omfwd"
    target="logs.example.net" port="6514" protocol="tcp"
    StreamDriver="gtls" StreamDriverMode="1"
    StreamDriverAuthMode="x509/name"
    StreamDriverPermittedPeers="logs.example.net"
    action.resumeRetryCount="-1"
    queue.type="linkedList" queue.filename="fwd" queue.saveOnShutdown="on")

Kuyruk ayarları işin en önemli kısmıdır. action.resumeRetryCount="-1" sonsuza kadar yeniden dener; queue.saveOnShutdown="on" ile desteklenen disk tabanlı kuyruk ise toplayıcıya ulaşılamadığında kayıtları tutar ve bağlantı geri geldiğinde gönderir. Bu ikisi olmadan, toplayıcının yeniden başlatılması kanıtlarınızda bir boşluk bırakır ve bu boşluktan sizi haberdar edecek hiçbir mekanizma olmaz. sudo systemctl restart rsyslog ile uygulayın ve herhangi birine güvenmeden önce kayıtların toplayıcıya ulaştığını doğrulayın.

Kapatılması gereken bir açık daha var: toplayıcı, denetlenen kişilerin giriş yapamayacağı bir makine olmalıdır. Eğer aynı yönetici grubu log sunucusunda root yetkisine sahipse, dosyayı kopyalamış olursunuz, korumuş olmazsınız. Ayrı kimlik bilgileri, ayrı anahtarlar ve ideal olarak ayrı bir sağlayıcı hesabı kullanın. Bu, birçok Linux sunucusunu yönetmek için merkezi bir yol oluşturmayı ihtiyaç duymadan önce değerli kılan mantıkla aynıdır ve ele geçirilmiş bir VPS üzerinde çalışırken ilk saatin yararlı mı yoksa işe yaramaz mı olacağını belirleyen farktır.

Normal bir kullanıcının kaydı yeniden yazamadığını doğrulayın

Varsayımda bulunmak yerine iddiayı test edin. Sudo yetkisi olmayan sıradan bir hesaptan:

echo test >> /var/log/auth.log
cat /var/log/audit/audit.log
auditctl -D
id -nG

Sırasıyla şunları bekleyin: Permission denied, çünkü auth.log dosyasının sahibi syslog, grubu adm ve izin modu 640'tır; tekrar Permission denied, çünkü denetim günlüğü 600 modundadır ve sahibi root kullanıcısıdır; çalıştırmayı reddeden bir hata, çünkü denetim kurallarını değiştirmek CAP_AUDIT_CONTROL yetkisi gerektirir; ve ne adm ne de systemd-journal grubunu içermeyen bir grup listesi.

Son kontrol, insanların başarısız olduğu kısımdır. adm üyeliği /var/log/auth.log dosyasına okuma erişimi, systemd-journal üyeliği ise tüm günlüğe okuma erişimi sağlar. İkisi de yazma erişimi sağlamaz, dolayısıyla ikisi de kurcalamaya izin vermez. Her ikisi de bir kişinin sistemdeki tüm kimlik doğrulama satırlarını okumasına olanak tanır; bu, bir forum yanıtından usermod -aG satırını kopyalayarak değil, bilinçli bir şekilde verilmesi gereken bir karardır.

Son olarak, yeniden başlatma sonrasında kalıcı olması gereken iki durumu doğrulayın:

sudo auditctl -s
systemctl is-enabled auditd

enabled 2, kural kümesinin bir sonraki önyüklemeye kadar kilitli olduğu anlamına gelir. İkinci komuttan gelen enabled, auditd servisinin o önyüklemeden sonra tekrar başladığını gösterir. Yalnızca bir sonraki çekirdek güncellemesine kadar geçerli olan bir kural kümesi, denetim izi (audit trail) sayılamaz.

FAQ

Belirli bir kullanıcının çalıştırdığı tüm komutları nasıl görebilirim?

Kullanıcının uid değerini id -u alice ile bulun, ardından denetim günlüğünü (audit log) giriş uid'sine göre sudo ausearch -ul 1000 -ts today -i ile aratın. Aramayı yalnızca execve kuralıyla sınırlamak için -k exec ekleyin. Giriş uid'si oturum açma sırasında atanır ve su ile sudo -i işlemlerinden etkilenmez; bu sayede ilgili hesabın açtığı bir root kabuğu içinde çalıştırılan komutlar da yakalanır. Bu yöntem yalnızca kurallar yüklendikten sonra çalıştırılan komutlar için geçerlidir, çünkü audit sistemi yapılandırılmamış olayların geçmişini tutmaz. Verinin genel yapısını görmek isterseniz kural bazlı sayıları sudo aureport -k --summary -i ile listeleyebilirsiniz.

Bir kullanıcı yaptıklarını gizlemek için bash geçmişini silebilir mi?

Evet, bu işlem herhangi bir yetki gerektirmez. ~/.bash_history dosyasının sahibi kullanıcıdır ve dosya 600 modunda olduğu için kullanıcı dosyayı düzenleyebilir, içeriğini silebilir veya dosyayı tamamen kaldırabilir. Ayrıca unset HISTFILE ile geçmişin yazılmasını durdurabilir, set +o history ile oturum sırasında kaydı kesebilir veya HISTCONTROL=ignorespace ayarlandığında komutların başına boşluk koyarak tekil komutları gizleyebilir. Bash, dosya içeriğini kabuk kapandığında yazar; bu nedenle kill -9 $$ ile sonlandırılan bir oturum hiçbir kayıt bırakmaz. Kabuk geçmişini kanıt olarak değil, yalnızca bir ipucu olarak değerlendirin.

sudo, sudo -i içinde gerçekleşen işlemleri günlüğe kaydeder mi?

Hayır. sudo yalnızca çalıştırılması istenen komutu günlüğe kaydeder, bu nedenle sudo -i komutu kabuk için tek bir satır üretir ve sonrasında hiçbir şey kaydetmez. O root kabuğu içinde yazılan her komut sudo için görünmezdir, çünkü sudo artık sürecin bir parçası değildir. sudo su -, sudo bash ve kabuk kaçışına (shell escape) izin veren tüm programlar aynı şekilde davranır. Bu boşluğu iki yöntem kapatır: orijinal giriş uid'si ile ilişkilendirilmiş her programı kaydeden execve üzerindeki audit kuralları ve en başta kabuk erişimi vermeyen sudoers kuralları.

auditd sunucumu yavaşlatır mı?

Bu tamamen iş yükünüzün başlattığı süreç sayısına bağlıdır, bu yüzden bir rakama güvenmek yerine ölçüm yapın. Çoğunlukla istek yanıtlayan bir sunucu çok az exec işlemi yapar ve performans kaybı hissetmez. Ancak bir derleme sunucusu veya CI çalıştırıcısı sürekli exec işlemi yapar ve ciddi yavaşlama yaşayabilir; çünkü çekirdek audit birikim kuyruğu (backlog) dolduğunda, olayı üreten süreç yer açılana kadar duraklatılır. sudo auditctl -s komutunu gerçek yük altında çalıştırın ve backlog ile lost değerlerini izleyin. Sıfırdan büyük herhangi bir lost değeri, kayıtların atıldığını gösterir; bu en kötü senaryodur çünkü günlükte görünmez boşluklar oluşur.

Audit günlükleri nerede saklanmalıdır?

Saniyelerle ölçülen bir gecikme ile başka bir makinede saklanmalıdır. Denetlenen sunucuda root yetkisine ulaşan herhangi biri /var/log/audit/audit.log dosyasını silebilir ve /var/log/auth.log dosyasını yeniden yazabilir; bu nedenle yerel kopyalar yalnızca kimsenin gizlemeye çalışmadığı olaylar hakkında bilgi verir. Günlükleri audisp-remote eklentisi ile merkezi bir auditd sunucusuna iletin veya audit syslog eklentisini etkinleştirerek tüm syslog akışını rsyslog üzerinden TLS ile yönlendirin. Toplayıcıya kendi kimlik bilgilerini atayın ve denetlenen hesapların bu sunucuya erişimi olmadığından emin olun.