Postfix ile Transport Maps Yapılandırması

Mail sunucusu yönetiminde en sık karşılaşılan ihtiyaçlardan biri, farklı alıcılar veya domain’ler için e-postaları farklı yollardan iletmektir. Postfix’in transport maps özelliği tam olarak bu iş için var. Bir e-postanın nereye, nasıl ve hangi protokol üzerinden iletileceğini granüler seviyede kontrol edebilirsiniz. Bu yazıda transport maps’i sıfırdan yapılandıracak, gerçek dünya senaryolarına bakacak ve olası sorunlarla nasıl başa çıkacağınızı anlatacağım.

Transport Maps Nedir ve Neden Kullanılır?

Postfix, bir e-postayı teslim etmeden önce bir dizi karar mekanizmasından geçirir. Bu mekanizmalardan biri de transport tablosudur. Transport maps sayesinde Postfix’e şunu söyleyebilirsiniz: “Bu domain’den gelen mailler şu SMTP sunucusuna gitsin”, “Şu kullanıcının maili yerel olarak teslim edilsin” ya da “Bu domain’e gelen mailler bir relay üzerinden geçsin.”

Bunu neden yapmak istersiniz? Birkaç somut senaryo düşünelim:

  • Şirketinizin bir bölümü farklı bir mail sistemine taşındı, ama DNS henüz güncellenmedi. İlgili domain’in maillerini yeni sunucuya yönlendirmeniz gerekiyor.
  • Bazı domainlerin maillerini bir spam filtre servisi üzerinden geçirmek istiyorsunuz.
  • Test ortamınızdaki maillerin production’a karışmaması için belirli adresleri local delivery’e zorlamak istiyorsunuz.
  • ISP’nizin 25. portu blokladığı için belirli mailler için 587 portunu kullanmanız gerekiyor.

Transport maps, tüm bu senaryolarda tek bir yapılandırma dosyasıyla çözüm sunar.

Transport Maps’in Temel Yapısı

Transport tablosu, sol tarafta eşleştirme deseni ve sağ tarafta transport tanımından oluşur. Format şöyle:

# /etc/postfix/transport
# Format: pattern    transport:nexthop

example.com         smtp:[mail.example.com]:25
test.local          local:
criticalmail.org    smtp:[relay.provider.com]:587

Sol taraftaki pattern şunlar olabilir:

  • Tam domain adı: example.com – Sadece bu domain için geçerli
  • Alt domain wildcard: .example.com – example.com’un tüm subdomain’leri için
  • Tam e-posta adresi: [email protected] – Sadece bu adres için
  • Boş string ya da catch-all: Diğer tüm eşleşmeler için

Sağ taraftaki transport:nexthop ifadesinde ise:

  • smtp: Standart SMTP ile ilet
  • lmtp: Local Mail Transfer Protocol
  • local: Yerel teslim
  • virtual: Virtual mailbox teslimi
  • discard: Maili sessizce at
  • error: Hata döndür ve maili reddet
  • relay: Relay üzerinden gönder

Köşeli parantez kullanımı çok önemli bir detay: [mail.example.com] şeklinde köşeli parantez kullanırsanız Postfix MX kaydına bakmaz, doğrudan o host’a bağlanır. Köşeli parantez kullanmazsanız Postfix önce MX kaydını sorgular.

Temel Kurulum ve İlk Yapılandırma

Önce Postfix’in kurulu olduğundan emin olalım:

# Debian/Ubuntu
sudo apt update && sudo apt install postfix

# RHEL/CentOS/Rocky Linux
sudo dnf install postfix

# Postfix versiyonunu kontrol et
postconf mail_version

Transport dosyasını oluşturalım:

sudo nano /etc/postfix/transport

Basit bir yapılandırmayla başlayalım:

# /etc/postfix/transport

# Bu domain'in maillerini direkt SMTP ile ilet, MX'e bakma
example.com         smtp:[mail.example.com]:25

# Bu domain'i relay üzerinden gönder
partner.org         smtp:[smarthost.isp.com]:587

# Test domain'ini local teslime zorla
test.internal       local:

# Bu adres için hata döndür
[email protected]    error:Mailiniz kabul edilmedi

# Alt domainlerin hepsini bir relay'e yönlendir
.corporate.net      smtp:[internal-relay.corp.net]:25

