Log4j Sicherheitslücke

Es gibt mal wieder eine Sicherheitslücke. Diesmal in der weit verbreiteten Java-Logging Bibliothek "Log4j" wie Heise berichtete.
Wenn man die Liste der Firmen anschaut, welche diese Bibliothek mutmaßlich einsetzen ist das auch leicht erschreckend. Hinzu kommt, dass Java eben auch mehr oder weniger die Hauptprogrammiersprache ist, wenn es um Geschäftsanwendungen geht. Eben weil es dazu auch schon sehr viele Bibliotheken gibt.
Dieser XKCD zum Thema Dependency bringt es wirklich gut auf den Punkt. Irgendjemand schreibt eine ziemlich gute Bibliothek und viele Programmierer nutzen diese einfach. Das ist durchaus legitim, man nennt es auch Open Source Software. Allerdings hatten wir doch schon mal mit Heartbleed Lücken in der OpenSSL Bibliothek das gleiche Szenario. Irgendjemand kümmert sich in seiner Freizeit unbezahlt um eine Bibliothek, die wiederum sehr viele große Firmen einfach kostenfrei nutzen. Vermutlich bekommt dieser Programmierer nicht mal irgendeine Form des Dankes zurück. Und dann wundern wir uns, wenn irgendwann mal eine Sicherheitslücke gefunden wird und plötzlich das ganze Internet davon betroffen ist. Die gesammelten Memes dazu sind jedenfalls goldig.

Dieser Tweet fasst die Situation auch nochmal gut zusammen. Besonders bemerkenswert finde ich die Tatsache, dass ausgerechnet die Minecraft Leute diesen Bug entdeckt haben. Das kam wirklich unerwartet. Scheinbar ist die Mod Community dort mittlerweile auch sehr gut in solchen Dingen. :D

Ich bin echt gespannt, was nun alles bei uns in der Firma davon betroffen ist und wie schnell man das Problem abstellen kann.

Update vom 13.12.2021:

Heise hat schon einen Artikel mit Lösungsvorschlägen veröffentlicht.

Golem hat natürlich auch einen Beitrag dazu veröffentlicht.

SQL Grundlagen - Teil 1

Da ich nie studiert habe, fehlen mir manchmal noch die Grundlagen um manchmal die Theorie dahinter zu verstehen. Ich hab allerdings vor vielen Jahren mal eine Ausbildung zum FISI (Fachinformatiker für Systemintegration) abgeschlossen. Da gab es auch mal Datenbanken mit den 3 Normalformen. Letztendlich um Primärschlüssel und Fremdschlüssel zu verwenden und die Tabellen konsistent zu halten und um Daten nicht mehrfach abzuspeichern. Manchmal ist die Normalisierung nervig, wenn man beispielsweise eine Tabelle Auftrag hat und dort nur ein Verweis auf die Adresse besteht. Um beispielsweise dann die Auftragskopfdaten und die Firmenbezeichnung anzuzeigen müssen Auftrag und Adresse verknüpft werden. Andererseits hat dies auch wieder den Vorteil, dass man später die neuen Firmendaten nur an einer Stelle (nämlich in der Adresse) ändern muss.

In meinen Beispielen beziehe ich mich nun ausschließlich auf den MS SQL Dialekt. Bei anderen Datenbanksystemen gibt es definitiv Unterschiede.

Bisher verband ich mit SQL immer nur SELECT * FROM ADRESSE. Damit gebe ich beispielsweise alle Datensätze der Tabelle mit dem Namen ADRESSE aus. Das kann für einen Überblick schon mal sinnvoll sein. Ist es allerdings eine sehr große Tabelle mit mehreren Tausend oder gar Millionen Datensätze ist das eher unpraktisch, da damit sehr viel Last erzeugt wird. Deshalb ist hier schon mal folgendes besser: SELECT TOP(100) * FROM ADRESSE Damit werden die obersten 100 Datensätze ausgegeben. So sieht man immer noch alle Spalten und kann sich ein Bild von der Tabelle machen ohne gleich eine enorme Last zu erzeugen.

Kennt man die Tabelle schon etwas genauer und möchte nur einen bestimmten Datensatz aufrufen kommt der WHERE Befehle ins Spiel. Beispielsweise um den Datensatz mit der Id 42 aufzurufen könnte ich folgenden Befehl abfeuern:
SELECT *
FROM ADRESSE
WHERE Id = 42

