Dovecot Quota ile Kullanıcı Depolama Limiti Nasıl Belirlenir

Mail sunucusu yönetiminin en can sıkıcı ama bir o kadar da kritik konularından biri kullanıcı depolama limitleridir. “Disk doldu, mail gelmiyor” diye arayan kullanıcılar, sistemi kilitleyen dev posta kutuları… Bunları yaşamadan önce Dovecot’un quota mekanizmasını doğru kurmak, ileride saçlarını yolmamak demektir. Bu yazıda Dovecot Quota’yı sıfırdan yapılandıracak, gerçek dünya senaryolarını ele alacak ve izleme/yönetim araçlarını inceleyeceğiz.

Dovecot Quota Nedir ve Neden Gereklidir?

Dovecot, varsayılan kurulumda kullanıcıların ne kadar depolama alanı kullandığını sınırlamaz. Yani bir kullanıcı teorik olarak tüm disk alanını doldurabilir. Kurumsal ortamlarda 200 kullanıcılı bir mail sunucusunda bu durum felakete davetiye çıkarır.

Dovecot Quota sistemi birkaç farklı backend üzerinden çalışır:

  • maildir_shared: Maildir formatındaki kutular için paylaşımlı sayaç
  • dict: Ayrı bir veritabanında (SQLite, Redis, PostgreSQL vb.) quota bilgisi tutar
  • fs: Dosya sistemi tabanlı quota (Linux disk quota ile entegre)
  • imapc: Uzak IMAP sunucu üzerinden quota okur
  • count: Sadece mesaj sayısını sınırlar (boyut değil)

Pratik ortamlarda en çok kullanılan yöntem dict ve maildir_shared kombinasyonudur. Biz bu yazıda hem basit Maildir kurulumunu hem de dict backend ile daha esnek yapıyı ele alacağız.

Temel Kurulum: Maildir + Count Backend

Önce basit bir senaryo ile başlayalım. Dovecot’un ana konfigürasyon dosyasını açıp quota eklentisini etkinleştiriyoruz.

# /etc/dovecot/conf.d/10-mail.conf dosyasini duzenle
nano /etc/dovecot/conf.d/10-mail.conf

Mail location satırını aşağıdaki gibi ayarlayın:

mail_location = maildir:~/Maildir

Şimdi quota eklentisini IMAP ve LDA (Local Delivery Agent) için aktif hale getirelim:

# /etc/dovecot/conf.d/20-imap.conf
protocol imap {
  mail_plugins = $mail_plugins quota imap_quota
}

# /etc/dovecot/conf.d/15-lda.conf
protocol lda {
  mail_plugins = $mail_plugins quota
}

# Lmtp kullaniyorsaniz
protocol lmtp {
  mail_plugins = $mail_plugins quota
}

Quota Plugin Yapılandırması

Asıl quota ayarları 90-quota.conf dosyasında yapılır. Eğer bu dosya yoksa oluşturun:

nano /etc/dovecot/conf.d/90-quota.conf

Temel yapılandırma şu şekilde görünür:

plugin {
  # Quota backend olarak count kullaniyoruz
  quota = count:User quota

  # Kural: 1GB depolama, 10000 mesaj limiti
  quota_rule = *:storage=1G
  quota_rule2 = *:messages=10000

  # Trash klasoru quota'ya dahil edilmesin (opsiyonel)
  quota_rule3 = Trash:storage=+200M
  quota_rule4 = Spam:ignore

  # Uyari: %80 dolunca bildirim gonder
  quota_warning = storage=80%% quota-warning 80 %u
  quota_warning2 = storage=95%% quota-warning 95 %u
  quota_warning3 = -storage=80%% quota-warning-below 80 %u

  # Grace period: limit asildiktan sonra kac MB daha kabul edilsin
  quota_grace = 10%%
}

Buradaki %% kullanımına dikkat edin. Dovecot konfigürasyonunda % karakterini escape etmek için çift yazmanız gerekir.

Quota Uyarı Scriptleri

Kullanıcıya depolama uyarısı göndermek için bir script oluşturmanız gerekiyor. Bu script Dovecot tarafından tetiklenir:

#!/bin/bash
# /usr/local/bin/quota-warning.sh

PERCENT=$1
USER=$2

cat << EOF | /usr/lib/dovecot/dovecot-lda -d $USER -o "plugin/quota=maildir:User quota:noenforced"
From: Mail Sistemi <[email protected]>
To: $USER
Subject: Posta Kutusu Doluluk Uyarisi - %$PERCENT
Content-Type: text/plain; charset=UTF-8

Sayın kullanicimiz,

