Mail sunucusu yönetiminde en sık karşılaşılan ihtiyaçlardan biri, gönderilen veya alınan e-postaların header bilgilerini değiştirmek ya da mesaj içeriğini belirli kurallara göre manipüle etmektir. Exim, bu konuda son derece güçlü ve esnek bir yapı sunar. Hem küçük ölçekli hosting ortamlarında hem de kurumsal mail altyapılarında header rewriting ve mesaj manipülasyonu ihtiyacı kaçınılmaz olarak karşınıza çıkar. Bu yazıda Exim’in bu yeteneklerini gerçek dünya senaryolarıyla detaylı biçimde ele alacağız.
Header Rewriting Nedir ve Neden Gerekli?
E-posta header’ları, bir mesajın kim tarafından, nereden, ne zaman gönderildiğini ve hangi sunuculardan geçtiğini tanımlayan metadata alanlarıdır. Bazı durumlarda bu header’ları değiştirmek zorunlu hale gelir.
Yaygın senaryolar şunlardır:
- Şirket içi kullanıcıların
[email protected]gibi internal adresler yerine[email protected]ile dışarıya mail atması - Birden fazla domain’i tek Exim instance üzerinden yönetirken doğru
Fromadresinin sağlanması - Eski sistemlerden gelen kötü formatlanmış header’ların düzeltilmesi
- Gizlilik nedeniyle iç altyapı bilgilerinin dışarıya sızmasının engellenmesi
- Spam filtrelerinde sorun çıkaran eksik ya da hatalı header’ların tamamlanması
Exim’de Header Rewriting Mekanizması
Exim’de header manipulation iki farklı katmanda yapılabilir: router/transport seviyesinde ve global rewrite kuralları aracılığıyla. Her iki yöntemin de kullanım alanları farklıdır.
Global Rewrite Kuralları
/etc/exim4/exim4.conf dosyasında (ya da bölünmüş yapıda /etc/exim4/conf.d/rewrite/) begin rewrite bölümü altında global kurallar tanımlanır. Bu kurallar tüm mesajlara uygulanır.
Temel söz dizimi şöyledir:
begin rewrite
# Kaynak_Pattern Hedef_Adres Bayraklar
*@internal.local ${lookup{${local_part}}lsearch{/etc/exim4/rewrite_map}{$value}{$local_part}@sirket.com} frFT
Bayrakların anlamları:
- f: From header’ını yeniden yaz
- r: Reply-To header’ını yeniden yaz
- F: Envelope From adresini (MAIL FROM) yeniden yaz
- T: Envelope To adresini (RCPT TO) yeniden yaz
- s: Sender header’ını yeniden yaz
- c: Cc header’larını yeniden yaz
- b: Bcc header’larını yeniden yaz
- h: Mesajdaki tüm header adreslerini yeniden yaz
Basit Domain Rewrite Örneği
Bir şirkette sunucunuzun hostname’i mail.internal.local olsun ve kullanıcılar bu domain’den mail atıyor olsun. Dışarıya giden maillerde bu adresi @sirketadi.com olarak göstermek istiyorsunuz:
begin rewrite
# Internal local domain adreslerini public domain'e cevir
*@internal.local ${local_part}@sirketadi.com frFTs
*@mail.internal.local ${local_part}@sirketadi.com frFTs
Bu kural hem header’lardaki adres bilgisini hem de SMTP envelope adresini dönüştürür. Restart gerekmez, exim -bV ile syntax kontrolü yapabilirsiniz:
exim -bV
Router Seviyesinde Header Manipülasyonu
Router’lar, Exim’in mesajları nereye ileteceğine karar verdiği bileşenlerdir. Bu noktada headers_add, headers_remove ve headers_rewrite direktifleri devreye girer.
headers_add Kullanımı
Bir mesaja yeni header eklemek için headers_add direktifini transport veya router bloğunda kullanabilirsiniz:
# /etc/exim4/conf.d/transport/30_exim4-config_remote_smtp
remote_smtp:
driver = smtp
hosts_try_auth = <; $host_address
headers_add = "X-Mailer-Info: Sent via Corporate Mail Gatewayn
X-Organization: Sirket Adi A.S."
tls_certificate = /etc/ssl/certs/mail.crt
tls_privatekey = /etc/ssl/private/mail.key
Bu yapılandırma ile her dışa giden maile organizasyon bilgisi içeren custom header’lar eklenir. Özellikle mail tracking veya compliance gereksinimleri için oldukça kullanışlıdır.
headers_remove Kullanımı
Bazı durumlarda iç altyapı bilgilerini açığa çıkaran header’ları silmek istersiniz. Örneğin X-Originating-IP veya iç sunucu adlarını içeren Received header’ları:
remote_smtp_cleanup:
driver = smtp
headers_remove = "X-Originating-IP:X-PHP-Originating-Script:X-Source:X-Source-Args:X-Source-Dir"
hosts_try_auth = <; $host_address
message_size_limit = 52428800
Dikkat: Received header’larını silmek spam filtreleri açısından şüphe uyandırabilir ve bazı durumlarda SPF/DKIM doğrulamalarını bozabilir. Bu yüzden sadece gerçekten gereksiz olan header’ları kaldırın.
ACL ile Dinamik Header Manipülasyonu
Exim’in ACL (Access Control List) mekanizması, mesajları alış veya gönderim aşamasında koşullu olarak işleme sokmanıza olanak tanır. Bu, en güçlü ve en esnek yöntemdir.
DATA ACL ile Header Ekleme
# /etc/exim4/conf.d/acl/40_exim4-config_check_data
acl_check_data:
# Spam skorunu header olarak ekle
warn
condition = ${if def:spam_score}
message = X-Spam-Score: $spam_score
message = X-Spam-Bar: $spam_bar
# Sirket icinden gelen maillere departman bilgisi ekle
warn
condition = ${if match_domain{$sender_address_domain}{+local_domains}}
set acl_m_dept = ${lookup{$sender_address_local_part}lsearch{/etc/exim4/dept_map}{$value}{Unknown}}
message = X-Department: $acl_m_dept
# Gecis zamanini ekle
warn
message = X-Processed-By: mailgw01.sirket.com at $tod_full
accept
Bu ACL bloğu, spam skoru mevcut olan maillere skor bilgisini header olarak ekler, iç kullanıcıların departman bilgisini ekler ve her mesaja işlem zamanı bilgisi yazar.
Koşullu Header Rewrite
Belirli domain’lerden gelen maillerin From adresini değiştirmek isteyebilirsiniz:
# Router tanimlamasi
rewrite_from_router:
driver = redirect
condition = ${if match_domain{$sender_address_domain}{eski-sirket.com:eski-domain.net}}
headers_rewrite = *@eski-sirket.com ${local_part}@yeni-sirket.com f
headers_rewrite = *@eski-domain.net ${local_part}@yeni-sirket.com f
allow_fail
allow_defer
data = :
Gerçek Dünya Senaryosu 1: Hosting Ortamında PHP Mail Düzenleme
Paylaşımlı hosting ortamlarında PHP’nin mail() fonksiyonu sıklıkla hatalı veya eksik From adresleriyle mail gönderir. Bu durumda mesajlar spam klasörüne düşer ya da bounce yönetimi zorlaşır. Aşağıdaki yapılandırma bu sorunu çözer:
# Transport tanimlamasi - PHP maillerini yakala ve duzelt
php_mail_transport:
driver = smtp
hosts = 127.0.0.1
port = 25
# PHP'nin gonderdigi mesajlardaki From adresini duzenle
headers_rewrite = *@localhost webmaster@${sender_host_name} frFTs
# PHP script bilgilerini gizle
headers_remove = "X-PHP-Originating-Script:X-Source:X-Source-Args"
# Organizasyon bilgisi ekle
headers_add = "X-Mailer: PHP Application Mail"
# Router - localhost'tan gelen mailleri yakala
catch_php_mail:
driver = accept
condition = ${if eq{$sender_host_address}{127.0.0.1}}
transport = php_mail_transport
no_more
Bu yapılandırmayla PHP uygulamalarından gelen mailllerde localhost domain’i otomatik olarak gerçek hostname ile değiştirilir ve debugging header’ları temizlenir.
Gerçek Dünya Senaryosu 2: Çoklu Domain Yönetimi
Bir hosting firmasında 50 farklı müşterinin mail’ini tek Exim instance üzerinden yönettiğinizi düşünün. Her müşterinin kendi domain’i var ama SMTP auth kullanarak aynı sunucu üzerinden mail atıyorlar.
# /etc/exim4/conf.d/rewrite/50_multidomian_rewrite
begin rewrite
# Kimlik dogrulamis kullanicilarin adreslerini duzelt
# Kullanici veritabanindan gercek From adresini al
* ${if authenticated{$authenticated_id}
{${lookup mysql{SELECT email FROM mail_users
WHERE username='${quote_mysql:$authenticated_id}'
LIMIT 1}
{$value}
{$sender_address}}}
{$sender_address}}
fFs
Bu gelişmiş rewrite kuralı, kimlik doğrulaması yapan kullanıcıların mail adreslerini MySQL veritabanından çekerek otomatik olarak doğru From adresiyle değiştirir.
Gerçek Dünya Senaryosu 3: Mailing List Header Yönetimi
Bir mailing list uygulaması çalıştırıyorsanız, Reply-To header’larını düzenlemek kritik önem taşır:
# Mailing list transport
mailing_list_transport:
driver = smtp
# List adresine reply-to ekle
headers_add = ${if match{$h_To:}{[email protected]}
{Reply-To: [email protected]
List-Unsubscribe: <mailto:[email protected]>n
List-Id: Sirket Listesi <liste.sirket.com>n
Precedence: list}
{}}
# Orijinal gondericinin adresini koru ama list bilgisi ekle
headers_rewrite = * ${sender_address} r
return_path = [email protected]
String Expansion ile Gelişmiş Rewrite
Exim’in string expansion motoru, header rewriting’i son derece dinamik hale getirir. Değişkenler, koşullar ve lookup fonksiyonları bir arada kullanılabilir:
# Zaman bazli header rewrite ornegi
begin rewrite
# Mesai saatleri disinda gelen maillere out-of-office bilgisi ekle
# (Bu ornekte header ekleme yapilir, gercekte auto-reply icin farkli yaklasim gerekir)
*@sirket.com ${if >{$tod_epoch}{$value}
{[email protected]}
{[email protected]}}
frFT
Daha pratik bir örnek olarak, gelen mail adreslerini normalize etmek (büyük/küçük harf tutarlılığı sağlamak) için:
begin rewrite
# Tum adresleri kucuk harfe donustur (case normalization)
# local part buyuk harf iceriyorsa kucultur
*@sirket.com ${lc:$local_part}@sirket.com T
*@*.sirket.com ${lc:$local_part}@${lc:$domain} T
Header Rewrite Kurallarını Test Etme
Yazdığınız kuralların doğru çalışıp çalışmadığını production’a almadan önce test etmek kritiktir. Exim bu konuda birkaç yararlı araç sunar:
# Syntax kontrolu
exim -bV
# Belirli bir adres icin rewrite sonucunu goster
exim -brw [email protected]
# Test mesaji gondererek header'lari incele
echo "Test mesaji" | exim -v -f [email protected] [email protected] 2>&1 | head -50
# Mail queue'daki bir mesajin header'larini goster
exim -Mvh MESAJ_ID
# Routing kararini goster (rewrite dahil)
exim -bt [email protected]
exim -brw komutu özellikle değerlidir, çünkü sadece rewrite sonucunu gösterir ve neyin nasıl değiştiğini açıkça ortaya koyar. Bir adres için birden fazla kural varsa hangisinin uygulandığını da görebilirsiniz.
Güvenlik Konuları ve Best Practice’ler
Header manipülasyonu güçlü bir araç olduğu kadar yanlış kullanıldığında ciddi güvenlik sorunlarına da yol açabilir.
Dikkat edilmesi gereken konular:
- DKIM imzalama ile çakışma: Header rewrite DKIM imzalamadan önce mi sonra mı yapıldığına dikkat edin. İmzaladıktan sonra From veya Subject gibi imzalanmış header’ları değiştirirseniz DKIM doğrulaması başarısız olur. Exim’de imzalama genellikle transport aşamasında yapıldığından rewrite önce gerçekleşir, ama bunu mutlaka test edin.
- SPF uyumu: Envelope From adresini değiştirirken SPF kayıtlarınızın yeni adresi kapsadığından emin olun.
- Loop detection: Rewrite kuralları yanlış yazılırsa mail loop’larına neden olabilir.
exim -btile routing’i mutlaka test edin. - Logging: Header değişikliklerini log’a almak için
log_selector = +all_parents +subjectayarını kullanabilirsiniz.
# Exim log ayarlari - header degisikliklerini takip icin
log_selector = +all_parents +subject +sender_on_delivery
+incoming_interface +received_sender
Performans Optimizasyonu
Büyük ölçekli ortamlarda çok sayıda rewrite kuralı performansı olumsuz etkileyebilir. Bunu minimize etmek için birkaç öneri:
- Rewrite kurallarını en spesifik’ten en genel’e doğru sıralayın, böylece early match gerçekleşir
lsearchyerine mümkünsedbmveyacdbformat lookup dosyaları kullanın, bunlar çok daha hızlıdır- MySQL lookup kullanıyorsanız bağlantı sayısını
mysql_serversile sınırlandırın - Gereksiz regex kullanmaktan kaçının, sabit string eşleştirmeleri çok daha hızlıdır
# Yavaş lsearch yerine cdb (Constant Database) kullan
# Once cdb olustur:
# makemap cdb /etc/exim4/rewrite_map.cdb < /etc/exim4/rewrite_map.txt
begin rewrite
*@internal.local ${lookup cdb{/etc/exim4/rewrite_map.cdb}{$local_part}{$local_part}@sirket.com} frFTs
Troubleshooting: Yaygın Sorunlar ve Çözümleri
Problem: Rewrite kuralı çalışıyor ama DKIM doğrulaması başarısız oluyor.
Çözüm: DKIM imzalamayı rewrite’tan sonra gerçekleştirdiğinizden emin olun. Exim’de bu genellikle transport seviyesinde dkim_domain ve dkim_selector direktifleriyle yönetilir. Rewrite kuralları DKIM imzalamadan önce uygulandığı için sorun genellikle yanlış header’ın imzalanmasından kaynaklanır.
Problem: headers_remove ile sildiğiniz header hala görünüyor.
Çözüm: Header adının büyük/küçük harf duyarlılığını kontrol edin. exim -Mvh MESAJ_ID ile ham header’ları görüntüleyip tam adı kopyalayın.
Problem: Rewrite sonrası bounce mailleri yanlış adrese gidiyor.
Çözüm: Envelope From (F bayrağı) ve From header (f bayrağı) arasındaki farkı gözden geçirin. Bounce’lar envelope adresine döner, görünen adrese değil.
# Detayli debug modu ile problemi tespit et
exim -d+rewrite -v -f [email protected] [email protected] < /dev/null 2>&1 | grep -i rewrite
Sonuç
Exim’in header rewriting ve mesaj manipülasyonu yetenekleri, mail altyapısı yöneticilerine son derece geniş bir kontrol imkanı sunar. Global rewrite kurallarından ACL tabanlı dinamik manipülasyona, basit header ekleme/silme işlemlerinden veritabanı destekli karmaşık dönüşümlere kadar neredeyse her senaryo için bir çözüm mevcuttur.
Bu yazıda ele aldığımız konuların özeti şöyle sıralanabilir:
begin rewritebölümü global adres dönüşümleri için temel araçtır ve bayrak sistemi esneklik sağlarheaders_addveheaders_removetransport ve router seviyesinde ince ayar yapmanıza olanak tanır- ACL’ler koşullu ve dinamik manipülasyon için en güçlü yöntemdir
- String expansion motoru rewrite kurallarını programatik hale getirir
- Test araçları özellikle
exim -brwproduction’a geçmeden önce mutlaka kullanılmalıdır
Mail sunucusu yönetiminde en kritik kural her zaman geçerlidir: değişikliklerinizi test ortamında doğrulayın, log’ları aktif tutun ve özellikle DKIM/SPF gibi authentication mekanizmalarıyla etkileşimi göz ardı etmeyin. İyi yapılandırılmış bir Exim kurulumu, karmaşık mail akış gereksinimlerini zarif biçimde karşılayabilir.