"Enter"a basıp içeriğe geçin

Proxmox Mail Gateway ile Rspamd Entegrasyonu: Docker, Unbound ve cPanel Bypass Koruması

Mail sunucusu yöneten herkesin karşılaştığı temel problemlerden biri spam, phishing ve zararlı içerikli e-postaları kullanıcıya ulaşmadan önce mümkün olduğunca doğru şekilde filtrelemektir. Proxmox Mail Gateway, bu konuda oldukça başarılı bir gateway çözümüdür. Ancak bazı yapılarda Rspamd gibi modern ve güçlü bir antispam motorunu da ek skor motoru olarak kullanmak ciddi avantaj sağlayabilir.

Bu yazıda Proxmox Mail Gateway üzerinde Rspamd’i doğrudan PMG içine kurmak yerine ayrı bir Docker sunucusunda çalıştırıp, PMG custom check mekanizması ile entegre etmeyi anlatacağım. Ayrıca DNS sorguları için Unbound kullanımı ve cPanel üzerindeki mail hesaplarını PMG bypass girişimlerine karşı koruma konusunu da ele alacağız.

Kurulum Mimarisi

Kurduğumuz yapının genel mimarisi şu şekilde:

Internet

Proxmox Mail Gateway

PMG custom_check script

rspamc ile Docker üzerindeki Rspamd

Rspamd + Redis + Unbound

cPanel / Mail Server

Bu modelde Proxmox Mail Gateway ana mail gateway olarak çalışmaya devam eder. Rspamd ise PMG’ye ek bir antispam skor motoru gibi davranır. PMG maili alır, custom check script ile Rspamd’e gönderir, Rspamd analiz sonucunu döndürür ve PMG bu skora göre kendi rule/quarantine sistemini işletir.

Neden Rspamd’i Ayrı Docker Sunucusunda Çalıştırdık?

Rspamd’i doğrudan PMG üzerine kurmak mümkündür. Ancak ayrı bir Docker sunucusunda çalıştırmanın bazı avantajları vardır:

  • PMG sistemi daha temiz kalır.
  • Rspamd bağımsız şekilde güncellenebilir.
  • Redis, Unbound ve Rspamd birlikte izole çalışır.
  • Birden fazla PMG sunucusu aynı Rspamd servisini kullanabilir.
  • Hata durumunda PMG mail akışı bozulmadan devam edebilir.

Docker Compose ile Rspamd, Redis ve Unbound Kurulumu

Örnek Docker Compose dosyamız şu şekilde olabilir:

version: '3.8'services:
rspamd:
image: rspamd/rspamd:latest
container_name: rspamd
ports:
- "11333:11333"
- "11334:11334"
volumes:
- /opt/rspamd/config:/etc/rspamd/local.d
- /opt/rspamd/data:/var/lib/rspamd
- /opt/rspamd/logs:/var/log/rspamd
depends_on:
- redis
- unbound
dns:
- 172.28.0.53
networks:
rspamd_net:
ipv4_address: 172.28.0.10
restart: unless-stopped redis:
image: redis:alpine
container_name: rspamd-redis
volumes:
- /opt/rspamd/redis:/data
networks:
rspamd_net:
ipv4_address: 172.28.0.20
restart: unless-stopped unbound:
image: mvance/unbound:latest
container_name: rspamd-unbound
networks:
rspamd_net:
ipv4_address: 172.28.0.53
restart: unless-stoppednetworks:
rspamd_net:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/24

Burada Rspamd container DNS olarak Unbound container’ını kullanır. Bu özellikle RBL, URIBL, SURBL, SPF, DKIM, DMARC ve ASN sorguları için daha sağlıklı bir yapı sağlar.

Rspamd Portları Ne İşe Yarar?

Rspamd tarafında portları karıştırmamak önemlidir:

11333 = Normal scan worker, PMG custom check için kullanılır
11334 = Controller / Web UI
11332 = Milter / proxy worker

PMG custom check entegrasyonunda genellikle 11333 portunu kullanırız. Web arayüzüne erişmek için ise 11334 kullanılır. 11334 portunu mümkünse public internete açmamak, VPN veya SSH tunnel ile erişmek daha güvenlidir.