Posta kutunuz %$PERCENT oraninda dolmakta.

Mevcut limitiniz: 1 GB
Lutfen eski veya gereksiz mailleri siliniz.

Bu mesaj otomatik olarak olusturulmustur.
EOF

Script’e çalıştırma izni verin:

chmod +x /usr/local/bin/quota-warning.sh

Dovecot konfigürasyonunda bu scripti tanımladığınızdan emin olun. quota_warning satırındaki komut quota-warning servisine işaret etmelidir:

# /etc/dovecot/conf.d/90-quota.conf icine ekle
service quota-warning {
  executable = script /usr/local/bin/quota-warning.sh
  user = dovecot
  unix_listener quota-warning {
    user = vmail
    mode = 0600
  }
}

Dict Backend ile Esnek Quota Yönetimi

Basit sabit limitler çoğu zaman yetmez. Farklı kullanıcıların farklı limitlere sahip olması gerekir; örneğin müdürlerin 5GB, normal çalışanların 1GB kotası olabilir. Bunun için dict backend kullanımı daha uygun olacaktır.

Önce SQLite ile basit bir dict kurulumu yapalım:

# /etc/dovecot/dovecot-dict-auth.conf.ext
connect = /var/lib/dovecot/quota.db

map {
  pattern = priv/quota/storage
  table = quota
  username_field = username
  value_field = bytes
}

map {
  pattern = priv/quota/messages
  table = quota
  username_field = username
  value_field = messages
}

SQLite veritabanını oluşturun:

sqlite3 /var/lib/dovecot/quota.db << 'SQL'
CREATE TABLE quota (
  username TEXT PRIMARY KEY,
  bytes INTEGER DEFAULT 1073741824,
  messages INTEGER DEFAULT 10000
);

-- Ornek kullanicilari ekle
INSERT INTO quota VALUES ('[email protected]', 2147483648, 20000);
INSERT INTO quota VALUES ('[email protected]', 1073741824, 10000);
INSERT INTO quota VALUES ('[email protected]', 5368709120, 50000);
SQL

chown dovecot:dovecot /var/lib/dovecot/quota.db
chmod 640 /var/lib/dovecot/quota.db

Kullanıcı Başına Özel Quota: UserDB ile Entegrasyon

Gerçek dünyada quota limitlerini veritabanından çekmek çok daha esnek bir yaklaşımdır. Dovecot’un passwd-file veya SQL tabanlı userdb’si ile quota limit’ini kullanıcı özelinde tanımlayabilirsiniz.

SQL tabanlı kurulum için /etc/dovecot/dovecot-sql.conf.ext dosyasını düzenleyin:

# Mevcut kullanici sorgusunu quota bilgisiyle genisletin
user_query = SELECT home, uid, gid, 
  CONCAT('*:storage=', quota_mb, 'M') AS quota_rule 
  FROM users 
  WHERE username = '%u' AND active = 1

# Veritabaninda quota_mb kolonu olmasi gerekiyor
# ALTER TABLE users ADD COLUMN quota_mb INT DEFAULT 1024;

Bu yaklaşım ile her kullanıcının quota bilgisi MySQL/PostgreSQL’den dinamik olarak çekilir. Kullanıcının limitini değiştirmek istediğinizde sadece veritabanını güncellemeniz yeterli olur, Dovecot yeniden başlatmaya gerek yoktur.

Quota Durumunu Kontrol Etme

Kullanıcıların quota durumunu kontrol etmek için doveadm aracı kullanılır:

# Tek kullanicinin quota durumunu goster
doveadm quota get -u [email protected]

# Tum kullanicilarin quota durumunu listele
doveadm quota get -A

# Quota istatistiklerini ozetle
doveadm quota recalc -u [email protected]

# Belirli bir domain altindaki tum kullanicilari listele
for user in $(doveadm user '*@example.com'); do
  echo "=== $user ==="
  doveadm quota get -u $user
done

Tipik bir doveadm quota get çıktısı şöyle görünür:

Quota name    Type    Value  Limit  %
User quota    STORAGE 524288 1048576 50
User quota    MESSAGE 1523   10000   15

Değerler kilobayt cinsindendir. Yüzde sütunu doluluk oranını gösterir.

Quota Aşıldığında Ne Olur?

Dovecot quota limitine ulaşıldığında yeni mail teslimini reddeder. Gönderen tarafa şu hata kodu döner:

452 4.2.2 Mailbox full / Over quota

Bu davranışı test etmek için şu yöntemi kullanabilirsiniz:

# Test amacli dusuk quota ata
doveadm quota set -u [email protected] STORAGE=1

