SSD Nodes Learn 🎉 VPS $5.50/aydan başlayan
Rehberler Matt ConnorYazan Matt Connor · Güncellendi 2026-08-21

Self-hosted uygulamalardan e-posta nasıl gönderilir?

Kendi posta sunucunuzu kurmadan uygulamalarınızdan e-posta gönderin. SMTP relay kullanımı, SPF, DKIM, DMARC yapılandırması ve 25 numaralı port engeli için çözüm yolları.

Self-hosted uygulamaların e-posta göndermek için ihtiyaç duydukları

Self-hosted uygulamalardan e-posta göndermek için bir posta sunucusuna ihtiyacınız yoktur. Bir aktarıcıya (relay) ihtiyacınız vardır: Sunucuda bir kez yapılandırılan ve kutudaki her uygulamanın giden postalarını teslim ettiği, kimlik doğrulamalı bir SMTP hesabı. Bir posta kutusu çalıştırmak zor bir iştir ve bu, farklı bir sorundur.

Posta almak, tüm internetten 25 numaralı port üzerinden gelen bağlantıları kabul etmek, spam filtrelemek, posta kutularını depolamak, yedeklemek ve sunucu var olduğu sürece bir IP itibarını korumak anlamına gelir. Bu iş gerçekten zorlaştı. Posta göndermek ise parola sıfırlama, kayıt onayı, "yedekleme başarısız" uyarısı ve forum yanıt bildirimi anlamına gelir. Bunlar kısa, düşük hacimli ve tek tek gönderilen iletilerdir. Bir aktarıcı bunları yönetir ve kurulumu bir öğleden sonranızı alır.

Hangi sorunu çözmeye çalıştığınıza karar verin. Kendi posta kutunuzu çalıştırmanın hala değip değmeyeceği, gerçek bir cevabı olan gerçek bir sorudur ve çoğu insan için cevap hayırdır. Cevabınız evet ise, bir VPS üzerinde tam kapsamlı Mailcow posta sunucusu dürüst yoldur. Diğer yarısı olan gönderme işlemi ise neredeyse herkesin ihtiyaç duyduğu ancak neredeyse kimsenin planlamadığı kısımdır.

Öncelikle iki terimi açıklayalım. SMTP (simple mail transfer protocol), bu sürecin her aşamasında kullanılan protokoldür. Smarthost olarak da adlandırılan bir aktarıcı, kimlik doğrulamalı postalarınızı kabul eden ve bunları kendi adreslerini ve kendi itibarını kullanarak ileriye ileten bir sunucudur.

VPS sunucunuz neden 25 numaralı port üzerinden e-posta gönderemiyor

Hemen hemen her VPS sağlayıcısı, varsayılan olarak giden TCP 25 numaralı portu engeller. 25 numaralı port, e-posta sunucularının birbirine ulaşmak için kullandığı porttur; bu nedenle giden 25 numaralı portu açık olan ele geçirilmiş bir VPS, doğrudan her alıcı e-posta sunucusuna spam gönderebilir. Sağlayıcılar bu paketleri reddetmek yerine doğrudan düşürür; bu yüzden karşılaşılan belirti bir hata mesajı değil, bağlantının askıda kalıp zaman aşımına uğramasıdır.

Bunu sunucu üzerinden test edin:

sudo apt update && sudo apt install -y netcat-openbsd
nc -vz -w 5 gmail-smtp-in.l.google.com 25
nc -vz -w 5 smtp.relay.example 587

Eğer ilk komut beş saniye boyunca beklerken ikincisi anında yanıt veriyorsa, engelleme doğrulanmış demektir. Bazı sağlayıcılar hesap incelemesinin ardından bu engeli kaldırır. Çoğu ise kaldırmaz.