Trotzdem bekomme ich hiermit vermutlich wieder zu viele Informationen zurück. Ich habe mit dem WHERE Id = 42 zwar den Datensatz auf die Id 42 eingegrenzt, aber bekomme trotzdem weiterhin alle Spalten angezeigt. Möchte ich beispielsweise nur den Namen, die Straße, die PLZ und den Ort bekommen, könnte folgendes Beispiel sinnvoll sein.
SELECT Name, Straße, PLZ, Ort
FROM ADRESSE
WHERE Id = 42

Das ist dann quasi schon ziemlich der einfache Standard, wenn es nur um Spalten innerhalb einer Tabelle geht.

Möchte man aber nun Daten ausgeben, die in verschiedenen Tabellen sind, ist eine Verknüpfung möglich. Dabei verknüpft man immer mit einer Spalte, die in den beiden Tabellen vorhanden ist und nach Möglichkeit auch eindeutig. Dabei gibt es INNER JOIN, LEFT JOIN und RIGHT JOIN. Der INNER JOIN verknüpft die Datensätze, die in beiden Tabellen vorhanden sind. LEFT JOIN dagegen gibt alle Datensätze von der linken Tabelle aus und ergänzt mit den Datensätze, die in der rechten vorhanden sind. RIGHT JOIN macht es entsprechend umgekehrt. So, dass bei LEFT und RIGHT eine Tabelle führend ist und nicht nur die gemeinsamen Datensätze aus beiden Tabellen ausgegeben werden.

Nehmen wir beispielsweise an, wir möchten nun einen Auftrag und seine Positionen ausgeben. Dann wird rein logisch betrachtet der Auftrag mit seinen Kopfdaten und die Auftragspositionen mit den Positionen jeweils eigene Positionen sein. Sicherlich gibt es dazu aber in beiden Tabellen eindeutige Schlüsselspalten. Beispielsweise die Auftragsnummer. Da hier aller Wahrscheinlichkeit in beiden Tabellen immer mindestens ein Auftragskopf und mindestens eine Position vorhanden ist, wird ein INNER JOIN ausreichen. Ein LEFT JOIN wäre dann interessant, wenn man alle Aufträge haben will und dabei auch Aufträge OHNE Positionen erwartet.
SELECT a.Auftragsnr, a.Kdnr, ap.PosNr, ap.Artikelnr, ap.Menge, ap.Preis
FROM AUFTRAG a (NOLOCK)
INNER JOIN AUFTRAGPOSITION ap (NOLOCK) ON ap.Auftragsnr = a.Auftragsnr
WHERE a.KdNr = 23

Ich habe im obigen Beispiel jeder Tabelle auch noch einen Alias verpasst. Für Auftrag hier die a und für Auftragsposition ap. Der Grund dafür ist relativ einfach. Da wir nun mehrere Tabellen verknüpft haben, sind die einzelnen Spaltennamen nicht mehr eindeutig. Beispielsweise kommt Auftragsnr in beiden Tabellen vor. Um uns und dem SQL Server die Angabe der Tabellen leichter zu machen, verwende ich hier kleine Aliase. Mit a.Auftragsnr drücke ich also aus, dass ich die Auftragsnummer aus der Tabelle AUFTRAG haben möchte.
Außerdem hab ich mit INNER JOIN AUFTRAGPOSITION ap (NOLOCK) ON ap.Auftragsnr = a.Auftragsnr klar gemacht, dass ich eine Verknüpfung der Auftragstabelle mit der Auftragspositionentabelle wünsche und nur die gleichen Datensätze verknüpft werden, wo jeweils die Auftragsnummer gleich ist.
Außerdem hab ich die Ausgabe auf die Datenzahlen vom Kunden mit der Kundennummer 23 eingegrenzt.

Das (NOLOCK) Statement macht klar, dass der Befehl ohne Schreibzugriff erfolgen soll. Das ist besonders interessant, wenn in der Datenbank immer wieder Abfragen erfolgen, die auch mal zeitintensiv sind. Ein gutes Beispiel zu den Auswirkungen von (NOLOCK) findet man hier. Generell macht ein (NOLOCK) also nur Sinn, wenn im Hintergrund noch viele Daten geändert werden und man trotzdem schon mal Daten erhalten möchte.

Im nächsten Teil geht es dann weiter mit GROUP BY und ORDER BY.

Do you write Code with your mouse?