# Mail gondererek testi yap, sonra eski degerine dondur
doveadm quota set -u [email protected] STORAGE=1048576

Önemli: Quota aşımında mevcut maillere dokunulmaz, sadece yeni teslimat engellenir. Kullanıcı mevcut kutusunu okuyabilir ve silebilir.

Postfix ile Entegrasyon: Pre-delivery Quota Kontrolü

Dovecot quota yalnızca teslimat sırasında devreye girer. Ama Postfix tarafında da quota kontrolü yaparsanız, dolu kutuya mail kabul edilmez ve gereksiz bounce üretilmez. Bunun için Postfix’te quota_status servisini etkinleştirin:

# /etc/dovecot/conf.d/90-quota.conf
service quota-status {
  executable = quota-status -p postfix
  inet_listener {
    port = 12340
  }
  client_limit = 1
}
# /etc/postfix/main.cf
smtpd_recipient_restrictions =
    ...
    check_policy_service inet:127.0.0.1:12340
    ...

Bu yapılandırma sayesinde Postfix, mail kabul etmeden önce Dovecot’a “bu kullanıcının kotası dolu mu?” diye sorar. Kota doluysa mail hiç kabul edilmez, gönderene anında 452 döner.

Quota Recalculate: Bozulmuş Sayaçları Düzeltme

Zaman zaman quota sayaçları gerçek disk kullanımıyla uyumsuz hale gelebilir. Bu genellikle şu durumlarda olur:

  • Dosyalar doğrudan silindi (Dovecot bypass edildi)
  • Sistem çökmesi yaşandı
  • Migration sırasında sayaçlar güncellenmedi

Bu durumda recalc komutunu kullanın:

# Tek kullanici icin quota'yi yeniden hesapla
doveadm quota recalc -u [email protected]

# Tum kullanicilar icin (dikkatli kullanin, ag uzerinde yogunluk yaratir)
doveadm quota recalc -A

# Sadece belirli domain icin
doveadm quota recalc -u '*@example.com'

Büyük sistemlerde tüm kullanıcılar için recalc yapmak ciddi I/O yüküne yol açabilir. Bunu gece yarısı bir cron job olarak çalıştırmak daha akıllıca olur:

# /etc/cron.d/dovecot-quota-recalc
0 2 * * 0 root /usr/bin/doveadm quota recalc -A >> /var/log/quota-recalc.log 2>&1

Gerçek Dünya Senaryosu: Şirket Mail Sunucusu Yapılandırması

Diyelim ki 150 kullanıcılı bir şirket için mail sunucusu yönetiyorsunuz. Farklı departmanlar için farklı kotalar gerekiyor:

  • Yöneticiler: 10GB
  • Yazılım ekibi: 5GB
  • Diğer personel: 2GB
  • Genel kullanıcılar: 1GB

Bu senaryoyu hayata geçirmek için MySQL tabanlı bir yapı kuralım:

-- users tablosuna quota_mb kolonu ekle
ALTER TABLE mail_users ADD COLUMN quota_mb INT DEFAULT 1024;
ALTER TABLE mail_users ADD COLUMN department VARCHAR(50);

-- Departmana gore quota ata
UPDATE mail_users SET quota_mb = 10240 WHERE department = 'yonetim';
UPDATE mail_users SET quota_mb = 5120 WHERE department = 'yazilim';
UPDATE mail_users SET quota_mb = 2048 WHERE department = 'diger';

Dovecot SQL sorgusunu güncelleyin:

# /etc/dovecot/dovecot-sql.conf.ext
user_query = SELECT 
  CONCAT('/home/vmail/', username) AS home, 
  5000 AS uid, 
  5000 AS gid, 
  CONCAT('*:storage=', quota_mb, 'M') AS quota_rule 
  FROM mail_users 
  WHERE username = '%u' AND active = 1

Dovecot’u yeniden yükleyin (restart değil, reload yeterli):

doveadm reload

Quota Raporlama Scripti

Yönetici olarak hangi kullanıcıların kotaya yaklaştığını düzenli görmek istersiniz. Şu script %80 üzeri doluluk oranındaki kullanıcıları listeler:

#!/bin/bash
# /usr/local/bin/quota-report.sh

THRESHOLD=80
REPORT_FILE="/tmp/quota-report-$(date +%Y%m%d).txt"

echo "Quota Raporu - $(date)" > $REPORT_FILE
echo "================================" >> $REPORT_FILE
echo "" >> $REPORT_FILE

