SMTP Oturumunu Elle Sürmek: telnet ve openssl ile Teslimat, TLS ve Kimlik Doğrulama Ayıklama
Nodemailer, Postfix ve sendmail SMTP'yi senden gizler; teslimat patladığında elinde bir "451" ve hiçbir bağlam kalmaz. Bir oturumu telnet ve openssl ile elle sürüp EHLO yeteneklerini, TLS zincirini ve tam yanıt kodunu kendi gözünle görmeyi öğren — her bounce'ı 90 saniyede yer belirle.
EvilMail Team1 Ağustos 202612 dk okuma
Bir kullanıcı evilmail.pro üzerinden mail gönderiyor, karşı taraf almıyor ve PM2 logunda tek bir satır var: Message failed: 451. Bu satır sana hiçbir şey söylemez. Alıcı MX greylist'e mi düşürdü, TLS el sıkışması mı koptu, SPF mi reddetti, yoksa gönderen kotası mı doldu — hepsi 451 dönebilir ve Nodemailer sana bunların hangisi olduğunu göstermez. Kütüphane katmanı EHLO yanıtını, TLS sertifika zincirini ve genişletilmiş yanıt metnini yutar; geriye sadece üç haneli bir sayı bırakır.
Çıplak bir SMTP oturumu bu katmanı kaldırır. telnet ve openssl s_client ile 25, 587 ve 465 portlarını elle konuşturduğunda sunucunun gerçekte hangi yetenekleri duyurduğunu, TLS'in nerede koptuğunu ve RCPT TO'nun 550 kalıcı mı yoksa 451 geçici mi döndüğünü satır satır görürsün. mail-tester puanı ya da "SMTP test" web formları sana bir yorum verir; elle oturum sana yer gerçeğini verir. Bir kez öğrendiğinde her bounce'ı doksan saniyelik bir teşhise indirgersin. Aşağıda tek bir başarısız teslimatı bir post-mortem gibi baştan sona çözüyoruz.
Doğru port, doğru araç: telnet mi openssl mı
Üç portun rolü birbirinden kesin ayrıdır ve yanlış portu yanlış araçla konuşturmak seni saatlerce yanlış yöne çeker.
Port 25
SMTP Hata Ayıklama: telnet ve openssl ile Elle Oturum Sürme Rehberi — EvilMail Blog
— MX'ten MX'e teslimat. Fırsatçı STARTTLS (varsa şifreler, yoksa düz gider), AUTH yoktur. Kütüphanenin dünyaya mail teslim ettiği yer.
Port 587 — Submission. STARTTLS ve AUTH zorunludur; istemcilerin kendi sunucularına mail bıraktığı yer.
Port 465 — Örtük (implicit) TLS, yani SMTPS. Bağlantı kurulur kurulmaz TLS başlar, öncesinde düz metin yoktur.
Kritik nokta: telnet yalnızca düz metin konuşur. 25 portunda greeting'i okumak, EHLO göndermek ve STARTTLS öncesi her şeyi görmek için mükemmeldir. Ama STARTTLS komutu kabul edilip TLS el sıkışması başladığı an telnet kör kalır — ekranına ikili çöp döker ve orada takılır. TLS'in içine girmen gereken her şey için openssl s_client gerekir; hem STARTTLS yükseltmesini (-starttls smtp) hem de 465'in örtük TLS'ini sürebilir. nc/ncat de düz metin için telnet yerine kullanılabilir, farkı önemsizdir.
-crlf bayrağı pazarlık konusu değildir. SMTP, satır sonu olarak CRLF (\r\n) ister. Terminalde düz Enter çoğu zaman sadece LF gönderir ve bazı katı sunucular buna 500 command unrecognized ile karşılık verir — komutun doğruydu ama satır sonu bozuktu. openssl s_client'a -crlf verdiğinde bu iş halledilir.
Baştan sona elle bir SMTP oturumu
25 portunda telnet ile tam bir konuşma nasıl görünür — her istemci satırının karşısına sunucu yanıtını yazıyorum:
text
$ telnet mx1.example.com 25
220 mx1.example.com ESMTP Postfix
EHLO test.evilmail.pro
250-mx1.example.com
250-STARTTLS
250-SIZE 52428800
250-8BITMIME
250 PIPELINING
MAIL FROM:<[email protected]>
250 2.1.0 Ok
RCPT TO:<[email protected]>
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
From: [email protected]
To: [email protected]
Subject: Elle test
Bu mesaj elle SMTP ile gonderildi.
.
250 2.0.0 Ok: queued as 4F2A1
QUIT
221 Bye
Dikkat edilecek üç kural: MAIL FROM ve RCPT TO adreslerinde açı parantezi zorunludur — <[email protected]>, çıplak adres değil. DATA gövdesi <CRLF>.<CRLF> ile, yani tek başına bir nokta içeren satırla biter. Ve gövdende satır başında nokta ile başlayan bir satır varsa (.imza gibi) onu dot-stuffing ile ikiye katlaman gerekir (..imza), yoksa sunucu onu veri sonu sanar. Kütüphaneler bunu senin için yapar; elle sürerken sen yaparsın.
EHLO cevabını okumak
EHLO yanıtı çok satırlıdır ve yapısı önemlidir: ara satırlar 250- (tire) ile, son satır 250 (boşluk) ile başlar. Parser son satırı bu boşluktan anlar. Duyurulan her satır bir yetenektir ve teşhisin yarısı buradadır:
STARTTLS — yoksa bu sunucu 25 portunda şifreleme sunmuyor demektir. Bu bir mail-tester puanı sorunu değil, sunucu config'i bozuk.
SIZE 52428800 — mesaj boyut limiti (burada 50 MB). Bunu aşarsan 552 5.3.4 ya da 550 5.3.4 alırsın; başlıklar + gövde + base64 ek şişmesini hesaba kat.
PIPELINING, 8BITMIME, SMTPUTF8, CHUNKING — istemci optimizasyonları; teşhiste nadiren sorun kaynağıdır, ama SMTPUTF8 yoksa Unicode yerel kısım reddedilebilir.
Pratik teşhis: kullanıcı "TLS ile gönderemiyorum" diyorsa ilk bakılacak yer EHLO'da STARTTLS satırının olup olmadığıdır. Yoksa sorun istemcide değil.
Çıktıda dört şeye bak. Birincisi Verify return code: 0 (ok) istediğindir. 10 sertifika süresi dolmuş, 20 (unable to get local issuer certificate) ara sertifika zinciri eksik gönderiliyor, 21 (unable to verify the first certificate) yine zincir kopuk demektir. İkincisi Protocol: 2026'da TLSv1.3 ya da TLSv1.2 beklersin; TLSv1.0/TLSv1.1 görürsen sunucu tehlikeli derecede eski. Üçüncüsü sertifikanın subject/issuer'ı — sunucu adıyla eşleşmeli. Dördüncüsü zincirin tam gelip gelmediği.
-servername (SNI) bayrağı şart, çünkü tek IP'de barındırılan çok sayıda domain varsa sunucu hangi sertifikayı sunacağını SNI'den bilir. SNI göndermezsen varsayılan sertifikayı alırsın ve ad uyuşmazlığı ("hostname mismatch") hatası çıkar — sertifika aslında doğrudur, sen yanlış istedin.
Sadece sertifikanın tarih ve adına bakmak istersen tek satırda kes:
Kopma sebeplerinin sözlüğü: wrong version number neredeyse her zaman "bu port TLS konuşmuyor" demektir — 465'e -starttls smtp ile ya da düz porta TLS ile bağlanmışsındır. sslv3 alert handshake failure protokol/cipher uyuşmazlığıdır; genellikle senin openssl'in eski TLS'i devre dışı bırakmış, sunucu da yeni TLS sunmuyordur. certificate verify failed: Hostname mismatch ise SNI'yi atladığının işaretidir.
Kimlik doğrulamayı elle sürmek: AUTH LOGIN ve PLAIN
AUTH'u yalnızca TLS içinde yap. Yani önce openssl s_client -starttls smtp -connect mail.example.com:587 ile şifreli oturuma gir, sonra AUTH gönder. Parolayı asla 25 portunda ya da STARTTLS öncesi göndermezsin — base64 şifreleme değildir, açık gider.
AUTH LOGIN akışı adım adım şöyledir: sunucu her adımda base64 ile kodlanmış bir istem (334) döner, sen base64 ile kodlanmış cevabı yazarsın.
Yanıt kodları teşhisi keskinleştirir: 235 kabul; 535 5.7.8 kimlik reddi (kullanıcı/parola yanlış ya da hesap kilitli); 530 5.7.0 "önce AUTH iste" — bunu görürsen neredeyse her zaman STARTTLS yapmadan AUTH denemişsindir, sunucu düz oturumda kimlik doğrulamayı reddediyordur; 538 şifreleme gerektiğini söyler.
Yanıt kodlarından teşhise: 4xx geçici, 5xx kalıcı
SMTP yanıt kodunun ilk hanesi her şeyi söyler: 4xx geçicidir, tekrar denenmelidir; 5xx kalıcıdır, config ya da DNS düzeltmen gerekir. İkinci ve üçüncü hane ile 5.7.1 gibi genişletilmiş kod da nedeni daraltır.
Geçici (4xx) ailesi:
421 4.x.x — servis kapanıyor ya da rate limit. Çok hızlı bağlandın, sunucu seni yavaşlatıyor.
450 / 451 4.7.1 — greylisting. Teşhisi kesin: 5-15 dakika bekle, aynı MAIL FROM / RCPT TO / IP üçlüsüyle tekrar dene; bu sefer geçerse greylist'ti. Baştaki 451 gizeminin en yaygın cevabı budur.
452 4.2.2 — alıcı kotası dolu.
Kalıcı (5xx) ailesi:
550 5.1.1 — kullanıcı yok. Adres yanlış ya da hesap silinmiş.
550 5.7.1 relay denied — bu MX senin için relay yapmıyor. Ya yanlış MX'e teslim ediyorsun ya da sunucu open-relay değil (olması da gerekmez).
550 5.7.23 — SPF fail. Gönderen IP, MAIL FROM domain'inin SPF kaydında değil.
550 5.7.26 — DKIM/DMARC hizalama başarısız.
554 5.7.1 — PTR/rDNS yok ya da IP bir RBL'de.
552 5.3.4 — mesaj SIZE limitini aştı.
Kritik ayrıntı: SPF, DKIM ve DMARC redleri genellikle RCPT TO aşamasında değil, `.` ile veriyi bitirdikten sonra düşer — çünkü sunucu başlıkları ve DATA'yı görmeden imzayı ve hizalamayı değerlendiremez. RCPT TO 250 dönüp de son 250 yerine 550 5.7.26 görürsen sorun alıcıda değil, senin DKIM imzanda ya da DMARC hizalamandadır.
PTR uyumunu hep kontrol et — 554/rDNS redlerinin kaynağı budur:
dig -x ile dönen PTR kaydı, MAIL FROM domain'inle tutarlı bir isme çözülmeli. IP 203.0.113.10 bir mail.evilmail.pro'ya çözülmüyorsa katı alıcılar seni 554 5.7.1 ile geri çevirir.
Hızlı teşhis kontrol listesi
Bir teslimat patladığında sırayla yürü:
1.dig MX example.com +short ile gerçek hedef MX'i bul — kütüphanenin bağlandığı yerin doğru olduğunu varsayma.
2.telnet mx 25 ile greeting'i (220) ve EHLO yanıtını al; STARTTLS satırı var mı bak.