ARC ile Yönlendirilen ve Mail Listesinden Geçen Postalarda Kimlik Doğrulamayı Kurtarmak
SPF ve DKIM, postanın gönderenden alıcıya düz gittiğini varsayar. Gerçekte posta yönlendirilir ve listelerden geçer; her iki durumda da kimlik doğrulama kırılır ve meşru posta reddedilir. ARC (RFC 8617), aradaki dürüst durakların gördüğü sonucu kriptografik olarak mühürleyip son alıcıya taşır. evilmail.pro'nun Postfix + OpenARC / rspamd yığınında hem imzalayan hem doğrulayan olarak ARC'ı gerçek başlıkları okuyarak kuruyoruz.
EvilMail Team20 Temmuz 202613 dk okuma
Somut bir senaryoyla başlayalım. [email protected], evilmail üzerinden bülten postası gönderiyor; SPF ve DKIM tertemiz. Alıcının kutusunda bir .forward kuralı var: gelen her şeyi Gmail'e itiyor. Gmail'e ulaşan postanın zarf MAIL FROM adresi hâlâ musteri.com, ama bağlanan IP artık evilmail'in relay'i değil, yönlendiricinin çıkış IP'si. Gmail SPF'i kontrol ediyor:
text
Authentication-Results: mx.google.com;
spf=fail (google.com: domain of [email protected] does not
designate 203.0.113.44 as permitted sender)
[email protected];
dkim=pass header.d=musteri.com;
dmarc=fail (p=REJECT sp=REJECT dis=REJECT) header.from=musteri.com
DKIM burada pass olabilirdi — sade bir alias forward gövdeyi değiştirmez. Ama musteri.com
ARC (Authenticated Received Chain) ile Yönlendirilen Postalarda Kimlik Doğrulama | evilmail.pro — EvilMail Blog
politikası
p=reject
ve DMARC hizalama SPF tarafında koptuğu için sonuç
dmarc=fail
. Politika gereği posta reddedilir. Oysa aradaki durak dürüsttü: forwarder gerçekten
musteri.com
'dan gelen, SPF ve DKIM geçmiş bir postayı taşıdı. Sorun şu —
son alıcının bunu bilmesinin hiçbir yolu yok.
Gördüğü tek şey, kendi kapısına vuran IP ve o an tutmayan bir imza.
ARC (Authenticated Received Chain, RFC 8617) tam olarak bu bilgi boşluğunu kapatır. SPF veya DKIM'i "tamir etmez"; aradaki her dürüst durağın gördüğü kimlik doğrulama sonucunu kriptografik olarak mühürler ve bir sonraki durağa taşır. Son alıcı şöyle diyebilir: "Bu posta bana ulaşmadan önce, güvendiğim bir forwarder onu SPF + DKIM + DMARC pass olarak gördü." Ardından kendi yerel politikasıyla DMARC hatasını override edebilir.
SPF ve DKIM tam olarak nerede kırılır
İki farklı kırılma var ve ikisini karıştırmamak gerekir.
Yönlendirme SPF'i öldürür. SPF, bağlanan IP'nin zarf gönderen alan adına yetkili olup olmadığını sorar. Forwarder yeni bir IP'den bağlanır ama MAIL FROM'u aynı tutar → spf=fail. SRS (Sender Rewriting Scheme) zarf adresini yeniden yazarak SPF'i kurtarabilir, ama bu sefer zarf alan adı forwarder'ın alanı olur ve DMARC'ın istediği identifier alignment (zarf alanı ile From: başlık alanının eşleşmesi) bozulur. SRS SPF'i kurtarır, DMARC hizalamasını değil.
Mail listesi DKIM'i öldürür. Mailman, Sympa ve benzeri liste yazılımları postayı olduğu gibi geçirmez: Subject'e [liste] etiketi ekler, gövdeye abonelik footer'ı basar, List-Id / List-Unsubscribe başlıkları enjekte eder. DKIM imzası ya gövde hash'ini (bh=) korur ya da h= ile imzalanmış başlıkları — liste bunların ikisine de dokunur, dolayısıyla dkim=fail.
DMARC geçmek için hizalı bir SPF veya hizalı bir DKIM pass ister. Yönlendirme + liste senaryosunda ikisi de gider. Geriye tek bir çıkış kalır: postayı reddetmek.
Bu noktada birileri DKIM'in l= (body length) etiketini önerir — imzayı gövdenin yalnızca ilk N baytıyla sınırlayıp footer eklemesine izin vermek. Yapmayın. l=, saldırganın imzalı gövdenin sonuna istediği içeriği eklemesine kapı açar; imza teknik olarak geçerli kalır ama mesaj artık sizin yazdığınız mesaj değildir. Bu bir çözüm değil, bir güvenlik açığıdır.
ARC ne yapar: üç başlık, bir zincir
RFC 8617, 2019'da Experimental statüyle yayımlandı; RFC 8601 (Authentication-Results) ve DKIM (RFC 6376) üzerine kuruludur. Postanın geçtiği her ADMD (yönetim alanı — liste, forwarder, gateway) mesaja bir ARC set ekler. Her set bir i= instance numarası taşır; ilk durak i=1, sonraki i=2 ve böyle devam eder. Bir set üç başlıktan oluşur:
ARC-Authentication-Results (AAR) — o durakta görülen SPF/DKIM/DMARC (ve varsa önceki arc) sonucunun anlık görüntüsü. Basitçe, o an üretilen Authentication-Results başlığının bir kopyasıdır.
ARC-Message-Signature (AMS) — DKIM imzası gibi çalışır: bh= gövde hash'i, h= imzalanan başlık listesi, c= canonicalization. Mesajı, o durakta müdahale edilmeden önceki hâliyle imzalar.
ARC-Seal (AS) — mührü vuran başlık. Zincirdeki önceki tüm ARC başlıklarını artı cv= sonucunu imzalar. Zinciri kuran ve kilitleyen budur.
cv= (chain validation) üç değer alır: none (yalnızca i=1'de), pass ve fail. En kritik davranış: bir durak zincirin önceki setlerini kurcalarsa cv=fail olur ve bu durum kalıcıdır — sonraki hiçbir durak zinciri "geri onaramaz". Zincir ya baştan sona bütündür ya da bozuktur.
Gerçek bir ARC zincirini okumak
Mailman'den çıkan tek duraklı bir postanın i=1 seti şöyle görünür (satır sonları okunurluk için kırıldı):
Etiketlerin anlamı: d= mührü vuran alan; s=arc DKIM key record'unu işaret eden selektör; a=rsa-sha256 imza algoritması; bh= gövde hash'i; cv=none ilk halka olduğunu söyler. AAR'ın kritik satırı dmarc=pass header.from=sender.com — liste, postayı orijinal gönderenden hizalı DMARC pass olarak gördüğünü bu kayıtla ilan ediyor. Son alıcının override kararında dayanacağı kanıt işte budur.
İkinci durak (Gmail forwarder gibi) i=2 setini ekler ve AAR'ında bir arc=pass satırı görünür — yani "bir önceki zinciri doğruladım, bütündü". Son alıcı kendi Authentication-Results başlığına şunu yazar:
Başlıkları elle debug ederken hatırlanacak kural: ARC başlıkları en üstte en yeni i= olacak şekilde saklanır. Zinciri okumak için aşağıdan (i=1) yukarı (i=n) doğru ilerleyin.
Postfix'e OpenARC ile imzalama + doğrulama eklemek
Önce anahtar. ARC anahtarı sıradan bir DKIM anahtarıdır; ARC'a özel bir üretim aracı yoktur, OpenDKIM'in opendkim-genkey aracıyla 2048-bit üretiriz:
Mode sv hem imzala (sign) hem doğrula (verify) demektir. DNS'e yayımlanan kayıt bir DKIM key record'unun tıpatıp aynısıdır — ARC'a özel bir DNS record tipi yoktur:
text
arc2026._domainkey.evilmail.pro. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."
Şimdi Postfix'te milter sırası — kurulumun en çok gözden kaçan ve en çok can yakan yeri burası. main.cf:
8891 OpenDKIM, 8894 OpenARC. Sıra kesinlikle OpenDKIM önce, OpenARC sonda olmalı. Neden? OpenARC'ın ürettiği AAR, o durakta çalışmış SPF/DKIM doğrulamasının sonucunu yansıtmalı. ARC milter'ı DKIM milter'ından önce çalışırsa, DKIM sonucu henüz üretilmemiş olur ve AAR boş ya da eksik bir dkim= satırıyla çıkar — zincir teknik olarak geçerli ama bilgi olarak değersiz olur. ARC hep en sonda mühür vurmalı.
rspamd tercih edenler için
Milter zincirini yönetmek istemeyen operatörler için rspamd tek serviste hem SPF/DKIM/DMARC verify hem ARC seal yapar. /etc/rspamd/local.d/arc.conf:
sign_authenticated = true yalnızca kimliği doğrulanmış oturumlardan gelen postaları imzalar. rspamd'nin avantajı net: doğrulama ve mühürleme aynı süreçte olduğu için milter sıralama derdi ortadan kalkar — AAR'a hangi sonucun yazılacağı konusunda yarış koşulu yaşamazsınız. Trade-off tek cümle: OpenDKIM + OpenARC daha modüler ve klasik yığınlara oturur, rspamd tek servisle daha az ayak izi ve daha az sıralama hatası verir.
Alıcı tarafı: doğrulamak yetmez, güvenmek gerek
İşte ARC'ın en yanlış anlaşılan kısmı. `arc=pass`, DMARC'ı otomatik geçirmez.cv=pass yalnızca "zincir kriptografik olarak bütün" der; zincirdeki durakların dürüst olduğunu söylemez. Karar akışı şudur:
DMARC pass → bitti, teslim et.
DMARC fail + ARC yok → alan sahibinin politikasını uygula (p=reject ise reddet).
DMARC fail + ARC cv=pass → en üst i= setinin AAR'ında orijinal dmarc=pass var mı? Ve o zincirdeki duraklara güveniyor muyum? İkisi de evetse override et.
Güven modeli tanım gereği out-of-band'dir: RFC size kime güveneceğinizi söylemez. Güven listenizi kendiniz kürersiniz — google.com, bilinen büyük liste operatörleri, kendi altyapınızdaki forwarder'lar. Bu listeyi gelişigüzel doldurursanız ARC, olduğu gibi bir DMARC-atlatma vektörüne dönüşür: kötü niyetli bir aracı dmarc=pass yazan bir AAR uydurur, mühürler ve siz körlemesine güvenirseniz, spoof'lanmış postayı politikayı ezerek teslim etmiş olursunuz.
Google ve Microsoft ARC'ı üretimde uygular; Gmail hem imzalar hem doğrular. Küçük ve orta ölçekli operatör için pratik tavsiye keskindir: imzalamayı herkes için aç (mühürlediğiniz zincir aşağı akıştaki alıcılara yardım eder, size zararı yok), ama override'ı yalnızca elle whitelist ettiğin forwarder'lara uygula. İmzalamak kolaydır; asıl mühendislik işi kime güveneceğine karar vermektir.
Mod ve sıra: OpenARC Mode sv; Postfix milter sırasında OpenARC en sonda (8891 sonra 8894).
Tek duraklı test: Kendine bir liste veya forward üzerinden posta gönder; ham başlıkta i=1 set'ini ve cv=none'ı gözle gör.
İki duraklı test: Kendi listenden başka bir kutuya zincirle; alıcıda cv=pass ve i=2'yi doğrula.
Alıcı loglaması: Son alıcı tarafında Authentication-Results içindeki arc=pass satırını logla; henüz karar için kullanma, sadece izle.
Güven listesi: Güvenilir forwarder whitelist'ini elle kür; override'ı yalnızca bu listeye uygula.
DMARC raporları: Forward kaynaklı fail'lerin haftalık toplu raporlarda düştüğünü takip et — ARC'ın işe yaradığının asıl kanıtı budur.
Sık yapılan üç hata
Milter sırası ters. OpenARC, OpenDKIM'den önce çalışıyor → AAR boş dkim= ile çıkar, zincir bilgisiz kalır. En yaygın ve en sinsi hata; çünkü her şey "çalışıyor" gibi görünür, sadece işe yaramaz.
1024-bit anahtar. Gmail ve Microsoft 1024-bit'i giderek reddediyor; bazı doğrulayıcılar mührünüzü hiç işleme almaz. 2048-bit pratik standarttır, altına inmeyin.
`cv=fail`'i "reddet" sanmak.cv=fail bir sinyaldir, tek başına drop sebebi değildir. Zincir bozuk olabilir ama posta yine de meşru olabilir — ARC yokmuş gibi davranıp normal DMARC politikasına düşün, cv=fail diye postayı çöpe atmayın. Bir de canonicalization tutarsızlığına dikkat: imzalarken relaxed/relaxed, doğrularken farklı bir varsayım kullanan yığınlar sessizce cv=fail üretir.