Engelleme, bir relay kullanmanın ana nedeni değildir. 25 numaralı port açık olsa bile, yeni bir VPS adresinden doğrudan gönderilen e-postalar spam klasörüne düşer veya doğrudan reddedilir; çünkü bu adresin bir gönderim geçmişi yoktur ve alıcıların barındırma alanı olarak değerlendirdiği bir IP bloğundadır. Google'ın gönderici kılavuzu, gönderen IP için geçerli ileri ve geri DNS kayıtları gerektirir; birçok VPS adresi ise değiştiremeyeceğiniz genel bir PTR (pointer) kaydı taşır. Bir relay, size halihazırda bir geçmişi olan adresler sağlar.

Çözüm, gönderim portlarını kullanmaktır. 587 numaralı port STARTTLS taşır; burada oturum düz metin olarak başlar ve yükseltilir. 465 numaralı port ise örtük TLS (transport layer security) taşır; burada oturum ilk bayttan itibaren şifrelidir. Her ikisi de kimliği doğrulanmış istemciler için tasarlanmıştır, her ikisi de VPS ağlarında açıktır ve relay servisiniz bunlardan en az birini destekler.

Bir aktarıcı ve gönderim alt alan adı seçin

Birçok işlemsel e-posta sağlayıcısı mevcuttur ve hepsi aynı işi yapar. Bunları dört kritere göre değerlendirin:

  • SMTP AUTH destekli 587 veya 465 numaralı gönderim portu
  • Sadece sağlayıcının değil, kendi alan adınız ve seçiciniz (selector) ile DKIM imzalama desteği
  • Panel veya webhook aracılığıyla okunabilir geri dönen e-posta (bounce) ve şikayet verileri
  • Hacminize uygun bir katman. Ağustos 2026 itibarıyla birçok sağlayıcı aylık birkaç bin mesajı ücretsiz sunmaya devam etmektedir; ancak bu şartlar sıkça değiştiğinden, herhangi bir blog yazısı yerine güncel fiyatlandırma sayfasını inceleyin.

Uygulama postalarını bir alt alan adından gönderin. example.com yerine notify.example.com gibi bir yapı kullanın. Alıcılar itibarı alan adı bazında puanlar; bu sayede uygulamalarınızdan kaynaklanan hatalı bir gönderim, faturalarınızın ve ekibinizin e-postalarının geldiği ana alan adını etkilemez. Sınırlar konusunda gerçekçi olun: Bazı alıcılar alt alan adı sinyallerini kurumsal alan adına dahil eder; bu nedenle alt alan adı kullanımı riski tamamen ortadan kaldırmaz, yalnızca etkisini azaltır.

Her self-hosted uygulama için röleyi bir kez yapılandırın

Cazip gelen yaklaşım, her uygulamanın ayarlar sayfasına gidip SMTP sunucusunu, kullanıcı adını ve şifresini yapıştırmaktır. Nextcloud, forum, Grafana, Vaultwarden ve çalışma süresi izleyicisi gibi uygulamaların hepsinde bu form bulunur. Bunu yaptığınızda kimlik bilgisi artık altı farklı yerde, altı farklı formatta bulunur; bunların bir kısmı veri olarak yedeklediğiniz bir veritabanının içindedir. Şifreyi değiştirdiğinizde bunların beşini güncellemeniz gerekir. Altıncısı gönderimi durdurur ve bunu sessizce yapar; çünkü çoğu uygulama SMTP hatasını sunucu tarafında günlüğe kaydeder ancak kullanıcıya yine de başarı sayfası gösterir.

Bunun yerine röleyi ana makinede bir kez yapılandırın ve uygulamaların yerel olarak gönderim yapmasını sağlayın. Bu işi iyi yapan iki araç vardır ve aralarındaki seçim kuyruklama ihtiyacına göre yapılır.

msmtp, daemon içermeyen sendmail uyumlu bir istemcidir. Bağlanır, gönderir ve çıkar. Kuyruklama yapmaz; bu nedenle röleye ulaşılamazsa ileti kaybolur ve çağıran uygulama sıfır olmayan bir çıkış durumu döndürür.

