Postfix'te Modern TLS: Doğru Portta Güçlü Cipher, DH ve Downgrade Koruması
"Postfix TLS hardening" rehberlerinin çoğu port 25 ile 587/465'i aynı kefeye koyup gelen postayı sessizce bozuyor. Portlara göre doğru zorunluluk, TLS 1.2/1.3, güçlü cipher, ölmüş dhparam efsanesi ve cipher'ı gerçekten anlamlı kılan tek şey: DANE + MTA-STS.
EvilMail Team25 Temmuz 202612 dk okuma
İnternetteki "Postfix TLS hardening" rehberlerinin büyük çoğunluğu tek bir satırı main.cf'e yazdırıp işi bitmiş sayıyor:
ini
smtpd_tls_security_level = encrypt
Bu satır, port 25'te gelen postanın bir kısmını sessizce çöpe atar. TLS'i STARTTLS ile pazarlayamayan ya da senin dayattığın protokol/cipher tabanını tutturamayan gönderen MTA mesajı teslim edemez; üstelik bir bounce bile görmeyebilirsin — postalar öylece kaybolur. Sorun cipher listende değil, TLS'i portlara göre ayırmamanda.
Doğrusu şu: gelen posta (25/tcp) için TLS her zaman fırsatçıdır (opportunistic); zorunlu TLS ve modern cipher yalnızca kimliği doğrulanmış submission portlarında (587/465) anlamlıdır. Daha keskin bir gerçek de var: fırsatçı TLS aktif bir MITM ile plaintext'e indirgenebildiği için, port 25'te "high cipher" tek başına tiyatrodur — gerçek bütünlük DANE ve MTA-STS'ten gelir. Aşağıda bu ayrımı kurarak sertifikadan cipher'a, dhparam efsanesinden downgrade korumasına kadar tam bir yapılandırma çıkaracağız.
Postfix'te TLS'in iki ayrı dünyası: fırsatçı (25) vs zorunlu (587/465)
Postfix, TLS davranışını smtpd_tls_security_level ile yönetir ve buradaki iki değer bambaşka dünyalar demektir:
`may` — TLS sunulur, karşı taraf isterse kullanır, istemezse plaintext'e düşülür. Port 25'te MTA-to-MTA trafiği için tek doğru ayar budur. RFC 3207 STARTTLS pazarlıklıdır ve dünyadaki milyonlarca MTA'nın hepsi senin tercih ettiğin cipher'ı konuşamaz.
`encrypt` — TLS zorunlu; kurulamıyorsa oturum reddedilir. Bunu port 25'e koyarsan, TLS yeteneği zayıf gönderenlerin postasını reddetmiş olursun.
Kritik detay: smtpd_tls_mandatory_protocols ve smtpd_tls_mandatory_ciphers gibi mandatory ayarları yalnızcasecurity_level = encrypt iken devreye girer. may bağlamında ise smtpd_tls_protocols ve smtpd_tls_ciphers (mandatory olmayan) geçerlidir. Bu ikiliyi karıştırmak, "ayarladım ama etki etmiyor" tuzağının ana kaynağıdır.
Mimari sonuç açık: main.cf'te global taban may kalır; submission (587) ve smtps (465) servisleri master.cf içinde -o ile override edilerek encrypt yapılır. Çünkü o portlardan bağlanan taraf yabancı bir MTA değil, senin kimliği doğrulanmış kullanıcındır — ondan modern TLS beklemek tamamen meşrudur.
Protokolleri TLS 1.2 ve 1.3 ile sınırlamak
Postfix 3.6 ile protokol seçimi için modern söz dizimi geldi. Eskiden SSLv3/TLSv1/1.1'i tek tek dışlardık:
ini
# Eski, hataya açık söz dizimi
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
>=TLSv1.2 hem TLS 1.2 hem 1.3'ü açar, altındakileri kapatır ve gelecekte 1.4 çıkarsa otomatik dahil eder. Port 25'te bile TLS 1.0/1.1'i kapatmak 2026 itibarıyla güvenlidir: ciddi hiçbir MTA artık 1.1 pazarlamıyor, dolayısıyla tabanı 1.2'ye çekmek teslimatı bozmaz. Giden tarafta aynı mantık smtp_tls_protocols ve smtp_tls_mandatory_protocols ile kurulur.
Cipher suite'leri sertleştirmek
Postfix'in high cipher sınıfı tls_high_cipherlist ile tanımlanır ve modern OpenSSL üzerinde zaten forward-secrecy'li AEAD şifrelemeleri öne alır. Global tabanı ve zorunlu bağlamı birlikte set edin:
ini
smtpd_tls_ciphers = high
smtpd_tls_mandatory_ciphers = high
tls_preempt_cipherlist = yes
smtpd_tls_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC4, 3DES, MD5, SEED, IDEA
smtpd_tls_eecdh_grade = auto
tls_preempt_cipherlist = yes sunucunun cipher sırasını istemciye dayatır; zayıf cipher tercihine yönlendiren downgrade saldırılarına karşı sıralamanın kontrolünü sende tutar. smtpd_tls_eecdh_grade = auto Postfix'in eğri/grup seçimini kendisinin yapmasını sağlar; ultra ayarına elle geçmek 2026'da gereksizdir ve uyumluluğu kısar.
TLS 1.3 tarafında bu ayarların çoğu geçersizdir: 1.3 ciphersuite'leri OpenSSL tarafında ayrı yönetilir ve zaten hepsi AEAD'dir — TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256, TLS_AES_128_GCM_SHA256. Yani elle ayıklayacağın zayıf bir 1.3 cipher'ı yok. Gerçek risk ve gerçek iş TLS 1.2 tarafındadır; exclude_ciphers listen orayı temizler.
DH parametreleri ve ECDHE: 2026'da gerçek durum
Yıllarca her rehber şu komutu yazdırıp statik bir dhparam.pem ürettirdi:
bash
openssl dhparam -out /etc/postfix/dh2048.pem 2048
2026'da bu büyük ölçüde ölü bir ritüel. Postfix 3.7 ve sonrası, sonlu-alan DHE için RFC 7919'un built-in ffdhe2048 grubunu kullanır; ayrı bir smtpd_tls_dh1024_param_file tanımlamak çoğu kurulumda gereksizdir. Dahası:
1024-bit dhparam dosyası aktif zararlıdır (Logjam sınıfı downgrade). Sistemde eski bir dh1024.pem referansı varsa silin, dosyayı üretmeyin.
TLS 1.3 sonlu-alan DH kullanmaz. Anahtar değişimi named group'larla yapılır: X25519, secp256r1. DH parametre dosyasının 1.3'te hiçbir etkisi yoktur.
DH parametresi yalnızca TLS 1.2 DHE cipher'ı seçildiğinde devreye girer — ve high + ECDHE önceliğiyle DHE neredeyse hiç seçilmez. Pratikte anahtar değişimi X25519 üzerinden döner.
Pratik karar net: ECDHE'yi öne al, DH dosyasını unut, `ffdhe2048`'i built-in bırak. İlla üretmek istersen 2048-bit üret (zararsız ama faydasız); 1024-bit'i asla tutma.
Tam yapılandırma: main.cf + master.cf
Global taban main.cf'e — burada her şey fırsatçı, security_level = may:
ini
# --- main.cf: TLS tabani (opportunistic) ---
smtpd_tls_security_level = may
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.evilmail.pro/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.evilmail.pro/privkey.pem
smtpd_tls_protocols = >=TLSv1.2
smtpd_tls_mandatory_protocols = >=TLSv1.2
smtpd_tls_ciphers = high
smtpd_tls_mandatory_ciphers = high
smtpd_tls_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC4, 3DES, MD5, SEED, IDEA
tls_preempt_cipherlist = yes
smtpd_tls_eecdh_grade = auto
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
# --- giden (client) taraf ---
smtp_tls_security_level = dane
smtp_dns_support_level = dnssec
smtp_tls_protocols = >=TLSv1.2
smtp_tls_mandatory_protocols = >=TLSv1.2
smtp_tls_ciphers = high
smtp_tls_mandatory_ciphers = high
smtp_tls_loglevel = 1
Zorunluluk master.cf'e — submission ve smtps servislerinde port bazında override:
ini
# --- master.cf: submission ve smtps ---
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_tls_auth_only=yes
-o smtpd_tls_mandatory_protocols=>=TLSv1.2
-o smtpd_tls_mandatory_ciphers=high
-o smtpd_sasl_auth_enable=yes
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_tls_security_level=encrypt
-o smtpd_tls_auth_only=yes
-o smtpd_sasl_auth_enable=yes
smtpd_tls_auth_only=yes kritik: kullanıcının SASL kimlik doğrulaması yalnızca TLS kurulduktan sonra kabul edilir, yani parola asla plaintext üzerinden gitmez. Uygulamak için:
Cipher'ı sertleştirmek yetmez: DANE ve MTA-STS ile downgrade'i öldürmek
Makalenin çekirdek noktası burada. Port 25'teki fırsatçı TLS, tanımı gereği aktif bir saldırganın STARTTLS'i sıyırıp (STARTTLS stripping) oturumu plaintext'e indirebileceği bir zemindir. Ne kadar "high cipher" dayatırsan dayat, saldırgan handshake'i hiç başlatmadan araya girerse cipher listenin bir hükmü kalmaz. Bütünlüğü sağlayan iki mekanizma var ve ikisi de DNS'te yaşar.
DANE (TLSA) — giden postada Postfix'e "bu MX'in sertifikası şu olmalı ve TLS zorunlu" der. DNSSEC şarttır, çünkü TLSA kaydının kendisinin kurcalanmadığından emin olmamız gerekir:
dns
_25._tcp.mail.evilmail.pro. IN TLSA 3 1 1 <cert-spki-sha256>
3 1 1 = DANE-EE / SPKI / SHA-256; sertifikanın public key özetini pinler. smtp_tls_security_level = dane + smtp_dns_support_level = dnssec ile Postfix bu kaydı bulunca TLS'i zorunlu kılar ve downgrade'i reddeder.
MTA-STS — alan sahibi olarak *gelen* postanı korur. DNSSEC'in olmadığı yerde politika HTTPS üzerinden servis edilir:
dns
_mta-sts.evilmail.pro. IN TXT "v=STSv1; id=20260704T000000"
_smtp._tls.evilmail.pro. IN TXT "v=TLSRPTv1; rua=mailto:[email protected]"
Politika dosyası https://mta-sts.evilmail.pro/.well-known/mta-sts.txt:
mode: enforce, gönderen tarafın (Gmail, Outlook vb.) TLS kuramadığında ya da sertifika eşleşmediğinde postayı teslim etmemesini sağlar; downgrade'i imkânsız kılar. TLS-RPT ise günlük agregat raporlar gönderir — başarısız TLS denemelerini ve olası downgrade girişimlerini gözle görürsün.
Doğrulama ve test
Yapılandırmayı canlıda test etmeden "bitti" demeyin. Postfix'in kendi aracı, DANE dahil zinciri baştan sona kontrol eder:
bash
posttls-finger mail.evilmail.pro
Protokol reddini elle doğrulayın — TLS 1.1 girişimi başarısız olmalı, TLS 1.3 465'te kurulmalı:
Dış doğrulama için internet.nl/mail, hardenize.com ve checktls.com gelen/giden zinciri, DANE ve MTA-STS'i bağımsızca puanlar. Son olarak logda başarı satırını okuyun — cipher ve protokolün gerçekte ne pazarlandığını burada görürsünüz:
text
Anonymous TLS connection established from ...:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
Hızlı kontrol listesi
Port ayrımı:main.cf'te smtpd_tls_security_level = may, encrypt yalnızca master.cf'te submission/smtps servislerinde.
Protokol tabanı:>=TLSv1.2 hem opportunistic (smtpd_tls_protocols) hem mandatory (smtpd_tls_mandatory_protocols) için, giden tarafta da (smtp_tls_protocols).
Cipher:high + smtpd_tls_exclude_ciphers ile RC4/3DES/DES/MD5/EXPORT/aNULL temizliği.