Fablock-Zugang per RFID

Bereits seit einiger Zeit haben wir uns damit auseinandergesetzt, den Zugang zum Fablab auch für diejenigen zu ermöglichen, die kein Telegram benutzen können oder wollen. Wie bereits bei der letzten Vereinssitzung erwähnt wurde, haben wir dafür Zugang mittels RFID-Tags bzw. -Karten gewählt.

Benutzungshinweise:

Zunächst muss ein entsprechender RFID-Tag eingerichtet werden, dies können alle Admins der Telegram-Gruppe fürs Fablock. (dazu siehe nächster Abschnitt)

Grundsätzlich ist darauf zu achten, dass die Tags kopiert werden können. Insbesondere ist es möglich die Tags aus einem gewissen Abstand (bis zu einigen Metern) auszulesen und so eine Kopie zu erstellen, wenn keine Schutzvorkehrungen getroffen werden. Dies kann dazu führen, dass sich jemand anderes gegenüber dem Lesegerät als du ausgibt.

Sollte ein Tag verloren gehen, sorge dafür, dass ein Admin dein Token sperrt. Dazu kannst du z. B. ein Mitglied kontaktieren, das Telegram-Zugang hat und die Nachricht entsprechend weitergeben kann. Im Zweifel wendest du dich an ein Vorstandsmitglied.

Das Lesegerät befindet sich am Küchenfenster (rechts von der Laterne). Das Lesegerät ist bereit, wenn die blaue LED dauerhaft leuchtet. Sollte die LED aus sein, ist das Lesegerät gesperrt oder gestört und kann gerade nicht verwendet werden.

Um das Fablock zu bedienen, muss der Tag an das Lesegerät gehalten werden. Mitunter kann es einige Sekunden dauern, bis der Tag gelesen wird. Dass der Tag gelesen wurde, erkennt man am Zustand der blauen LED. Nach dem Lesevorgang erlischt die LED zunächst.

Wurde der RFID-Tag als gültig erkannt, beginnt die LED zu blinken und das Fablock wird ausgelöst. In diesem Fall also vor zum Fenster des Community-Raums gehen und den Schlüssel nehmen.

Ist der Tag unbekannt, abgelaufen oder gesperrt, bleibt die LED aus. Der Leser kann erst wieder benutzt werden, wenn die LED wieder leuchtet. Mit jedem gescheiterten Leseversuch verlängert sich die Wartezeit. Dies dient als Schutzmechanismus, wenn jemand sich mit einem gefälschten Tag Zutritt verschaffen will.

Verwalten von Tags:

Über den Bot können die bestehenden Tags eingesehen und verwaltet werden. Die folgenden Telegram-Befehle stehen nur für Gruppen-Admins zur Verfügung:

  • /rfid_cards zeigt eine Liste aller bestehenden Tags mit ID, Name und Ablaufdatum
  • /rfid_create <ablaufdatum> <name> erstellt bzw. provisioniert einen neuen Tag
    • Nutzer*innen sind auf die Benutzungshinweise oben, insbes. auf die Gefahr des Klonens hinzuweisen. Wessen Tag verwendet wurde, steht im Zweifelsfall in der Telegram-Gruppe.
    • Beim Erstellen wird der Bot dazu auffordern, den Tag an das Lesegerät zu halten, da der Tag mit Daten beschrieben wird. Der Befehl sollte also nur genutzt werden, wenn man sich gerade im Lab aufhält.
    • Wird innerhalb 1 min kein Tag gelesen, wird der Befehl abgebrochen.
    • <ablaufdatum> ist entweder ein Datum im Format YYYY-MM-DD (ISO 8601) oder never (Tag soll nie ablaufen)
  • /rfid_expiry <id> <ablaufdatum> ändert oder entfernt das Ablaufdatum eines Tags
    • <ablaufdatum> ist entweder ein Datum im Format YYYY-MM-DD (ISO 8601) oder never (Tag soll nie ablaufen)
    • Das Ablaufdatum kann in der Vergangenheit liegen. So kann eine Karte temporär gesperrt werden.
  • /rfid_revoke <id> löscht einen Tag und damit dessen Zugangsberechtigung dauerhaft
    • <id> ist die ID, welche von /rfid_cards ausgegeben wird
    • für temporäre Sperren /rfid_expiry mit Ablaufdatum in der Vergangenheit verwenden (s. o.)
    • Der Tag kann nur wieder Zugangsberechtigung erhalten, indem er erneut über rfid_create eingerichtet wird. Dazu muss der Tag also ggf. wieder ins Fablab gebracht und von einem Admin eingerichtet werden.
  • /rfid_toggle sperrt oder entsperrt das gesamte Lesegerät.
    • Das Lesegerät teilt als Antwort auf den Befehl den aktuellen Zustand mit (ge- oder entsperrt)
    • Ist das Lesegerät gesperrt, ist ein Zugang per RFID-Tag nicht möglich.
    • Dies ist nur für Notfälle vorgesehen, z. b. wenn der Leser viele fehlgeschlagene Versuche meldet und gerade nicht nachgesehen werden kann, was los ist.
    • Beim erneuten Einschalten wird die Wartezeit zwischen fehlgeschlagenen Versuchen auf Null zurückgesetzt und der Leser kann sofort wieder benutzt werden.