Uydu (satellite) olarak yapılandırılmış Postfix, gerçek bir kuyruğa sahip tam teşekküllü bir posta aktarım aracıdır (MTA). İletiyi anında kabul eder, hata durumunda günlerce yeniden dener ve röle kimlik bilgilerini yalnızca root erişimine sahip bir dosyada tutar. Röle kesintisi sırasında bir uyarının kaybolması önemliyse veya birden fazla uygulama farklı sistem kullanıcıları olarak çalışıyorsa bunu kullanın.

msmtp, küçük seçenek

sudo apt update
sudo apt install -y msmtp msmtp-mta ca-certificates

msmtp-mta, /usr/sbin/sendmail sembolik bağını kurar; böylece sendmail komutunu çağıran her şey, msmtp'nin varlığından habersiz olarak ona ulaşır.

/etc/msmtprc dosyasını oluşturun:

defaults
auth            on
tls             on
tls_trust_file  /etc/ssl/certs/ca-certificates.crt
syslog          on

account         relay
host            smtp.relay.example
port            587
from            apps@notify.example.com
set_from_header on
user            <relay username>
password        <relay password>

account default : relay

set_from_header on her zaman bir From başlığı ayarlar ve mevcut olanı geçersiz kılar; bu nedenle uygulamanın ürettiği her şeyi from adresindeki değerle değiştirir. Bu ayar olmadan bir cron işi root@your-hostname olarak gönderim yapar ve röle, doğrulanmış bir adres olmadığı için bunu reddeder. syslog on, günlüğü syslog üzerinden gönderir, böylece journalctl -t msmtp ile okuyabilirsiniz. Paylaşılan bir logfile yolu bir alternatiftir ancak posta gönderen her kullanıcının yazma iznine sahip olması gerekir; bu, çok kullanıcılı bir sistemde bir tuzaktır.

İzinleri kendiniz ayarlayın. msmtp, kullanıcı bazlı yapılandırmalarda (~/.msmtprc) izinleri zorunlu tutar ve contains secrets and therefore must have no more than user read/write permissions hatasıyla çalışmayı reddeder. /etc/msmtprc üzerinde ise hiçbir şeyi zorunlu tutmaz, çünkü okunabilir olduğu sürece dosyayı doğrudan yükler.

sudo chown root:root /etc/msmtprc
sudo chmod 600 /etc/msmtprc
printf 'Subject: relay test\n\nsent from the host\n' | sudo sendmail -v you@example.com

-v, tüm SMTP iletişimini yazdırır, böylece röleden gelen her yanıtı görebilirsiniz. Başarılı bir gönderim, iletiyi kabul eden bir 250 yanıtıyla biter. Bir authentication failed satırı, kullanıcı adının veya şifrenin yanlış olduğu ya da rölenin hesap şifresi yerine bir API anahtarı beklediği anlamına gelir.

Şimdi işin püf noktası; birçok kişinin Postfix'e geçme nedeni budur. 600 modu ve root sahipliği ile yalnızca root gönderim yapabilir. www-data olarak çalışan bir uygulama dosyayı okuyamaz, msmtp onu atlar ve uygulama varsayılan hesabın bulunamadığına dair bir hatayla başarısız olur. Çözüm bir gruptur:

sudo chgrp mail /etc/msmtprc
sudo chmod 640 /etc/msmtprc
sudo usermod -aG mail www-data

Bunun ne anlama geldiğini açıkça belirtin: mail grubunun her üyesi, röle şifresini okuyabilir ve o makineden alan adınız adına posta gönderebilir. Tek başınıza yönettiğiniz bir VPS'de bu kabul edilebilirdir. Yazmadığınız birkaç uygulamanın farklı kullanıcılar olarak çalıştığı yerlerde bu kabul edilemez; bu durumda uygulamalar kimlik bilgilerini asla görmediği için Postfix daha iyi bir cevaptır.

Uydu olarak Postfix

