ManageSieve ile Sieve Script'lerini Uzaktan Yönetmek: Merkezi Dağıtım ve Sürümleme
4000 kullanıcılı bir sunucuda ~/sieve altındaki filtreleri elle düzenlemek ölçeklenmez: geri alma yok, tutarlılık yok. ManageSieve (RFC 5804) script deposunu bir API'ye dönüştürür; git, CI ve sieve_before katmanlarıyla birleştirince kullanıcı filtreleri ile kurumsal politika ayrışır, her deploy CHECKSCRIPT ile doğrulanır, rollback tek bir SETACTIVE komutuna iner.
EvilMail Team4 Ağustos 202611 dk okuma
4000 hesaplık bir sunucuda /var/mail/vhosts/*/sieve dizinlerini find ile taradığınızda ne çıkacağını asla bilemezsiniz. Kimi kullanıcı .dovecot.sieve dosyasını Roundcube üzerinden düzenlemiş, kimi admin bir gece SSH'la girip elle bir fileinto satırı eklemiş, kimisinde de üç ay önce kopyalanmış ama artık kimsenin hatırlamadığı bir require ["imapsieve"] satırı duruyor. Bu satırlardan biri Pigeonhole'un desteklemediği bir extension'a atıfta bulunuyorsa, o kullanıcının teslimatı sessizce durur: log'a bir sieve: compile error düşer, mesajlar implicit keep ile INBOX'a gitmek yerine LMTP tarafında birikir.
Sorun Sieve'in kendisi değil. RFC 5228 olgun, deterministik ve hızlı bir filtreleme dili. Eksik olan yönetim düzlemi: script'i kim, ne zaman, hangi sürümle koydu; geçen ayki hâline nasıl dönülür; kurumsal politika ile kullanıcının kişisel filtresi nerede ayrışır. ManageSieve tam olarak bu boşluğu doldurur — script deposunu, dosya kopyalamak yerine üzerine deploy pipeline kurabileceğiniz bir API'ye çevirir.
ManageSieve gerçekte ne yapıyor
ManageSieve ile Uzaktan Sieve Script Dağıtımı ve Sürümleme | evilmail.pro — EvilMail Blog
ManageSieve, RFC 5804 ile standartlaştırılmış, IANA'nın sieve servisine ayırdığı 4190 numaralı portta dinleyen, satır tabanlı ve capability müzakereli bir protokoldür. (Eski dağıtımlarda kullanılan 2000 portu Cisco'nun SCCP/Skinny servisiyle çakıştığı için terk edildi; 2026'da 4190 dışında bir şey görüyorsanız yapılandırma eskimiş demektir.) Protokol IMAP'e çok benzer: bağlanır bağlanmaz sunucu bir capability listesi tükürür, siz STARTTLS ile şifreli katmana geçer, AUTHENTICATE ile SASL üzerinden kimlik doğrularsınız.
Komut seti dar ve amaca yönelik: LISTSCRIPTS, PUTSCRIPT, GETSCRIPT, CHECKSCRIPT, SETACTIVE, DELETESCRIPT, RENAMESCRIPT, HAVESPACE, CAPABILITY, NOOP, LOGOUT. Sürümleme stratejisinin dayandığı kritik kısıt şu: kullanıcı başına birden çok isimli script saklanabilir, ama aynı anda yalnızca biri aktiftir. Aktifliği SETACTIVE belirler. Bu tek cümle, bütün rollback mimarisinin temelidir — eski sürümü silmeden yeni sürümü koyar, aktifi değiştirir, sorun çıkarsa aktifi geri alırsınız.
Ham bir oturum protokolü en çıplak haliyle gösterir:
{180+} gördüğünüz şey ManageSieve'in literal uzunluk sözdizimidir: sonraki 180 baytın script gövdesi olduğunu söyler. STARTTLS zorunludur; SASL PLAIN yalnızca TLS katmanı içinde kabul edilmelidir, aksi halde parolayı düz metin gönderirsiniz. Mümkünse OAUTHBEARER tercih edin, ama pratikte çoğu deploy hattı PLAIN + TLS ile yürür.
Dovecot Pigeonhole tarafını açmak
Pigeonhole, Dovecot'un Sieve implementasyonudur ve ManageSieve servisini de o sağlar. Üç dosyaya dokunursunuz. Önce protokol listesine sieve eklenir (10-master.conf civarı):
Depolama mantığı diskte şöyle işler: her isimli script ~/sieve/<isim>.sieve olarak durur, aktif olan ise ~/.dovecot.sieve symlink'i üzerinden işaret edilir. Bir script ilk kez yorumlandığında Pigeonhole onu <isim>.svbin bytecode dosyasına derler; kaynak dosyanın mtime değeri değiştiğinde otomatik yeniden derler. Bizim kurulumda bu dosyalar uid/gid 5000 (evilmail vhost kullanıcısı) sahipliğinde olmalı — .svbin yazılamıyorsa Pigeonhole her teslimatta baştan derler ve loglarınız failed to create binary uyarılarıyla dolar.
Birkaç operasyonel not: sieve_max_script_size varsayılanda cömerttir, onu makul bir değere (256k fazlasıyla yeter) çekin ki tek bir kullanıcı megabaytlık bir script'le LMTP worker'ını yormasın. 4190 portu internete açıksa brute-force yüzeyidir; Dovecot'un auth failed satırlarını yakalayan bir fail2ban jail'i ekleyin. TLS sertifikası IMAP ile aynı olabilir, ayrı bir şey gerekmez.
Uzaktan yönetim: üç araç, üç senaryo
Deployment açısından ManageSieve'e üç farklı yükseklikten dokunursunuz.
doveadm sieve — sunucuya yerel, admin yetkisiyle çalışır, kullanıcının parolasını gerektirmez. Toplu migrasyon ve otomasyon için en temiz araç budur:
-a bayrağı put ederken script'i aynı anda aktifleştirir; bunu ayırıp önce koyup sonra activate etmek daha kontrollü bir akış verir.
sieve-connect — ağ üzerinden, kullanıcı kimliğiyle konuşan bir Perl istemcisi. CI runner'ınız uzaktaki mail sunucusuna deploy ederken bunu kullanırsınız; doveadm'in aksine sunucuya SSH gerektirmez:
Ham ManageSieve — yukarıdaki openssl s_client oturumu. Bunu üretimde kullanmazsınız ama protokolün ne konuştuğunu anlamak ve bir capability müzakeresini debug etmek için birebirdir.
İş bölümü basit: doveadm operatörün elindeki toplu araç, sieve-connect pipeline'ın ağ üzerinden çalışan deploy istemcisi, ham oturum ise öğrenme ve arıza teşhisi içindir.
Merkezi politika ile kullanıcı filtresini ayırmak
Asıl mimari karar burada verilir. En yaygın hata, kurumsal politikayı kullanıcının aktif script'inin içine gömmektir; kullanıcı script'ini düzenlediği an politikayı da siler. Pigeonhole bunun için üç katman sunar ve mesaj bu katmanlardan sırayla geçer:
sieve_before kullanıcıdan önce çalışır: kurumsal spam eşiği, uyumluluk arşivleme, kara liste. sieve_after kullanıcıdan sonra çalışır — hiçbir kural mesajı yerleştirmediyse devreye giren son-çare fileinto. Bu iki katmanı config yönetimiyle (Ansible + git) dağıtırsınız; kullanıcı bunlara asla dokunamaz.
Ortadaki katman kullanıcının kendi script'idir ve RFC 6609'un include extension'ı burada devreye girer. sieve_global dizinini tanımladıysanız, kullanıcı script'i kurumsal tabanı include :global "org-baseline" ile çağırabilir. Tabanı güncellediğinizde değişiklik, her kullanıcının script'ini yeniden deploy etmeden herkese yayılır. Kullanıcı kendi kurallarını yazar, siz tabanı kontrol edersiniz.
require ["fileinto","mailbox","imap4flags","include"];
include :global "org-baseline";
if header :contains "X-Spam-Flag" "YES" {
fileinto :create "Junk";
stop;
}
if address :domain :is "from" "bulten.example" {
setflag "\\Seen";
fileinto :create "Bulten";
}
Sürümleme ve dağıtım hattı
Tek kaynak git deposudur. Gerçeği kullanıcı diskindeki ~/sieve dizini değil, repodaki sieve/*.sieve dosyaları temsil eder. Pipeline dört adımda çalışır ve her adım bir öncekine bağımlıdır:
1. Offline derleme doğrulaması. CI runner mail sunucusuna hiç dokunmadan sievec policy.sieve çalıştırır. Çıktı policy.svbin ise derleme temiz; syntax hatası veya bilinmeyen extension varsa sievec sıfırdan farklı exit döner ve pipeline burada durur. Bozuk bir require satırının üretime hiç ulaşmamasını sağlayan ilk kapı budur.
2. İsimli sürümle PUTSCRIPT. Eskiyi silmeden policy-v4 adıyla yenisini koyarsınız. İsimlendirme konvansiyonu kritik: monoton artan bir sürüm numarası (policy-v3, policy-v4) rollback hedefini belirsizlikten kurtarır.
3. Sunucu tarafı CHECKSCRIPT. Offline sievec sizin runner'ınızın Pigeonhole sürümünü test eder; CHECKSCRIPT ise gerçek üretim sunucusunun tam da o extension setiyle script'i kabul edip etmediğini doğrular. İki ortam arasındaki sürüm farkı ancak burada yakalanır.
4. SETACTIVE. Aktif script'i yeni sürüme çevirir. Bir sorun çıkarsa SETACTIVE "policy-v3" saniyeler içinde önceki sürüme döner — eski bytecode zaten depoda olduğu için ne veri kaybı ne de yeniden derleme gecikmesi yaşanır.
Üretime çıkmadan önce iki güvenlik ağı daha kurun: bir [email protected] canary kullanıcısına deploy edip birkaç sentetik mesajla davranışı gözleyin, ve sieve-filter ile mevcut posta kutusundaki gerçek mesajlar üzerinde dry-run yaparak yeni script'in neyi nereye taşıyacağını hiçbir şeyi taşımadan görün.
Pratik kontrol listesi
4190 STARTTLS-only mu? Şifresiz SASL PLAIN'i reddettiğinizi düz nc ile bağlanıp doğrulayın.
sieve_before ile kurumsal politika ayrı katmanda mı? Spam/uyumluluk kuralları kullanıcı script'inin içinde durmamalı.
CI'da CHECKSCRIPT gate'i var mı?sievec exit kodu pipeline'ı gerçekten durduruyor mu, yoksa uyarıyı yutup deploy'a devam mı ediyor?
İsimli sürümler saklanıyor mu? En az son 3 sürüm depoda kalmalı ki rollback bir komuttan ibaret olsun.
doveadm vs sieve-connect yetki ayrımı net mi? Toplu admin işi doveadm, ağ üzerinden CI deploy'u sieve-connect; ikisini karıştırmayın.
sieve_max_script_size ayarlı mı? Varsayılana güvenmeyin, makul bir tavan koyun.
Tehlikeli extension'lar whitelist'te mi?editheader, vacation :days, imapsieve gibi yan etkili extension'lar sieve_extensions içinde bilinçli açılmalı, körlemesine değil.
.svbin izin sorunları loglanıyor mu?uid/gid 5000 sahipliği bozulunca her teslimatta yeniden derleme olur; bu uyarıyı bir alert'e bağlayın.
evilmail.pro tarafında hem geçici hem kalıcı posta altyapısını tam bu modelle işletiyoruz: kurumsal filtre tabanı git'te sürümlü, kullanıcı script'leri ManageSieve üzerinden, her deploy doğrulama kapısından geçiyor.