Die unbenutzten Tags und Karten werden im Regal in der Küche in der Kiste mit der Aufschrift „Funk/RFID“ aufbewahrt. (TODO: Aufschrift der Kiste ist eventuell eine leicht andere?) Müssen neue Tags beschafft werden, müssen diese kompatibel zu MIFARE Classic (13,56 MHz) sein.

Projektbericht

Während des Projekts gab es verschiedene Rückschläge, für die wir aber Lösungen gefunden haben. Im folgenden ein kurzer Abriss:

Nachdem die Software für den RFID-Leser soweit funktionierte, mussten wir feststellen, dass das Fensterglas des Fensters am Community-Raum, an dem auch das bisherige Fablock angebracht ist, zu dick für den RFID-Leser ist. Wird der Leser auf der Innenseite des Fensters angebracht, können Tags nicht mehr gelesen werden.

Da die Fenster in anderen Räumen dünner sind, haben wir als alternative Lösung identifiziert, einen zweiten Raspberry Pi an einem anderen Fenster anzubringen. Dafür schien die Küche am besten geeignet.

Da es nun zwei Raspberry Pis gab, mussten diese mit einander kommunizieren, um die vollständige Funktionalität abzubilden. Es erschien zunächst am einfachsten, dass ein zweiter Telegram-Bot eingerichtet wird, welcher dann von sich aus den entsprechenden Befehl an den bestehenden Telegram-Bot sendet. Nachdem die Entwicklung abgeschlossen war und der zweite Bot funktionierte, stellte sich allerdings die Erkenntnis ein, dass die Telegram-API es grundsätzlich nicht zulässt, dass Bots gegenseitig Nachrichten sehen können.

Also musste hier noch einmal ein etwas anderes Konzept gewählt werden. Als finale Lösung unterhalten sich die Skripte auf den beiden Raspberries nun per TCP-Verbindung im LAN. Gegenüber dem vorherigen Ansatz würde dies auch noch funktionieren, wenn das LAN zwar funktioniert, jedoch keine Internetverbindung aus dem Fablab mehr hergestellt wird.

Der zweite Telegram-Bot bleibt trotzdem erhalten, da in der Zwischenzeit festgestellt wurde, dass das Management der RFID-Tags am angenehmsten über Telegram zu lösen ist.

Schließlich wurde das Hardware-Setup noch etwas aufgeräumt. Erst war der zweite Raspberry Pi mit mehreren USB-Verlängerungen an eine Steckdose in der Küche angeschlossen. Damit gab es allerdings Probleme mit der Spannungsversorgung. Stattdessen wurde eine zusätzliche Steckdose montiert, was auch dafür sorgt, dass die Steckdose am Eingang der Küche nicht „dauerbelegt“ ist und weiterhin benutzt werden kann. Hierbei danke an André, Christopher und @ron.

Im Rahmen des Projekts wurde auch die Software des bestehenden Fablocks etwas aktualisiert und um die nötigen Zusatzfunktionen erweitet.

Am Projekt haben insbesondere auch @martinh und @Nanu mitgewirkt.

1 „Gefällt mir“

Der Bot zum Verwalten von RFID ist aber ein anderer als der aktuelle FabLockBot .?

Ja, da er auch auf dem anderen Raspberry Pi läuft. Der Bot lauscht aber in der gleichen Gruppe, muss man also eigentlich nicht drüber nachdenken.

1 „Gefällt mir“

Macht es Sinn eine „Step by Step“ Doku zu machen, falls das in zwei Jahren mal jemand nachbauen/ändern und. Nachvollziehen muss. Was genau gemacht wurde?