sudo debconf-set-selections <<'EOF'
postfix postfix/main_mailer_type select Satellite system
postfix postfix/mailname string notify.example.com
postfix postfix/relayhost string [smtp.relay.example]:587
EOF
sudo DEBIAN_FRONTEND=noninteractive apt install -y postfix libsasl2-modules

libsasl2-modules isteğe bağlı değildir. Bu olmadan Postfix warning: SASL authentication failure: No worthy mechs found hatasını günlüğe kaydeder, çünkü PLAIN ve LOGIN mekanizması kütüphaneleri /usr/lib/sasl2 altında yüklü değildir.

Geri kalanını, /etc/postfix/main.cf dosyasını yerinde düzenleyen postconf -e ile ayarlayın:

sudo postconf -e 'relayhost = [smtp.relay.example]:587'
sudo postconf -e 'smtp_sasl_auth_enable = yes'
sudo postconf -e 'smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd'
sudo postconf -e 'smtp_sasl_security_options = noanonymous'
sudo postconf -e 'smtp_tls_security_level = encrypt'
sudo postconf -e 'smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt'
sudo postconf -e 'inet_interfaces = loopback-only'

Röle ana bilgisayar adının etrafındaki köşeli parantezler, Postfix'in bu isim için bir MX kaydı aramasını engeller ve doğrudan isme bağlanmasını sağlar. Bazı röle ana bilgisayar adları başka bir yeri işaret eden MX kayıtları yayınlar; parantez kullanmazsanız postanız yanlış sunucuya gider.

smtp_tls_security_level = encrypt, TLS'yi zorunlu kılar, böylece ileti asla açık metin olarak gönderilmez. Sertifikayı doğrulamaz. Postfix'in kendi belgeleri bu konuda açıktır: bu seviyede, sunucu sertifikası güvenilmez olsa veya yanlış isim taşısa bile teslimat devam eder. Sertifikanın kontrol edilmesini istiyorsanız verify veya secure kullanın ve smtp_tls_CAfile ayarını koruyun.

Kimlik bilgisi, yalnızca root erişimine sahip tek bir dosyaya gider:

echo '[smtp.relay.example]:587 relay-username:relay-password' | sudo tee /etc/postfix/sasl_passwd
sudo chmod 600 /etc/postfix/sasl_passwd
sudo postmap hash:/etc/postfix/sasl_passwd
sudo systemctl restart postfix

postmap, Postfix'in fiilen okuduğu dizinlenmiş kopyayı oluşturur. Metin dosyasını daha sonra düzenleyip postmap komutunu unutursanız, Postfix günlükte size hiçbir uyarı vermeden eski veritabanını kullanmaya devam eder. Postfix 3.9 ve daha yeni sürümlerde varsayılan harita türü lmdb'dir; bu nedenle tercih ederseniz hem parametrede hem de postmap argümanında lmdb: yazın. Türü her iki satırda da belirtmek, senkronize kalmalarını sağlar.

Uygulamalar postalarını hala root@hostname olarak adresler. Göndereni yeniden yazın:

echo '/.+/    apps@notify.example.com' | sudo tee /etc/postfix/sender_canonical
sudo postconf -e 'sender_canonical_classes = envelope_sender, header_sender'
sudo postconf -e 'sender_canonical_maps = regexp:/etc/postfix/sender_canonical'
sudo systemctl reload postfix

Bir regexp: tablosu doğrudan okunur, bu nedenle postmap gerektirmez. Artık her ileti aynı zarf göndereni ve aynı From başlığı ile çıkar; rölenin istediği de budur. Bunun bedeli, yanıtların hepsinin tek bir yere düşmesidir; bu nedenle yanıtların bir kişiye ulaşması gereken her uygulamanın içinde bir Reply-To başlığı ayarlayın.

Bir test gönderin ve günlüğü okuyun:

printf 'Subject: postfix relay test\n\nsent through the queue\n' | sendmail you@example.com
sudo tail -n 20 /var/log/mail.log