Rspamd Temel Config Dosyaları

Docker volume yapımıza göre Rspamd local config dosyaları host üzerinde şu dizinde tutulur:

/opt/rspamd/config

Redis Config

# /opt/rspamd/config/redis.conf
servers = "redis:6379";

Bayes Classifier Config

# /opt/rspamd/config/classifier-bayes.conf
backend = "redis";
servers = "redis:6379";

Normal Worker Config

# /opt/rspamd/config/worker-normal.inc
bind_socket = "0.0.0.0:11333";

Controller Config

# /opt/rspamd/config/worker-controller.inc
bind_socket = "0.0.0.0:11334";
password = "$2$HASH_BURAYA";
enable_password = "$2$HASH_BURAYA";

Controller şifresini oluşturmak için:

docker exec -it rspamd rspamadm pw

Unbound DNS Kullanımı

Rspamd DNS tabanlı kontrolleri yoğun kullandığı için Unbound kullanmak mantıklıdır. İlk aşamada Cloudflare DNS-over-TLS gibi forward yapıları kullanılabilir. Ancak antispam tarafında en doğru sonuçlar için Unbound’un tam recursive resolver olarak çalışması daha sağlıklıdır.

Recursive Unbound çalıştığında loglarda root, TLD ve authoritative DNS sunucularına direkt sorgular görürsünüz:

priming . IN NS
reply from <.> 202.12.27.33#53
reply from <com.> 192.12.94.30#53
reply from <google.com.> 216.239.32.10#53

Bu, Unbound’un Cloudflare gibi public resolver üzerinden değil, doğrudan recursive çalıştığını gösterir.

PMG Üzerinde rspamc Kurulumu

PMG, Docker’daki Rspamd servisine bağlanmak için rspamc client aracına ihtiyaç duyar.

apt update
apt install rspamd-client jq -y

Eğer rspamd-client paketi bulunamazsa:

apt install rspamd jq -y
systemctl disable --now rspamd

PMG üzerinde Rspamd servisini çalıştırmak zorunda değiliz. Sadece rspamc binary’si yeterlidir.

PMG Custom Check Script

PMG tarafında custom check script’i ile mail dosyası Rspamd’e gönderilir. Rspamd skoruna göre PMG’ye OK veya SCORE: x döndürülür.

Script dosyası:

/usr/local/bin/pmg-rspamd-check.sh

Örnek sade ve stabil script:

#!/bin/bash
set -euo pipefail

API_VERSION="${1:-}"
QUEUE_FILE="${2:-}"

RSPAMD_HOST="X.X.X.X"
RSPAMD_PORT="11333"
TIMEOUT_SECONDS="5"

if [[ -z "$API_VERSION" || -z "$QUEUE_FILE" || ! -f "$QUEUE_FILE" ]]; then
echo "OK"
exit 0
fi

logger -t pmg-rspamd-check "called api=${API_VERSION} file=${QUEUE_FILE}"

RESULT="$(timeout "${TIMEOUT_SECONDS}" rspamc -h "${RSPAMD_HOST}:${RSPAMD_PORT}" -j symbols "$QUEUE_FILE" 2>/dev/null || true)"

logger -t pmg-rspamd-check "result_len=${#RESULT}"

if [[ -z "$RESULT" ]]; then
echo "OK"
exit 0
fi

SCORE="$(echo "$RESULT" | jq -r '.score // 0' 2>/dev/null || echo 0)"
ACTION="$(echo "$RESULT" | jq -r '.action // "no action"' 2>/dev/null || echo "no action")"

logger -t pmg-rspamd-check "rspamd_score=${SCORE} action=${ACTION}"

if ! [[ "$SCORE" =~ ^-?[0-9]+([.][0-9]+)?$ ]]; then
echo "OK"
exit 0
fi

case "$ACTION" in
"reject")
echo "SCORE: 12"
exit 0
;;
"add header")
echo "SCORE: 5"
exit 0
;;
"rewrite subject")
echo "SCORE: 4"
exit 0
;;
esac