Das notwendige Setup für Hardware und Software ist hier dokumentiert: https://github.com/fablabcb/fablock/blob/master/RFID-companion/README.md

Und der Code selber befindet sich auch in dem Repository.

1 „Gefällt mir“

Ein unabhängiger Audit ist mir nicht bekannt und könnte ich natürlich selbst nicht durchführen. Wenn du das tun möchtest, wird dich sicherlich niemand aufhalten. Wenn es Fragen geben sollte, kann ich diese auch gern versuchen, zu beantworten.

Natürlich wurde nicht das Gäste-WLAN für die Verbindung genutzt. Sollte aber insofern das WLAN kompromittiert sein, könnte dies ggf. ein Problem darstellen, da die beiden Softwares sich über „rohes“ TCP unterhalten. Auch dann wäre es aber immer noch insofern unbedenklich, dass immer nur eine Verbindung gleichtzeitig bestehen kann, und in der Regel sollte die TCP-Verbindung dauerhaft bestehen.

Da alles gesagte im Quellcode nachvollzogen werden kann und insbesondere eine Dokumentation der Funktionalität sicherlich für alle Benutzer verfügbar sein sollte (soll heißen, nicht alle potenziellen RFID-Fablock-Benutzer müssen ein Discourse-Konto mit Zugangsbeschränkung haben), ist mir etwas unklar, was eine Zugangsbeschränkung hier bringen sollte.

Also wer alles den WLAN Schlüssel hat ist unbekannt :smiley:

Der Gäste-Schlüssel steht an der Wand. Sollte als Gäste-Wlan eingerichtet sein, auf dem TP Link. Was immer das im Sinne der Sicherheit heißt, hat bisher auch noch nie wer geprüft. Eventuell kann man damit auf alle Geräte im Netz zugreifen.

Es gibt außerdem noch den WLAN AP in der Küche. Da kenn ich die Konfig nicht, aber aber vermute man kommt auf das ganze Netzwerk.

Wenn wir hier noch mit VLAN arbeiten wollen etc. Dann müssen wir mal aufrüsten, bisher ist es einfach nur eine „Heimnetzwerk“ . Einfacher UMTs Router und switch … ja ok der noch PoE , wenn ich mich recht entsinne.

Wir können da gern mal richtig Geld ausgeben :wink:

EDIT:

Btw sollten TCP Verbindungen dauerhaft bestehen, allerdings ist es oft so, das ein Time-Out Mechanismus gibt, der Ressourcen von inaktiven Verbindungen freigibt. Das muss man meist aktiv ausschalten. (hab ich so im Hinterkopf)

Ja, deswegen wird auf beiden Seiten auf TCP-Ebene das Keepalive aktiviert: https://github.com/fablabcb/fablock/blob/69f9b83d967092484fba7d9509af4afb627e8af3/RFID-companion/tcp_client.py#L44-L48 (client) bzw. https://github.com/fablabcb/fablock/blob/69f9b83d967092484fba7d9509af4afb627e8af3/Software/tcp_server.py#L34-L38 (server)

Die beiden Skripte bauen beim Start eine normalerweise dauerhafte Verbindung auf (s.o.). Der „Server“ akzeptiert dabei immer nur 1 Verbindung. Sobald also die Verbindung hergestellt ist, kann keine weitere Verbindung hergestellt werden. Sofern ist, solange die Verbindung steht kein (weiterer) Zugriff möglich.

Die Verbindung wird über das existierende (interne) Netzwerk hergestellt, dass auch über das WLAN verfügbar ist.

Über die Verbindung wird der „Befehl“ zum Öffnen des Fensters übertragen bzw. geantwortet ob das erfolgreich war. Da die Nachricht an sich keine Information enthält, wäre die Verwendung von TLS zur Verschlüsselung nach meiner Einschätzung nicht besonders sinnvoll.

TLS könnte sicherlich trotzdem zur Authentifizierung der Verbindung verwendet werden, dann müsste man natürlich beide Seiten mit Zertifikaten ausstatten usw. Es gab grundsätzliche Überlegungen zum Thema Authentifizierung bzw. Verschlüsselung über die ich auch mit anderen gesprochen habe. Daraufhin wurde mir jedoch gesagt, dass davon auszugehen wäre, dass das verwendet WLAN sicher ist, und man müsse sich darüber keine Gedanken machen. Ich gebe zu, dass ich dazu auch kein besonders großes Interesse an eine Befassung mit mTLS in Python hatte/habe.

