Sahne şu: 587 açık, smtpd_sasl_auth_enable=yes, STARTTLS "destekleniyor". Kurulum çalışıyor gibi görünüyor, test maili gidiyor, herkes evine gidiyor. Gece 02:00'de birisi çalınmış bir parolayla — ya da hiç parola olmadan, çünkü relay kısıtı gevşek — porta bağlanıp saatte 40.000 mesaj bastırıyor. Sabah IP'niz Spamhaus SBL ve CBL'de, PTR kaydınız temiz olsa bile Gmail 421 ile kapıyı yüzünüze kapatıyor. Listelerden çıkmak günler, itibarın toparlanması haftalar sürüyor.
Bu felaketin kaynağı çoğu zaman karmaşık bir zafiyet değil. Bir portun "TLS'i destekliyor" olmasıyla "TLS'i zorunlu kılıyor" olması arasındaki farktır. Submission portunda şifreleme ve kimlik doğrulama opsiyonel değildir; ikisi de zorunludur ve kimliği doğrulanmış bir kullanıcı bile kendi adresinden başkası gibi gönderemez. Aşağıda saldırganın gerçekten hangi kapıdan girdiğini gösterip o kapıları Postfix master.cf üzerinde tek tek kapatıyoruz.
587, 465 ve 25 farklı işler için var
Üç portu aynı kefeye koymak, sorunun yarısıdır. Rolleri net ayıralım:
- Port 25 — MTA↔MTA relay (RFC 5321). Komşu posta sunucuları buraya bağlanıp _size ait_ domainlere teslimat yapar. Kimlik yoktur, olmaz da — dünyanın herhangi bir MTA'sı size mesaj getirebilmelidir. Bu yüzden 25'te asla
AUTHsunulmaz. 25'te SASL açık bırakmak, klasik open relay reçetesidir. - Port 587 — submission / MSA (RFC 6409). Sizin kullanıcılarınızın istemcilerinin (Thunderbird, telefon, uygulama) bağlandığı port. STARTTLS ile şifrelenir ve zorunlu kimlik doğrulama ister. Burada teslimat değil, gönderim yapılır.
- Port 465 — submissions / implicit TLS (RFC 8314). Bağlantının ilk baytından itibaren TLS içindedir; STARTTLS pazarlığı yoktur. "Obsolete" değildir — RFC 8314 tam tersine cleartext submission'ı deprecate etmiş, 465'i modern tercih olarak öne çıkarmıştır. Yeni kurulumda 465'i birincil, 587'yi uyumluluk için tutun.
MSA (submission) ile MTA (relay) ayrı sorumluluklardır. Birini diğerinin ayarlarıyla yönetmeye kalkarsanız ya 25'i fazla sıkıp inbound teslimatı kırarsınız ya da 587'yi fazla gevşetip spam topuna dönüşürsünüz.
Submission servisini Postfix'te kilitlemek
Sertleştirmeyi main.cf içindeki global ayarlarla yapmayın. Port 25 gevşek kalmalı (smtpd_tls_security_level=may, çünkü şifreleme yapamayan eski MTA'lar hâlâ var), submission ise katı olmalı. Ayrımı master.cf üzerinde servis bazlı -o override'larıyla kurarsınız:
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_tls_auth_only=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/auth
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o smtpd_sender_login_maps=hash:/etc/postfix/sender_login_maps
-o smtpd_sender_restrictions=reject_sender_login_mismatch,reject_unknown_sender_domain
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/auth
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o smtpd_sender_login_maps=hash:/etc/postfix/sender_login_maps
-o smtpd_sender_restrictions=reject_sender_login_mismatch,reject_unknown_sender_domainKritik satırlar: smtpd_relay_restrictions=permit_sasl_authenticated,reject bir beyaz liste yaklaşımıdır — kimliği doğrulanmışı geçir, geri kalan _her şeyi_ reddet. reject en sonda olduğu için varsayılan davranış "hayır"dır. SASL için Dovecot soketine bağlanıyoruz (smtpd_sasl_type=dovecot, smtpd_sasl_path=private/auth); evilmail.pro tarafında Dovecot parola şeması PLAIN, vhost'lar 5000:5000 sahipliğinde ve Postfix bu sokete private/auth üzerinden erişir. smtps bloğundaki smtpd_tls_wrappermode=yes, 465'in implicit TLS doğasını verir — STARTTLS pazarlığı yoktur.
AUTH'u yalnızca şifreli kanalda sunmak
smtpd_tls_auth_only=yes bu kurulumun kalbidir. Bu satır olmadan sunucu, istemci daha STARTTLS demeden EHLO yanıtında 250-AUTH LOGIN PLAIN reklamını yapar. İstemci de gördüğü şeye uyar ve parolayı cleartext gönderir. Pasif bir dinleyici — aynı ağdaki bir makine, ele geçirilmiş bir switch, kötü bir Wi-Fi — parolayı ham olarak yakalar. Daha kötüsü STARTTLS komut enjeksiyonu sınıfıdır (CVE-2011-0411 ve türevleri): istemcinin TLS handshake'inden _önce_ tampona yazdığı komutlar, şifreli oturum başladığında sunucu tarafından işlenmeye devam eder. Saldırgan böylece kurbanın kimliğine iliştirilmiş komutlar enjekte edebilir.
tls_auth_only=yes ile EHLO çıktısı iki farklı hâl alır: TLS öncesinde AUTH satırı _görünmez_, sadece STARTTLS sunulur; TLS kurulduktan sonra yeni EHLO'da AUTH belirir. 465'in implicit TLS'i bu tuzağı tümden eler — ilk bayttan itibaren şifreli olduğu için "öncesi" diye bir aşama yoktur.
Kimliği zarfa bağlamak: authenticated spoofing'i durdurmak
Çoğu kurulum buraya kadar gelir ve durur; oysa en sık atlanan katman tam da budur. permit_sasl_authenticated sadece "bu kişi geçerli bir kullanıcı mı?" sorusunu yanıtlar. [email protected] olarak giriş yapan biri, MAIL FROM satırına [email protected] yazıp kurum içi phishing atabilir — Postfix umursamaz, çünkü kimlik ile zarf birbirinden ayrıktır. Bu boşluk, ele geçirilen bir hesabın en zararlı silahıdır.
Çözüm smtpd_sender_login_maps ile login↔envelope-from eşlemesidir. Bir hash map hazırlayın:
# /etc/postfix/sender_login_maps
[email protected] [email protected]
[email protected] [email protected]
[email protected] [email protected]postmap /etc/postfix/sender_login_maps
postfix reloadmaster.cf'teki -o smtpd_sender_restrictions=reject_sender_login_mismatch,... bu haritayı devreye alır: giriş yapılan SASL kullanıcısı, MAIL FROM adresinin haritadaki sahibiyle eşleşmiyorsa mesaj 553 5.7.1 Sender address rejected: not owned by user ile reddedilir. Çok adresli veritabanı kurulumlarında hash: yerine mysql: map kullanıp doğrudan virtual_users tablonuza bağlayabilirsiniz. Bir kullanıcının birden fazla adresten göndermesi gerekiyorsa, aynı login için map'e birden çok satır (veya sorgu sonucu) eklersiniz.
TLS'i gerçekten sıkılaştırmak
"Zorunlu TLS" sadece encrypt demek değildir; hangi protokol ve cipher'la şifrelediğiniz de önemlidir. TLS 1.0/1.1 ve SSLv3 hâlâ pazarlık edilebiliyorsa, downgrade saldırısı için kapı aralık kalır. main.cf'te tabanı çekin:
smtpd_tls_security_level = may
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_ciphers = high
tls_high_cipherlist = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.evilmail.pro/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.evilmail.pro/privkey.pemSertifikada fullchain.pem kullanın, yalnız cert.pem değil — ara sertifika zinciri eksikse bazı istemciler doğrulamayı reddeder. Let's Encrypt yenilemesinden sonra Postfix yeni sertifikayı kendiliğinden okumaz; certbot deploy hook'una postfix reload ekleyin. Inbound tarafı bu yazının kapsamı dışı, ama not düşeyim: giden TLS'i sertleştirmenin yanına gelen tarafta MTA-STS politikası ve DANE/TLSA kayıtları ekleyerek "başkası bize gönderirken de şifrele" garantisini tamamlarsınız — bu, HSTS'in SMTP dünyasındaki karşılığıdır.
Doğrulama: kapı gerçekten kapalı mı?
Config yazmak yarı iş. Kapının kapalı olduğunu kanıtlayın:
# 587: STARTTLS öncesi AUTH sunulmamalı, TLS kurulunca sertifika görünmeli
openssl s_client -starttls smtp -connect mail.evilmail.pro:587 -crlf
# 465: implicit TLS — bağlanır bağlanmaz sertifika döner
openssl s_client -connect mail.evilmail.pro:465
# Başarılı: auth'lu gönderim kuyruğa girer
swaks --server mail.evilmail.pro:587 -tls \
--auth LOGIN --auth-user [email protected] --auth-password '***' \
--from [email protected] --to [email protected]
# Reddedilmeli: auth yok → relay kapalı
swaks --server mail.evilmail.pro:587 -tls --to [email protected]
# → 554 5.7.1 <[email protected]>: Relay access denied
# Spoofing reddedilmeli: info olarak giriş, ceo olarak gönderim
swaks --server mail.evilmail.pro:587 -tls \
--auth LOGIN --auth-user [email protected] --auth-password '***' \
--from [email protected] --to [email protected]
# → 553 5.7.1 Sender address rejected: not owned by user
# Zayıf cipher taraması — TLSv1.0/1.1 satırı görünmemeli
nmap --script ssl-enum-ciphers -p 465,587 mail.evilmail.proopenssl çıktısında, STARTTLS çağrılmadan önceki EHLO yanıtında hiçbir 250-AUTH satırı bulunmamalı — varsa smtpd_tls_auth_only=yes devreye girmemiştir. Log tarafında son kontrol:
grep sasl_username /var/log/mail.log # başarılı, kimliği doğrulanmış gönderimler
grep "Relay access denied" /var/log/mail.log # auth'suz relay denemeleri
grep "SASL LOGIN authentication failed" /var/log/mail.log # brute-forceBrute-force ve suistimali sınırlamak
Zorunlu auth kapıyı kapatır ama parola denemelerini de davet eder — botlar artık relay yerine sözlük saldırısına döner. fail2ban ile bunu kesin:
# /etc/fail2ban/jail.local
[postfix-sasl]
enabled = true
port = smtp,submission,submissions
filter = postfix-sasl
logpath = /var/log/mail.log
maxretry = 5
bantime = 3600
findtime = 600Postfix'in kendi anvil sayacıyla da bağlantı ve auth hızını sınırlayın (main.cf):
smtpd_client_connection_rate_limit = 30
smtpd_client_auth_rate_limit = 10Kullanıcı başına _günlük gönderim kotası_ (ele geçirilen bir hesabın verebileceği hasarı 500 mesajla sınırlamak gibi) Postfix'in kendisinde yoktur; bunun için postfwd ya da bir policy servisi devreye alırsınız. Ele geçirilen hesap senaryosunda bu kota, felaketle sıradan bir olay arasındaki farktır.
Devreye alma kontrol listesi
- Port 25'te
smtpd_sasl_auth_enablekapalı — relay kimliksiz, AUTH sunulmuyor. - 587'de
smtpd_tls_auth_only=yesvesmtpd_tls_security_level=encryptaktif. - 465
smtpd_tls_wrappermode=yesile implicit TLS olarak çalışıyor. - Her iki submission servisinde
permit_sasl_authenticated,rejectbeyaz listesi var. smtpd_sender_login_maps+reject_sender_login_mismatchile authenticated spoofing kapalı.smtpd_tls_mandatory_protocolsvesmtpd_tls_protocolsile TLS 1.2 altı devre dışı.- fail2ban
postfix-sasl
Bu on maddeyi geçmiş bir submission portu, çalınmış tek bir parolayla bile spam topuna dönüşmez; en kötü ihtimalle o hesabı kilitler, IP itibarınızı değil. evilmail.pro altyapısını bu prensiple işletiyoruz: submission portunda TLS ve SASL opsiyonel değil, mimarinin kendisi.