if awk "BEGIN {exit !($SCORE >= 15)}"; then
echo "SCORE: 10"
elif awk "BEGIN {exit !($SCORE >= 8)}"; then
echo "SCORE: 5"
elif awk "BEGIN {exit !($SCORE >= 5)}"; then
echo "SCORE: 3"
else
echo "OK"
fi

exit 0

Yetki ve syntax kontrolü:

chmod +x /usr/local/bin/pmg-rspamd-check.sh
bash -n /usr/local/bin/pmg-rspamd-check.sh

PMG Config İçinde Custom Check Aktif Etme

PMG üzerinde /etc/pmg/pmg.conf dosyasına şu satırlar eklenir:

section: admin
custom_check 1
custom_check_path /usr/local/bin/pmg-rspamd-check.sh

Sonrasında:

pmgconfig sync --restart 1
systemctl restart pmg-smtp-filter

Test

PMG üzerinden Rspamd bağlantısı test edilebilir:

rspamc -h X.X.X.X:11333 -j symbols /tmp/test.eml | jq

Controller / Web UI istatistiği için:

rspamc -h X.X.X.X:11334 -P 'WEB_UI_SIFRENIZ' stat

PMG custom script test:

/usr/local/bin/pmg-rspamd-check.sh v1 /tmp/test.eml

Log izleme:

journalctl -f | grep pmg-rspamd-check

GTUBE ile Spam Testi

Spam filtresini test etmek için GTUBE test string’i kullanılabilir. Bu gerçek spam değildir; spam filtreleri için standart test içeriğidir.

cat > /tmp/gtube.eml <<'EOF'
From: spammer@example.com
To: test@example.com
Subject: GTUBE spam testXJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
EOF

Test:

rspamc -h X.X.X.X:11333 -j symbols /tmp/gtube.eml | jq
/usr/local/bin/pmg-rspamd-check.sh v1 /tmp/gtube.eml

Rspamd Üzerinde Local Domain Blacklist

Rspamd’de kendi domain blacklist map’inizi tanımlayabilirsiniz.

mkdir -p /opt/rspamd/config/maps
nano /opt/rspamd/config/maps/blacklist_sender_domains.map

Örnek:

spamdomain.example
bad-domain.tld
phishing-example.net

multimap.conf içine:

BLACKLIST_SENDER_DOMAIN {
type = "from";
filter = "email:domain";
map = "/etc/rspamd/local.d/maps/blacklist_sender_domains.map";
score = 8.0;
symbol = "LOCAL_BLACKLIST_SENDER_DOMAIN";
description = "Sender domain is in local blacklist";
}

Rspamd Üzerinde IP Whitelist

Güvenilir IP adreslerini whitelistlemek için:

nano /opt/rspamd/config/maps/ip_whitelist.map

Örnek:

1.2.3.4
5.6.7.0/24

multimap.conf içine:

LOCAL_IP_WHITELIST {
type = "ip";
map = "/etc/rspamd/local.d/maps/ip_whitelist.map";
score = -10.0;
symbol = "LOCAL_IP_WHITELIST";
description = "Sender IP is in local IP whitelist";
}

Config kontrol ve restart:

docker exec -it rspamd rspamadm configtest
docker compose restart rspamd

ASN Bazlı Skorlama

Spam yoğunluğu yüksek bazı ASN’leri tamamen engellemek yerine puanlandırmak daha sağlıklıdır. Bunun için bad_asn.map kullanılabilir.

nano /opt/rspamd/config/maps/bad_asn.map

Örnek:

14061 2 # DigitalOcean
16276 2 # OVH
53755 5 # Input Output Flood
63018 4 # Dedicated.com

multimap.conf içine:

LOCAL_BL_ASN {
type = "asn";
map = "/etc/rspamd/local.d/maps/bad_asn.map";
score = 1.0;
symbol = "LOCAL_BL_ASN";
description = "Sender ASN is on local blacklist";
}

Burada score = 1.0 kullanılması önemlidir. Çünkü map içindeki ikinci kolon zaten skor etkisini taşır.

cPanel Üzerinde PMG Bypass Koruması

