MX Kesimini Kayıp Mesaj Olmadan Yürütmek: TTL, Çift Teslimat ve Sağlayıcı Geçişi
Sağlayıcı değiştirirken MX'i çevirmek "kaydı düzelt" işi değil, bir zaman penceresi yönetimi işidir. TTL'in neden geriye dönük çalışmadığını, çift teslimat penceresini ve tek bir mesajı bile düşürmeyen kesim zaman çizelgesini gerçek dig/imapsync/swaks komutlarıyla anlatıyoruz.
EvilMail Team30 Temmuz 202612 dk okuma
Bir web sitesini yeni sunucuya taşırken bir A kaydını yanlış çevirirsen kullanıcı siteye ulaşamaz, sinirlenir, birkaç kez yeniler ve kayıt düzelince her şey normale döner. Hata gürültülüdür, anında fark edilir, hızlıca onarılır. Mail'de aynı hata sessizdir. Yanlış MX'e giden mesaj bounce olmaz — ya artık kimsenin okumadığı eski sunucuda birikip çürür, ya da eski kutu çoktan silindiği için gönderene "user unknown" ile geri döner. Üstelik gönderen bunu senin altyapı hatan değil, kendi yazım hatası sanar. Kaybı sen fark etmezsin; müşterin, ondan cevap bekleyen üçüncü taraf fark eder.
Bu yüzden MX kesimi bir "kaydı değiştir" işi değildir. Bir zaman penceresi yönetimi işidir. Kahraman düşük TTL değil; TTL'in nasıl davrandığını bilmek ve kesim anında iki sunucunun aynı anda posta kabul ettiği çift teslimat penceresini doğru boyutlandırmaktır. Bunu bir kez içselleştirdiğinde "cuma akşamı MX'i çevirdik" hikâyelerinin neden pazartesi veri kaybı raporuyla bittiğini de anlarsın.
Neden mail kesimi web kesiminden daha tehlikeli
Web tarafında istemci ile sunucu arasında retry yoktur; istek başarısızsa kullanıcı elle yeniler. Mail tarafında ise gönderen MTA, geçici bir hata alırsa mesajı günlerce kuyrukta tutup tekrar dener. Bu retry davranışı hem senin güvenlik ağın hem de en büyük tuzağın: doğru kullanırsan tek mesaj kaybetmezsin, yanlış kullanırsan kaybı günlerce göremezsin.
Bir miti de baştan çürütelim: DNS "yayılmaz". "Propagasyon" kelimesi, değişikliğin bir dalga gibi dünyaya yayıldığı ve birkaç saat beklersen her yere ulaştığı yanılgısını üretir. Gerçek şu: her resolver, senin kaydını sorguladığı anda aldığı cevabı kendi TTL sayacına göre bağımsız olarak cache'ler. Kimse kimseyle konuşmaz. Sen bir değişiklik yaptığında yaptığın tek şey, o resolver'ların
bir sonraki
sorgusunda görecekleri değeri değiştirmektir — daha önce cache'ledikleri değeri değil. Kesimi kontrol etmek, bu bağımsız cache ömürlerini önceden kısaltmak demektir.
TTL gerçekte nasıl çalışır (ve neden geriye dönük düşürülemez)
TTL, bir resolver kaydı cache'lediği andan itibaren o snapshot'ı kaç saniye tutacağını söyler. Kritik nokta: TTL, cache anındaki değere kilitlenir. MX kaydının TTL'ini bugün 3600'den 300'e indirdiğinde, dün seni 3600 TTL ile sorgulayıp cache'lemiş bir resolver hâlâ o eski değeri tam 3600 saniye tutmaya devam eder. Senin yeni "300" değerin ona ancak cache'i dolup yeni sorgu yaptığında ulaşır.
Bunun pratik sonucu tek cümlelik bir kuraldır ve makalenin belkemiğidir: düşük TTL'in işe yaraması için, kesimden en az "eski TTL + güvenlik payı" kadar önce yayınlanmış olması gerekir. 3600 TTL ile çalışıyorsan, 300'e inme kararını kesimden en az bir saat, güvenli olmak için birkaç saat önce vermelisin ki eski 3600'lük snapshot'ların hepsi doğal ömrünü tamamlayıp yenisiyle değişsin.
İki kaydın TTL'i ayrı ayrı önemlidir: MX kaydının kendisi ve MX'in işaret ettiği mail host'un A/AAAA kaydı. Sadece MX'i düşürüp mail host A kaydını 3600'de unutmak klasik hatadır — MX'i çevirsen bile eski IP saatlerce cache'te kalır.
Bir de kimsenin bakmadığı yer: SOA kaydının minimum alanı, negatif cache süresini belirler (RFC 2308'e göre negatif TTL, SOA minimum ile SOA'nın kendi TTL'inin küçüğüdür). Yani "bu kayıt yok" (NXDOMAIN veya no-data) cevabı da bu süre kadar cache'lenir. Yeni bir kayıt henüz yayında değilken bir resolver "veri yok" cevabı aldıysa, kaydı yayınlasan bile o resolver bu süre dolana kadar "yok" demeye devam eder. Geçişten önce SOA minimum'unu da düşürmelisin.
dig çıktısındaki TTL sütununu okumayı öğren. Aynı komutu art arda çalıştırırsan sayacın geri saydığını görürsün — sıfıra ulaştığında resolver bir sonraki sorguyu yetkili sunucuya taşır:
bash
dig MX evilmail.pro @8.8.8.8 +noall +answer
# evilmail.pro. 2431 IN MX 10 yeni-mx.saglayici.net.
# birkaç saniye sonra tekrar: 2418, sonra 2405 ...
Kesim öncesi envanter: neyin taşındığını bilmeden taşıma
MX tek başına taşınmaz. Geçişten önce her kaydın mevcut değerini ve TTL'ini bir tabloya döküp yanına hedef değeri yaz. Unutulan her kayıt bir teslimat veya kimlik doğrulama açığıdır:
Sağlayıcıya özgü hedefler de bu aşamada netleşir. Google Workspace artık tek MX kullanıyor: smtp.google.com (priority 1). Microsoft 365'te hedef <tenant>.mail.protection.outlook.com (priority 0), autodiscover ise autodiscover.evilmail.pro CNAME autodiscover.outlook.com. Kendi Postfix altyapına geçiyorsan mail host'un A ve PTR kayıtlarının birbiriyle tutarlı olduğunu (FCrDNS) baştan doğrula, yoksa ilk giden maillerin yarısı spam'e düşer.
Geri sayım: TTL'i ne zaman, kaça indirmeli
Zaman çizelgesini somut tut. Aşağıdaki aralıklar evilmail.pro'nun kendi altyapı taşımalarından çıkan, kanıtlanmış değerler (s = saat, g = gün):
T-72s — Envanteri çıkar, mevcut TTL'leri ve değerleri not et. Henüz hiçbir şeye dokunma.
T-48s — MX ve mail host A/AAAA kayıtlarının TTL'ini 300'e (agresif, kısa bir kesim planlıyorsan 60'a) indir. SOA minimum'u da 300'e çek ki negatif cache kısalsın. Bu adım kesimin 48 saat öncesindedir çünkü eski 3600'lük TTL'lerin tamamının doğal olarak dolmasını bekliyoruz — matematiği "eski_TTL + güvenlik payı" ile kuruyoruz.
T-24s — SPF'e ikinci sağlayıcıyı ekle (aşağıda). DKIM yeni selector kaydını yayınla ama eskiyi bırakma.
T-1s — Çoklu resolver doğrulaması; her yerde düşük TTL'in görünür olduğunu teyit et.
T=0 — imapsync delta geçişi + MX'i çevir.
T+7g — Eski kutuları kapat, çift MX'i kaldır, TTL'i tekrar 3600'e yükselt.
En sık yapılan hata TTL'i kesim biter bitmez yükseltmektir. Erken yükseltirsen pencereyi kilitlersin: bir sorun çıkıp geri dönmen gerektiğinde artık düşük TTL'in yok, saatlerce eski değere mahkûmsun. TTL raise her zaman kesimden sonraya, en az bir haftaya bırakılır.
Çift teslimat penceresi: asıl güvenlik ağı
Kesimin kalbi burasıdır. Eski sunucuyu MX'i çevirir çevirmez kapatmıyorsun. İki seçeneğin var: ya eski sunucuyu yüksek sayılı (düşük öncelikli) bir yedek MX olarak tutuyorsun, ya da eski sunucu maili kabul edip yeni sunucuya forward ediyor. Kesim öncesi zone şöyle görünür:
evilmail.pro. 300 IN MX 10 yeni-mx.saglayici.net.
evilmail.pro. 300 IN MX 20 eski-mx.evilmail.pro.
evilmail.pro. 300 IN TXT "v=spf1 include:_spf.yeni.net include:_spf.eski.net -all"
Burada RFC 5321'in retry davranışı devreye girer ve seni kurtarır. Cache'i bayat bir gönderen eski MX'e ulaşır; eski sunucu maili ya kabul edip forward eder ya da geçici hata (4xx) döner. 4xx alan gönderen MTA mesajı kuyruğa alır ve tekrar tekrar dener. Postfix'te bu yeniden deneme, varsayılan maximal_queue_lifetime/bounce_queue_lifetime değeri olan 5 güne kadar sürer; delay_warning_time ayarlanmışsa gönderene arada bir "Delayed" uyarısı da gider (varsayılanı kapalıdır, çoğu sunucu bu ara uyarıyı hiç yollamaz). Yani birkaç saatlik cache gecikmesi asla mesaj kaybettirmez — sistem senin için bekler.
Tehlike sadece tek bir senaryoda gerçekleşir: eski mailbox silinmişse eski sunucu kalıcı hata (5xx, "user unknown") döner ve gönderen anında, geri dönüşsüz bir bounce yer. Retry kuyruğu 5xx'i beklemez. İşte tam bu yüzden eski kutular kesimden sonra en az 5-7 gün açık kalmalıdır. Retry penceresinin süresi kadar eski kutuyu ayakta tutarsan, en tembel resolver bile yeni MX'i görene kadar hiçbir gönderen 5xx yemez.
Kesim anı: sıralı yürütme
Sıra önemlidir. SPF'i MX'ten önce güncellemezsen, yeni sunucudan çıkan ilk mailler softfail/fail yer ve alıcının spam kutusuna düşer. DKIM yeni selector'ı da MX'ten önce yayında olmalı; eski selector transit mesajlar için hâlâ dursun.
bash
# 1) Delta senkron — ilk tam geçişten bu yana gelen yeni mesajları taşır
imapsync --host1 eski.mail --user1 [email protected] --password1 X \
--host2 yeni.mail --user2 [email protected] --password2 Y \
--ssl1 --ssl2 --automap
# 2) Yeni MX'e canlı teslimat testi — 250 kodunu ve Received başlığını doğrula
swaks --to [email protected] --server yeni-mx.saglayici.net --tls
# 3) MX'i çevir (zone'da), sonra çoklu resolver'dan görünürlüğü teyit et
for r in 8.8.8.8 1.1.1.1 9.9.9.9; do
echo "== $r =="; dig +short MX evilmail.pro @$r
done
Zone'u her düzenlediğinde SOA serial'ını artırmayı unutma; artırmazsan slave/secondary NS'ler değişikliği çekmez ve yetkili sunucular birbiriyle çelişir.
Doğrulama ve izleme
Kesimden sonraki ilk 48 saat kritik. Her iki sunucunun loglarını paralel izle. Yeni sunucuda mesajların düştüğünü, eski sunucuda düşen mesajların azaldığını görmelisin:
bash
tail -f /var/log/mail.log # her iki sunucuda
postqueue -p # Postfix bekleyen kuyruk
Eski sunucuya düşen son mesajın zaman damgasını takip et. Bu son mesaj T+72s'ten önce kesiliyorsa pencereyi doğru boyutlandırmışsın demektir — bütün resolver'lar yeni MX'e geçmiş. Hâlâ T+5g'de eski sunucuya mesaj düşüyorsa ya TTL'i yeterince önceden indirmemişsin ya da bir yerde uzun cache'li bir forwarder var.
DMARC agregat (rua) raporlarını da bekle; ertesi gün gelen raporlarda yeni kaynak IP'nin SPF ve DKIM'den pass aldığını doğrula. Bu, "mailler gidiyor" ile "mailler gerçekten kimlik doğrulayarak gidiyor" arasındaki farktır.
Kesim kontrol listesi
[ ] TTL (MX + mail host A/AAAA + SOA minimum) 300/60'a indirildi ve eski TTL'in tamamı doldu
[ ] SPF her iki sağlayıcının include'unu içeriyor (kesimden önce)
[ ] DKIM yeni selector yayında, eski selector hâlâ duruyor
[ ] imapsync tam geçiş gün önce, delta geçiş kesim anında tamamlandı
[ ] Eski kutular açık ve çift MX (ya da forward) ayakta
[ ] swaks ile yeni MX'e canlı 250 teslimatı doğrulandı
[ ] TTL'i 3600'e geri yükseltme ve eski kutu kapatma T+7g için takvime alındı
[ ] Kesim hafta içi, retry kuyruğunu izleyebilecek biri masasındayken yapıldı
Cuma akşamı MX çevirmenin tek sorunu senin yorgun olman değil; retry kuyruğunun ilk "delayed" uyarısını yolladığı ve 5 gün boyunca sessizce yeniden denediği pencerenin tam ortasında kimsenin logları izlemiyor olmasıdır. MX kesimini bir olay değil, planlı bir zaman penceresi olarak yürüt — o zaman geçiş, kimsenin fark etmediği bir işlem olur. Fark edilmemesi zaten başarının tanımıdır.