fhem / fhem-docker

A basic Docker image for FHEM house automation system, based on Debian Linux.
https://fhem.de/
MIT License
84 stars 27 forks source link

sendemail fails - no TLS support on docker-minimal image #254

Open jmpmn-jr opened 4 months ago

jmpmn-jr commented 4 months ago

Describe the bug I use the fhem-docker minimal image and noticed that sending emails did not work anymore. sendemail returned NOTICE => Authentication not supported by the remote SMTP server!Jul 09 11:15:46 10035a7b7822 sendemail[23963]: ERROR => Received: 530 Authentication required

After checking on fhem cmd line i get the error ERROR => No TLS support! SendEmail can't load required libraries. (try installing Net::SSLeay and IO::Socket::SSL)

I tried to use TLS with TLS=auto (first case) and TLS=yes (2nd case)

To Reproduce Steps to reproduce the behavior:

  1. I use function DebianMail as described in https://wiki.fhem.de/wiki/E-Mail_senden in 99_myUtils.pm
  2. As described I tested with { DebianMail('adress@host.com','Test','Test-Text');; }
  3. Depending on the settings in sendemail line (-o tls=yes) I get the log message

Expected behavior I am not sure if the additional libraries should be included in the image or added individually

sidey79 commented 4 months ago

The requested modules are installed, but i guess, the sendemail command uses the system perl installation and not the installation for perl.

The different approaches to send some emails are ugly.

I think about, providing some functionality via a helper module.

There are good perl modules which should make this very simple. I only need something, which requests the module mentioned here: https://metacpan.org/pod/Email::Sender::Manual::QuickStart

jmpmn-jr commented 4 months ago

Hi,
Danke fürs reinschauen und den Kommentar. Kann ich was beitragen zum ausprobieren oder den Mail Versand auf einen anderen Sender umstellen?

Grüße

sidey79 commented 4 months ago

Ich könnte durchaus etwas Hilfe gebrauchen.

Ich habe das Paket Email::Stuffer identifiziert. Es wird aktuell gepflegt und scheint durchaus für unser Problem ein geeignetes Mittel zu sein.

Ich habe ein Image erzeugt, welches dieses Paket beinhaltet:

ghcr.io/fhem/fhem-minimal-docker:dev-issue254-bullseye

Um den Versand zu testen kann man folgende Funktion anlegen, diese funktioniert sehr ähnlich wie debianMail:

sub stufferMail
{
    use Email::Stuffer;

    my $rcpt = shift;
    my $subject = shift; 
    my $text = shift; 
    my $attach = shift; 
    my $ret = "";
    my $error;
    my $konto = getKeyValue("myEmailKonto"); 
    my $passwrd = getKeyValue("myEmailPasswrd"); 
    my $from = $konto; # or use different KeyValue if konto is not the from email address
    my $provider = "smtp.1und1.de:587"; # smtp.domain.tld:port see provider documentation
    Log 1, "sendEmail RCP: $rcpt";
    Log 1, "sendEmail Subject: $subject";
    Log 1, "sendEmail Text: $text";
    #Log 1, "sendEmail Anhang: $attach";
    if (not defined($attach)){$attach=''}

    #Email::Stuffer->new()->($from)
    #     ->transport('SMTP', { host => "$provider" });

    my ($host,$port) = split(/:/, $provider);
    Log 1, "sendEmail von $from über $host:$port an $rcpt";
    my $result = Email::Stuffer->from($from)
              ->to($rcpt)
              ->subject($subject)
              ->text_body($text)
              ->transport('SMTP', { host => $host, port => $port, sasl_username => qq[$from] , sasl_password => qq[$passwrd], debug => 1 , ssl => "starttls" } )
              ->send_or_die;

    $result;
}

Ich habe es bisher noch nicht geschafft mich am Mailserver des Providers zu authentifizieren.

sidey79 commented 4 months ago

OK habe es gerade geschafft. Die Funktion ist angepasst. Es wird die SSL Option nicht automatisch erkannt.

jmpmn-jr commented 4 months ago

Hi, danke fürs untersuchen. Ich habe testweise im Container die fehlenden Module nachinstalliert dann scheitert es aber an der Version von sendemail. Als andere Option hatte ich aus dem forum einen Weg mit curl gefunden, aber da kämpfe ich noch mit den Sonderzeichen. Ich probiere es morgen mal aus. Gruß

jmpmn-jr commented 4 months ago

Hi, ich habe heute morgen eine test Instanz erstellt und mit der vorgeschlagen Funktion getestet.
Erst klemmte es, aber ich habe vergessen den SMTP Server anzupassen. Problem war vor dem Schirm... Hat also auch funktioniert bei mir. Danke!

sidey79 commented 4 months ago

Danke, jetzt muss ich mal schauen wie man damit was "anständiges baut".

sidey79 commented 4 months ago

