Exchange Server’da Journaling ile E-posta Uyumluluk Yönetimi
Yıllar önce bir finans şirketinde çalışırken başıma gelen bir olay, Exchange journaling konusunu hiç aklımdan çıkarmadı. Hukuk departmanı bizi aradı ve eski bir çalışanın iki yıl önceki e-postalarını mahkemeye sunmamız gerektiğini söyledi. O an journaling kurulu değildi. O anı yaşayan herkes bilir, “neden önceden yapmadık” sorusu havada asılı kalır ve cevabı yoktur. Bu yazıyı okuyorsanız, umarım o soruyu sormadan önce okuyorsunuzdur.
Exchange Journaling Nedir ve Neden Önemlidir
Exchange Server’da journaling, kısaca e-posta trafiğinin merkezi bir arşiv deposuna kopyalanması işlemidir. Ancak bu tanım işin teknik boyutunu anlatır, yasal boyutunu değil. Türkiye’de özellikle bankacılık, finans, sağlık ve kamu sektöründe faaliyet gösteren şirketlerin BDDK, SPK, KVKK ve çeşitli sektörel mevzuat kapsamında e-posta arşivleme yükümlülükleri bulunmaktadır. Exchange journaling tam da bu noktada devreye girer.
Journaling ile backup’ı karıştırmak çok yaygın bir hata. Backup, felaket senaryoları için vardır. Journaling ise her gönderilen ve alınan e-postanın değiştirilemez bir kopyasını oluşturmak içindir. Kullanıcı e-postayı silse bile, journal kaydı varlığını sürdürür. Bu fark kritiktir.
Exchange Server’da iki tür journaling vardır:
- Standard Journaling: Belirli bir mailbox veritabanındaki tüm kullanıcıları kapsar
- Premium Journaling: Journal kuralları aracılığıyla daha granüler kontrol sağlar, belirli kullanıcıları, dağıtım gruplarını veya alıcı tiplerini hedef alabilir
Premium journaling için Exchange Enterprise CAL lisansı gerektiğini şimdiden belirtelim. Eğer bütçe kısıtınız varsa standard journaling ile başlamak da makul bir tercihtir.
Ortamı Hazırlamadan Önce
Journal hedefi olarak kullanacağınız posta kutusunu mevcut kullanıcı mailbox’larından izole bir şekilde oluşturmalısınız. Bu mailbox’ın birkaç özelliği olması gerekir: boyut kotası çok yüksek veya sınırsız olmalı, normal kullanıcıların erişimi olmamalı ve bu mailbox’a gelen e-postalar için journaling tekrar tetiklenmemelidir (aksi hâlde sonsuz döngüye girersiniz).
Önce dedicated bir journal mailbox oluşturalım:
New-Mailbox -Name "JournalArchive" `
-Alias "journalarchive" `
-UserPrincipalName "[email protected]" `
-OrganizationalUnit "OU=ServiceAccounts,DC=sirket,DC=com,DC=tr" `
-Password (ConvertTo-SecureString "G@venliSifre2024!" -AsPlainText -Force) `
-ResetPasswordOnNextLogon $false
Ardından bu mailbox’ın kotasını kaldıralım veya çok yüksek bir değer atayalım:
Set-Mailbox -Identity "JournalArchive" `
-IssueWarningQuota unlimited `
-ProhibitSendQuota unlimited `
-ProhibitSendReceiveQuota unlimited `
-UseDatabaseQuotaDefaults $false
Bu mailbox’a normal kullanıcıların erişememesi için izinleri de düzenleyelim. Varsayılan olarak Domain Admins ve Organization Management rolündeki hesaplar erişebilir, bunu daha da kısıtlayabilirsiniz.
Standard Journaling Yapılandırması
Standard journaling, bir mailbox veritabanı seviyesinde çalışır. O veritabanındaki tüm kullanıcıların gönderip aldığı e-postalar journal mailbox’ına kopyalanır.
Set-MailboxDatabase -Identity "Mailbox Database 01" `
-JournalRecipient "[email protected]"
Yapılandırmayı doğrulamak için:
Get-MailboxDatabase -Identity "Mailbox Database 01" |
Select-Object Name, JournalRecipient
Çıktıda JournalRecipient alanında belirlediğiniz adres görünüyorsa standard journaling aktif demektir. Birden fazla veritabanınız varsa her biri için bu komutu ayrı ayrı çalıştırmanız gerekir.
Premium Journaling: Journal Kuralları
Premium journaling’in asıl gücü, kural tabanlı yapısında yatar. Diyelim ki sadece muhasebe departmanının dış alıcılarla yaptığı yazışmaları arşivlemek istiyorsunuz. Ya da üst düzey yöneticilerin tüm iç ve dış trafiğini kayıt altına almak istiyorsunuz. Bunu standard journaling ile yapamazsınız.
Tüm organizasyon için global bir journal kuralı oluşturmak:
New-JournalRule -Name "Global-Journal-Kural" `
-JournalEmailAddress "[email protected]" `
-Scope Global `
-Enabled $true
Sadece belirli bir kullanıcı veya dağıtım grubu için kural oluşturmak:
New-JournalRule -Name "Yonetim-Journal-Kural" `
-JournalEmailAddress "[email protected]" `
-Recipient "[email protected]" `
-Scope Global `
-Enabled $true
Scope parametresi üç değer alabilir:
- Global: Hem iç hem dış e-postalar
- Internal: Sadece organizasyon içi e-postalar
- External: Sadece dış alıcılarla yapılan yazışmalar
Mevcut journal kurallarını listelemek için:
Get-JournalRule | Select-Object Name, JournalEmailAddress, Scope, Enabled
Bir kuralı geçici olarak devre dışı bırakmak gerektiğinde (bakım penceresi, test gibi durumlarda):
Disable-JournalRule -Identity "Global-Journal-Kural"
Tekrar aktif etmek için:
Enable-JournalRule -Identity "Global-Journal-Kural"
Journal Raporlarını Anlamak
Journal mailbox’ına gelen e-postalar sıradan e-postalar gibi görünmez. Her journal kaydı bir journal raporu formatında gelir. Bu raporun yapısını anlamak, özellikle üçüncü parti arşivleme çözümleriyle entegrasyon yaparken önemlidir.
Journal raporu iki kısımdan oluşur. İlk kısım, meta veri içeren bir wrapper mesajdır: gönderen, alıcılar, zaman damgası ve konu bilgisi burada yer alır. İkinci kısım ise orijinal e-postanın kendisidir, ek olarak iliştirilmiş hâlde. Yani journal mailbox’ını açtığınızda her orijinal e-posta için bir wrapper mesajı görürsünüz ve orijinal içerik o mesajın eki olarak bulunur.
Bu yapı, bazı durumlarda e-posta miktarını oldukça şişirebilir. Özellikle büyük ekler içeren e-postalarda journal mailbox hızla dolabilir. Bu nedenle production ortamlarında journal mailbox’ı genellikle Exchange üzerinde tutmaz, üçüncü parti bir arşivleme çözümüne yönlendirirsiniz. Ziwit, Mimecast, Barracuda veya yerli çözümler bu noktada devreye girer.
Alternate Journal Recipient Yapılandırması
Journal mailbox’ına ulaşılamadığı durumlarda (disk dolması, sunucu hatası gibi) e-postalar teslim edilemez hâle gelebilir. Bu kritik bir uyumluluk sorunudur çünkü journal hedefine ulaşılamayan e-postalar varsayılan olarak gönderilmez. Exchange bu konuda sizi uyarmak için alternate journal recipient mekanizmasını sunar.
Set-TransportConfig -JournalingReportNdrTo "[email protected]"
Bu ayar sayesinde journal tesliminde sorun yaşandığında sistem yöneticisine bildirim gider. Ancak burada dikkat edilmesi gereken bir husus var: bu adresi journal mailbox’ının kendisi yapmayın. Döngüsel bir bağımlılık oluşturursunuz.
Mevcut yapılandırmayı kontrol etmek için:
Get-TransportConfig | Select-Object JournalingReportNdrTo
Envelope Journaling
Özellikle dağıtım listesi üyelerine gelen e-postaların tüm alıcı bilgilerini yakalamak istediğinizde envelope journaling devreye girer. Standart journaling raporu, e-postanın TO ve CC alanlarını gösterir, ancak dağıtım listesinin expand edilmiş halindeki gerçek alıcıları yakalamaz. Envelope journaling bu sorunu çözer.
Set-TransportConfig -JournalArchivingEnabled $true
Bu özellik etkinleştirildiğinde, dağıtım listesi üzerinden giden bir e-postanın her alıcısı için ayrı bir journal kaydı oluşturulur. Bu durum journal mailbox’ındaki e-posta sayısını önemli ölçüde artırabilir, ama uyumluluk açısından çok daha sağlam bir kayıt tutarsınız.
Gerçek Dünya Senaryosu: Hukuki Süreç Desteği
Bir müşterimde yaşanan durumu aktarayım. İK departmanından ayrılan bir çalışanın şirkete karşı iş mahkemesine başvurduğu ve 14 aylık e-posta yazışmalarının delil olarak talep edildiği bir davada journaling sisteminin önemi bir kez daha ortaya çıktı.
Journal veritabanında belirli bir kullanıcının belirli tarih aralığındaki e-postalarını aramak için Exchange Management Shell’i kullandık:
Get-Mailbox -Identity "JournalArchive" |
Search-Mailbox -SearchQuery "From:'[email protected]' AND Received:01/01/2023..12/31/2023" `
-TargetMailbox "[email protected]" `
-TargetFolder "Dava-2024-01" `
-LogLevel Full `
-LogOnly
Önce -LogOnly parametresiyle neyin bulunduğunu gördük, sonra gerçek kopyalama işlemini yaptık. Bu iki adımlı yaklaşım, istemeden yanlış şeyleri kopyalamanın önüne geçer.
Bu senaryo Exchange 2016 ve 2019 için geçerlidir. Exchange Online için ise Compliance Center üzerinden eDiscovery araçlarını kullanmak daha modern ve kullanışlı bir yaklaşımdır.
Journaling ve Performans
Journaling, gözden kaçırdığında sürpriz performans sorunlarına yol açabilen bir özelliktir. Her e-posta teslimi sırasında ek bir kopyalama işlemi gerçekleştiğinden, yoğun e-posta trafiği olan ortamlarda transport katmanında bir yük oluşur.
Birkaç pratik gözlem:
- Journal mailbox’ını ayrı bir mailbox veritabanına koyun, kullanıcı veritabanlarıyla karıştırmayın
- Journal mailbox veritabanı için ayrı diskler kullanın, I/O çakışmasını önleyin
- Journal mailbox boyutunu düzenli izleyin, alarmlar kurun
- Büyük ortamlarda dedicated bir Edge veya Hub Transport sunucusu üzerinden journal trafiğini yönlendirmeyi değerlendirin
Transport log’larını izlemek için:
Get-TransportService | Get-MessageTrackingLog -EventId JOURNAL `
-Start (Get-Date).AddHours(-24) |
Select-Object Timestamp, Sender, Recipients, MessageSubject |
Sort-Object Timestamp -Descending
Bu komut son 24 saatte gerçekleşen journal olaylarını listeler. Eğer burada beklenenden az kayıt görüyorsanız, journaling’in düzgün çalışmadığının ilk işareti olabilir.
Sorun Giderme
En sık karşılaşılan sorun, journal mailbox’ının dolması veya erişilemez hale gelmesidir. Bu durumda Exchange e-posta teslimini engelleyebilir.
Journaling ile ilgili olayları Windows Event Log üzerinden takip etmek için:
Get-EventLog -LogName Application -Source "MSExchange*" `
-EntryType Error,Warning -Newest 50 |
Where-Object {$_.Message -like "*journal*"} |
Select-Object TimeGenerated, EntryType, Message
Journal kurallarının gerçekten tetiklenip tetiklenmediğini test etmek için basit bir test e-postası gönderip ardından journal mailbox’ında o e-postayı aramak yeterlidir. Ama bunu otomatize etmek istiyorsanız küçük bir test scripti işinize yarayabilir:
$testMailParams = @{
To = "[email protected]"
From = "[email protected]"
Subject = "Journal Test - $(Get-Date -Format 'yyyy-MM-dd HH:mm')"
Body = "Bu e-posta journal sisteminin calısıp calışmadığını doğrulamak için gönderilmiştir."
SmtpServer = "mail.sirket.com.tr"
}
Send-MailMessage @testMailParams
Start-Sleep -Seconds 60
$journalCheck = Search-Mailbox -Identity "JournalArchive" `
-SearchQuery "Subject:'Journal Test - $(Get-Date -Format 'yyyy-MM-dd HH:mm')'" `
-LogOnly `
-LogLevel Full `
-TargetMailbox "[email protected]" `
-TargetFolder "JournalTest"
if ($journalCheck.ResultItemsCount -gt 0) {
Write-Host "Journal çalışıyor - $($journalCheck.ResultItemsCount) kayıt bulundu" -ForegroundColor Green
} else {
Write-Host "UYARI: Journal kaydı bulunamadı!" -ForegroundColor Red
}
Bu scripti bir zamanlanmış görev olarak günlük çalıştırırsanız, journaling sisteminin sağlıklı olduğunu düzenli olarak doğrularsınız.
Uyumluluk Raporlaması
Birçok organizasyonda journaling’in kurulu olduğunu iç denetçilere veya düzenleyici kurumlara kanıtlamak gerekir. Bunun için mevcut journal yapılandırmasını belgelendiren bir rapor almak işinize yarayabilir:
$report = @()
$report += "=== Exchange Journaling Yapılandırma Raporu ==="
$report += "Tarih: $(Get-Date -Format 'dd.MM.yyyy HH:mm')"
$report += ""
$report += "--- Mailbox Veritabanı Journal Ayarları ---"
Get-MailboxDatabase | Select-Object Name, JournalRecipient | ForEach-Object {
$report += "Veritabanı: $($_.Name) | Journal Alıcı: $($_.JournalRecipient)"
}
$report += ""
$report += "--- Journal Kuralları ---"
Get-JournalRule | ForEach-Object {
$report += "Kural: $($_.Name) | Hedef: $($_.JournalEmailAddress) | Kapsam: $($_.Scope) | Durum: $($_.Enabled)"
}
$report += ""
$report += "--- Transport Yapılandırması ---"
$transportConfig = Get-TransportConfig
$report += "NDR Adresi: $($transportConfig.JournalingReportNdrTo)"
$report += "Envelope Journaling: $($transportConfig.JournalArchivingEnabled)"
$report | Out-File -FilePath "C:ReportsJournal-Raporu-$(Get-Date -Format 'yyyyMMdd').txt" -Encoding UTF8
Write-Host "Rapor oluşturuldu." -ForegroundColor Green
Bu raporu aylık olarak çalıştırıp uyumluluk dosyanızda saklamanızı öneririm.
Dikkat Edilmesi Gereken Noktalar
Journaling yaparken KVKK kapsamında düşünülmesi gereken bazı durumlar var. Kişisel veri niteliğindeki e-postaların belirli bir süre tutulup sonra imha edilmesi gerekebilir. Bu durum retention policy ve journaling’i birlikte yönetmeyi zorunlu kılar. Hukuk ve uyumluluk ekiplerinizle bu süreyi netleştirmenizi şiddetle tavsiye ederim; teknik konfigürasyon kolaydır ama neyi, ne kadar tutacağınız konusunda hukuki dayanak olmadan ilerlemeyin.
Ayrıca journal mailbox’ına erişimi olan kişilerin listesini minimumda tutun ve bu erişimi loglamak için audit logging’i aktif edin:
Set-Mailbox -Identity "JournalArchive" -AuditEnabled $true `
-AuditOwner @("Update","Move","MoveToDeletedItems","SoftDelete","HardDelete") `
-AuditDelegate @("Update","Move","MoveToDeletedItems","SoftDelete","HardDelete","SendAs","Create") `
-AuditAdmin @("Update","Move","MoveToDeletedItems","SoftDelete","HardDelete","SendAs","Create","Copy")
Sonuç
Exchange journaling, “kurulumu on dakika, faydası yıllarca” diyebileceğimiz nadir özelliklerden biridir. Ancak bu kolaylık, ihmal gerekçesi olmamalı. Doğru yapılandırılmış bir journaling sistemi; hukuki süreçlerde kuruluşunuzu korur, denetim gerekliliklerini karşılar ve e-posta tabanlı her türlü anlaşmazlıkta güvenilir bir kayıt kaynağı sağlar.
Önceliklerinizi şöyle sıralayabilirsiniz: önce journal mailbox’ını doğru şekilde izole edin, sonra ihtiyacınıza göre standard veya premium journaling’i aktif edin, NDR adresini yapılandırın, ardından monitoring ve raporlama scriptlerini devreye alın. Son adım olarak hukuk ekibinizle retention süresini belirleyin.
Sistemi kurduktan sonra test etmeden geçmeyin. Journaling’in çalıştığını varsaymak ile çalıştığını bilmek arasındaki fark, mahkeme salonunda ağır bedellerle öğrenilebilir. Yukarıda paylaştığım test scriptini hemen çalıştırabilirsiniz.