Teslim edilen bir ileti, status=sent ve ardından rölenin kendi yanıtını parantez içinde günlüğe kaydeder. Başka herhangi bir şey, nedenini belirtir. Connection timed out ile birlikte status=deferred, bir şeyin hala 25 numaralı porta yönlendirildiği anlamına gelir. Host or domain name not found. Name service error for name=smtp.relay.example type=A, röle ana bilgisayar adının yanlış olduğu veya makinede DNS'in bozuk olduğu anlamına gelir. mailq takılı kalanları listeler ve sudo postqueue -f bunları hemen yeniden dener.

Docker container'larından ana makine rölesine erişim

Bir container, binary imaj içerisinde bulunmadığı ve kuyruk paylaşılmadığı için ana makinenin sendmail komutunu çağıramaz. Bunun yerine container'lara bir ağ hedefi tanımlayın. Postfix, Docker köprü adresi üzerinde dinleme yapabilir.

ip -4 addr show docker0
sudo postconf -e 'inet_interfaces = 127.0.0.1, 172.17.0.1'
sudo postconf -e 'mynetworks = 127.0.0.0/8 172.17.0.0/16'
sudo systemctl restart postfix

Kendi köprü adresinizi ilk komuttan okuyun; bu komutu kopyalamayın çünkü bir Compose projesi kendi ağını farklı bir alt ağda oluşturur ve docker network inspect <name> bunu yazdırır. Burada reload yerine restart kullanın: Postfix belgeleri, inet_interfaces değişikliğinden sonra servisi durdurup başlatmanız gerektiğini belirtir; yeniden yükleme (reload) değişikliği algılamayacaktır. Her uygulama daha sonra SMTP sunucusu olarak 172.17.0.1 adresini, 25 numaralı portu kullanır; trafik ana makineden dışarı çıkmadığı için kimlik doğrulama ve TLS gerekmez. Servisleriniz bir Compose ağı üzerinde çalışıyorsa, VPS üzerinde Docker Compose çalıştırma bölümü bu alt ağın nereden geldiğini açıklar.

Bu adım hata yapmaya en müsait kısımdır. Geniş bir mynetworks ayarıyla herkese açık bir adres üzerinde dinleme yapan Postfix, açık bir röledir (open relay): yabancılar sizin röle hesabınız üzerinden e-posta gönderir, servis sağlayıcı hesabınızı askıya alır ve alan adınızın itibarı aylarca zarar görür. Her değişiklikten sonra her iki tarafı da kontrol edin.

ss -tlnp | grep ':25'

Çıktı yalnızca loopback adresini ve köprü adresini göstermelidir. Başka bir makineden yapılan nc -vz your.server.ip 25 bağlantısı başarısız olmalıdır.

Gönderici alan adı için SPF, DKIM ve DMARC

İlk gerçek gönderimden önce her üç kaydı da yayınlayın. Bu kayıtlar ücretsizdir, DNS tabanlıdır ve alıcıların ilk kontrol ettiği öğelerdir.

SPF (sender policy framework), alan adınızı zarf göndericisi (envelope sender) olarak kimlerin kullanabileceğini listeler. Bunu gönderim yapan alt alan adında yayınlayın:

notify.example.com.  IN  TXT  "v=spf1 include:_spf.relay.example -all"

Rölenizin kendi kurulum sayfasından include: değerini kopyalayın; çünkü çözümlenemeyen bir include ifadesi, başarılı sonuç yerine kalıcı bir hata almanıza neden olur. SPF değerlendirmesi, on DNS sorgulama mekanizmasından sonra durur ve permerror sonucunu döndürür; alıcılar bunu başarısızlık olarak kabul eder, bu nedenle include sayısını düşük tutun. Her isim için tam olarak bir adet v=spf1 kaydı yayınlayın: iki adet kayıt bulunması da permerror hatasına yol açar.