Ich bin ja eher Windows orientiert. Aber zumindest privat nutze ich dann doch schon seit 2009 / 2010 hauptsächlich Linux. Trotzdem bin ich noch in vielerlei Hinsicht ein Mausklicker. Als ich dann mal unter Windows angefangen habe mit Visual Studio zu programmieren hat sich das Programmieren etwas zu verbessern. Kompilieren und Co. geht ja gut mit Tastaturkürzeln. Als ich dann irgendwann Git entdeckt habe, hab ich das aber doch eher wieder per Mausklick erledigt. Einfach weil es nicht gut integriert war.
Unter Linux hab ich aber dann neulich mal die ZSH entdeckt. Damit ist die Shell echt deutlich geiler geworden. Man gibt beispielsweise "git" ein und es werden sinnvolle Befehle vorgeschlagen.
Ein Buch geht noch weiter. Ich habe es zwar nicht gelesen, aber der Weg ist interessant. Für mich ist es nicht wirklich praktisch, da ich doch sehr Windows lastig bin, was die Arbeit angeht. Aber es soll ja auch Leute geben, die beruflich programmieren und dafür vielleicht auch Linux oder Mac nutzen. :)
Hier geht's zum Buch.

Raspberry Pi - Chromium automatisch starten lassen und Ausschalter

Da wir aktuell wegen Corona in unserer Gemeinde ein wenig die Technik hochfahren und es einfach halten wollen, benötigen wir einen relativ einfachen Zugang um das digitale Interface vom Mischpult bereitzustellen. Das Interface wird ganz einfach über eine URL im Browser aufgerufen. Daher lag es nahe einen alten Raspberry Pi 3 (der ist nicht ultraschnell, aber auch nicht so langsam wie der 1er oder 2er) zu nehmen.

Und so hab ich es gemacht:
- RaspiOS installiert und die Grundeinrichtung durchlaufen (Assistenten beim ersten Starten durchmachen).
- Einen Ausschaltknopf anhand dieser Anleitung erstellt. Wobei ich das Starten vom Python Skript später in die LXDE-pi/autostart geschoben habe, da ich den Chrome in der grafischen Oberfläche starte.

Folgenden Code mit sudo nano shutdown.py erzeugen:

# !/bin/python

# Einfaches Skript zum Ausschalten vom Raspberry Pi auf Knopfdruck.

# von Inderpreet Singh

import RPi.GPIO as GPIO

import time

import os

# Legt Nutzung der Broadcom SOC Pin-Anschlussnummern fest

# Setzt den Pin mit eingeschalteten internen Pullup-Widerständen und im Nur-Lesen-Modus

GPIO.setmode(GPIO.BCM)

GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Unsere Funktion dafür, was passieren soll, wenn man den Button drückt

def Shutdown(channel):

print("Shutting Down")

time.sleep(5)

os.system("sudo shutdown -h now")

# Fügt ein, dass unsere Funktion ausgeführt wird, wenn der Knopfdruck stattfindet

GPIO.add_event_detect(21, GPIO.FALLING, callback=Shutdown, bouncetime=2000)

# Warte jetzt!

while 1:

time.sleep(1)

Das ganze kann man mal testen indem man das Skript laufen lässt mit python3 shutdown.py. Es erscheint "Shutting down" und 5 Sekunden später ist dann der Pi ausgeschaltet und kann stromlos gemacht werden.

- Außerdem soll beim Start automatisch der Chromium mit einer definierten URL im Kiosk Mode aufgerufen werden. Dazu kann man eine Autostart Datei erstellen. Hier muss erst der Ordnerpfad erstellt werden: /home/pi/.config/lxsession/LXDE-pi/ Fehlende Unterordner einfach erstellen.
Dann mit folgendem Befehl sudo nano /home/pi/.config/lxsession/LXDE-pi/autostart das Editorfenster öffnen und folgendes hineinpasten:

# Bildschirmschoner deaktivieren
@xscreensaver -no-splash
@xset s off
@xset -dpms
@xset s noblank

# lädt Chromium im Vollbild bei einem Neustart
@chromium-browser --kiosk http://192.168.2.4/mixer.html

# Shutdown Skript starten
@python3 /home/pi/shutdown.py

Damit wird der Chromium mit der Mixer URL im Vollbild Kiosk Modus gestartet und der Ausschalter aktiviert.
Eine relativ einfache Geschichte um ein digitales Mixer Interface per Netzwerk bereitzustellen. Klar es geht auch per WLAN und Tablet, aber ein fester Platz ist auch schick.
Man braucht nur folgende Komponenten:
- Digitales Mischpult (beispielsweise Soundcraft)
- Router (als DHCP Server und Switch)
- Raspberry Pi mit Maus und Monitor (Tastatur für die bessere Einrichtung)