SFTP aus IP-Symcon zu einem IONOS-Server

@paresy Hallo zusammen,

zunächst auf diesem Weg einen guten Start in ein gesundes und erfolgreiches neues Jahr.

Ich möchte gerne aus einem Symcon-Script per SFTP eine Datei zu einem IONOS-Server übertragen. FTP funktioniert leider nicht mehr, da IONOS etwas geändert hat.

PHP benötigt dazu eine Library:

use phpseclib\Net\SFTP;

$sftp = new SFTP($host, 22);

if (!$sftp->login($user, $pass)) {

echo "sucess";

}

Kann mir jemand einen Tipp geben wie und wo ich diese in der SymBox ablegen muss?

Viele Grüße aus dem eiskalten Unterallgäu

Harry :man_raising_hand:t3:

Hi Harry,

im Prinzip geht das fast überall. Ich würde es aber vermutlich unter /var/lib/symcon/scripts/phpseclib machen. Dann hast du die auch im Backup mit drin.

paresy

@paresy Danke für den Tipp - werde ich versuchen und berichten.

Und sonst gehts gut? Warst Du über die Feiertage in Bayern?

Gruß

Harry

Ich habe das Verzeichnis nach “/mnt/data/symcon/scripts/phpseclib” kopiert.

Dann das Script:

use phpseclib\Net\SFTP;

// SFTP-Credentials
$host = "paperlesspaper.harrykellner.de";
$user = "p123456789";
$pass = "​**********";

$sftp = new SFTP($host);
$sftp->login($user, $pass);

Es kommt folgende Fehlermeldung in der Zeile

$sftp = new SFTP($host);

Fatal error: Uncaught Error: Class "phpseclib\Net\SFTP" not found in /mnt/data/symcon/scripts/21662.ips.php:21
Stack trace:
#0 {main}
  thrown in /mnt/data/symcon/scripts/21662.ips.php on line 21

Ich finde meinen Fehler leider nicht - Hilfe.

In diversen Anleitungen wird immer von einem Composer gesprochen. Muss ich den auch noch auf der SymBox installieren?

Du musst noch die PHP Dateien per Include reinholen die du brauchst.

Composer geht auch, ist aber ein wenig anders und sinnvoller, wenn du mehrere Bibliotheken brauchst. Der klassische manuell Weg geht auch.

paresy

Die phpseclib besteht aus diversen Dateien und Klassen.
Ich nutze dafür einen autoloader, welchen du eventuell für dich abwandeln kannst ($LibPath anpassen).

@paresy Danke, ich dachte durch den use-Befehl wird alles eingebunden. Ich werde das weiter ausprobieren.

Viele Grüße aus dem Unterallgäu

Harry

@Nall-chan Danke für die schnellen Tipps. Ich werde das auch ausprobieren.

Viele Grüße aus dem Unterallgäu

Harry

@Nall-chan

Hallo Michael,

das Modul SSH-Client läuft (Danke dafür) und ein ‘ls’ liefert den Inhalt des Server-Verzeichnisses. :+1:t2:

Wie würde der Commando-String für einen Datei-Upload lauten? In der Doku habe ich kein passendes Beispiel gefunden. Etwas mit ‘cp’ für kopieren? Ich bin nicht so der Linux-Befehle-Spezialist. :grimacing:

Viele Grüße aus dem Unterallgäu

Harry

Das ist nur ein SSH Client. Damit kannst du nix hochladen.
Er nutzt aber die gleiche Library.
Für dein Script wäre der autoloader wichtig.
Da ich die SFTP Klasse nie benutzt habe, kann ich dir auch nicht sagen wie du damit etwas hochladen kannst.

Danke für die Info. :man_raising_hand:t3:

@paresy

Hallo Michael,

das mit include führt von einem Fehler zum nächsten. :slightly_frowning_face: Irgendwie ist in der phpseclib-Library eine Verwirrung mit den Verzeichnissen (phpseclib3 und phpseclib4) drin. Da komme ich nicht weiter. :frowning:

Das SSH-Client-Modul von Nall-chan kann leider keine Dateien hochladen, obwohl es in der SSH-Doku ein scp gibt? Auch mit der Syntax komme ich nicht klar. :frowning: Seinen autoloader-Tipp verstehe ich nicht, dafür bin ich zu wenig Informatiker.

Es muss doch einen Weg geben, aus einem IP-Symcon-Script eine JSON-Datei an einen Web-Server zu senden. :man_shrugging:t3:

Frustrierte Grüße aus dem Unterallgäu

Harry

Vermutlich hast du bei Github den Master Zweig genommen?
Benutze den Branch 3.0 oder 2.0.

Hat auch nie jemand behauptet. Ich weiß immer noch nicht wie du darauf kommst.

Welche Doku ist hier gemeint?

Probier dies mal aus. → phpseclib liegt bei mir unter scripts:

scripts/phpseclib/phpseclib

$AutoLoader = new AutoLoaderPHPSecLib('phpseclib');
$AutoLoader->register();

class AutoLoaderPHPSecLib
{
    private $namespace;

    public function __construct($namespace = null)
    {
        $this->namespace = $namespace;
    }

    public function register(): void
    {
        spl_autoload_register([$this, 'loadClass']);
    }

    public function loadClass($className): void
    {
        $LibPath = __DIR__ . DIRECTORY_SEPARATOR . 'phpseclib' . DIRECTORY_SEPARATOR;
        $file = $LibPath . str_replace(['\\', 'phpseclib3'], [DIRECTORY_SEPARATOR, 'phpseclib'], $className) . '.php';
        var_dump($file);
        if (file_exists($file)) {
            require_once $file;
        }
    }
}
$host = '';
$user = '';
$pass = '';

/** Entweder mit use */
use phpseclib3\Net\SFTP;
$sftp = new SFTP($host, 22);

/** Oder ganze Angabe der Klasse mit Namespace \phpseclib3\Net\  */
//$sftp = new \phpseclib3\Net\SFTP($host, 22);

@Nall-chan

Hallo Michael,

danke für Deine ausführlichen Erklärungen.

Ich habe nach SFTP und SSH gegoogelt und da werden verschiedene Befehle aufgezeigt.

ls, cd, mkdir usw. funktionieren - wahrscheinlich weil sich das lokal auf dem Server abspielt. U.a. wird auch cp und scp erwähnt und daher dachte ich das wären allgemeine SSH-Kommandos.

Das mit dem Master-Zweig ist tatsächlich so - mein Fehler! Ich werde den Branch 3.0 nochmals versuchen. In der Versionshistorie steht bei Master ja “Do not use in production” - habe ich natürlich überlesen. Sorry.

Viele Grüße aus dem Unterallgäu

Harry

Hallo Michael,

leider wieder der Class-not-found-Fehler. Die Verzeichnisstruktur scheint nicht zu passen.

Ich habe den Branch 3.0 benutzt und wie in Deinem Screenshot nach scripts/phpseclib/phpseclib kopiert. In den Codezeilen steht jedoch phpseclib3. Auch in den Files wird phpseclib3 genutzt? Oder korrigiert das die Autoloaderzeile?

Auch das ändern auf scripts/phpseclib/phpseclib3 funktioniert nicht.

Warum zwei Verzeichnisse phpseclib?

Gruß Harry

Weil das erste Verzeichnis das hier enthält:

Und ja, der namespace hat eine 3 am Ende, aber die Verzeichnisse nicht, das wird aber in der Klasse schon beachtet.

Ich hatte oben ein var_dump noch vergessen zu entfernen.
Das sollte eigentlich zeigen was versucht wird zu laden.

Prima - einen Schritt weiter - danke. Dieses Verzeichnis hatte ich nicht gefüllt.

Die Klasse wird jetzt geladen. Nun kann ich mich mit dem korrekten Login und dem Übertragen der Datei befassen. :+1:t2:

Nochmals vielen Dank für die schnelle Hilfe.

Ein schönes Wochenende und viele Grüße aus dem Unterallgäu

Harry

1 „Gefällt mir“

Hallo Michaels,

nach weiterem Kampf mit User und Passwort habe ich es endlich per SFTP geschafft eine JSON-Datei hochzuladen: paperlesspaper

// SFTP-Credentials
$host = "plp.harrykellner.de";
$user = "xxxxxxxxxx";
$pass = "**********";

$datei = "plp.json";

// Daten 
$data = array(
    'Temperatur1'         => GetValueFloat(12345),
    'Temperatur2'         => GetValueFloat(12346),
    'Luftfeuchtigkeit'    => GetValueInteger(12347),
    'Luftdruck'           => GetValueFloat(12348),
    'Tagesenergie'        => GetValueFloat(12349),
    'Batterieprozent'     => GetValueFloat(12340),
    'Timestamp'           => $time
);

// Daten ins JSON-Format bringen ...
$json = json_encode($data);

// ... und in einer Datei abspeichern
$number = file_put_contents($datei, $json);

// SFTP-Verbindung aufbauen ...
$sftp = new \phpseclib3\Net\SFTP($host);

if (!$sftp->login($user, $pass)) {
    IPS_LogMessage($_IPS['SELF'], "*** ".IPS_GetName($_IPS['SELF'])." - Skript #".$_IPS['SELF']. " *** SFTP Login fehlerhaft ***" );
}

// ... und Datei übertragen
$result = $sftp->put($datei, $json);

if ($result) {
    IPS_LogMessage($_IPS['SELF'], "*** ".IPS_GetName($_IPS['SELF'])." - Skript #".$_IPS['SELF']. " *** SFTP Datei-Upload erfolgreich ***" );
}

Nun geht es nur noch darum die richtigen Daten auszuwählen und das Ganze aufzuhübschen. Nochmals vielen Dank für Eure Unterstützung.

Viele Grüße aus dem Unterallgäu

Harry

2 „Gefällt mir“