Ich habe noch ein wenig das Problem untersucht wenn man sendEmail wie folgt von der Kommandozeile aufruft, dann findet sendEmail auch die notwendigen Packages um startTLS machen zu können:

perl -I $PERL5LIB /usr/bin/sendEmail

Ich hänge jetzt an TLS setup failed: hostname verification failed

sidey79 commented 4 months ago

Ich denke, das ist ein Problem, das mit einer Inkompatibilität mit sendMail zusammen hängt. https://forum.fhem.de/index.php?topic=135178.0

Ich habe jetzt eine kleine Funktion, erstellt die die E-Mail mittels curl versendet. Die kann man recht einfach aus DebianMail heraus aufrufen:

return CurlMail(@_,$sender,$konto,$passwrd,$provider);

######## CurlMail -  Mail aus einem Container mittels curl  über ein SSL Verbindung versenden ############ 
sub CurlMail
{ 
 my $rcpt = shift;
 my $subject = shift; 
 my $text = shift; 
 my $sender = shift;
 my $konto = shift;
 my $passwrd = shift;
 my $provider = shift;

 Log 1, qq[CurlMail: RCP: $rcpt];
 Log 1, qq[CurlMail: Subject: $subject];
 Log 1, qq[CurlMail: Text: $text];

 my $ret;
 my $curl_command = qq[curl --no-progress-meter --ssl-reqd $provider --login-options AUTH=PLAIN --user "$konto:$passwrd" --mail-from "$sender" --mail-rcpt "$rcpt" --mail-rcpt-allowfails -H "Subject: $subject" -H "From: <$sender>" -F '=(;type=multipart/alternative' -F "=$text" -F "= <body>$text</body>;type=text/html" -F '=)']; 

 #$ret=qx(\$curl_command);

 open CURL, "$curl_command 2>&1 |" or die "Can't open curl $!\n";
 $ret = <CURL>;
 close CURL;

 #$ret =~ s,[\r\n]*,,g;    # remove CR from return-string 

 Log 1, qq[CurlMail: curl returned: $ret] if ($ret); 
}

Theoretisch könnte man man das sendMail script austauschen und von dort auch curl aufrufen, aber ich ahne, dass es wieder Probleme gibt :)

jmpmn-jr commented 4 months ago

Ich probiere das morgen mal aus. Ich hatte im Container auch die Pakete manuell nachinstallieren können und bin am der sendemail host Verifikation hängen geblieben. Es gibt wohl in ein korrigierten Paket, aber ich wusste nicht, wie ich das dauerhaft in den Container bekomme. Ich probiere die Lösung mit curl morgen mal aus. In der bash hatte das schon geklappt. In perl noch nicht wahrscheinlich weil ich falsch mit ' und " hantiert habe. Ich teste morgen und geb ne Rückmeldung. Wenn das hinhaut, könnte man den Weg gehen.

sidey79 commented 4 months ago

Die Pakete sind alle schon da. Es gibt Patches für Sendemail, ob es davon kommt oder dadurch gelöst wird weiss ich nicht, aber die Variante mittels curl funktioniert bei mir im V4 Image ohne irgendwas installieren zu müsste.

jmpmn-jr commented 4 months ago

Ich habe die jetzt das angepasste Perl-Script (was curl nutzt)im dev Container, aber auch mit dem aktuellen release container ausprobiert, also dem "produktiv" SBC. Beides klappte problemlos. Vielen Dank dafür. Ich habe nochmal ein bischen Forschung betrieben. SendEmail bzw sendemail ist ein Perl-wrapper script das schon ein paar Tage auf dem Buckel hat. Der Fix für die Hostname verification ist in einem neueren Paket zwar gepatcht worden, aber einen wirklichen Maintainer scheint es nicht mehr zu geben. Der Weg mit curl scheint mir zukunftsträchtiger, das wird noch eine Weile gepflegt werden :-)

Von daher könnte man die Lösung im Kommentar akzeptieren und müsste folglich am Container nichts anpassen.

Ich muss mal im fhem forum/wiki schauen, wem ich eine Aktualisierung des Wiki Artikels vorschlagen kann. Dann könnte man den auch in Richtung curl updaten. BTW, soll ich das Ticket hier mit close with comment schliessen?

sidey79 commented 4 months ago

Ich bin noch unschlüssig, wie ich mit sendEmail verfahre.

Aktuell ist es im Container installiert, aber Starttls funktioniert nicht, TLS geht, wenn die Parameter beim Aufruf angegeben werden.

Wenn also jemand von V3 auf V4 ein Update macht, bekommt er im Zweifelsfall nicht mit, dass der E-Mail Versand streikt. So ging es mir selbst auch, da ich alles noch per push Nachricht schicke, ist mir das fehlen der E-Mails nicht aufgefallen.

Ich könnte jetzt beim Starten des Containers in der 99_MyUtils suchen und Meldungen im Docker Log ausgeben. Ich könnte es auch in DockerImage Info einblenden.