Bir sunucuya Postfix kurup tek alan adıyla posta almak birkaç dakikalık iştir. İkinci alan adını eklediğiniz an ise işler değişir: bazı mesajlar "Recipient address rejected: User unknown in local recipient table" hatasıyla geri döner, bazıları hiç ulaşmaz, bazıları da beklemediğiniz bir kutuya düşer. Sebep neredeyse her zaman aynıdır — Postfix'in alan adlarını üç ayrı sınıfa ayırdığını bilmeden ikinci alan adı yanlış sınıfa yazılmıştır. Postfix virtual domain yapılandırması, bu üç sınıfın ne işe yaradığını ve bir alan adının neden yalnızca birinde bulunabileceğini anlamakla başlar.
Bu rehberde tek bir Postfix örneği üzerinde birden fazla alan adına nasıl posta alacağını, mydestination, virtual_alias_domains ve virtual_mailbox_domains arasındaki farkı, hash tablolarıyla küçük ölçekli bir kurulumu, teslimatı Dovecot'a LMTP ile devretmeyi ve alan adları arası yönlendirmeyi anlatacağım. Sonunda da yıllardır aynı şekilde tekrar eden hataları ve bunları saniyeler içinde yakalayan doğrulama komutlarını bulacaksın.
Postfix'in Üç Alan Adı Sınıfı#
Postfix bir mesajı kabul etmeden önce şu soruyu sorar: "Bu alıcının alan adı benim mi, değilse aktarmalı mıyım?" Cevabı üç ayrı listede arar ve bir alan adı bu listelerden yalnızca birinde bulunmalıdır. Aynı alan adını iki listeye birden yazmak, Postfix'in kendi içinde döngüye girmesine ya da mesajı sessizce yanlış yere teslim etmesine yol açar.
| Parametre | Kimin için | Posta kutusu var mı | Teslimat aracı |
|---|---|---|---|
mydestination | Sistemin kendi alan adı | Evet, /etc/passwd kullanıcılarına | local(8) |
virtual_alias_domains | Yalnızca yönlendirme yapan alan adları | Hayır | Başka bir adrese devredilir |
virtual_mailbox_domains | Gerçek sanal kutusu olan alan adları | Evet, sanal kutular | virtual(8) veya LMTP |
mydestination sistemin klasik Unix hesaplarına teslim yapar. Yani [email protected] adresinin çalışması için sunucuda ali adında bir Unix kullanıcısı olması gerekir. Bu, tek alan adlı basit kurulumlar dışında istemeyeceğin bir modeldir: her posta hesabı için sistem kullanıcısı açmak hem güvenlik hem yönetim açısından gereksiz yüktür.
virtual_alias_domains posta kutusu barındırmaz; sadece adresleri başka adreslere çevirir. virtual_mailbox_domains ise gerçek kutuları olan alan adlarıdır ve çoklu alan adı kurulumlarında asıl kullanacağın sınıf budur. Kritik bir ayrıntı: virtual_alias_maps tüm alan adları için çalışır, sadece alias alan adları için değil. Yani bir sanal kutu alan adında da takma ad tanımlayabilirsin; alias çözümü kutu aramasından önce yapılır.
Temel main.cf Yapılandırması#
Küçük ve orta ölçekli bir kurulumda alan adı ve kutu listelerini düz dosyalarda tutmak fazlasıyla yeterlidir. Önce main.cf içinde sınırları netleştir:
# /etc/postfix/main.cf
myhostname = mail.firmaniz.com
mydomain = firmaniz.com
# Sadece sunucunun kendi kimliği burada kalsın.
# Sanal alan adlarını buraya ASLA yazma.
mydestination = $myhostname, localhost.$mydomain, localhost
# Sanal kutusu olan alan adları
virtual_mailbox_domains = /etc/postfix/vmail_domains
# Adres -> kutu yolu eşlemesi
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
# Takma adlar (tüm alan adları için geçerli)
virtual_alias_maps = hash:/etc/postfix/virtual
# Teslimatı Dovecot LMTP'ye devret
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains için düz bir liste dosyası kullanabilirsin; her satırda bir alan adı:
# /etc/postfix/vmail_domains
firmaniz.com
ornek.com
ikinci-marka.com
Bu dosya bir arama tablosu (lookup table) değil, düz liste olduğu için postmap çalıştırmana gerek yok. Buna karşılık hash: önekiyle tanımlanan vmailbox ve virtual dosyaları birer veritabanıdır ve her düzenlemeden sonra derlenmeleri gerekir. Bu ayrımı karıştırmak, "dosyayı düzenledim ama hiçbir şey değişmedi" şikayetinin bir numaralı sebebidir.
Kutu ve Takma Ad Tablolarını Doldurmak#
vmailbox tablosu her adresin diskteki karşılığını söyler. Maildir kullanıyorsan yolun sonuna eğik çizgi koymayı unutma; sondaki / olmadan Postfix mbox formatı varsayar ve tek dosyaya yazar:
# /etc/postfix/vmailbox
# adres kutu yolu (sondaki / = Maildir)
[email protected] firmaniz.com/ali/
[email protected] firmaniz.com/destek/
[email protected] ornek.com/info/
[email protected] ikinci-marka.com/satis/
virtual tablosu ise takma adları tutar. Burada üç farklı desen sık kullanılır: bire bir yönlendirme, birden çok alıcıya dağıtım ve alan adının tamamını yakalayan catch-all girdisi:
# /etc/postfix/virtual
# Tek adrese yönlendirme
[email protected] [email protected]
# Birden çok alıcıya dağıtım (virgülle)
[email protected] [email protected], [email protected]
# Alan adları arası yönlendirme
[email protected] [email protected]
# Catch-all: eşleşmeyen her adres
@ornek.com [email protected]
Her iki dosyayı düzenledikten sonra derle ve Postfix'i yeniden yükle:
postmap /etc/postfix/vmailbox
postmap /etc/postfix/virtual
postfix reload
Catch-all satırının maliyetini bilerek kullan: eşleşmeyen tüm adresleri kabul ettiğin için sözlük saldırılarının ürettiği çöp de kutuna düşer. Ne zaman değdiğini, ne zaman zarar verdiğini catch-all e-posta adresi yazısında ayrıntısıyla ele aldım.
Teslimatı Dovecot'a LMTP ile Devretmek#
Postfix'in kendi virtual(8) teslimatçısı çalışır ama kota, sieve filtreleri ve indeksleme gibi işleri bilmez. Modern kurulumlarda teslimatı Dovecot'a LMTP üzerinden devretmek standart yaklaşımdır: Postfix mesajı kabul eder, Dovecot kutuyu yazar, kotayı uygular ve sieve kurallarını çalıştırır.
Dovecot tarafında LMTP servisini Postfix'in chroot dizini içinde bir Unix soketi olarak yayınla:
# /etc/dovecot/conf.d/10-master.conf
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}
Ardından protokol listesine lmtp eklendiğinden emin ol ve servisi yeniden başlat:
# Etkin protokolleri kontrol et
doveconf -n protocols
# Örnek çıktı: protocols = imap lmtp sieve
systemctl restart dovecot
systemctl reload postfix
# Soket gerçekten oluşmuş mu
ls -l /var/spool/postfix/private/dovecot-lmtp
Bu modelde Postfix artık kutuların diskte nerede olduğunu bilmek zorunda değildir; virtual_mailbox_maps yalnızca "bu adres geçerli mi" sorusuna cevap veren bir doğrulama tablosuna dönüşür. Değeri bile boş bırakmak yerine kutu yolunu yazmaya devam etmen zararsızdır, ama teslimatı yapan Dovecot'tur.
Doğrulama: Yapılandırmayı Test Etmek#
Yapılandırmayı canlıya almadan önce her katmanı ayrı ayrı sorgula. Postfix'in tablolarına doğrudan soru sorabilirsin ve bu, log okumaktan çok daha hızlıdır:
# Bu alan adı sanal kutu alan adı olarak tanınıyor mu?
postmap -q ornek.com /etc/postfix/vmail_domains
# Bu adres için kutu tanımlı mı?
postmap -q [email protected] hash:/etc/postfix/vmailbox
# Takma ad nereye çözülüyor?
postmap -q [email protected] hash:/etc/postfix/virtual
# Varsayılandan farklı tüm ayarları listele
postconf -n | grep -E 'virtual|mydestination'
Ardından gerçek bir SMTP oturumu aç ve RCPT TO aşamasında ne cevap geldiğine bak. Bu test, DNS ve istemci ayarlarını devreden çıkardığı için sorunu tam olarak Postfix katmanında yakalar:
# Yerel makinede 25. porta bağlan
telnet 127.0.0.1 25
# EHLO test.local
# MAIL FROM:<[email protected]>
# RCPT TO:<[email protected]>
# 250 2.1.5 Ok -> adres kabul edildi
# 550 5.1.1 ... -> adres tanınmadı, tabloları kontrol et
# QUIT
Uzaktan bağlantı ve TLS testleri için SMTP test aracımızı kullanarak port, TLS modu ve PTR uyumunu tek ekranda görebilirsin. Daha geniş bir arıza tespiti gerekiyorsa mesajın kuyruk kimliğini alıp logda baştan sona takip et; teşhisi hızlandıran tek yöntem budur.
Sık Yapılan Hatalar ve Tuzaklar#
Alan adını iki sınıfa birden yazmak. En sık ve en kafa karıştırıcı hata budur. firmaniz.com hem mydestination hem virtual_mailbox_domains içindeyse Postfix ya Mail for firmaniz.com loops back to myself hatası verir ya da mesajı local(8) ile teslim etmeye çalışıp var olmayan Unix kullanıcısında takılır. Kural nettir: bir alan adı üç listeden yalnızca birinde bulunur.
$mydomain değerinin sessizce miras alınması. mydestination varsayılan değeri bazı dağıtımlarda $myhostname, $mydomain, localhost biçiminde gelir. mydomain = firmaniz.com yazıp mydestination satırını hiç düzenlemezsen, ana alan adın farkında olmadan yerel teslimat sınıfına girer. postconf mydestination komutu gerçek etkin değeri gösterir; dosyaya baktığında gördüğün değil.
postmap çalıştırmayı unutmak. hash: tablolarında Postfix metin dosyasını değil, yanındaki .db dosyasını okur. Metin dosyasını düzenleyip postmap çalıştırmazsan hiçbir değişiklik etkili olmaz — ve loglarda buna dair hiçbir uyarı görmezsin.
Maildir yolunun sonundaki eğik çizgi. firmaniz.com/ali ile firmaniz.com/ali/ arasındaki tek karakter fark, mbox ile Maildir arasındaki farktır. Yanlış olan tarafı seçtiğinde mesajlar teslim edilir ama IMAP istemcisi hiçbir şey göremez.
Alias'ın kutudan önce çalıştığını unutmak. virtual_alias_maps içinde [email protected] için bir yönlendirme varsa, aynı adresin vmailbox tablosundaki kutusu hiç kullanılmaz. Mesaj kutuya düşmüyorsa önce alias tablosuna bak.
Yönlendirme yaparken SPF'i düşünmemek. Alan adları arası yönlendirme kurduğunda mesajı sen aktardığın için alıcı taraf SPF kontrolünde senin IP'ni görür. Bu, mail yönlendirmenin SPF'i neden bozduğu sorusunun tam olarak kaynağıdır ve büyük sağlayıcılara giden yönlendirmelerde teslim sorunlarına yol açar.
Kaç Alan Adına Kadar Düz Dosya Yeter#
Hash tabloları hızlıdır ve on binlerce satırda bile sorun çıkarmaz; asıl sınır teknik değil, operasyoneldir. Yeni bir hesap açmak için sunucuya SSH ile bağlanıp dosya düzenlemek ve postmap çalıştırmak gerekiyorsa, hesap sayısı arttıkça bu iş sürdürülemez hale gelir.
| Ölçek | Önerilen yöntem | Gerekçe |
|---|---|---|
| 1-3 alan adı, 20'ye kadar kutu | Hash dosyaları | Bağımlılık yok, yedeklemesi kolay |
| 5-50 alan adı | Hash + basit yönetim betiği | Hâlâ hafif, sürüm kontrolüne alınabilir |
| 50+ alan adı veya panel gerekiyorsa | MySQL/PostgreSQL tabloları | Web arayüzü, kota, delegasyon |
Kutu sayısı arttığında ya da müşterilerine kendi hesaplarını yönetme imkânı vermek istediğinde veritabanı tabanlı bir yapıya geçmek doğru adımdır; bunun kurulumunu MySQL tabanlı Postfix kullanıcı yönetimi yazısında baştan sona ele aldım. Geçiş sırasında main.cf içinde yalnızca tablo tanımlarının kaynağı değişir, mantık aynı kalır.
Sıkça Sorulan Sorular#
Postfix'te kaç alan adı barındırabilirim#
Pratikte bir sınır yoktur; yüzlerce alan adını tek bir Postfix örneğinde barındırabilirsin. Sınırı belirleyen şey alan adı sayısı değil, toplam mesaj hacmi, disk performansı ve eşzamanlı IMAP bağlantısı sayısıdır. Düz hash dosyalarıyla onlarca alan adını rahatça yönetirsin; yüzlerce alan adına çıktığında yönetim kolaylığı için veritabanı tabanlı bir yapıya geçmek daha mantıklı olur.
virtual_alias_domains ile virtual_mailbox_domains arasındaki fark nedir#
virtual_alias_domains içindeki alan adlarının hiçbir posta kutusu yoktur; gelen her adres mutlaka başka bir adrese çözülmek zorundadır, çözülemezse mesaj reddedilir. virtual_mailbox_domains ise gerçek kutuları olan alan adlarıdır ve mesaj doğrudan diske teslim edilir. Bir alan adının hem kutuları hem yönlendirmeleri olacaksa onu sanal kutu alan adı olarak tanımlar, yönlendirmeleri de virtual_alias_maps içinde ayrıca yazarsın.
Mail for domain loops back to myself hatası neden olur#
Bu hata neredeyse her zaman aynı alan adının hem mydestination hem de sanal alan adı listelerinden birinde bulunmasından kaynaklanır. Postfix alan adını kendi yerel alanı sanır, teslim edecek bir yerel kullanıcı bulamaz ve mesajı tekrar kendine yönlendirmeye çalışır. postconf mydestination çıktısını kontrol et ve sanal alan adlarını oradan çıkar; sorun genellikle tek satırlık bir düzeltmedir.
Yeni bir alan adı eklerken Postfix'i yeniden başlatmam gerekir mi#
Hayır, tam yeniden başlatma gerekmez. Tablo dosyalarını düzenleyip postmap ile derledikten sonra postfix reload komutu yeterlidir; bu komut çalışan süreçleri kesmeden yapılandırmayı tazeler. Yalnızca master.cf üzerinde servis tanımı değiştirdiysen ya da Postfix'i yeni kurduysan systemctl restart postfix gerekir.
Alias tablosunu düzenledim ama değişiklik uygulanmıyor, neden#
En olası sebep postmap komutunu çalıştırmamış olmandır; Postfix metin dosyasını değil derlenmiş .db dosyasını okur. İkinci olasılık, aynı adres için başka bir tabloda daha yüksek öncelikli bir eşleşme bulunmasıdır. postmap -q [email protected] hash:/etc/postfix/virtual komutuyla tablonun gerçekte ne döndürdüğünü doğrula, sonra /var/log/mail.log içinde ilgili kuyruk kimliğini takip et.
Sanal kutuları hangi kullanıcı yazacak#
LMTP ile Dovecot'a devrettiğinde kutuları Dovecot'un çalıştığı sistem kullanıcısı yazar; genellikle bunun için vmail adında ayrı bir kullanıcı ve grup oluşturulur. Postfix'in kendi virtual(8) teslimatçısını kullanıyorsan virtual_uid_maps ve virtual_gid_maps parametreleriyle sabit bir UID/GID belirtmen gerekir. Her iki durumda da kutuların bulunduğu dizinin sahipliğinin bu kullanıcıda olduğundan emin ol.
Kapanış#
Postfix'te çoklu alan adı yapılandırması, tek bir kuralı içselleştirdiğinde mekanik bir işe dönüşür: her alan adı üç sınıftan yalnızca birine aittir. Aklında kalması gereken pratik alışkanlıklar da bunun etrafında toplanıyor — mydestination içinde yalnızca sunucunun kendi kimliğini bırak, sanal alan adlarını virtual_mailbox_domains altında topla, her hash tablosu düzenlemesinden sonra postmap çalıştır ve canlıya almadan önce postmap -q ile tabloları sorgulayıp RCPT TO aşamasını gerçek bir SMTP oturumunda test et.
Kendi mail sunucunu kurmak yerine hazır ve yapılandırılmış bir altyapıyla başlamak istersen, SMTP sunucu paketlerimiz Postfix, Dovecot ve rDNS kaydı hazır teslim edilir. Kutularını doğrudan bir panelden yönetmeyi tercih edersen kurumsal e-posta çözümlerimiz bu işi tamamen üstlenir; tam kontrol isteyip yapılandırmanın bakımını bize bırakmak istediğinde ise sunucu yönetimi hizmetimiz Postfix ve Dovecot tarafını üstlenir.