Dosyayı kaydettikten sonra Postfix’in okuyabileceği binary formata çevirmeniz gerekiyor:

sudo postmap /etc/postfix/transport

Bu komut /etc/postfix/transport.db dosyasını oluşturur. Her transport dosyasını değiştirdiğinizde bu komutu çalıştırmanız şart.

Şimdi main.cf dosyasına transport_maps direktifini ekleyin:

sudo postconf -e 'transport_maps = hash:/etc/postfix/transport'

Ya da doğrudan /etc/postfix/main.cf dosyasına ekleyebilirsiniz:

transport_maps = hash:/etc/postfix/transport

Son olarak Postfix’i yeniden yükleyin:

sudo systemctl reload postfix

Birden Fazla Transport Dosyası Kullanmak

Büyük ortamlarda tek bir dosyayı yönetmek karmaşık hale gelebilir. Postfix birden fazla transport dosyasını destekler:

# main.cf
transport_maps = hash:/etc/postfix/transport,
                 hash:/etc/postfix/transport-relay,
                 hash:/etc/postfix/transport-local

Bu durumda Postfix listedeki dosyaları sırayla arar ve ilk eşleşmeyi kullanır. Öncelik sıralaması önemlidir.

# /etc/postfix/transport-relay
# ISP relay gerektiren domainler
heavyfiles.com      smtp:[relay.bigfiles.isp.com]:587
newsletter.net      smtp:[bulk-relay.provider.com]:25
# /etc/postfix/transport-local
# Yerel teslim zorunlu domainler
internal.company    local:
dev.company         local:

Her dosyayı oluşturduktan sonra postmap’i çalıştırmayı unutmayın:

sudo postmap /etc/postfix/transport-relay
sudo postmap /etc/postfix/transport-local
sudo systemctl reload postfix

Gerçek Dünya Senaryosu 1: Mail Migrasyonu Sırasında Yönlendirme

Diyelim ki şirketiniz eski mail sunucusundan (oldmail.company.com) yeni bir platforma (newmail.company.com) geçiyor. DNS değişikliği yapılmadan önce yeni sunucuya trafik yönlendirmeniz gerekiyor.

# /etc/postfix/transport

# Yeni platforma taşınan departmanların mailleri
it.company.com          smtp:[newmail.company.com]:25
hr.company.com          smtp:[newmail.company.com]:25
finance.company.com     smtp:[newmail.company.com]:25

# Henüz taşınmamış domainler eski sunucuya gitsin
legacy.company.com      smtp:[oldmail.company.com]:25

# Genel şirket maili yeni sunucuya
company.com             smtp:[newmail.company.com]:25

Bu senaryoda migration tamamlandıkça ilgili satırları tablodan kaldırabilir ve DNS’i güncellediğinizde transport kuralına gerek kalmaz.

Gerçek Dünya Senaryosu 2: TLS Zorunluluğu ile Güvenli İletim

Bazı ortamlarda belirli domainlere TLS şifrelemesi zorunlu tutularak mail gönderilmesi gerekir. Bu durumda transport maps ile birlikte smtp_tls_policy_maps veya özel bir transport tanımı kullanabilirsiniz.

master.cf dosyasına özel bir transport servisi ekleyin:

sudo nano /etc/postfix/master.cf
# /etc/postfix/master.cf
# TLS zorunlu SMTP transport
tlssmtp    unix  -       -       n       -       -       smtp
  -o smtp_tls_security_level=encrypt
  -o smtp_tls_CAfile=/etc/ssl/certs/ca-certificates.crt
  -o smtp_tls_note_starttls_offer=yes

Sonra transport dosyanızda bu servisi kullanın:

# /etc/postfix/transport
bank.com            tlssmtp:[mail.bank.com]:25
secure-partner.org  tlssmtp:[smtp.secure-partner.org]:587

Bu sayede belirtilen domainlere gönderilen mailler TLS olmadan iletilmez, bağlantı TLS’i desteklemiyorsa mail teslim edilmez ve kuyrukta bekler.

Gerçek Dünya Senaryosu 3: Null Delivery ve Test Ortamları

Test ortamlarında çok kritik bir ihtiyaç var: gerçek kullanıcılara test maili gitmesini engellemek. Transport maps ile bunu kolayca yapabilirsiniz:

# /etc/postfix/transport

# Tüm mailler discard edilsin (sessizce silinsin)
*                   discard:

# Sadece test adresleri local teslim alsın
test.internal       local:

Ya da daha spesifik bir yaklaşım:

# /etc/postfix/transport

# Harici domainlere gidecek mailler local log'a düşsün
gmail.com           discard:Test ortami - mail gonderilmedi
yahoo.com           discard:Test ortami - mail gonderilmedi
hotmail.com         discard:Test ortami - mail gonderilmedi

# Internal domainler normal gitsin
company.com         smtp:[mail.company.com]:25

discard transport’u, Postfix’e maili başarıyla teslim etmiş gibi davranmasını söyler ama mail hiçbir yere gitmez. Gönderici başarı raporu alır. error transport’u ise göndericiye hata döndürür.

Gerçek Dünya Senaryosu 4: Yük Dağılımı için Birden Fazla Relay

Yüksek hacimli mail gönderimlerinde tek bir relay tıkanabilir. Transport maps ile farklı domainleri farklı relay’lere yönlendirebilirsiniz:

# /etc/postfix/transport

# Büyük hacimli newsletter domainleri relay1'e
newsletter-heavy.com    smtp:[relay1.mailservice.com]:25
bulk-sender.net         smtp:[relay1.mailservice.com]:25

# Normal iş maili relay2'ye
business-normal.com     smtp:[relay2.mailservice.com]:587

# Kritik transactional mailler direkt gitsin
transactional.app       smtp:[dedicated-relay.mailservice.com]:587

Transport Maps ile LDAP Entegrasyonu

Büyük kurumsal ortamlarda transport kararları LDAP’tan alınabilir. Bu, transport kurallarını merkezi olarak yönetmenizi sağlar:

# main.cf
transport_maps = ldap:/etc/postfix/transport-ldap.cf, hash:/etc/postfix/transport
# /etc/postfix/transport-ldap.cf
server_host = ldap.company.com
server_port = 389
bind = yes
bind_dn = cn=postfix,ou=services,dc=company,dc=com
bind_pw = gizlisifre
search_base = ou=domains,dc=company,dc=com
query_filter = (mailDomain=%s)
result_attribute = mailTransport

LDAP entegrasyonu ile bir domain eklediğinizde ya da transport kuralını değiştirdiğinizde Postfix’i reload etmenize gerek kalmaz.

Sorun Giderme ve Debug

Transport maps ile ilgili sorunları tespit etmek için birkaç araç vardır.

Önce transport tablosunda bir adresin nasıl çözümlendiğini test edin:

# Belirli bir domain için transport lookup yap
postmap -q example.com hash:/etc/postfix/transport

# E-posta adresi için lookup
postmap -q [email protected] hash:/etc/postfix/transport

# Eğer sonuç dönmezse eşleşme yok demektir

Mail kuyruğunu inceleyin:

# Kuyruktaki tüm mailler
mailq

# Ya da postqueue ile
postqueue -p

# Belirli bir maili zorla gönder
postqueue -i QUEUE_ID

# Tüm kuyruğu temizle (dikkatli!)
postsuper -d ALL

Postfix loglarına bakın:

# Gerçek zamanlı log takibi
sudo tail -f /var/log/mail.log

# Belirli bir domain için filtrele
sudo grep "example.com" /var/log/mail.log | tail -50

# Transport ile ilgili loglar
sudo grep "transport" /var/log/mail.log | tail -20

Postfix’in yapılandırmasını test edin:

# Sözdizimi hatalarını kontrol et
sudo postfix check

# Aktif yapılandırmayı göster
postconf transport_maps

# Tüm non-default değerleri listele
postconf -n

Verbose modda transport lookup debug edebilirsiniz:

# Debug seviyesini geçici olarak artır
sudo postconf -e 'debug_peer_list = example.com'
sudo postconf -e 'debug_peer_level = 3'
sudo systemctl reload postfix

# Logları takip et
sudo tail -f /var/log/mail.log

# Testi bitirince debug'ı kapat
sudo postconf -e 'debug_peer_list ='
sudo postconf -e 'debug_peer_level = 2'
sudo systemctl reload postfix

Yaygın Hatalar ve Çözümleri

postmap çalıştırmayı unutmak: Transport dosyasını değiştirip postmap çalıştırmazsanız değişiklikler geçerli olmaz. Bu en sık yapılan hatadır. Her değişiklikten sonra şu sırayı takip edin:

sudo postmap /etc/postfix/transport
sudo systemctl reload postfix

# Değişikliğin geçerli olup olmadığını doğrula
postmap -q "hedef-domain.com" hash:/etc/postfix/transport

Köşeli parantez kullanımı: smtp:mail.example.com:25 ile smtp:[mail.example.com]:25 arasındaki fark kritiktir. İlkinde Postfix MX kaydına bakar, ikincisinde doğrudan bağlanır. Çoğu durumda direkt host belirtmek istiyorsanız köşeli parantez kullanmalısınız.

Boşluk yerine tab kullanımı: Transport dosyalarında pattern ile transport arasında tab veya boşluk kullanabilirsiniz ama tutarlı olun. Karma kullanım bazen beklenmedik sorunlara yol açabilir.

Dosya izinleri: Transport dosyası ve db dosyası Postfix tarafından okunabilir olmalıdır:

sudo chown root:postfix /etc/postfix/transport
sudo chown root:postfix /etc/postfix/transport.db
sudo chmod 640 /etc/postfix/transport
sudo chmod 640 /etc/postfix/transport.db

Transport Maps ile Güvenlik Düşünceleri

Transport maps güçlü bir araçtır ama yanlış yapılandırılırsa open relay sorunu yaratabilir. Şunlara dikkat edin:

  • relay_domains direktifini sadece relay yapmanız gereken domainleri kapsayacak şekilde ayarlayın
  • Transport tablosunda wildcard kullanırken dikkatli olun
  • smtpd_relay_restrictions ve smtpd_recipient_restrictions direktiflerini transport maps ile birlikte doğru yapılandırın

Güvenli bir temel yapılandırma örneği:

# /etc/postfix/main.cf
relay_domains = $mydestination, hash:/etc/postfix/relay_domains
transport_maps = hash:/etc/postfix/transport
smtpd_relay_restrictions = permit_mynetworks,
                            permit_sasl_authenticated,
                            reject_unauth_destination

Değişiklikleri Otomatize Etmek

Production ortamında transport tablosunu elle yönetmek hataya açıktır. Basit bir script ile süreci otomatize edebilirsiniz:

#!/bin/bash
# /usr/local/bin/update-postfix-transport.sh

TRANSPORT_FILE="/etc/postfix/transport"
BACKUP_DIR="/etc/postfix/backups"
DATE=$(date +%Y%m%d_%H%M%S)

# Backup al
mkdir -p $BACKUP_DIR
cp $TRANSPORT_FILE $BACKUP_DIR/transport_$DATE

# Yeni kuralı ekle
echo "$1    $2" >> $TRANSPORT_FILE

# postmap çalıştır
postmap $TRANSPORT_FILE

# Postfix'i reload et
systemctl reload postfix

echo "Transport kuralı eklendi: $1 -> $2"
echo "Postfix reload edildi."

# Doğrulama
postmap -q "$1" hash:$TRANSPORT_FILE

Script’i çalıştırılabilir hale getirin:

sudo chmod +x /usr/local/bin/update-postfix-transport.sh

# Kullanımı
sudo /usr/local/bin/update-postfix-transport.sh "yenidomain.com" "smtp:[relay.example.com]:25"

Sonuç

Postfix transport maps, mail routing üzerinde tam kontrol sağlayan vazgeçilmez bir araçtır. İster migration süreçlerinde geçici yönlendirme yapın, ister kalıcı relay yapılandırmaları oluşturun, ister test ortamlarında mail trafiğini izole edin; transport maps her durumda esnek bir çözüm sunar.

Kritik noktalara bir daha bakalım: Transport dosyasını her değiştirdiğinizde postmap çalıştırmayı unutmayın. Köşeli parantez kullanımının MX sorgusu davranışını etkilediğini aklınızda tutun. Birden fazla transport dosyası kullanırken öncelik sırasına dikkat edin. Sorun yaşadığınızda postmap -q ile lookup testleri yapın ve mail.log’u detaylıca inceleyin.

Transport maps’i doğru yapılandırdıktan sonra mail routing sorunlarının büyük çoğunluğunu tek bir dosyadan yönetebilirsiniz. Bu, özellikle karmaşık kurumsal mail altyapılarında operasyonel yükü ciddi ölçüde azaltır.

Yorum yapın