doveadm user '*' | while read USER; do
  QUOTA_INFO=$(doveadm quota get -u "$USER" 2>/dev/null | grep STORAGE)
  if [ -z "$QUOTA_INFO" ]; then
    continue
  fi

  VALUE=$(echo "$QUOTA_INFO" | awk '{print $3}')
  LIMIT=$(echo "$QUOTA_INFO" | awk '{print $4}')
  PERCENT=$(echo "$QUOTA_INFO" | awk '{print $5}')

  if [ "$PERCENT" -ge "$THRESHOLD" ] 2>/dev/null; then
    echo "UYARI: $USER - %$PERCENT dolu ($VALUE / $LIMIT KB)" >> $REPORT_FILE
  fi
done

# Raporu mail ile gonder
if [ -s "$REPORT_FILE" ]; then
  mail -s "Quota Uyari Raporu" [email protected] < $REPORT_FILE
fi

cat $REPORT_FILE

Bu scripti haftalık çalışacak şekilde cron’a ekleyin:

# /etc/cron.d/quota-report
0 8 * * 1 root /usr/local/bin/quota-report.sh

Sık Karşılaşılan Sorunlar ve Çözümleri

Quota uyarı maili gelmiyor: quota_warning tanımındaki servis adının service quota-warning bloğuyla birebir eşleştiğini kontrol edin. Dovecot loglarına bakın:

tail -f /var/log/mail.log | grep -i quota

Kullanıcı kota dolduğunda hala mail alıyor: quota_grace değerini kontrol edin. Bu değer 0 ise bile bazen race condition nedeniyle bir iki mail geçebilir. Postfix entegrasyonunu (quota-status servisi) etkinleştirmek bu sorunu büyük ölçüde çözer.

doveadm quota get boş dönüyor: Eklentinin doğru protokol blokuna eklendiğini doğrulayın. mail_plugins satırında hem quota hem de imap_quota bulunmalıdır.

# Konfigurasyonu dogrula
doveadm config -n | grep -i quota

Quota sayacı negatif gösteriyor: Bu genellikle migration sonrası oluşur. doveadm quota recalc -u KULLANICI komutu ile düzeltin.

Dovecot Admin Panel Entegrasyonu

Eğer bir web panel (Postfixadmin, iRedAdmin gibi) kullanıyorsanız, bu paneller genellikle kendi quota yönetim arayüzlerine sahiptir. Ama doğrudan veritabanına müdahale de mümkündür. Örneğin Postfixadmin kullananlar için:

# Postfixadmin mailbox tablosunda quota kolonu bulunur
# mysql -u postfix -p postfix
UPDATE mailbox SET quota = 5368709120 WHERE username = '[email protected]';
# 5368709120 = 5GB (byte cinsinden)

Postfixadmin ve Dovecot entegrasyonunda quota_rule yerine Postfixadmin’in kendi quota mekanizmasını kullanmak daha tutarlı sonuçlar verir.

Performans İpuçları

  • count backend dict’e göre daha hızlıdır çünkü ayrı bir veritabanı I/O’su yoktur. Mümkünse count backend tercih edin.
  • Çok kullanıcılı sistemlerde quota_max_mail_size parametresi ile tek seferde gelen dev ekli mailleri sınırlayabilirsiniz:
# /etc/dovecot/conf.d/90-quota.conf
plugin {
  quota_max_mail_size = 50M
}
  • Dovecot’un quota sayaçları cache’lenir. Cache süresi için quota_service_refresh_interval parametresini ayarlayabilirsiniz (varsayılan: 1 dakika).

Sonuç

Dovecot Quota, mail sunucusu yönetiminin olmazsa olmazlarından biridir. Basit sabit limitlerden başlayıp veritabanı tabanlı dinamik kotaya kadar geniş bir esneklik sunar. Postfix ile entegre çalışınca pre-delivery kontrolü de yapabildiğiniz için gereksiz bounce trafiğinden kurtulursunuz.

Önerilen yaklaşım şu sırayla ilerlemenizdir: Önce basit count backend ile Maildir quota’yı çalıştırın, sistemi test edin. Ardından farklı kullanıcı grupları için farklı limitler gerekiyorsa SQL tabanlı user_query ile dinamik quota’ya geçin. Son adım olarak Postfix quota-status entegrasyonunu ekleyin.

Quota sistemi kurulduktan sonra düzenli recalc ve raporlama scriptleri ile sisteminizi sağlıklı tutabilirsiniz. “Disk doldu, mail gelmiyor” telefonu almak yerine proaktif uyarılar sayesinde kullanıcılar durumun farkına varmadan önce siz müdahale edebilirsiniz. Bu da hem son kullanıcı memnuniyetini artırır hem de sizi gereksiz stres ve gece yarısı çağrılarından korur.

Yorum yapın