1 „Gefällt mir“

Wie gesagt war mein bisheriger Stand, dass davon auszugehen wäre, dass das bisherige Setup sicher ist. Ja sicherlich hätte ich das auch hinterfragen können, aber habe es aus Bequemlichkeit nicht getan, wie gesagt.

Wenn du dafür eine Lösungsidee hast, freue ich mich über einen Pull Request, Code oder einen Lösungsansatz. Sonst werde ich mir dann bei Gelegenheit eine Lösung dafür überlegen.

Wie gesagt bin ich nicht ganz sicher, ob wie bisher vorgeschlagen TLS die richtige Lösung ist, aber wahrscheinlich kommt es am Ende nicht so genau darauf an, wie effizient das Protokoll ist.

Python hat ja auch ein eingebautes TLS-Modul, insofern vielleicht doch wieder naheliegend. Wäre nur einmal Einrichtungsaufwand mit den Zertifikaten usw.

Ich werfe hier nochmal meinen an anderer Stelle schon mal mündlich formulierten (:wink:) Vorschlag in den Ring:

Könnte man vom RFID-Pi nicht einfach ein Shell-Script triggern, welches sich per SSH mit Key-Auth an dem Fablock-Pi anmeldet und dort ein Script ausführt, welches das Schloss in Bewegung setzt?

Durch SSH haben wir automatisch gleich sichere Authentifizierung. Die beiden Pis sind eh im gleichen Netz, also ist SSH da auch nicht irgendwie geblockt.

So sparen wir uns Mühe und Aufwand, ein sichere Client-Server-Lösung zu entwickeln. Und das „Gesamtsystem“ (die beiden Pis im internen WLAN) wird nicht unsicherer, als es ohnehin schon ist (die Pis sind ja physikalisch zugreifbar, ein Baddie könnte also ne Menge Unfug treiben, wenn er sich mal kurz die SD-Karte aus nem Pi schnappt)

Ehrlich gesagt finde ich das gar nicht so schwierig:

SSH funktioniert ohne Zertifikate.
Das praktische ist, dass man wahrscheinlich auf dem Fablab-Pi sogar einen separaten non-root-User anlegen könnte, der nur eben jenes Skript ausführen darf, welches das Lock betätigt.

Wenn der RFID-Pi „kompromittiert“ ist, dann ist auch nur der SSH-Key des non-privileged Users kompromittiert.
Wenn der Fablock-Pi „kompromittiert“ ist, dann ist eh alles egal. :wink:

Mir ging’s darum, mit Bordmitteln eine Lösung zu schaffen, die grundsätzlich ausreichend sicher ist und verhältnismäßig wenig Aufwand bei der Umsetzung bedeutet.

„Kanonen auf Spatzen“ ist hier kein Argument, finde ich. Es besticht die geringe Komplexität. Das alles haste in <30 Minuten erledigt.

Das Konzept mit SSH funktioniert nicht so wirklich, weil es kein Skript zum „einfach ausführen“ gibt. Die Motorkontrolle erfolgt in einem dauerhaft laufenden Python-Skript.

Dann ist die Implementierung von TLS auf Basis der bereits existierenden TCP-Verbindung vermutlich einfacher und sauberer, sonst müsste man entweder aus Python einen Systembefehl ausführen oder eine SSH-Bibliothek installieren.

Dieser Beitrag wurde von der Community gemeldet und ist vorübergehend ausgeblendet.

Beruhige dich bitte hier mal etwas, ich sehe hier keinen Grund, zynisch zu werden.

Es war nicht die Rede davon, dass die Kryptographie an sich geringe Komplexität aufweist, sondern dass man ja SSH wie von ron gesagt „mit Bordmitteln“ schon hat. Wenn SSH die ganze Kryptographie schon beinhaltet, müssten wir uns nicht damit beschäftigen, deswegen für uns „geringe Komplexität“, abgesehen dass es wie von mir gerade geschrieben leider nicht ganz so einfach ist.

1 „Gefällt mir“

Ah ok, das ist ein guter Hinweis. Ich hatte gedacht, man kann auch irgendwie per Skript die GPIOs(?) triggern. Von außen da dann dazwischen grätschen, bringt wahrscheinlich nur den State von dem Skript durcheinander.

Habe jetzt eine Absicherung der Verbindung mittels TLS implementiert: add TLS to networking · fablabcb/fablock@3c2037a · GitHub

1 „Gefällt mir“