DKIM (domainkeys identified mail), her iletiyi rölenin elinde tuttuğu özel bir anahtarla imzalar; alıcılar ise eşleşen genel anahtarı DNS üzerinden çeker. Röleniz size bir seçici (selector) ve yayınlamanız için bir TXT kaydı ya da CNAME verir:

sel1._domainkey.notify.example.com.  IN  CNAME  sel1.dkim.relay.example.

DKIM, SPF'den daha önemlidir çünkü DKIM yönlendirmelerde (forwarding) geçerliliğini korur. Bir posta listesi veya bir .forward kuralı iletinizi ilettiğinde, ileti yönlendiricinin IP adresinden gelir; bu durumda SPF başarısız olur ancak imza doğrulanmaya devam eder.

DMARC (domain-based message authentication, reporting and conformance), her iki kontrol de uyuşmadığında alıcılara ne yapmaları gerektiğini söyler ve geri bildirim raporu ister. Bunu kurumsal alan adınızda yayınlayın:

_dmarc.example.com.  IN  TXT  "v=DMARC1; p=none; rua=mailto:dmarc@example.com; adkim=r; aspf=r"

p=none ile başlayın ve raporları iki hafta boyunca inceleyin. p=none teslimat üzerinde hiçbir şeyi değiştirmez, yalnızca raporlamayı açar; alan adınız üzerinden gönderim yapan ancak unuttuğunuz sistemleri bu şekilde bulursunuz. Ardından p=quarantine seviyesine, daha sonra p=reject seviyesine geçin. İlk günden p=reject yayınlamak, fatura sisteminizin alan adınız üzerinden gönderim yaptığını, faturası ulaşmayan bir müşteri aracılığıyla öğrenmenize neden olur.

DNS panelinizin ne gösterdiğine değil, dünyanın ne gördüğüne bakın:

dig +short TXT notify.example.com
dig +short TXT sel1._domainkey.notify.example.com
dig +short TXT _dmarc.example.com

Boş çıktı, kaydın henüz yayılmadığı veya ismin yanlış olduğu anlamına gelir. Beş dakika önce düzelttiğiniz bir kayıt, önceki TTL (time to live) süresi boyunca önbelleklerde hatalı kalabilir; bu nedenle bir sonuca varmadan önce TTL değerini kontrol edin.

From ve Return-Path adreslerini uyumlu tutun

Her ileti iki farklı gönderici adresi taşır ve bunlar farklı şekillerde denetlenir. Zarf göndericisi (envelope sender), SMTP MAIL FROM komutunda belirtilir ve teslim edilen iletide Return-Path olarak görünür. Başlık kısmındaki From adresi ise okuyucunun gördüğü adrestir.

SPF, zarf göndericisinin alan adını bağlantıyı kuran IP adresi ile karşılaştırarak denetler. DKIM, d= olarak imzayı atan alan adını bildirir. DMARC, yalnızca bu iki alan adından en az biri başlıkta yer alan From alan adıyla uyumlu olduğunda başarılı olur. Varsayılan ayar olan gevşek uyumlulukta (adkim=r, aspf=r) alt alan adları kabul edilir; bu nedenle notify.example.com adresindeki bir zarf göndericisi, example.com adresindeki bir From başlığı ile uyumlu sayılır. Sıkı uyumlulukta ise bu durum geçerli değildir.

Pratik kural basittir: From başlığı ile zarf göndericisini aynı alan adına yerleştirin; böylece bu sorun hiç ortaya çıkmaz. msmtp içinde set_from_header on komutunun ve Postfix içinde sender_canonical_maps komutunun yaptığı tam olarak budur.

Teslim edilen bir iletideki sonucu inceleyin. Gmail üzerinde "Orijinali göster" seçeneği, alıcının yazdığı başlığı görüntüler:

Authentication-Results: mx.google.com;
       dkim=pass header.i=@notify.example.com;
       spf=pass (google.com: domain of apps@notify.example.com designates 198.51.100.25 as permitted sender) smtp.mailfrom=apps@notify.example.com;
       dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=example.com

