Kendi sunucunda Postfix kurdun, apt install postfix bir dakikada bitti, ama şimdi /etc/postfix/main.cf dosyasını açtığında karşında yüzlerce satır var ve hangisinin ne yaptığından emin değilsin. Postfix main.cf yapılandırması, bir posta sunucusunun kim olduğunu, kimden mail kabul edeceğini, kimin adına mail gönderebileceğini ve bu trafiği nasıl şifreleyeceğini belirleyen tek merkezdir. Buradaki tek bir yanlış satır ya mail göndermeni engeller ya da — çok daha kötüsü — sunucunu açık röle (open relay) hâline getirip birkaç saat içinde tüm IP itibarını yakar.
Bu rehberde main.cf dosyasını ezberletmeye çalışmayacağım. Bunun yerine dosyayı mantıksal bloklara ayıracağız: kimlik parametreleri, kabul/röle kuralları, TLS, SASL kimlik doğrulama, kısıtlama zinciri ve kaynak limitleri. Her bloğun ne işe yaradığını, hangi değeri neden seçtiğini ve yanlış ayarlandığında hangi hatayı log'da göreceğini anlatacağım. Sonunda elinde açık röle olmayan, TLS'i zorlayan ve modern alıcıların kabul ettiği bir başlangıç yapılandırması olacak.
main.cf Dosyası Nerede Durur ve Nasıl Okunur#
Postfix'in iki ana yapılandırma dosyası vardır: /etc/postfix/main.cf genel davranışı, /etc/postfix/master.cf ise hangi servislerin hangi portta çalışacağını tanımlar. main.cf düz bir anahtar = değer listesidir; satır başında boşluk varsa o satır bir öncekinin devamı sayılır, # ile başlayan satırlar yorumdur. Değişkenleri $degisken biçimiyle birbirinin içinde kullanabilirsin — Postfix bunları çalışma anında çözer.
Dosyayı elle düzenlemek yerine postconf -e komutunu kullanmanı öneririm; söz dizimini bozmaz ve aynı anahtarı iki kez yazma hatasına düşmezsin. Aynı anahtar dosyada iki kez geçerse sonuncusu kazanır ve bu, saatlerce "ama ben ayarladım" dedirten klasik bir tuzaktır.
# Varsayılandan farklı olan tüm ayarları listele (en faydalı komut)
postconf -n
# Tek bir parametrenin etkin değerini oku
postconf myhostname
# Bir parametreyi güvenle ayarla (dosyaya yazar)
postconf -e "myhostname = mail.firmaniz.com"
# Söz dizimi ve izin kontrolü + servisi yeniden yükle
postfix check && systemctl reload postfix
postconf -n çıktısı, bir sorunu anlatırken paylaşman gereken tek şeydir: ham dosyayı değil, yalnızca senin değiştirdiğin satırları gösterir. Varsayılan bir değeri merak edersen postconf -d parametre_adi yeterlidir.
Kimlik Parametreleri: myhostname, mydomain, myorigin#
Postfix'in "ben kimim" sorusuna verdiği cevap üç parametrede toplanır. myhostname sunucunun tam nitelikli alan adıdır (FQDN) ve SMTP oturumunda EHLO komutuyla karşı tarafa gönderilen isimdir. mydomain genellikle myhostname'in ilk etiketi atılmış hâlidir. myorigin ise yerel olarak üretilen, alan adı içermeyen adreslerin sonuna eklenecek alan adını belirler; root kullanıcısının gönderdiği bir cron maili bu sayede [email protected] olur.
# /etc/postfix/main.cf — kimlik bloğu
myhostname = mail.firmaniz.com
mydomain = firmaniz.com
myorigin = $mydomain
# Karşı tarafa gösterilen banner'dan sürüm bilgisini kaldır
smtpd_banner = $myhostname ESMTP
biff = no
append_dot_mydomain = no
Buradaki en kritik nokta myhostname değerinin gerçek olmasıdır. Bu isim hem DNS'te bir A kaydına çözülmeli, hem de sunucunun IP adresinin ters DNS (PTR) kaydı birebir aynı ismi döndürmelidir. Gmail ve Outlook gibi büyük alıcılar bu eşleşmeyi kontrol eder; tutmuyorsa mailin doğrudan spam klasörüne düşer ya da hiç kabul edilmez. PTR kaydını genellikle IP'yi aldığın sağlayıcı üzerinden talep edersin, kendi DNS panelinden ayarlayamazsın. Gönderim yaptığın hostname ile PTR'nin uyuşup uyuşmadığını hızlıca kontrol etmek için SMTP test aracımızı kullanabilirsin.
smtpd_banner satırını da atlama. Varsayılan banner Postfix'in tam sürümünü açık eder; saldırganın işini kolaylaştırmanın hiçbir faydası yok.
Kimi Kabul Ediyoruz: mydestination, mynetworks ve relay_domains#
Bu blok, sunucunun açık röle olup olmayacağını belirleyen bloktur ve dikkatle okunmayı hak eder. mydestination, "bu sunucu şu alan adlarına gelen mailin son durağıdır" listesidir. mynetworks, kimlik doğrulaması olmadan röle yapmasına izin verilen IP aralıklarını içerir. relay_domains ise sunucunun başka bir sisteme iletmek üzere mail kabul edeceği alan adlarını tutar.
# Bu sunucunun kendisi için teslim alacağı alan adları
mydestination = $myhostname, localhost.$mydomain, localhost
# Sanal posta kutuları kullanıyorsan alan adı BURAYA DEĞİL,
# virtual_mailbox_domains'e yazılır — ikisinde birden olmamalı
virtual_mailbox_domains = firmaniz.com, ornek.com
virtual_mailbox_base = /var/mail/vhosts
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_alias_maps = hash:/etc/postfix/virtual
# Kimlik doğrulamasız röleye izin verilen ağlar — SADECE localhost
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
# Başka sunucuya iletim yapmıyorsan boş bırak
relay_domains =
Aşağıdaki tablo, açık röle sorununun neden çoğunlukla mynetworks satırından çıktığını özetliyor:
| Ayar | Güvenli değer | Riskli değer | Sonuç |
|---|---|---|---|
mynetworks | 127.0.0.0/8 | 0.0.0.0/0 | Tüm internet kimlik doğrulamasız röle yapar |
mynetworks_style | host | subnet / class | Veri merkezinin tüm bloğu röle yetkisi kazanır |
relay_domains | boş | $mydestination dışı geniş liste | Yabancı alan adları için backscatter üretir |
smtpd_relay_restrictions | tanımlı | tanımsız | Röle kararı tamamen recipient zincirine kalır |
Bir alan adının hem mydestination hem virtual_mailbox_domains içinde bulunması, Postfix'in başlangıçta uyarı vermesine ve teslimatın beklenmedik şekilde yerel kullanıcılara gitmesine yol açar. İkisinden birini seç. Sanal kullanıcılı (veritabanı ya da dosya tabanlı) bir kurulum yapıyorsan mydestination içinde yalnızca sunucunun kendi ismi kalmalı.
TLS Ayarları: Gelen ve Giden Bağlantıları Şifrelemek#
Postfix'te TLS ayarları ikiye ayrılır: smtpd_ önekli olanlar sana gelen bağlantıları (sen sunucusun), smtp_ önekli olanlar senin gittiğin bağlantıları (sen istemcisin) yönetir. Bu tek harflik fark, yanlış satırı düzenleyip "neden hiçbir şey değişmedi" demenin bir numaralı sebebidir.
# --- Gelen bağlantılar (sunucu tarafı) ---
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.firmaniz.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.firmaniz.com/privkey.pem
smtpd_tls_security_level = may
smtpd_tls_mandatory_protocols = >=TLSv1.2
smtpd_tls_protocols = >=TLSv1.2
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
# --- Giden bağlantılar (istemci tarafı) ---
smtp_tls_security_level = may
smtp_tls_mandatory_protocols = >=TLSv1.2
smtp_tls_CApath = /etc/ssl/certs
smtp_tls_loglevel = 1
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_security_level = may değeri fırsatçı TLS (opportunistic TLS) anlamına gelir: istemci destekliyorsa şifreli, desteklemiyorsa açık devam eder. Port 25 üzerinde bunu encrypt yapma — TLS konuşamayan yasal gönderenlerin mailini reddeder ve mail kaybedersin. encrypt değeri yalnızca kullanıcıların bağlandığı submission portu (587) ve smtps (465) için anlamlıdır ve orası da master.cf içinde ayarlanır.
Sertifikanın Let's Encrypt ile yenilenmesi hâlinde Postfix'in dosyayı yeniden okuması gerekir; certbot yenileme kancasına systemctl reload postfix eklemeyi unutma, yoksa 90 gün sonra süresi dolmuş sertifika sunmaya devam edersin. Alan adın için zorunlu TLS ilan etmek istiyorsan bir sonraki adım MTA-STS kaydı kurmaktır; TLS hatalarını rapor olarak toplamak istersen TLS-RPT kaydı devreye girer.
SASL Kimlik Doğrulama ve Submission Portu#
Kullanıcıların Outlook ya da telefonundan mail gönderebilmesi için kimlik doğrulaması gerekir. Postfix bu işi kendisi yapmaz; genellikle Dovecot'un SASL soketine devreder. Böylece IMAP şifresiyle SMTP şifresi tek yerde durur.
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $mydomain
# Kimliği doğrulanan kullanıcının zarf gönderici adresini kendi adresiyle sınırla
smtpd_sender_login_maps = hash:/etc/postfix/vmailbox
smtpd_sender_restrictions = reject_authenticated_sender_login_mismatch
Kimlik doğrulama trafiği yalnızca 587 ve 465 portlarında açılmalıdır; port 25 sunucular arası teslimat içindir ve orada AUTH reklamı yapmak bot taramalarını davet eder. Bu ayrım master.cf içinde yapılır:
# /etc/postfix/master.cf
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
Dovecot tarafında da karşılık gelen SASL soketinin açık olması gerekir; bunun ayrıntısını Dovecot yapılandırma rehberi yazısında adım adım anlattım. smtpd_sender_login_maps satırını ihmal etme: bu olmadan, doğrulanmış herhangi bir kullanıcı [email protected] adına mail gönderebilir. İç kaynaklı sahteciliği kapatan tek ayar budur.
Kısıtlama Zinciri: smtpd_recipient_restrictions#
Postfix, gelen her maili bir dizi kural listesinden geçirir. Listeler yukarıdan aşağı işlenir, ilk kesin karar (permit ya da reject) kazanır ve kalan kurallara bakılmaz. Sıralama bu yüzden içerikten daha önemlidir.
# Röle kararını burada ver — Postfix 2.10+ için doğru yer burasıdır
smtpd_relay_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_non_fqdn_recipient,
reject_unknown_recipient_domain,
reject_unlisted_recipient,
reject_rbl_client zen.spamhaus.org,
permit
smtpd_helo_required = yes
smtpd_helo_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_invalid_helo_hostname,
reject_non_fqdn_helo_hostname
reject_unlisted_recipient sayesinde var olmayan bir kutuya gelen mail SMTP oturumu sırasında reddedilir; kabul edip sonra geri dönmek (backscatter) yerine anında "550 User unknown" demek hem itibarını korur hem de kuyruğunu şişirmez. reject_rbl_client satırı ise kara listedeki IP'leri en ucuz noktada eler — içerik taraması yapan Rspamd ya da SpamAssassin katmanına iş düşmeden önce.
Yeni bir kısıtlama eklerken önce warn_if_reject önekiyle dene: warn_if_reject reject_rbl_client ... şeklinde yazarsan Postfix reddetmez, sadece log'a "would reject" satırı düşer. Bir hafta log okuyup yanlış pozitif olmadığından emin olduktan sonra öneki kaldır.
Boyut, Kuyruk ve Performans Parametreleri#
Son blok, sunucunun kaynak sınırlarını çizer. Varsayılanlar küçük bir sunucu için genellikle iyidir ama iki değeri neredeyse her kurulumda değiştirmen gerekir.
# Ek dosya sınırı — base64 şişmesi nedeniyle gerçek sınırın ~%75'i kadardır
message_size_limit = 52428800 # 50 MB
mailbox_size_limit = 0 # sınırsız (kota Dovecot tarafında)
# Teslim edilemeyen mail için uyarı ve vazgeçme süreleri
delay_warning_time = 4h
maximal_queue_lifetime = 3d
bounce_queue_lifetime = 2d
# Aynı hedefe eşzamanlı bağlantı sayısı — çok yükseği greylisting tetikler
default_destination_concurrency_limit = 10
smtp_destination_rate_delay = 1s
message_size_limit değerini seçerken şunu unutma: MIME kodlaması eklerin boyutunu yaklaşık üçte bir oranında büyütür, yani 50 MB'lık bir sınır pratikte 35 MB civarında bir dosyaya izin verir. Sınırı aşan mail 552 Message size exceeds fixed limit ile reddedilir.
Kuyruğun sağlığını izlemek günlük rutinin parçası olmalı:
# Kuyrukta bekleyen mail sayısı
mailq | tail -n 1
# Belirli bir hedefe takılan mailleri gör
postqueue -p | grep -B1 "ornek.com"
# Kuyruğu hemen dene (dikkat: yoğun kuyrukta yük yaratır)
postqueue -f
# Tek bir maili kuyruktan sil
postsuper -d ABCDEF123456
Gönderim hacmin arttıkça tek sunucudan gitmek yerine ayrılmış bir gönderim altyapısına geçmek isteyebilirsin; SMTP sunucu paketlerimiz Postfix, Dovecot ve Rspamd kurulu, PTR kaydı hazır teslim edilir. Tüm yığını kendin yönetmek istersen VDS üzerinde tam root erişimiyle bu dosyayı sıfırdan yazabilirsin.
Sık Yapılan Hatalar ve Tuzaklar#
Yıllar içinde aynı hataları defalarca gördüm; büyük çoğunluğu şu altı başlıkta toplanıyor.
- Aynı anahtarı iki kez yazmak. main.cf'de
mynetworksiki farklı satırda tanımlıysa ikincisi geçerlidir.postconf -n | sort | uniq -dile kontrol et, ya dapostconf -ekullanarak bu riski tamamen ortadan kaldır. mynetworksiçine tüm veri merkezi bloğunu yazmak.mynetworks_style = subnetvarsayılanı, sunucunun bulunduğu /24 bloğunu röle yetkisiyle donatır. Komşu sunucular senin adına spam gönderebilir.mynetworks_style = hostyap ve listeyi elle tanımla.- PTR ile
myhostnameuyuşmazlığı. Log'da450 4.7.25 Client host rejected: cannot find your hostnamegörüyorsan sorun karşı tarafta değil, senin ters DNS kaydındadır. - Sertifika yenilendikten sonra reload etmemek. Postfix sertifikayı bellekte tutar; dosya değişse de eskisini sunmaya devam eder.
reloadyerinerestartrefleksi.postfix reloadçalışan teslimatları bozmadan yapılandırmayı tazeler; ana port ayarlarını (master.cf) değiştirdiysen restart gerekir, diğer her şey için reload yeterlidir.- Log okumadan parametre değiştirmek.
journalctl -u postfix -fya datail -f /var/log/mail.logaçık olmadan yapılan her deneme kör atıştır. Reddedilen her mail, sebebini SMTP yanıt kodunda söyler.
En sık karşılaşacağın yanıt kodlarının kısa bir sözlüğü:
| Kod | Anlamı | İlk bakılacak yer |
|---|---|---|
| 450 4.7.1 | Geçici ret, genellikle greylisting | Birkaç dakika bekle, tekrar denenecek |
| 550 5.1.1 | Alıcı kutusu yok | virtual_mailbox_maps / alias tabloları |
| 554 5.7.1 | Röle reddedildi ya da politika engeli | smtpd_relay_restrictions, SPF/DMARC |
| 421 4.7.0 | Hız sınırı, çok fazla bağlantı | destination_concurrency_limit düşür |
| 552 5.3.4 | Mesaj boyutu aşıldı | message_size_limit |
Sıkça Sorulan Sorular#
main.cf değişikliği için Postfix'i yeniden başlatmam gerekir mi#
Çoğu durumda hayır. systemctl reload postfix komutu main.cf'i yeniden okur ve çalışan teslimatları kesmeden yeni değerleri uygular. Yeniden başlatma (restart) yalnızca master.cf üzerinde port ya da servis tanımı değiştirdiysen, ya da Postfix paketini güncellediysen gerekir. Her değişiklikten önce postfix check çalıştırıp söz dizimi hatası olmadığını doğrulaman iyi bir alışkanlıktır.
Sunucumun açık röle olup olmadığını nasıl kontrol ederim#
En hızlı yol postconf -n | grep -E "mynetworks|relay" çıktısına bakmaktır; mynetworks yalnızca localhost içermeli ve smtpd_relay_restrictions satırı reject_unauth_destination ile bitmelidir. Ardından dışarıdaki bir makineden kendi sunucuna telnet ile bağlanıp, sana ait olmayan iki alan adı arasında mail göndermeyi dene; sunucu "554 Relay access denied" demelidir. Kabul ediyorsa portu derhal kapat ve kısıtlamaları düzelt.
Postfix mail gönderiyor ama Gmail'e ulaşmıyor, nereden başlamalıyım#
Önce /var/log/mail.log içinde Gmail'in döndürdüğü tam yanıt satırını bul; Google neredeyse her zaman sebebi kod ve bağlantı adresiyle birlikte söyler. En yaygın üç sebep ters DNS kaydının eksik olması, SPF veya DKIM doğrulamasının başarısız olması ve IP'nin kara listede bulunmasıdır. DNS tarafındaki eksikler için Gmail'e mail gitmiyor yazısındaki kontrol listesini takip edebilirsin.
message_size_limit değerini kaça ayarlamalıyım#
Kullanıcılarının göndermesini istediğin gerçek ek boyutunun yaklaşık 1,4 katını yaz. MIME kodlaması ikili dosyaları şişirdiği için 50 MB'lık bir sınır pratikte 35 MB'lık bir eke izin verir. Sınırı çok yükseltmenin bedeli, tek bir maildeki geçici hatanın kuyruğunda uzun süre yer kaplaması ve disk kullanımının artmasıdır. Alıcı taraf da kendi sınırını uygular; sen 100 MB kabul etsen bile karşı sunucu 25 MB'da reddedebilir.
mydestination ile virtual_mailbox_domains arasındaki fark nedir#
mydestination, mailin yerel Unix kullanıcılarına teslim edileceği alan adlarını listeler; her kullanıcının sistemde gerçek bir hesabı olması gerekir. virtual_mailbox_domains ise sanal kullanıcıları tanımlar; kullanıcılar dosya ya da veritabanı tablosunda tutulur, işletim sistemi hesabı gerekmez. Bir alan adı ikisinde birden bulunamaz; modern kurulumlarda neredeyse her zaman sanal kutu yaklaşımı tercih edilir.
Postfix yerine başka bir MTA kullanmalı mıyım#
Postfix, güvenli varsayılanları, okunabilir yapılandırması ve geniş dokümantasyonu nedeniyle çoğu senaryoda doğru seçimdir. Exim daha esnek bir kural diline sahiptir ama öğrenme eğrisi diktir; OpenSMTPD çok daha sade bir yapılandırma sunar fakat ekosistemi dardır. Günde birkaç yüz binin altında mail gönderen bir kurum için Postfix'ten ayrılmayı gerektiren teknik bir sebep genellikle yoktur.
Kapanış#
main.cf dosyasını korkulacak bir şey olmaktan çıkaran şey, onu bir bütün olarak değil bloklar hâlinde okumaktır: önce kimlik, sonra kabul ve röle kuralları, sonra TLS, sonra kimlik doğrulama, en son kaynak sınırları. Aklında kalması gereken dört alışkanlık şunlar: değişiklikleri postconf -e ile yap ve postconf -n ile doğrula, mynetworks satırını asla genişletme, sertifika yenilemesinden sonra reload'ı unutma ve her yeni kısıtlamayı önce warn_if_reject ile bir hafta izle. Log dosyası açık değilken parametre değiştirmemek de en az bunlar kadar değerli.
Bu yığını sıfırdan kurmak yerine hazır ve doğru yapılandırılmış bir gönderim altyapısı istiyorsan SMTP sunucu paketlerimiz Postfix, Dovecot, Rspamd ve DKIM anahtarı kurulu, rDNS kaydı tanımlanmış hâlde teslim edilir. Her şeyi kendin yönetmeyi tercih ediyorsan tam root erişimli VDS sunucuları uygun bir başlangıçtır; kurulum ve bakımı bize bırakmak istersen sunucu yönetimi hizmetimiz Postfix bakımını da kapsar. Yalnızca posta kutusu ihtiyacın varsa kendi sunucunu yönetmeden kurumsal e-posta çözümümüz çok daha az bakım ister.