(Debian8) Telnet/Netcat scripte bleiben einfach stehen

NoahsRaven

New Member
Also ich versuche(!) mich mal möglichst kurz zu fassen:

SOLL: Ein Shell-Script soll an einem Prompt eine E-Mail-Adresse abfragen, den Mailserver der Domain ermitteln.
Dann soll der Mailserver mittels telnet/netcat abgefragt werden ob die E-Mail-Adresse existiert ohne ein Nachricht zu senden. (ähnlich wie z.B. bei http://www.mailtester.com/ nur eben per shell)

ABER: Da bin ich noch lange nicht.
Dies ist lediglich Phase1, ein Shell-Script finden über das man jeden(!) Mail- Server per Telnet/netcat auf Port 25 abfragen kann.
Derzeit schlage ich mich mit Shell-Scripten rum in denen der MailServer und die E-Mail-Adresse statisch eingetragen sind.
Weil diese Scripte einfach stehen bleiben.

BEMERKUNG: die Befehle der unten zu sehenden Scripte einzeln und manuell in die Shell eingetragen funktionieren immer aber eben nicht als Shellscript zusammen gefasst.

Drei verschiedene Versionen habe ich getestet

1. Version (telnet pur)
erstellt u.a. nach https://de.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol
Code:
#!/bin/bash
telnet mx00.kundenserver.de 25       
HELO [Hostname meines Mailservers]                 
MAIL FROM:<Absende-Adresse>    
RCPT TO:<Empfangs-Adresse>      
DATA                                    
From: <Absende-Adresse>
To: <Empfangs-Adresse>
Subject: Testmail Script Telnet VM

Lorem ipsum dolor sit amet, consectetur adipisici elit, eiusmod tempor incidunt ut labore et dolore magna aliqua.
.

QUIT
Funktionieren bei allen getesteten Servern (mx01.t-online.de und mx00.kundenserver.de) bis Zeile 'telnet -a . . . '
befinden sich dann immer noch in Telnet-Shell haben aber offensichtlich probs mit den Zeilenumbrüchen
man kann die Telnet-Shell dann sogar noch manuell weiterverwenden.


2. Version (per netcat)
siehe: http://www.linuxjournal.com/content/sending-email-netcat
besteht aus zwei Dateien
Datei 1 z.B. mt_t-online_nc.sh
Code:
/bin/nc mx01.t-online.de 25 < mt_t-online_nc.txt >> protokoll_t-online.txt

Datei 2 z.B. mt_t-online_nc.txt
Code:
HELO [Hostname meines Mailservers]                 
MAIL FROM:<Absende-Adresse>    
RCPT TO:<Empfangs-Adresse>      
DATA                                    
From: <Absende-Adresse>
To: <Empfangs-Adresse>
Subject: Testmail Script Netcat VM

Lorem ipsum dolor sit amet, consectetur adipisici elit, eiusmod tempor incidunt ut labore et dolore magna aliqua.
.

QUIT
Funktioniert nur bei t-online.de,
bleibt bei GMX und 1&1 vor dem ersten Telnet Befehl (HELO bzw. EHLO) einfach stehen.
Gmail gibt zurück: '451 4.5.0 SMTP protocol violation, see RFC 2821 k44-v6si1051607wre.219 - gsmtp'


3. Version (telnet gepiped)
Siehe: https://community.spiceworks.com/to...mmands-and-shell-script-not-sending-mail-body
Code:
#!/bin/bash
(
echo helo [Hostname meines Mailservers] ;
sleep 1;
echo mail from: Absende-Adresse;
#sleep 2;
echo rcpt to: Empfangs-Adresse;
#sleep 2;
echo data;
#sleep 2;
echo subject: Testmail Script VM Telnet piped;
#sleep 2;
echo From: Absende-Adresse;
echo To: Empfangs-Adresse;
echo Subject: Testmail Script Telnet_piped VM;
echo Testmail Script Telnet_piped VM;
echo .;
#sleep 3;
echo quit;
#sleep 5;
echo exit
) | telnet mx01.t-online.de 25 >> protokoll_t-online.txt
Funktionieren bei allen getesteten Servern (mx01.t-online.de und mx00.kundenserver.de) bis Zeile 'telnet -a . . . '
befinden sich dann immer noch in Telnet-Shell haben aber offensichtlich probs mit den Zeilenumbrüchen
man kann die Telnet-Shell dann sogar noch manuell weiterverwenden.

Linux version 3.16.0-4-amd64 (debian-kernel@lists.debian.org) (gcc version 4.8.4 (Debian 4.8.4-1) ) #1 SMP Debian 3.16.51-3 (2017-12-13)
telnet 0.17-36

Hat jemand eine Idee was falsch läuft?

MFG Noah's Raven
 

GwenDragon

Registered User
Eben mal den Server mit einer Masse von SMTP-Kommandos zudreschen ist nicht die Art und Weise wie SMTP kunktioniert. Sowas machen nur Spambots so.
Ein Protokoll beim Nachrichtentransfer besteht aus dem Senden von Befehlen und Empfangen von Statusmeldungen.
Lies doch einfach mal die Standards dazu. http://www.rfc-base.org/txt/rfc-2821.txt

Woher nimmst du die Erkenntnis, dass nach
HELO [Hostname meines Mailservers]
oder
MAIL FROM:<Absende-Adresse>
oder
RCPT TO:<Empfangs-Adresse>
nicht schon der Server eine (Fehler-)Meldung zurück gibt?
Du prüfst das ja nicht wenn du nur was rauspustest!
 
Last edited by a moderator:

NoahsRaven

New Member
Hi,

naja wenn ich die Befehle in der Telnet-shell einzeln eingebe kommen schon Meldungen zurück.
Eben die 250 ...ok - Meldungen.
Da komme ich sogar bis zum Absenden einer E-Mail mit Text.
Versuche ich es am selben Server mit derselben E-Mail-Adresse im Script funktioniert es nicht.
Selbst wenn ich wie in Version 3 Pausen zum warten einfüge.
Aber ich werde mich erst mal um die Fehlermeldung kümmern die Gmail ausgibt.
kann sein das das der Schlüssel ist, weil auch Gmail funxt bei Einzeleingaben aber nicht im Script.
 

GwenDragon

Registered User
Du musst die Befehle zeilenweise senden und einlesen, ob es eine Status-/Fehlermeldung gibt, auf die du reagieren musst -- So wie jeder Client das auch macht.
Statusmeldungen stehen in der genannten RFC von SMTP.

Wenn du es mit telnet oder nc machen musst, ok.
Ansonsten gibt es für Python, PHP oder Perl nette fertige Module, die das einfacher machen.
 
Last edited by a moderator:

NoahsRaven

New Member
Ich muss es nicht per Shell/Telnet/Netcat machen.
Nur verstehe ich von den anderen Scriptsprachen noch weniger als davon.
Ich habe mir da ein paar Beispiele schon angeschaut und einfach nix verstanden, daher lasse ich die Finger davon.
(aber wenn du Empfehlungen hast ...)

Die Seite die du vorgeschlagen hast habe ich im Rahmen meiner Suche zum Gmail-Fehler ('451 4.5.0 SMTP protocol violation, see RFC 2821 k44-v6si1051607wre.219 - gsmtp') auch schon gefunden.

Es scheint als meckere Gmail über meinen Hostnamen.
Ich habe zwar PTR und SPF gesetzt aber soeben gemerkt das mein Server immer noch localhost.localdomain zurückgibt wenn man ne Rückfrage per Telnet macht.
Ich denke mal dort und/oder in ein paar anderen Kleinigkeiten die ich in RFC 2821 nicht beachtet habe liegt der Schlüssel. (auch für die anderen Server)
 

danton

Debian User
Du sendest mehrere SMTP-Befehle in einem Rutsch, ohne auf die Rückmeldung des Servers zu warten - und das ist ein Verstoss gegen das SMTP-Protokoll. Wie es Gwen oben schon schrieb, mußt du nach jeder Zeile, die du an den Server sendest, abwarten, was er darauf antwortet, bevor du den nächsten Befehl sendest. Also nicht einfach drauf los feuern, ohne zu beachten, was der Mailserver dir mitteilt...
 

GwenDragon

Registered User
Dein Server ist localhost.localdomain? Kein Wunder, dass dich manche Maislerver abweisen. Das ist kein gültiger Fully Qualified Domainname (FQDN) im Sinne von deren Spamfiltern.

Setze den Hostname richtig (auch für boot und in /etc/hostname) und gut ist. Siehe man hostname.
Sollte dein rechner per DHCP einen bekommen, musst du das ändern.
 

NoahsRaven

New Member
Ok, danke erstmal an euch beiden.

dazu habe ich dann aber noch 2 Fragen:

1. lt. https://de.wikipedia.org/wiki/Fully-Qualified_Host_Name
müsste ich, wenn mein FQDN 'test.meine-domain.de.' ist, bei meinem server nur 'test' als Hostnamen in /etc/hostname eintragen.
Dies ist nicht korrekt oder? Es sollte doch wohl immer noch 'test.meine-domain.de.' lauten, oder?

2. ich habe mir den Telnet Befehl mal angeschaut
Telnet hat keinen eigenen Warte-Befehl, oder?
Muss ich das also wirklich so lösen wie in Version 3?
 
Wenn es unbedingt die Holzhammermethode sein muss, nimm wenigstens "expect" o.ä. mit dem man eine grundlegende Logik implementieren kann.
 

danton

Debian User
1. lt. https://de.wikipedia.org/wiki/Fully-Qualified_Host_Name
müsste ich, wenn mein FQDN 'test.meine-domain.de.' ist, bei meinem server nur 'test' als Hostnamen in /etc/hostname eintragen.
Dies ist nicht korrekt oder? Es sollte doch wohl immer noch 'test.meine-domain.de.' lauten, oder?

Der Hostname ist nur Teil des FQDN, der FQDN setzt sich aus Hostname (in deinem Beispiel test) und Domain (im Beispiel meine-domain.de) zusammen. Innerhalb einer Domain müssen Hostnamen logischerweise eindeutig sein, d.h. jeder Server bekommt einen anderen Namen. In /etc/hostname kommt also test rein - die Datei heist nicht umsonst hostname. Dieser FQDN gehört übrigens auch in den PTR-Record deiner IP und es muß auch ein A-Record existieren, der aus diesem FQDN wieder die IP auflöst.
 

DeaD_EyE

Blog Benutzer
Stackoverflow hat meistens Antworten parat.

https://stackoverflow.com/questions/22233848/how-to-verify-an-email-address-in-python-using-smtplib

Den Code hab ich mal ein bisschen abgeändert und den regexcheck entfernt, ob es sich um eine gültige E-Mail handelt.

Code:
#/usr/bin/python3

import sys
import socket
import smtplib
import DNS as dns
# pip3 install --user py3dns
# oder besser
# python3 -m venv ~/pyenv
# source ~/pyenv/bin/activate
# pip install py3dns
#
# danach für den Start:
# source ~/pyenv/bin/activate
# python ~/path/to/script


me = 'me@domain.com'
email_address = sys.stdin.read().strip() # liest von stdin
domain_name = email_address.split('@')[1]
records = dns.mxlookup(domain_name)
mxRecord = records[0][1]
host = socket.gethostname()
server = smtplib.SMTP()
server.set_debuglevel(0)


try:
    server.connect(mxRecord)
    server.ehlo()
    server.mail(me)
    code, message = server.rcpt(email_address)
    server.quit()
except smtplib.SMTPServerDisconnected:
    # Server hat die Verbindung einfach beendet. z.B. weil die IP geblacklisted ist.
    print('N')
    sys.exit(1)
except Exception as e:
    print('Exception:', e)
    # hier weitere exceptions abfangen und entsprechend reagieren
    


# Assume 250 as Success
if code == 250:
    print('Y')
    sys.exit(0)
else:
    print('N')
    sys.exit(1)

Es müssten noch weitere Exceptions abgefangen werden.
Dann steht noch die Frage im Raum, wann ist helo und wann ist ehlo zu nutzen. Braucht man für die Abfrage eine tls session?

Was mir auch noch aufgefallen ist, dass Mailprovider gerne dynamische IP Adressen blocken. Generell halte ich die Abfrage ob eine E-Mail Adresse existiert für sehr fehlerhaft. Du wirst sicherlich einige false negatives bekommen.

Das sieht dann so aus:
Code:
andre@andre-GP70-2PE:~$ echo "andre334@gmx.de" | python3 check_mail.py 
N

Die Adresse gibt es und die Abfrage ist nicht erfolgreich, da meine IP Adresse geblockt ist. Also ein false negative.
Mit meiner gmail Adresse geht es. Ich hab bis jetzt aber keine andere Adresse gefunden, mit der es klappt.
 
Last edited by a moderator:

NoahsRaven

New Member
Vielen Dank erst mal für die Unterstützung

@killerbees19 expect ist mir bei meiner Suche auch schon untergekommen.
Habe es aber erst mal ignoriert weil ich es unter, in Tutorials angebenen, Pfaden wie /usr/local/bin/expect nicht fand
inzwischen weis ich das ich es nachinstallieren musste und unter /usr/bin/expect finde.
habe jetzt auch schon ne viel versprechende Seite dazu gefunden: https://petervibert.com/wp/expect-smtp-script/

@danton alles erledigt(PTR, A-Record und SPF hatte ich ja schon vorher),
habe zwischenzeitlich herausgefunden das ich den Hostnamen im postfix zusätzlich ändern muss damit beim Ansprechen per telnet nicht localhost.localdomain da steht.

@DeaD_EyE danke für den Tipp.
Ob ich jetzt wirklich auf eine andere Programmiersprache umsteige muss ich aber erst noch sehen.
Wie gesagt von php, perl, python etc. habe ich noch weniger Plan.
Und derzeit stehe ich deinem Vorschlag wie ein Ochs vorm neuen Tor.
Ixch werde mir das von Stackoverflow mal reinziehen.

So jetzt habe ich erst mal ne Menge zu tun.

MFG Noah's Raven
 

GwenDragon

Registered User
@NoahsRaven Du wirst übrigens mit deinem Bash-Skript bei manchen Servern auf die Nase fallen, weil das Greylisting dich erst mal (weil unbekannt) abweist und du dann soundsoviel Minuten warten musst -- das ist bei manchen SMTP-Servern eine Anti-Spam-Maßnahme.
 
Top