Mail domainlerinin MX kaydını PMG’ye yönlendirmek tek başına yeterli değildir. Eğer saldırgan gerçek cPanel mail sunucusunun IP adresini bulursa, MX’i bypass ederek doğrudan cPanel’e mail göndermeyi deneyebilir.

Bunu engellemek için cPanel Exim tarafında domain bazlı ACL eklenebilir. Mantık şudur:

Eğer alıcı domain PMG korumalı listedeyse
ve bağlantı PMG IP’sinden gelmiyorsa
RCPT aşamasında reddet.

PMG IP Listesi

nano /etc/exim_pmg_allowed_hosts

Örnek:

127.0.0.1

Buraya sadece cPanel’in Exim loglarında PMG’den gelen bağlantı olarak gördüğü gerçek IP adresi yazılmalıdır.

PMG Korumalı Domain Listesi

nano /etc/exim_pmg_protected_domains

Örnek:

enkitech.com.tr
example.com
customer-domain.com

cPanel Exim ACL

cPanel 128 üzerinde doğru custom ACL alanı şu şekilde olabilir:

/usr/local/cpanel/etc/exim/acls/ACL_RECIPIENT_BLOCK/custom_begin_recipient

İçeriği:

deny
domains = lsearch;/etc/exim_pmg_protected_domains
!hosts = net-iplsearch;/etc/exim_pmg_allowed_hosts
!authenticated = *
message = This domain accepts mail only through EnkiTech SafeMail gateway.
log_message = PMG_BYPASS_BLOCKED: direct SMTP to protected domain=$domain from $sender_host_address sender=$sender_address recipient=$local_part@$domain

Burada net-iplsearch kullanılması önemlidir. Eğer dosyada CIDR subnet kullanılacaksa iplsearch yerine net-iplsearch tercih edilmelidir.

Rebuild ve restart:

/scripts/buildeximconf --force
/scripts/restartsrv_exim

Kuralın Exim config’e girdiğini kontrol etmek için:

grep -n "PMG_BYPASS_BLOCKED" /etc/exim.conf

Bypass Testi

Dış bir sunucudan doğrudan cPanel IP’sine test:

swaks \
--server CPANEL_IP \
--from test@example.net \
--to user@protected-domain.com \
--helo mail.example.net

Beklenen cevap:

550 This domain accepts mail only through EnkiTech SafeMail gateway.

PMG üzerinden gelen mail ise kabul edilmelidir.

Güvenlik Önerileri

  • Rspamd 11333 portunu sadece PMG IP adresine açın.
  • Rspamd 11334 Web UI portunu public internete açmayın.
  • Unbound query loglarını testten sonra kapatın.
  • Redis volume’unu düzenli yedekleyin.
  • ASN blacklist gibi agresif kurallarda düşük skorla başlayın.
  • cPanel tarafında sadece gerçek PMG IP’sini allow list’e ekleyin; mümkünse /24 gibi geniş subnetlerden kaçının.
  • PMG ve cPanel loglarını ilk birkaç gün yakından izleyin.

Sonuç

Proxmox Mail Gateway tek başına güçlü bir mail gateway çözümüdür. Ancak Rspamd’i Docker üzerinde ayrı bir servis olarak çalıştırıp PMG custom check ile entegre etmek, spam tespit kalitesini artırmak ve daha esnek kurallar yazmak için oldukça etkili bir yöntemdir.

Bu yapı sayesinde PMG’nin quarantine, tracking center ve rule engine avantajları korunurken; Rspamd’in modern scoring, Redis tabanlı öğrenme, DNSBL/URIBL, ASN ve custom map özelliklerinden de yararlanılabilir.

Ek olarak cPanel Exim üzerinde yapılan PMG bypass koruması sayesinde gerçek mail sunucusunun IP adresi bilinse bile korunan domainlere doğrudan mail gönderimi engellenmiş olur. Bu, özellikle hosting ve çoklu müşteri barındıran yapılarda önemli bir güvenlik katmanıdır.

İlk Yorumu Siz Yapın

    Bir yanıt yazın

    E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir