meine "Cloud"

meine "Cloud"

meine selbstgebaute Cloud

Die Vorteile einer Cloud-Datensicherung sind wohl unbestritten. Mein Vertrauen in Cloud-Anbieter (speziell die aus "Übersee") ist allerdings begrenzt. Außerdem sind sie nicht so preiswert, wie meine selbst programmierte Lösung:

Für 120 GB Webspace mit FTP-Zugang zahle ich monatlich nur einen Euro. Dort findet sich also auch ausreichend Platz für meine "private Cloud", und weil ich für einen Mobilfunk-Vertrag mit 120 GB Highspeed-Volumen nur 12 Euro monatlich zahle, kann ich mir einen DSL- oder Glasfaser-Vertrag sparen.
Meine sicherungswürdigen Dateien, die alle in einem Verzeichnis meines PCs liegen, sichere ich verschlüsselt im Webspace.

Ich habe mich dabei für die Programmiersprache PYTHON entschieden, weil man unter allen (?) Betriebssystemen einen kostenlosen PYTHON-Interpreter findet. So habe ich von jedem meiner Geräte mit Internetzugang (und einem PYTHON-Interpreter!) Zugriff auf meine aktuellen Dateien.

Mit drei PYTHON-Skripten habe ich mir eine (bei Bedarf vollautomatische) Cloud-Datensicherung programmiert.
Ich ver- und entschlüssele (ausschließlich lokal !) mithilfe der "Fernet"-Bibliothek.
Bei Bedarf (oder zeitgesteuert) wird auf meinem PC das Upload-Skript gestartet. zuerst prüft dieses, ob seit der letzten Sicherung Dateien neu erstellt bzw. geändert wurden. Ggf. werden nur von diesen verschlüsselte Kopien  per FTP zu meinem Webspace übertragen.
Falls ich irgendwann eine im Webspace gesicherte Datei benötigen sollte, starte ich das Download-Skript und wähle die benötigte Datei aus. Das Entschlüsseln dieser Datei kann ich anschließend wiederum lokal mit dem Entschlüsselungs-Skript durchführen. 

So sieht z.B. mein Download-Skript aus:

Versucht erst mal, dieses Skript (s.u.) zum Laufen zu bringen. Wenn Ihr das geschafft habt, könnt Ihr mich bei Bedarf zum Thema Verschlüsselung kontaktieren.

Falls das Skript so nicht funktioniert, erwartet der Webspace-Anbieter offensichtlich ein abweichendes Anmelde-Verfahren beim FTP-Server.

#============================================================

import pathlib, os 
import ftplib
from ftplib import FTP_TLS
import time
from datetime import datetime, timezone
from datetime import timedelta

def s2z(ds):            # originalen Zeitstring aus DIR zu Zeit konvertieren
    if ds[9] == ":":    # Datumsangabe mit Zeit ohne Jahr = aktuelles Jahr
        ds = datetime.now().strftime("%Y") + " " + ds      
        z = datetime.strptime(ds,"%Y %b %d %H:%M")
    else:               # Datum ohne Zeit mit Jahr
        z = datetime.strptime(ds,"%b %d  %Y")
    return z

if __name__ == '__main__':
    ftps_server = "meinFTPserver.de"   # anpassen!
    ftps_user = "meinBenutzername"     # anpassen!
    ftps_pw = "meinFTPpasswort"        # anpassen!
    quell_verz = "//htdocs//wichtig//aes//"      # anpassen!
    ziel_verz = "C:/wichtig/aes/"                # anpassen!

    ftps = FTP_TLS(ftps_server)
    ftps.login(ftps_user, ftps_pw)
    ftps.prot_p()                     # Übertragung komplett verschlüsselt
    ftps.encoding = "utf-8"
    ftps.cwd(quell_verz)

    data1=[]
    data2=[]                          # nur für Dateien
    ftps.dir(data1.append)            # DIR in Liste einlesen
    print("=" * 50)
    print(quell_verz)
    print("=" * 50)
    
    i=0
    for x in data1:
        if x[0] == "-":        # nur wenn kein Verzeichnis
            data2.append(x)
            i = i + 1
            dateiname = x[56:]             # Dateiname
            date_time = s2z(x[43:55])      # Datum-Zeit aus originalem Datum-Zeit-String
            dzs = date_time.strftime(" %d.%m.%Y %H:%M ")      # zu neuem Datum-Zeit-String
            print(str(i).rjust(2), x[32:42], dzs, dateiname)
#                          Zähler    Größe  Dat-Zeit   Name
    print()
    k = int(input("für Download Nr. eingeben (0=Ende): "))

    if k < 1 or k > data2.__len__():
        print("Abbruch")
    else:
        os.chdir(ziel_verz)       # lokales Zielverz. setzen (sonst aktuelles Verz.)
        downd = (data2[k-1][56:].strip())  # ausgewählte Datei

        diff=0
        server_z = (date_time - datetime(1970, 1, 1)).total_seconds()
        print("Zeit remote: ", server_z)
        lokale_d = downd[:-4]         # lokal schon vorhanden ?
        print(lokale_d)
        try:
            lokale_z = os.path.getmtime(downd) # wann zuletzt geändert ?
            print("Zeit lokal ",lokale_z)
            diff = server_z - lokale_z  # wenn diff > 0, dann ist Serverdatei aktueller 
            print("Diff: ",diff)
        except:
            print(f"{downd} lokal noch nicht vorhanden")
            diff = 99
        if diff > 0:  # ok , Download
            with open(downd, "wb") as file:
                ftps.retrbinary(f"RETR " + downd, file.write)   # Download im binary mode
                print(f"{downd}  Download fertig, lokal entschlüsseln mit _aes_ent.py")
        else:
            print(f"{downd} - kein Download - lokale Datei ist aktueller")
    ftps.quit

#===========================================================================