Bash Konzept für eine "sichere" Datenbankverbindung über "unsichere" Clients

Executor55

Lt. Commander
Registriert
Okt. 2004
Beiträge
1.699
Hi
meine Frage würde sicher in mehrere Kategorien passen aber insgesamt wohl am besten in die Kategorie Programmierung.

Ich schildere mal eben folgendes Szenario:
Ein Ubuntu Server hostet eine MariaDB 10.x Datenbank einer Zeiterfassung (Gleitzeit) mit mehreren Tabellen.
Diese Datenbank wird Grundsätzlich nur über einen weitern Ubuntu Server, der einen Apache 2.4 Webserver hostet, angesprochen und beschrieben.
Nun soll die Möglichkeit des "Ein/Ausstechens", was bisher nur per persönlichem Login auf der Webseite auf dem Webserver möglich war, erweitert werden. Hierzu soll es möglich sein sich über eine personalisierte Chipkarte an einem Terminal einzustechen.

Die Idee ist einen Raspberry Pi mit einem Kartenlesegerät auszustatten und diesen per Netzwerk an den Datenbank-Server zu verbinden.
Dabei sei folgendes gesagt:
  • Der RPi steht an einem nicht überwachten Ort (Kameras o.Ä.)
  • Er ist quasi nicht durch Diebstahl oder Manipulation geschützt und dies wird auch nicht möglich sein.

tl;dr=
Wie programmiere ich eine Programmlogik für Datenbankverbindungen in einem Bash-Script, die auf einem unkontrolliertem Client nicht manipuliert werden darf?
Oder: Wie lagere ich die Programmlogik auf den Datenbank-Server aus, der in einer kontrollierten Umgebung steht?

PS: Bitte keine Programmvorschläge, mir geht es hier ausschließlich darum zu verstehen was hier "best practice" ist.
 
Warum unbedingt Bash?
 
Du brauchst eine API, die auf einem vertrautem Server läuft. Auf der Chipkarte ist dann ein Token o.Ä. der vom RPi mit der gewollten Aktion an die API gesendet wird. Der Server beschreibt dann die Datenbank.
 
Toms schrieb:
Warum unbedingt Bash?
Ne muss nicht. Weil es eben nicht wirklich umfangreich ist einen Zeitstempel einer Person in eine Datenbank zu schreiben dachte ich an Bash... kann aber alles sein.

Bagbag schrieb:
Du brauchst eine API, die auf einem vertrautem Server läuft. Auf der Chipkarte ist dann ein Token o.Ä. der vom RPi mit der gewollten Aktion an die API gesendet wird. Der Server beschreibt dann die Datenbank.
Die Chipkarten kann ich leider nicht beschreiben, aber ja da sind eindeutige, personenspezifische Daten drauf, wie LDAP-Benutzername und auch Benutzerzertifikate.

Wie läuft das mit einer API. Ist das ein eigener Dienst auf dem Server, der programmiert werden muss? oder direkt ein Werkzeug das MariaDB mitbringt?

Danke
 
Executor55 schrieb:
Die Chipkarten kann ich leider nicht beschreiben, aber ja da sind eindeutige, personenspezifische Daten drauf, wie LDAP-Benutzername und auch Benutzerzertifikate.
Das spielt ja an sich keine Rolle, einfach irgendwas, um den Nutzer zu identifizieren.

Executor55 schrieb:
Wie läuft das mit einer API. Ist das ein eigener Dienst auf dem Server, der programmiert werden muss? oder direkt ein Werkzeug das MariaDB mitbringt?
Ja, das müsste man dann programmieren. Sollten aber wenige dutzend Zeilen in beliebiger Sprache ausreichend sein.
 
Executor55 schrieb:
tl;dr=
Wie programmiere ich eine Programmlogik für Datenbankverbindungen in einem Bash-Script, die auf einem unkontrolliertem Client nicht manipuliert werden darf?
Geht an sich ganz simpel. JDBC-Client installieren, dann per mysql -remotehost ... < statement.sql ausführen. Das kannst Du relativ einfach in ein Bashscript packen.
Executor55 schrieb:
Oder: Wie lagere ich die Programmlogik auf den Datenbank-Server aus, der in einer kontrollierten Umgebung steht?
Mit Hilfe von SQL-Statements und Trigger. ;)
 
Gerä versiegeln. Nicht optional.

wenn das Teil weg ist, geschenkt, aber wenn es unerkannt manipulierbar ist, ist das Kompromittierung by design.
Und das WIRD passieren, wenn das Ding für jedermann gut erreichbar ist.

Damit wäre ein gut Teil bereits abgefrühstückt. Wa bleibt ist die Frage, wie Du das Netzwerk gegen den raspberry absichern willst.

Jetzt hab ich nur noch wenig mit maria zu tun, aber
was mir spontan einfiele wäre SSL+Clientauthentifizierung, Kerberos und/oder LDAP mit kurzen Anmeldefenstern. Sagen wir es darf nur zweimal am Tag synchronisiert werden.

Ziel muß sein, daß der geklaute rpi nicht als breites Scheunentor ins Netzwerk verwendet werden kann.
 
Bagbag schrieb:
Das spielt ja an sich keine Rolle, einfach irgendwas, um den Nutzer zu identifizieren.

Bis jetzt identifizierst Du nur die Chipkarte. Sofern Du nicht vorhast sie mit Superkleber auf oder einem kleinen chirugischen Eingriff unter der Haut zu befestigen sagt die noch nichts über die Person die sie gerade handhabt.

(wenn man schon Paranoid genug ist um mit Manipilation zu rechnen, dann aber auch richtig)
 
Dann schreibe ich den Satz halt etwas um: "Um den Nutzer, der gestempelt werden soll, zu identifizieren".
 
Der Raspi/Kartenleser darf in dem Fall nur simpler "Signalwandler/Weiterleiter" spielen und keinerlei Credentials beinhalten.

Ablauf wäre dann:
  • Person hält Karte davor
  • Raspi liest user & cert aus und wirft das gegen einen Server. Das kann der Webserver mit erledigen oder z.B. ein zweiter Raspi der nicht direkt manipulierbar ist.
  • Zweiter Raspi/Server erhält user & cert und prüft gegen das ldap ob User enabled ist und ob das Cert noch passt und wenn beides ja, dann prüfe letzten Eintrag in der Tabelle "Zeiterfassung" des Users. Wenn der letzte Wert "einstempeln" dann erzeuge neuen Eintrag mit "ausstempeln" und vice versa. Gib anschließend Feedback an den ersten Raspi/Kartenleser mit Status OK. Falls Prüfung gegen ldap nicht korrekt oder Eintrag in DB nicht korrekt, gebe Status ERROR an ersten Raspi/Kartenleser zurück.
  • Erster Raspi gibt dem User Rückmeldung ob ein-/ausstempeln erfolgreich war oder eben nicht.

Der erste Raspi hält somit keinerlei Credentials vor da er nur vom Kartenleser Daten einliest und diese weiter gibt und ein. Natürlich solltest du bei jedem Schritt Timeouts setzen und so schlanken und effizienten Code wie möglich schreiben da ich Mitarbeiter natürlich keine Lust haben ne halbe Minute oder länger zu warten ob die Buchung jetzt erfolgreich ist oder nicht.
Bonuspunkte für: Die ein-/austempeln Vorgänge in eine Queue packen, z.b. sqs oder mqtt oder ähnliches und Feedback "personalisieren". Dann könnten rein theoretisch mehrere User schnell hintereinander einstempeln, die Vorgänge werden in die Queue gepackt und dann abgearbeitet und jeder erfolgreiche Vorgang bekommt ein "$user: kommen ok" oder "$user: gehen ok" oder eben "$user: Fehler".
Noch mehr Bonuspunkte wenn auch gleich das Stundenkonto jeweils korrekt angegeben wird.

Alles in allem wäre das ein schönes Abschlussprojekt für einen Fachinformatiker so vom Aufbau und Umfang her^^ Muss ich mir für unsere nächsten Azubis mal merken...
 
  • Gefällt mir
Reaktionen: Myron
Danke mal soweit für die Antworten.

@PHuV:
Aber was hindert einen daran, das Bash-Skript zu manipulieren und durch beliebige SQL-Befehle zu ersetzen? Hierbei sind doch die SQL-Statements und Trigger immer Clientseitig oder übersehe ich etwas?!

Um das Szenario kurz zu ergänzen:
Der RPi hängt in einem Netz/Port, an dem sonst nichts hängt. Sein GW ist eine IPFire und blockt alles außer spezifische Dienste wie HTTP/s bzw. MariaDB und das folgende:
Um Manipulation an der RPi SD-Karte zu verhindern hab ich sie einfach entfernt ;-)
Der Pi (explizit nur diese Mac-Adresse) bootet jetzt über PXE/TFTP und NFS. Somit ist sein Betriebssystem schonmal auf einem Server ausgelagert, der in dem kontrollierten Bereich steht.
Dann habe ich mir überlegt anstatt Bash-Skripte auszuführen kann ich auch compilierte Binarys verwenden, die den Quellecode, wie die SQL-Statements, nicht (so leicht) preis geben...
Wenn ich das ganze jetzt noch ergänze was @snaxilian beschrieben hat, sollte ich ja ganz gut aufgestellt sein.

Dazu noch eine Frage @snaxilian:
"Zweiter Raspi/Server erhält user & cert und prüft gegen das ldap ob User enabled ist und ob das Cert noch passt ..."
Meine Nutzer verwenden Karten mit Public Certs, deren Private Certs ich nicht habe und deren LDAP ich nicht Administriere. Lässt sich das Cert dann in irgendeiner Form sinnvoll verwenden? Für einen einfachen Abgleich in dem ich die Public Certs jedes Nutzers in meiner DB vorhalte und vergleiche müsste ich aber vorher auch alle Public Certs einlesen und in der DB speichern was zwar möglich aber umständlich wäre und womöglich bestimmt gegen irgendwelchen Bestimmungen verstößt, was noch zu prüfen wäre ...
 
Den private key brauchst du nicht und im besten Fall bekommst du es auch nicht. Wenn du ist es ja nicht mehr privat und gehört damit zurück gezogen. Ich bin auch davon ausgegangen, dass das ldap/ad erreichbar ist. Dann kann man so relativ einfach überprüfen ob das Zertifikat zu dem User passt und ob es noch gültig ist.

Wenn du jedoch keinerlei Zugriffe aufs ldap/ad hast, dann kannst du natürlich keine Verifizierung machen und den Teil ignorieren. Das alles hätten wir uns aber auch sparen können wenn du Superheld solche relevanten Informationen die das Projekt betreffen, direkt genannt hättest. So dreht man sich nur unnötigerweise im Kreis...

(Grundlegend: du hast ein Schlüsselpaar (public & private), erzeugst ein Zertifikat bzw den CSR, signierst den mit dem private key und verteilst den public key an alles und jeden. Authentifiziere ich mich jetzt mit dem Zertifikat oder signiere damit wieder etwas, z.B. eine Datei kann jeder nur anhand des public keys prüfen ob das Zertifikat von mir ist da die Prüfung nur korrekt ist wenn es mit meinem privaten Schlüssel erzeugt/signiert wurde. Halbwegs korrekte Begrifflichkeiten bei der Kryptografie sind wichtig ;))
 
Alles gut und schön, aber ändert nichts daran, daß Dein RasPi eine siebzehnjährige nackte Jungfrau im Rotlichtmilieu von New York ist.... mit einem Leuchtschild in der Hand, wo "Nimm mich!" draufsteht. Selbst wenn Du der einen Keuschheitsgürtel gibst und nen Schlüssel für die Notdurft, nimmt den der nächste weg und hey presto, EX Jungfrau.

Noch dazu läßt Du sie alleine und das mit Ansage.

SD Karte raus, okay, das hilft schon mal. Aber wenn einer eine reinsteckt und die Stromzufuhr kurz unterbricht, was dann?

LDAP adminstrieren und Zugriff drauf haben sind verschiedene Dinge. Hast Du Zugriff?

Für die Zeiterfassung mußt Du notwendigerweise mit personenbezogenen Daten arbeiten. Das läßt sich nicht vermeiden.

Das größte Problem sind die Mitarbeiter. Wenn die zwei Stunden einstechen können, bevor sie da sind, und drei, nachdem sie gehen, dann garantiere ich mit qualifizierter Signatur, daß die das machen werden. Erwischt werden sie nicht. Wie auch?


