Beiträge von sls

    Allerdings verstehe ich jetzt nicht wie Deiner Meinung nach der Aufbau sein soll. Doch so wie im ersten Ansatz? Wie kann ich da die RPi vom Homenetz separieren mit IPTables? Dazu muss doch ein Router mit IPTables dazwischen liegen :conf:

    Habe ich doch oben geschrieben. 1. Fritzbox -> 2.1 Router 2.2AP -> DMZ (Rpi), LAN (Sonstige Clients)

    Welche Access Points hast du denn im Einsatz? Warum Mesh? Weil die Fritzbox das anbietet und "Mesh" so fancy klingt? :)

    1. Fritzbox: dient nur noch als Modem und leitet alle Anfragen an den Router weiter (Passthrough, Router wird Exposed-Host)

    2.1 Router: Empfehlung ist hier Edgerouter oder eben Mikrotik Routerboard. Damit hast du die volle Flexibilität

    2.2 Access Point: WLAN Netz(e), am Edgerouter kannst du die Subnetze an logische WLAN-Interfaces anlegen, du kannst dann über deinen AP sogar die DMZ als WLAN ausbilden. Dazu dein LAN und ggf. noch ein Gast-WLAN. Oder IoT.

    Das war ja genau mein Problem bei dem ersten Ansatz :) Deshalb habe ich es ja umgedreht: Die WLAN Clients sind im FB Homenetz zusammen mit den anderen HomeSystemen und die RPi haengt in einem eigenen Subnetz welches keinen Zugriff auf das Homenetz hat.

    Ich habe mich nur auf die linke Version deiner Skizze bezogen, weil die rechte Seite vom Netzwerk-Design noch kaputter ist.

    Der Router hängt dort ja dann nur zum Selbstzweck am LAN-Netz.

    Wenn du dir das zutraust und Sicher im Umgang mit IPTables bist, würde ich das mit dem Edgerouter umsetzen. Du kannst hier natürlich auch erstmal Das Management-Netz (also das Fritzbox-Lan) so weiter verwenden und PAT auf Fritzbox aktiviert lassen. Du konfigurierst den Edgerouter dann auch mit Src-Nat, und es spielt überhaupt keine Rolle wie oft du hier "NAT'test". Wenn die Fritzbox in späteren Migrationsschritten dann nur noch die PPPoE-Aushandlung macht, kannst du das PAT hier auflösen.

    framp: man kann es auch unnötig kompliziert machen :)

    Ich verstehe nicht was du mit dem WLAN an der DMZ willst. Die WLAN-Clients gehören in ein eigenes Netz (oder ins Lan-Netz, je nach dem). Sinn der DMZ ist nicht dass du dort auch noch Clients betreibst, die dir auch alle Hops gehen wenn jemand den Pi kompromitiert.

    Der Connection State der Verbindung vom Client aus einem anderen Subnetz zur DMZ wäre dann in Iptables-Sprech "related, established". Beim Edgerouter lassen sich solche dedizierte Regeln mit den jeweiligen Ziel oder Ursprungs-Interfaces oder Adressen ebenso einrichten. Hier steht dir ein vollwertiger Packet Filter zur Verfügung.

    Ich würde das wohl eher so bauen: Fritzbox in Passthrough (Exposed Host auf Edgerouter)-> Edgerouter (Firewall, Netzsegmentierung) -> DMZ, LAN (WLAN mittels Access Point, vergiss den AVM-Krempel).

    Doppel NAT ist nicht besonders schoen.

    Die wuerde dann nur noch Modem und Telefonfunktion haben wenn ich eine FW dahinter setze.

    Was imho völlig ok ist, lieber würde ich eine eigene Whitelisting Firewall mit dem Edgerouter o.ä. konfigurieren, als diesen AVM-Geräten zu trauen. Da weiß man ja auch nicht so recht was die machen, welche Ports dann plötzlich für irgendwelche Dienste offen sind, usw. usf.

    Und was genau ist am PAT zwischen den beiden Hops "nicht so schön"? ;)

    Zitat

    Auf dieser Seite sind ein paar FWs getestet worden. Preislich liegen die um die €500 was mir fuer den Zweck zu viel ist. Maximal sind €200 drin. Falls jemand eine FW in dieser Preisklasse empfehlen kann wuerde ich den Weg mit der FW gehen. Ansonsten muss ich wohl die Doppelnatter schlucken

    Das von Der_Imperator skizzierte Setup ist relativ straightforward und habe ich so ähnlich mit einem Mikrotik Routerboard im Einsatz. In einem anderen Setup habe ich den Edgerouter im Einsatz, sind auch relativ brauchbar.

    Man kann das m.E. schon mit einer eigenen Implementierung und sockets versuchen, da muss halt ein Protokoll her dass sowohl die Text- als auch Bilddateien erkennt und eine saubere Kommunikation gewährleistet.

    HTTP eignet sich übrigens nicht besonders gut zum Austauschen von größeren Dateien. Besonders nicht in REST.

    Wie kann ich denn anstelle von Text Dateien wie zum Bilder übergeben? Mit welcher Funktion kann ich Bilder oder ganz allgemein ausgedrückt, Dateien einlesen und dann versenden?

    Bilddateien liegen auf deinem PC bereits als Binärdaten vor. Du kannst diese in Python als solche mit dem with-Statement einlesen und dann über einen TCP-Socket versenden. Da bei der Übertragung über das Netwerk und Sockets, besonders größerer Dateien, Fragmentierung der Daten vorgenommen wird, musst du dich dann halt um einen geeigneten Mechanismus kümmern der dem Client vermittelt, ab wann der Datenstrom für eine Bilddatei vollständig ist.

    Um es kurz zu machen: nimm' eine fertige Bibliothek.

    journalctl -f gibt einen Fehler für die dritte Zeile der Regel aus: Invalid key/value pair

    Dann passt die Syntax der Regel nicht, versuch' mal:

    Code
    ACTION=="add", RUN+="/etc/udev/scripts/start-move-usb-data.sh $env{ID_FS_UUID}"

    Du musst dann allerdings auch dein Bash-Skript anpassen, wenn du die UUID verwenden willst:

    Code
    echo mount /dev/disk/by-uuid/$ID_FS_UUID /media/pi/$ID_FS_UUID | at now

    Ich habe die Rechte der Scripte neu gesetzt und konnte nun zumindest erreichen, dass ein Script "Test" in eine Logfile schreibt, sobald ein USB-Stick eingesteckt wird. Die Udev-Regel funktioniert also. $ID_FS_LABEL, bzw. $1 werden in den Scripten aber allen Anschein nach nicht zugeordnet. Hier nochmal Tipps?

    Kannst du mal folgendes testen:

    Code
    udevadm monitor --env

    Wenn du den USB-Stick einsteckst, sollten hier nun sämtliche Label erscheinen. Wird ID_FS_LABEL hier auch angezeigt?

    ERGÄNZUNG: das Problem ist, dass du das ID_FS_LABEL über die udev-Regel nicht an dein Bash-Skript weiterreichst.

    Hier hatte ich ja gezeigt, wie man das in der udev-Regel macht:

    Code
    ACTION=="add", RUN+="/etc/udev/scripts/start-move-usb-data.sh '%E{ID_FS_LABEL}'"

    start-move-usb-data.sh muss diesen Übergabeparameter dann natürlich setzen:

    Bash
    #!/bin/bash
    ID_FS_LABEL=$1
    echo $0: $ID_FS_LABEL>>/tmp/script.log
    [...]

    Liegt es am Script, dass die Ausführung nicht gelngt, oder an der rules, die das Script nicht ausführen kann? Es muss die Regel sein, da das unabhängig aufgerufen läuft.

    udev erkennt das Event dass du einen USB-Stick, oder was auch immer, einsteckst, und führt dann dein Bash-Skript aus. Das siehst du im logfile. Die logzeile verrät dir aber auch, dass udev in ein Timeout läuft, weil irgendwas in deinem Bashskript nicht funktioniert, oder zu lange brauch um eine Rückmeldung an udev zu geben. Das ist wichtig, da udev sonst für immer blockiert und alle weiteren Aktionen nicht mehr ausführen kann.

    Warum dein Bash-Skript nun nicht funktioniert, kann verschiedene Gründe haben. Zum einen sollte man blockierende Operationen nicht mit udev ausführen. Das kann man in der Shell umgehen, indem man Prozesse im Hintergrund ausführen lässt. Üblicherweise macht man das mit einem &-Zeichen hinter dem Befehl, z.b.:

    Code
    ping google.com &

    Hier werden zwar die einzelnen Antworten auf der Kommandozeile angezeigt, du könntest aber beliebige andere Prozesse in der selben Shell ausführen, was ohne dem &-Zeichen nicht ginge.

    Für Raspbian* gibt es noch das at-Package. Das macht wohl etwas ähnliches, und du verwendest es ja in deinem ersten Skript "start_move_usb_data.sh":

    Bash
    #!/bin/bash
    echo $0: $ID_FS_LABEL>>/tmp/script.log
    if [ -z "$ID_FS_LABEL" ]
    then
    exit 0
    fi 
    mkdir -p /media/pi/$ID_FS_LABEL
    echo mount /dev/disk/by-label/$ID_FS_LABEL /media/pi/$ID_FS_LABEL
    echo mount /dev/disk/by-label/$ID_FS_LABEL /media/pi/$ID_FS_LABEL | at now
    echo /home/pi/data/move-usb-data.sh $ID_FS_LABEL | at now

    Hier jeweils in Zeile 9 und 10. In Zeile 8 machst du das gleiche wie in Zeile 9 jedoch blockierend! Macht keinen Sinn.

    Der erste Schritt ist also, bevor du irgendwas anderes herumprobierst, Zeile 8 loszuwerden:

    Bash
    #!/bin/bash
    echo $0: $ID_FS_LABEL>>/tmp/script.log
    if [ -z "$ID_FS_LABEL" ]
    then
    exit 0
    fi 
    mkdir -p /media/pi/$ID_FS_LABEL
    echo mount /dev/disk/by-label/$ID_FS_LABEL /media/pi/$ID_FS_LABEL | at now
    echo /home/pi/data/move-usb-data.sh $ID_FS_LABEL | at now

    Wenn du das Skript modifiziert hast, starte dein System direkt mal durch. In POSIX soll das zwar alles immer out-of-the-box funktionieren, ich würde mich aber bei diesen ganzen schrottigen Derivaten nicht darauf verlassen :)

    Anschließend sehen wir weiter.

    Um die Scripte geht es mir noch gar nicht. Ich möchte zunächst, dass überhaupt ein Script beim Einstecken ausgeführt wird. Selbst ein Script mit "echo test" wird nicht gestartet.

    Du hast doch ein paar Beiträge vorher selbst geschrieben dass udev in ein timeout läuft, siehe logzeile. Die Regel greift, das Skript wird ausgeführt, blockiert aber und läuft in ein timeout.

    Ergänzung: du willst mit `at now` was erreichen, wenn du eine Zeile drüber udev offensichtlich nicht bewahrst dass die Routine blockiert?

    In deinem Script oben, warum einmal mit at now, einmal ohne?

    Code
    echo mount /dev/disk/by-label/$ID_FS_LABEL /media/pi/$ID_FS_LABEL
    echo mount /dev/disk/by-label/$ID_FS_LABEL /media/pi/$ID_FS_LABEL | at now

    Auch kritisch ist, dass du in einem Script ein weiteres Script aufrufst. Das ganze über udev ist nicht robust und du läufst in merkwürdige Fehler, wie du aktuell siehst. Versuch's lieber über eine systemd-unit. Du kannst dir auch ganz schnell dein System mit dem herumgefrickel zerlegen.

    Wenn du jetzt abschließend noch (unsauber) lösen möchtest, versuche mal alles in ein Script zu packen.

    Und dein Skript?

    Code
    ls -lart /etc/udev/scripts/

    Dann noch udev_log anpassen, die Datei findet sich unter /etc/udev/udev.conf:

    Code
    udev_log=debug
    #children_max=
    #exec_delay=
    #event_timeout=180
    #timeout_signal=SIGKILL
    #resolve_names=early

    Hier die Zeile "udev_log" auskommentieren und am besten auf debug setzen, anschließend udev neustarten und ins log schauen, es wird dann mehr ausgegeben.

    Dennoch stellt sich zunächst das Problem, dass die udev-Regel das Script gar nicht erst auslöst. Wieso nicht?

    Es ist schwierig dir zu helfen, wenn du nicht die genauen Befehle hier hinschreibst und die korrespondieren (Fehler-)Meldungen, sondern immer ein "bash /etc/irgendwas/..."

    Udev ist nicht so designed dass du einfach irgendeinen Pfad zu einem Script hinwirfst in der Hoffnung es würde dann schon ausgeführt. In dem Artikel steht beschrieben wie man udev-debugging aktiviert, damit du in der Logging-Facility deiner Wahl (vermutlich journalctl -f) prüfen kannst, was udev auf deinem System macht. Dort siehst du alle Regeln die udev lädt, was passiert wenn du neue Blockgeräte ein- und aussteckst, ob udev irgendwelche Fehler meldet.

    Daher nochmal die Frage(n):

    In separatem Fenster log prüfen:

    Code
    sudo journalctl -f

    Was passiert wenn du:

    Code
    sudo udevadm control --reload
    sudo udevadm trigger

    eingibst?

    Wie ist die Ausgabe von:

    Code
    ls -lart /etc/udev/rules.d/

    Welchen Kernel verwendest du?

    Code
    uname -r

    Welche systemd-Version?

    Code
    systemctl --version


    Wenn alle Stricke reißen kannst du auch eine systemd-unit schreiben die mittels udev getriggert wird.