Mail sunucusu yönetiminde en can sıkıcı anlardan biri, postfix kuyruğunun dolup taşması ya da binlerce mesajın neden gönderilmediğini anlamaya çalışmaktır. Üretim ortamında bir mail sunucusu yönetiyorsanız, kuyruk yönetimini iyi bilmek sizi ciddi baş ağrılarından kurtarır. Bu yazıda postfix kuyruğunun nasıl çalıştığını, nasıl izleneceğini ve sorunların nasıl çözüleceğini gerçek senaryolarla ele alacağız.
Postfix Kuyruk Yapısı Nasıl Çalışır?
Postfix, mailleri farklı kuyruk dizinlerinde saklar ve her kuyruğun kendine özgü bir işlevi vardır. Bu yapıyı anlamadan kuyruk yönetimi yapmak körü körüne bir iş olur.
Postfix’in ana kuyruk dizini genellikle /var/spool/postfix altındadır. Bu dizin altında şu alt dizinler bulunur:
- incoming: Yeni gelen ve henüz işlenmemiş mesajlar buraya düşer.
smtpdvepickupdaemonları mesajları buraya yazar. - active: O an teslim edilmeye çalışılan mesajlar burada bulunur. Bu kuyruk sürekli hareket halindedir.
- deferred: Teslim edilemeyen ve daha sonra tekrar denenecek mesajlar buradadır. En çok dikkat edilmesi gereken kuyruk budur.
- hold: Manuel olarak veya bir filtre tarafından bekletilen mesajlar buradadır. Postfix bunlara otomatik olarak dokunmaz.
- corrupt: Bozuk ya da okunamayan mesajlar buraya taşınır.
- bounce: Geri dönen mesajların bildirimleri burada işlenir.
Bir mail sunucusunda asıl sorun genellikle deferred kuyruğunda yaşanır. Binlerce ertelenmiş mesaj hem disk alanı tüketir hem de sunucu performansını etkiler.
Kuyruk Durumunu İzleme
Kuyruğu izlemek için birkaç farklı araç kullanabilirsiniz. En temel olanı mailq komutudur:
mailq
Bu komut aslında sendmail -bp ile aynı işi yapar ve tüm kuyrukta bekleyen mesajları listeler. Çıktı şu şekilde görünür:
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
3F2A9C1234 2048 Mon Dec 4 10:23:45 [email protected]
[email protected]
A1B2C3D456 1024 Mon Dec 4 09:15:22 [email protected]
(connect to mail.domain.com[1.2.3.4]:25: Connection refused)
[email protected]
-- 2 Kbytes in 2 Requests.
Kuyrukta kaç mesaj olduğunu hızlıca görmek için:
mailq | tail -1
Ya da daha ayrıntılı istatistik için postqueue komutunu kullanabilirsiniz:
postqueue -p | grep "^[A-F0-9]" | wc -l
Bu komut aktif kuyruk ID’lerini sayar ve toplam bekleyen mesaj sayısını verir. Yüzlerce ya da binlerce mesaj görüyorsanız bir sorun var demektir.
Kuyruk Boyutunu Hızlıca Kontrol Etme
Üretim ortamında kuyruğu monitoring sistemine bağlamak için şu scripti kullanabilirsiniz:
#!/bin/bash
# postfix_queue_check.sh
QUEUE_SIZE=$(postqueue -p | grep -c "^[A-F0-9]")
DEFERRED=$(find /var/spool/postfix/deferred -type f | wc -l)
ACTIVE=$(find /var/spool/postfix/active -type f | wc -l)
HOLD=$(find /var/spool/postfix/hold -type f | wc -l)
echo "Toplam kuyruk: $QUEUE_SIZE"
echo "Ertelenen: $DEFERRED"
echo "Aktif: $ACTIVE"
echo "Bekletilen: $HOLD"
# Uyarı eşiği 500 mesaj
if [ "$QUEUE_SIZE" -gt 500 ]; then
echo "UYARI: Kuyruk boyutu kritik seviyede!"
exit 2
fi
Deferred Kuyruğunu Analiz Etme
Ertelenen mesajların neden ertelendiğini anlamak, sorunun kaynağını bulmak açısından kritiktir. postqueue -p çıktısındaki parantez içindeki mesajlar size hata nedenini gösterir.
Deferred kuyruğundaki hataları toplu görmek için şu komutu kullanabilirsiniz:
postqueue -p | grep "^(" | sort | uniq -c | sort -rn | head -20
Bu komut en sık karşılaşılan hata mesajlarını frekanslarına göre sıralar. Örnek çıktı:
145 (connect to mail.example.com[192.168.1.1]:25: Connection refused)
89 (Host or domain name not found. Name service error)
34 (delivery temporarily suspended: connect to mx.domain.com)
Bu çıktıya bakarak sorunun bağlantı problemi mi, DNS sorunu mu yoksa başka bir şey mi olduğunu anlayabilirsiniz.
Belirli Bir Mesajın İçeriğini İnceleme
Deferred kuyruğundaki belirli bir mesajın başlıklarını ve içeriğini görmek için:
postcat -q <QUEUE_ID>
Örneğin:
postcat -q A1B2C3D456
Bu komut mesajın tüm başlıklarını, gönderici/alıcı bilgilerini ve mesaj gövdesini gösterir. Spam ya da kötü amaçlı içerik araştırırken bu komut hayat kurtarır.
Kuyruğu Yönetme: Yeniden Deneme, Silme ve Beklemeye Alma
Deferred Kuyruğunu Yeniden Denemeye Zorlama
Postfix varsayılan olarak ertelenen mesajları belirli aralıklarla yeniden dener. Ancak bir sorun çözüldüğünde kuyruğu hemen yeniden denemeye zorlamak istersiniz:
postqueue -f
Bu komut tüm deferred mesajları yeniden active kuyruğuna alır ve teslim denemesi yapar. DNS sorunu çözdüyseniz ya da hedef sunucu tekrar ayağa kalktıysa bu komutu kullanın.
Tüm Kuyruğu Silme
Bazen kuyruğu tamamen temizlemek gerekir. Özellikle bir spam saldırısı sonrası ya da yanlış yapılandırma nedeniyle oluşan onbinlerce mesajı temizlemek için:
postsuper -d ALL
Dikkat: Bu komut tüm kuyruktaki mesajları geri dönüşsüz siler. Üretim ortamında bu komutu çalıştırmadan önce iki kez düşünün.
Sadece deferred kuyruğunu temizlemek için:
postsuper -d ALL deferred
Hold kuyruğunu temizlemek için:
postsuper -d ALL hold
Belirli Mesajları Silme
Tek bir mesajı silmek için:
postsuper -d <QUEUE_ID>
Belirli bir alıcıya giden mesajları silmek daha pratik bir ihtiyaçtır. Örneğin bir kullanıcının hesabı kapatıldı ve ona giden tüm kuyruktaki mesajları silmek istiyorsunuz:
#!/bin/bash
# Belirli alıcıya giden mesajları sil
TARGET_EMAIL="$1"
if [ -z "$TARGET_EMAIL" ]; then
echo "Kullanim: $0 <[email protected]>"
exit 1
fi
postqueue -p | grep -B1 "$TARGET_EMAIL" | grep "^[A-F0-9]" |
awk '{print $1}' | tr -d '*!' |
while read queue_id; do
echo "Siliniyor: $queue_id"
postsuper -d "$queue_id"
done
Belirli Gönderenden Gelen Mesajları Silme
Spam gönderen bir iç kullanıcıyı tespit ettiyseniz ve kuyruktaki tüm mesajlarını temizlemek istiyorsanız:
#!/bin/bash
# Belirli gönderenden gelen mesajları sil
SENDER_EMAIL="$1"
postqueue -p | awk "BEGIN{found=0}
/^[A-F0-9]/{id=$1; found=0}
/$SENDER_EMAIL/{found=1}
found && id{print id; id=""}" |
tr -d '*!' |
while read queue_id; do
postsuper -d "$queue_id"
done
Mesajları Hold Kuyruğuna Alma
Şüpheli bir mesajı silmek yerine incelemek için hold kuyruğuna alabilirsiniz:
postsuper -h <QUEUE_ID>
Tüm active ve deferred mesajları hold’a almak için:
postsuper -h ALL
Hold’daki bir mesajı serbest bırakmak için:
postsuper -H <QUEUE_ID>
Gerçek Dünya Senaryoları
Senaryo 1: Toplu Spam Saldırısı Sonrası Kuyruk Temizleme
Bir sabah ofise geldiniz ve postfix kuyruğunda 50.000 mesaj birikmiş. Log dosyaları incelendiğinde bir web uygulamasının form üzerinden spam gönderdiği anlaşılıyor.
# Önce durumu değerlendir
postqueue -p | tail -1
# Çıktı: -- 50000 Kbytes in 47892 Requests.
# Hangi sender'dan geldiğini bul
postqueue -p | grep "^[A-F0-9]" | head -100 |
while read line; do
id=$(echo $line | awk '{print $1}' | tr -d '*!')
postcat -q $id 2>/dev/null | grep "^sender:"
done | sort | uniq -c | sort -rn | head -10
# Spam kaynağını bulduktan sonra önce web uygulamasını durdur
# Sonra kuyruğu temizle
postsuper -d ALL deferred
postsuper -d ALL hold
Senaryo 2: Hedef Sunucu Geçici Olarak Kapalıydı
Bir müşteri sunucusu 3 saatliğine bakıma girdi ve bu sürede 200 mesaj deferred kuyruğuna düştü. Sunucu geri geldiğinde mesajların hemen gönderilmesini istiyorsunuz:
# Sadece belirli domain'e giden deferred mesajları yeniden dene
postqueue -p | grep "customer-domain.com" | grep "^[A-F0-9]" |
awk '{print $1}' | tr -d '*!' |
while read id; do
postsuper -H $id 2>/dev/null
postsuper -h $id 2>/dev/null
done
# Ya da daha basit yol: tüm deferred'ı yeniden dene
postqueue -f
Senaryo 3: Kuyruktaki Mesajları Farklı Bir Sunucuya Yönlendirme
Mail sunucusu değişikliği yapıyorsunuz ve eski sunucudaki kuyruktaki mesajları yeni sunucuya taşımak istiyorsunuz. Bu senaryo biraz daha karmaşıktır:
# Eski sunucuda postfix'i durdur
systemctl stop postfix
# Kuyruk dosyalarını yeni sunucuya kopyala
rsync -avz /var/spool/postfix/deferred/ newserver:/var/spool/postfix/deferred/
rsync -avz /var/spool/postfix/active/ newserver:/var/spool/postfix/active/
# Yeni sunucuda sahiplik düzelt
chown -R postfix:postfix /var/spool/postfix/deferred/
chown -R postfix:postfix /var/spool/postfix/active/
# Yeni sunucuyu başlat ve kuyruğu işle
systemctl start postfix
postqueue -f
Kuyruk Parametrelerini Optimize Etme
Postfix’in kuyruk davranışını main.cf dosyasındaki parametrelerle kontrol edebilirsiniz.
Önemli parametreler:
- maximal_queue_lifetime: Deferred kuyruğundaki bir mesajın ne kadar süre tutulacağı. Varsayılan 5 gündür.
maximal_queue_lifetime = 3dşeklinde düşürebilirsiniz. - bounce_queue_lifetime: Geri dönen mesajların ne kadar süre tutulacağı. Varsayılan 5 gündür.
- queue_run_delay: Deferred kuyruğunun ne sıklıkla kontrol edileceği. Varsayılan 300 saniyedir.
- minimal_backoff_time: İlk yeniden deneme gecikmesi. Varsayılan 300 saniyedir.
- maximal_backoff_time: Maksimum yeniden deneme gecikmesi. Varsayılan 4000 saniyedir.
- qmgr_message_active_limit: Aynı anda active kuyruğunda olabilecek maksimum mesaj sayısı. Varsayılan 20000’dir.
# main.cf'e eklenecek örnek optimizasyon ayarları
postconf -e "maximal_queue_lifetime = 3d"
postconf -e "bounce_queue_lifetime = 1d"
postconf -e "queue_run_delay = 300s"
postconf -e "minimal_backoff_time = 300s"
postconf -e "maximal_backoff_time = 4000s"
postconf -e "qmgr_message_active_limit = 20000"
# Değişiklikleri uygula
postfix reload
Kuyruk İzleme ve Otomasyon
Kuyruğu düzenli olarak izlemek için bir cron job oluşturabilirsiniz:
#!/bin/bash
# /usr/local/bin/postfix_monitor.sh
LOG_FILE="/var/log/postfix_queue.log"
ALERT_EMAIL="[email protected]"
THRESHOLD_WARN=200
THRESHOLD_CRIT=1000
QUEUE_TOTAL=$(postqueue -p 2>/dev/null | grep -c "^[A-F0-9]" || echo 0)
DEFERRED=$(find /var/spool/postfix/deferred -type f 2>/dev/null | wc -l)
ACTIVE=$(find /var/spool/postfix/active -type f 2>/dev/null | wc -l)
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
echo "$TIMESTAMP - Toplam: $QUEUE_TOTAL | Deferred: $DEFERRED | Active: $ACTIVE" >> $LOG_FILE
if [ "$QUEUE_TOTAL" -gt "$THRESHOLD_CRIT" ]; then
echo "KRITIK: Postfix kuyruğu $QUEUE_TOTAL mesaj içeriyor! Deferred: $DEFERRED" |
mail -s "[KRITIK] Postfix Kuyruk Alarmı - $(hostname)" $ALERT_EMAIL
elif [ "$QUEUE_TOTAL" -gt "$THRESHOLD_WARN" ]; then
echo "UYARI: Postfix kuyruğu $QUEUE_TOTAL mesaj içeriyor. Deferred: $DEFERRED" |
mail -s "[UYARI] Postfix Kuyruk Alarmı - $(hostname)" $ALERT_EMAIL
fi
Bu scripti crontab’a ekleyin:
# Her 15 dakikada bir kontrol et
*/15 * * * * /usr/local/bin/postfix_monitor.sh
Kuyruk Log Analizi
Postfix logları /var/log/mail.log ya da /var/log/maillog dosyasında tutulur. Kuyruk sorunlarını debug etmek için log analizinden daha iyi bir yöntem yoktur:
# Son 1 saatteki teslim hatalarını göster
grep "$(date -d '1 hour ago' '+%b %e %H')" /var/log/mail.log |
grep "status=deferred" |
awk '{print $NF}' | sort | uniq -c | sort -rn | head -20
# Belirli bir domain'e gönderim sorunlarını incele
grep "to=<.*@problematic-domain.com>" /var/log/mail.log |
grep "status=" | tail -50
# Başarılı teslim oranını hesapla
SENT=$(grep "status=sent" /var/log/mail.log | wc -l)
DEFERRED=$(grep "status=deferred" /var/log/mail.log | wc -l)
BOUNCED=$(grep "status=bounced" /var/log/mail.log | wc -l)
TOTAL=$((SENT + DEFERRED + BOUNCED))
echo "Gönderilen: $SENT | Ertelenen: $DEFERRED | Geri Dönen: $BOUNCED"
echo "Başarı oranı: $(( (SENT * 100) / TOTAL ))%"
Sık Karşılaşılan Kuyruk Sorunları ve Çözümleri
“Connection refused” hatası: Hedef mail sunucusunun portu kapalı ya da güvenlik duvarı engelliyor. Hedef sunucuya telnet ile bağlantı testi yapın.
“Host or domain name not found”: DNS sorunu. MX kaydını dig MX domain.com ile kontrol edin.
“Message size exceeds fixed limit”: Hedef sunucunun mesaj boyutu limiti aşılmış. message_size_limit parametresini kontrol edin.
“Too many connections”: Hedef sunucu bağlantı limitini aşmış. smtp_destination_concurrency_limit parametresini düşürün.
Kuyruk çok yavaş işleniyor: default_process_limit ve smtp_destination_concurrency_limit değerlerini sunucu kapasitesine göre artırın.
Sonuç
Postfix kuyruk yönetimi, mail sunucusu yöneticiliğinin temel becerilerinden biridir. mailq, postqueue, postsuper ve postcat komutlarını avucunuzun içi gibi bilmek, sorunları hızlıca tespit etmenizi ve çözmenizi sağlar. Kuyruğu düzenli izlemek, erken uyarı sistemleri kurmak ve log analizini alışkanlık haline getirmek sizi reaktif yönetimden proaktif yönetime taşır.
En önemli tavsiye: Deferred kuyruğunu görmezden gelmeyin. Binlerce ertelenmiş mesaj hem bir sorunun belirtisi hem de başka sorunların habercisidir. Küçük bir kuyruk sorunu zamanında müdahale edilmezse ciddi bir mail delivery krizine dönüşebilir. Monitoring scriptinizi kurun, eşiklerinizi belirleyin ve alarmlarınızı dinleyin.