Nein, das Terminal muß schon ganz klar unter Kontrolle stehen, unter steter Kontrolle stehen, und versiegelt sein. Siegel kaputt => jemand hat es geöffnet => ALLE Buchungen seit Bekanntwerden des Siegelbruchs ungültig.

Mach das mal, wenn die Kiste in der Pampa rumhängt. Da werden Lose gezogen und der mit dem kürzesten darf die nächste Woche früh um sechs aufstehen und alle Smartcards einchecken.
 
Executor55 schrieb:
@PHuV:
Aber was hindert einen daran, das Bash-Skript zu manipulieren und durch beliebige SQL-Befehle zu ersetzen? Hierbei sind doch die SQL-Statements und Trigger immer Clientseitig oder übersehe ich etwas?!
Indem man es entsprechend über Linux-Mittel absichert und z.B. Schreibrechte entzieht. Wird vielfach in der Welt so gemacht. Letztlich kann auch die Datenbank direkt gehackt werden, wenn man einen Weg findet. Und Du kannst doch direkt auf der Datenbank selbst ohne Client entsprechende Prozeduren laufen lassen.
 
Der Materielle Diebstahl eines RPis wäre zu verkraften.

Wenn jemand eine SD-Karte reinsteckt ok ... und? Wenn er die Stromzufuhr unterbricht ... noch besser! Damit ist ein NFS gemountetes Betriebssystem weg und er hat nichts mehr davon.

Definiere "Zugriff" aufs AD. Ich und alle anderen sind nur Nutzer dieses ADs.
Die Frage ist: Lässt sich das Public-Nutzer-Zertifikat in irgendeiner Form (von jedem) vom AD validieren?! So wie sich ein SSL-Zertifikat auch von jeder CA, die es ausgestellt hat validieren lässt. Das müsste ich mal prüfen/erfragen/testen.

Und das Problem mit dem 2 Stunden früher einstechen ohne anwesend zu sein lässt sich glaube ich keinem Zeiterfassungssystem verhindern. Sowas hat man immer irgendwie. Und wenn der Kollege die Karte mitnimmt und sich für ihn einsticht ... Das muss organisatorisch gelöst und stichprobenartig überprüft werden.
 
Niemand interessiert die Hardware, jeden interessiert die Manipulierbarkeit und der Datenabgriff.

Sd Karte rein, Teil bootet via Pxe, aber nun kann ich Daten auf die Sd schreiben lassen, und wenn ich gut bin, klon ich die Startumgebung auf die SD, unterbinde PXE und hab meinen mitm installiert.

Merkt keiner. Sd Karte ist in Sekunden getauscht und nachts merkt auch keiner, daß er nicht einchecken oder auschecken kann.


Bei ZE geht es um bares Geld. Da ist das Interesse fast grenzenlos.
 
SD Karte rein und neustarten ... ok. Wie kopierst du da dann Dinge? Ohne (root-)login? Ohne HDMI oder USB, was über modprobe.d geblacklistet ist?

Aber mal abgesehen davon: Wir sind keine IT Firma und ich werde mir mehr Gedanken drum machen müssen den Benutzern zu erklären wie sie ihre Karte richtig rum reinstecken als das ich mir Sorgen machen muss, dass mir einer das Teil manipuliert auf dem Level auf dem wir uns bereits bewegen...

Ich muss mir weiterhin Gedanken um die Authentifizierung machen.

Danke trotzdem soweit für die Beiträge.
 
Je nach Anforderung reicht es ja einfach den Nutzernamen aus der Karte auszulesen.
 
Executor55 schrieb:
Aber was hindert einen daran, das Bash-Skript zu manipulieren und durch beliebige SQL-Befehle zu ersetzen? Hierbei sind doch die SQL-Statements und Trigger immer Clientseitig oder übersehe ich etwas?!
Indem dein Raspberry Pi nicht direkt gegen die Datenbank arbeitet, sondern eine API auf dem Webserver bedient und mitteilt, dass Kartennummer XYZ (ggf. mit validiertem Zertifikat) bitte ein-/ausstempeln möchte. Die Plausibilisierung (Validation und Sanitization) findet dann ebenfalls in der Software, die auf dem Webserver läuft, statt.

Ein Raspberry Pi ist von der Hardware-Security übrigens eher unterdurchschnittlich.
 
  • Gefällt mir
Reaktionen: Myron und snaxilian
Zurück
Oben