Burada her üç denetim de başarılıdır. Başka herhangi bir sonuç, başarısız olan denetimi ve genellikle nedenini belirtir; bu, konuyla ilgili alabileceğiniz en hızlı hata ayıklama bilgisidir.

Hacim gelmeden önce bounce ve şikayetler

Bounce, bir alıcının mesajınızı reddetmesidir. Hard bounce kalıcıdır ve Gmail bunu 550 5.1.1 The email account that you tried to reach does not exist olarak ifade eder. Soft bounce geçicidir; dolu bir posta kutusu veya greylisting için 4xx kodu döner ve relay işlemi kendiliğinden yeniden dener.

Relay servisleri hard bounce oranınızı ölçer ve var olmayan adreslere posta göndermeye devam eden hesapları askıya alır; çünkü bu örüntü, satın alınmış bir liste görüntüsü verir. Şikayetler daha önemlidir. Şikayet, bir kişinin spam butonuna basmasıdır. Google'ın gönderici rehberi (Ağustos 2026 itibarıyla kontrol edilmiştir), göndericilerin Postmaster Tools üzerinde raporlanan %0,30 spam oranının altında kalmasını ister ve %0,10'un altında kalınmasını tavsiye eder.

Hacim gelmeden önce hazır bulundurulması gereken dört şey:

  • Bounce kayıtlarını görebilmek için bir webhook veya relay servisinin suppression listesini haftalık olarak incelemek
  • Yanıtların ulaşması gereken yerde Reply-To ayarı yapılmış, birinin okuduğu gerçek bir From adresi
  • Herhangi bir adresi listeye eklemeden önce onay almak, böylece sahibi tarafından girilmeyen hiçbir adrese gönderim yapmamış olursunuz
  • Posta tetikleyen her türlü form üzerinde bir hız sınırı (rate limit)

Self-hosted uygulamalar en çok bu son iki maddede başarısız olur. Korumasız bir kayıt formu, herkesin bir başkasının adresini girmesine izin verir; sunucunuz onay postasını gönderir ve yabancı kişi bunu spam olarak işaretler. Kayıt formunuzda abonelik bombardımanını durdurma konusu, bir kötüye kullanım (abuse) görevi olduğu kadar bir teslim edilebilirlik (deliverability) görevidir.

Toplu postaları bu yoldan uzak tutun. Bültenler, işlemsel (transactional) postalarda bulunmayan liste yönetimi ve abonelikten çıkma (unsubscribe) başlıklarına ihtiyaç duyar; bu yüzden onları kendi itibarına sahip ayrı bir alt alan adında self-hosted bir Listmonk örneği üzerinden çalıştırın. Self-hosted bir forumdan gelen bildirim postaları ise arada kalır; yapı olarak işlemsel, hacim olarak topludur ve genellikle kurulumunuzun dayanıklılığını gösteren ilk şeydir.

Referans olarak, Gmail'in toplu gönderici kuralları günde 5.000'den fazla Gmail adresine gönderim yapıldığında geçerli olur ve pazarlama postalarında SPF, DKIM, DMARC ile tek tıkla abonelikten çıkma özelliğini zorunlu tutar. Çoğu self-hosted uygulama bu sınıra asla ulaşmaz. Kimlik doğrulama kısmı ise artık hacimden bağımsız olarak her göndericiden beklenmektedir.

Güvenmeden önce test edin

swaks bu işlem için kullanılan araçtır. SMTP protokolünü kullanır ve tüm iletişimi ekrana yazdırır; böylece hangi adımın başarısız olduğunu görebilirsiniz.

sudo apt install -y swaks
swaks --to you@example.com --from apps@notify.example.com --server smtp.relay.example --port 587 --tls --auth-user '<relay username>' --auth-password '<relay password>'

Bu komut, kimlik bilgilerini doğrudan relay üzerinde test eder. Uygulamalarınızın gerçekte kullandığı yolu test etmek için aracı ana relay sunucusuna yönlendirin:

swaks --to you@example.com --from apps@notify.example.com --server 127.0.0.1

Ardından sonucu sunucu üzerinden, gerçek e-postalarla uçtan uca doğrulayın. Yapılandırma dosyalarına bakarak bu sürecin doğruluğunu kanıtlayamazsınız, bu nedenle testi bizzat çalıştırın:

  • SPF, DKIM, DMARC kayıtlarınızı ve mesaj içeriğinizi okuyarak puanınızın gerekçelerini sunan mail-tester.com gibi bir puanlama servisine gönderim yapın.
  • Kullanıcılarınızın aktif olarak kullandığı iki farklı sağlayıcıdaki posta kutularına gönderim yapın ve ham mesaj içerisindeki Authentication-Results değerini inceleyin.
  • Hizalama sonucunun net olmadığı durumlarda bir mesajı learndmarc.com üzerinden analiz edin.
  • Gönderimi yalnızca komut satırından değil, doğrudan uygulamanın kendisinden tetikleyin; çünkü From başlığını belirleyen asıl unsur uygulamadır.

Son olarak dürüst bir uyarı: Tüm kayıtları doğru yapılandırılmış yepyeni bir alan adı bazen yine de spam klasörüne düşebilir. Bunun nedeni, alan adının bir geçmişinin olmaması ve alıcıların geçen hafta ortaya çıkan alan adlarına karşı temkinli yaklaşmasıdır. Küçük adımlarla başlayın ve insanların beklediği e-postaları gönderin. İtibar bu şekilde inşa edilir ve hiçbir yapılandırma ayarı bu süreci atlamanızı sağlamaz.

FAQ

Why is outbound port 25 blocked on my VPS?

Nearly every provider blocks outbound TCP port 25 by default, because a compromised server with that port open can deliver spam straight to receiving mail servers. The packets are dropped rather than refused, so the symptom is a connection that hangs and then times out, not an error message. Confirm it by running nc -vz -w 5 gmail-smtp-in.l.google.com 25 next to nc -vz -w 5 smtp.relay.example 587: the first sits there, the second answers at once. The answer is not to ask for the block to be lifted. Send through a relay on submission port 587 or 465, which stay open and are meant for authenticated clients.

Do I need SPF, DKIM and DMARC just to send a few app notifications?

Yes, and volume does not change that. Receivers apply the same checks to one password reset as to a campaign of fifty thousand messages. Without SPF and DKIM your mail is unauthenticated, and Google's current sender guidance requires at least one of them from every sender. Without DMARC you get no reports, so the first sign of a problem is a user saying the reset link never arrived. All three are DNS records, they cost nothing, and publishing them takes about ten minutes.

Should I use msmtp or Postfix as the relay client?

Use msmtp when one person administers the box and losing a message during a relay outage is acceptable. It is a single config file with no daemon, and because it does not queue, an unreachable relay means the message is gone. Use Postfix as a satellite when you want a queue that retries for days, or when several apps run as different system users. Postfix keeps the relay password in a root-only file that apps never read, while msmtp needs its config readable by every user that sends.

Why does my app's mail get rejected because it comes from root?

Cron jobs and many apps build the sender from the local user and hostname, producing something like root@srv1.localdomain. That is not an address you verified at the relay, so the relay refuses the message with a 553 or 554 reply naming the sender address. Fix it at host level rather than in each app: set_from_header on together with a from address in /etc/msmtprc, or sender_canonical_maps with sender_canonical_classes = envelope_sender, header_sender in Postfix. Set Reply-To inside each app if replies need to reach a person.

Does a separate subdomain for app mail really protect my main domain?

Partly, and it is still worth doing. Receivers track reputation per domain, so complaints against notify.example.com largely stay with notify.example.com while your main domain keeps delivering. The limit is real: some receivers roll subdomain signals up to the organisational domain, and a DMARC policy published at the organisational level applies to subdomains unless you set sp= separately. Treat the subdomain as damage limitation rather than a guarantee.