Leseempfehlung: ‚Countdown to Zeroday‘ von Kim Zetter

Es ist schon etwas Zeit vergangen seit der letzten Leseempfehlung hier, aber meine gerade beendete Urlaubslektüre hat sich für mich sehr gelohnt. Es ist Countdown to Zero Day: Stuxnet and the Launch of the World’s First Digital Weapon (ISBN 0-77043-617-X) von Kim Zetter. Zwar ist das Buch schon aus dem Jahr 2014 und angesichts der schnellen Entwicklungen im IT Bereich daher nicht mehr ganz up to date. 

Aber es ist trotzdem lesenswert, denn die Stuxnet Schadsoftware ist bis heute (2022) ein einzigartiges Beispiel für eine digitale Waffe, die auch zum Einsatz kam bzw. deren Einsatz entdeckt wurde.

Die Autorin nimmt auf den 500 Seiten alle Aspekte in Augenschein, vielleicht manchmal schon zu umfassend, darunter diese:

Die Sicht der Sicherheitsforscher

Die Personen, die mit der Analyse der ungewöhnlich komplexen Schadsoftware befasst waren, insbesondere bei Symantec und dem deutschen Unternehmen Langner, erfahren eine umfassende Porträtierung. Und die für sie neuen Fragestellungen:

  • Ist es insbesondere für ein US Unternehmen wie Symantec eigentlich opportun eine von der US Regierung beauftragte Operation zu (zer)stören?
  • Wie ist es mit den möglichen persönlichen Risiken, denen man sich dabei im Gegensatz zur Analyse irgendeiner beliebigen Virussoftware aussetzt?
  • Ist man in irgendeiner Weise mitschuldig, wenn der digitale Angriff aufgedeckt wird und die Geheimdienste ihre Strategie dann offenbar auf Mordanschläge umstellen?

Die Funktion der Waffe

Es gibt ein umfangreiche Beschreibung der ‘Nutzlast’ der Schadsoftware, sozusagen des digitalen Sprengkopfs. Dieser bestand aus auf die spezielle Steuerungssoftware von Siemens, die attackiert wurde, zugeschnittenen Elementen, die so ganz anders funktionieren als der Code, den Sicherheitsforscher im Umfeld gängiger Betriebssysteme wie Windows oder Linux gewohnt sind, was die Analyse sehr erschwerte.   

Das Ziel der Waffe

Die Schadsoftware richtete sich – das kann heute wohl als sicher gelten – gegen das iranische Nuklearprogramm bzw. den Teil, in dem die Urananreicherung mit tausenden von Zentrifugen erfolgt. 

Und war damit ein Teil eines über Jahrzehnte – bis heute – andauernden Konflikts zwischen dem Iran, der USA, Israel, aber auch weiteren Staaten. Hier rollt das Buch die verschiedenen Parteien auf, wobei es naturgemäß schwierig ist die eigentlich Verantwortlichen zum Reden zu bringen oder auch nur zu benennen.

Ein wesentlicher Teil des Buches befasst sich auch mit der Frage ob so eine Schadsoftware ein kriegerischer Akt ist. Das ist keine unwichtige Frage, denn die Alternativen aus Sicht der USA und Israels wären eindeutige kriegerische Akte wie Luftangriffe.

Und würden die USA – wenn sie in ähnlicher Weise angegriffen würden – so eine Attacke genauso einschätzen, wie sie es damals als Angreifer getan haben?

Was braucht es sonst noch um so eine Waffe zu entwickeln

Was in der Berichterstattung über Stuxnet oft zu kurz kam ist die Frage wie es überhaupt technisch möglich war eine Software zu entwickeln, die in offenbar sehr subtiler Weise komplexe Hardware – die Zentrifugen der Urananreicherung – beschädigen und in ihrer Leistung einschränken kann.

Hier wird klar, dass solche Angriffe kaum ohne einen umfangreichen Maschinenpark und langen Vorlauf realisierbar sind.   

War Stuxnet erfolgreich

Die Antwort auf diese Frage ist überraschend kompliziert und vielfältig. Da niemand der Personen, die es am besten wissen könnten, ein Interesse hat die tatsächlichen Fakten offenzulegen gibt es nur umfangreiche Indizien, die die befragten Expert*innen aber auch wieder ganz unterschiedlich auslegen.

Interessant ist auch die Frage ob die Autor*innen der Schadsoftware hätten aggressiver vorgehen sollen. Es wäre vermutlich ‘leicht’ gewesen tausende von Zentrifugen zu zerstören, aber damit hätte man die Iraner auch direkt darauf gestoßen, dass irgendetwas grundsätzlich nicht stimmt. 

Der Umgang staatlicher Stellen mit Zero Day Lücken

Stuxnet nutzte eine – zumindest für damalige Verhältnisse – ungewöhnliche große Anzahl von Zero Day Lücken – also vor ihrer Entdeckung in Schadsoftware zumindest bei den jeweiligen Softwareanbietern wie Microsoft unbekannte Lücken – aus. Insgesamt waren es 4.

Hier wird der Konflikt diskutiert den staatliche Stellen haben, die auf der einen Seite die Sicherheit ihrer Bürger und der Infrastruktur sichern sollen, aber auf der anderen Seite solche Lücken für Geheimoperationen in Reserve halten möchten. Teilweise sogar die gleichen staatlichen Stellen.

Seit damals hat sich einiges getan was Bug Bounty Programme angeht, aber der Markt für solche Lücken in wichtigen Systemen ist eigentlich nur noch größer geworden und die Preise viel höher, die Unternehmen wie Apple, Google oder Microsoft bieten müssen, damit sie halbwegs sicher sein können das Fehler in ihren global eingesetzten Produkten bei ihnen gemeldet werden, und nicht bei einer der vielen Plattformen, die sie an den Meistbietenden verkaufen.

Die Büchse der Pandora – geöffnet, aber nicht genutzt?

Das Ende des Buches wird die Metapher der Büchse der Pandora verwendet: Haben die Personen, die Stuxnet auf den Iran und letztlich auf die Welt losgelassen haben damit einen Präzedenzfall geschaffen, der sich nicht mehr ungeschehen macht? Ähnlich den Detonationen der ersten Atombomben?

Dieser Argumentation kann man sich kaum verschließen, aber es ist heute – 8 Jahre nach dem Erscheinen des Buches – festzustellen, dass vergleichbare Ereignisse seitdem nicht wieder bekannt geworden sind. Auch im aktuellen Angriffskrieg Russlands gegen die Ukraine scheinen solche Mittel eher nachrangig – wenn überhaupt – zum Einsatz zu kommen.

Tatsächlich kommen heute große Infrastrukturausfälle durch digitale Angriffe vor, siehe z. B. den Angriff auf die Colonial Pipeline, der zu massiven Störungen der Energieversorgung in den USA führte. Aber diese Angriffe werden von Kriminellen ausgeführt, denen es um Geld geht, nicht von Staaten oder Geheimdiensten. Und die viel simplere Sicherheitslücken ausnutzen und auf diese Weise teilweise überraschend tief in hochwichtige Systeme eindringen.

Das liegt vielleicht daran, dass sich eine digitale Waffe oft nur einmal einsetzen lässt, danach ist ihr Wirkmechanismus bekannt und kann abgestellt werden. Und der Angegriffene bekommt mit der Schadsoftware auch eine Blaupause dafür, wie diese Waffe funktioniert, und kann sie nachbauen. Das macht den Einsatz riskant und trotz der ‘Vorteile’ – hauptsächlich wie schwer es ggf. ist nachzuweisen, wer für einen Angriff verantwortlich war – nur für wenige Szenarien attraktiv. 

Empfehlung

Wer sich für IT Sicherheit interessiert, aber dabei nicht rein für die Bits und Bytes, der findet hier interessanten Lesestoff in einer Tiefe, die sich mir damals, als das Thema ganz aktuell war, so nicht erschlossen hat.

Und 8 Jahre später die Prognosen zur Ausbreitung und zum Einsatz von digitalen Waffen mit der Realität vergleichen zu können ist ebenfalls spannend.

Release 1.4.0 des Anti-DoS-Valves – auf einem ChromeBook entwickelt

Es gibt eine neue Version des Anti-DoS-Valves, sie bringt die zusätzliche Konfigurationsoption nonRelevantPaths, die es in bestimmten Einsatzkonstellationen erleichtert das Valve punktuell zu öffnen, ohne dabei die Konfiguration sehr kompliziert und pflegeaufwändig werden zu lassen.

Das eigentlich interessante ist aber aus meiner Sicht das: Diese Version ist komplett auf einem ChromeBook entwickelt worden. Und das ging gut und zwar so:

Crostini als Linux Unterbau

Wie schon in dem Post ‚Emacs unter ChromeOS‚ ist wieder es weiterhin Crostini, welches sein Versprechen

Welcome to the containers project where we support running arbitrary code inside of VMs in Chrome OS

auch dieses Mal wahr macht. Auch wenn es darum geht innerhalb dieses Containers wieder andere Container auszuführen.

VS Code als Entwicklungsumgebung

Microsoft hat mit Visual Studio Code vielleicht nicht die allermächtigste Entwicklungsumgebung der Welt geschaffen, aber eine, die auf nahezu allem Plattformen ausgeführt werden kann. Auch die Inbetriebnahme auf meinem aktuellen ChromeBook, einem Acer Spin 713 mit i3 Prozessor und 8GB RAM, ging problemlos von statten und die Umgebung fühlt sich – zumindest mit meinem kleine Anti-DoS-Valve-Projekt, schnell und ruckelfrei an.

Screenshot VS Code unter ChromeOS

Schnell hat man seinen Code von GitHub geholt und VS Code hilft einem mit Vorschlägen für Extensions weiter. Da das meine ersten Gehversuche mit der IDE waren um so hilfreicher und mit netten Überraschungen versehen wie dem Hinweis der bereits enthaltenen Snyk Extension auf veraltete / unsichere Dependencies in der Maven Konfiguration.

Java und Maven habe ich separat installiert. Zwar scheint es als bringe VS Code dafür eine Möglichkeit, aber Amazons Corretto und Maven kann man auch so schnell installieren.

Eine Moment habe ich gebraucht um zu verstehen wo die Ergebnisse der JUnit Tests landen und bis jetzt habe ich auch nicht herausgefunden, wie man es hinbekommt, dass man bei gescheiterten Tests genau in der Programmzeile landet, in welcher der Test gescheitert ist. Aber für eine kleine Erweiterungsprogrammierung war das kein Showstopper.

Docker

Mit der Version 1.3.0 des Valves hatte ich eine Containter Konfiguration mitgeliefert, die es einem erlaubt das Valve mit geringem Aufwand in einem Tomcat Server auszuführen und zu testen.

Um das nun auch wieder nutzen zu können muss zuerst Docker installiert werden in der Linux VM. Das geht mit den Anweisungen auf der Docker Webseite problemlos. Und wie es das Versprechen der Containerisierung ist laufen die docker-Kommandos, welche ich exemplarisch in der README angegeben habe, auch hier problemlos. Nur musste ich ein sudo vor die Kommandos stellen, da ich noch nicht rootless unterwegs war:

Jetzt müsste man nur noch einen größeren Bildschirm an das ChromeBook hängen und schon könnte man flüssig auch größere Projekte damit angehen.

Komplexität 🤜🤛 IT Sicherheit: 2 interessante Beispiele

Beschäftigt man sich regelmäßig mit IT Sicherheitsthemen – etwa in dem man jede Woche den Security Now Podcast hört – gibt es immer wieder Momente in denen man völlig davon überzeugt ist, dass das Internet nur von Kaugummi und Klebeband zusammengehalten wird. Aber oft sind es auch Themen, die tief in die unheimlich komplex gewordenen Infrastukturen und Technologien führen, mit denen wir täglich hantieren. Das sind zwei Beispiele aus den letzten Wochen, die ich besonders spannend fand:

Trojan Source – UTF-8 und Tricks mit dem bidi Encoding 🔀

Aus Security Now 843: Zwei britische Forscher haben ein spannendes Paper mit dem Titel ‚Trojan Source: Invisible Vulnerabilities‚ veröffentlicht, welches im Endeffekt diese Kernaussage hat:

Bei der Prüfung eines Programmcodes kann man nicht mehr davon ausgehen, dass der Code, den man vor sich auf dem Bildschirm sieht, der gleiche Code ist, der später vom Compiler ‚gesehen‘ und in ein Programm übersetzt wird

So wie das Trojanische Pferd auch nicht das war, was es zu sein schien…Wenn man darüber einen Moment nachdenkt zieht es einem nach und nach das Fundament unter dem Füßen weg, auf dem die Überprüfung von Softwarequalität und -sicherheit von jeher stand:

Ein Mensch schaut sich in einem Editor den Quellcode, den ein anderer Mensch – oder inzwischen auch eine Maschine – geschrieben hat, versucht ihn zu verstehen und vergleicht ihn mit der Funktion, die der Code laut Pflichtenheft oder Eigenbeschreibung oder Stack Overflow Kommentar haben soll.

Im Paper werden nun unterschiedliche Verfahren beschrieben, wie man in Quellcode, der als Unicode gespeichert ist, subtile Täuschungen einschmuggeln kann. Und dabei kommt die Komplexität moderner Zeichensatzcodierungen, die den Anspruch haben letztlich jedes relevante Schriftsystem der Welt – und möglicherweise auch extraterrestrische – korrekt darstellen zu können, uns die Quere:

Neben vergleichsweise simplen Ticks wie dem Einfügen von breitenlosen und damit unsichtbaren Leerzeichen (Zero Width Space ZWSP), die Stringvergleiche scheitern lassen können, oder der Verwendung von Homoglyphen, die etwa zur Einführung alternativer Methodenaufrufe genutzt werden können, sind es die Nutzungen der Bidirectional Commands und davon gibt es einen ganzen Block:

Tabelle mit den UTF-8 Zeichen für Richtungswechsel. Quelle: https://www.w3.org/International/questions/qa-bidi-unicode-controls

Die lassen sich sogar verschachteln und ähnlich wie bei einem Stack in der Programmierung gibt es POP Anweisungen um Verschachtelungen wieder zu beenden und damit eine Schachtelungsebene nach oben zu gehen:

Tabelle mit den UTF-8 Zeichen für Richtungswechsel. Quelle: https://www.w3.org/International/questions/qa-bidi-unicode-controls

Gerade mit dem Isolates, die komplette Gruppen von Zeichen als gemeinsames Element behandeln, und Kombinationen von BiDi Anweisungen lassen sich leicht Fälle konstruieren, bei denen etwas, dass im Quellcodeeditor so aussieht:

...
/* Wenn Sicherheitsprüfung bestanden, dann return; */
if (check == true) 
     return;
else 
     throw new Exception("Keine Berechtigung!");

für den Compiler hingegen so erscheint:

...
/* Wenn Sicherheitsprüfung bestanden, dann */ return;
if (check == true) 
     return;
else 
     throw new Exception("Keine Berechtigung!");

Hier wird also aus dem scheinbaren Kommentar am Ende eine Programmanweisung, die die Logik komplett aushebelt. Das solche subtilen Änderungen manchmal weitreichende Probleme verursachen, dafür ist der goto fail;-Bug ein gutes Beispiel, den Apple vor Jahren in seinem Betriebssystem hatte. Hier sah der fehlerhafte Abschnitt so aus:

if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
	goto fail;
	goto fail;

Richtig wäre aber diese Variante gewesen:

if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
	goto fail;
goto fail;

Die dritte Zeile durfte also nicht eingerückt sein. Manchmal reicht schon ein TAB um den Unterschied zu machen und in diesem Fall gab es Vermutungen, dass vielleicht jemand dafür bezahlt worden sein könnte diesen subtilen Fehler an einer entscheidenden Stelle einzubauen. Das Risiko der Entdeckung wäre gering gewesen und man hätte sich leicht damit herausreden können, dass es sich um einen Tippfehler gehandelt hat. Mit Hilfe der BiDi-Trickserei wäre dieser Fehler nicht einmal bei einem sehr sorgfältigen Code Review sichtbar gewesen.

Da die Forscher bereits reale Beispiele für die Anwendung dieser Technik gefunden haben ist das keine rein theoretische Bedrohung. Da sich solcher Code sogar per Copy-and-Paste übernehmen lässt sind beliebte Vorgehensweisen in der modernen Softwareentwicklung ebenfalls gefährdet. Also noch mehr gefährdet, als sie es immer schon waren 🙈

Was kann man tun?

Grundsätzlich wird man wohl abwarten müssen bis die Werkzeuge wie Editoren, Compilier und vielleicht auch Linter sich dieses Problems annehmen. Bis dahin gibt es vielleicht diese Faustformeln:

  • Gerade in den Quellcode eingebrachte Texte wie Kommentare und Strings sind Einstiegspunkte für diese Art von Angriff
  • Die Auswirkung der bidi-Tricksereien enden beim nächsten Zeilenumbruch. Eine einheitliche Quellcodeformatierung, die z. B. eingebettete Kommentare nicht in der gleichen Zeile stehen lässt wie Code, kann ein paar Varianten vermutlich aushebeln
  • Bei der Nutzung von fremden Programmcodes muss man noch stärker als bisher schon auf deren Qualität achten. Was immer schon notwendig, und immer schon schwierig war

HTTP Request Smuggeling 🧱⛏️

Aus Security Now 846: Auch dieses Problem wird durch Komplexität verursacht, aber auf einer ganz anderen Ebene: Hier geht es darum, dass zwei oder mehr hintereinander geschaltete Webserver, die am Bedienen eines Webrequests beteiligt sind, das dabei verwendete HTTP Protokoll nicht einheitlich interpretieren.

Und im Endeffekt unterschiedliche Vorstellungen davon haben, welche Webrequests sie eigentlich gerade verarbeiten.

Dieses Problem ist kein ganz neues Problem, aber heute noch relevanter, da es inzwischen gängige Praxis ist, dass mehr als ein Server am Ausliefern einer Seite beteiligt ist:

  • Proxy Server werden vor den eigentlichen Applikationsserver geschaltet, um die Last zu verringern
  • Webserver wie Apache oder nginx liegen vor den Applikationsservern um TLS zu terminieren oder Loginfunktionen – z. B. Shibboleth – zu übernehmen
  • Loadbalancer sind Netzwerkkomponenten, die die Zugriffe auf nachgelagerte Server verteilen, um Lasten gleichmäßig verarbeitbar zu machen
  • Dienste wie Cloudflare bieten ihren Kunden durch vorschaltete Systeme Schutz vor Denial of Service Angriffen, die eigentlichen Server sind nicht mehr direkt erreichbar
  • Und alle denkbaren Kombinationen davon….

Für die effiziente Kommunikation zwischen diesen Servern werden verschiedene Webrequests gerne hintereinander gehängt, damit sie sich schnell über die gleiche Verbindung übertragen lassen.

Aber wie schafft man es dem einen Server etwas anderes vorzugaukeln, als dem später drankommenden Server? In dem man die zwei Optionen, die der HTTP Standard als Mittel bietet um die Länge eines Request zu definieren – und damit bei hintereinander gehängten Requests zu definieren, wo der eine aufhört und der andere beginnt – so trickreich nutzt, dass die beteiligten Server zu unterschiedlichen Ansichten darüber gelangen, wo die Grenze zwischen zwei Requests liegt. Auch wenn es laut dem Standard eigentlich klar wäre, wie vorzugehen ist:

“According to the HTTP/1.1 standards, if both Content-Length and Transfer-Encoding headers are passed, Transfer-Encoding takes precedence.”

Quelle auf Medium

Auf diese Weise kann es bei anfälligen Serverkombinationen – und laut diesem Paper sind das viele – gelingen einen Zugriff auf einen Backend Server abzusetzen, der eigentlich von den davor geschalteten Servern gefiltert werden sollte. Das kann insbesondere dann relevant sein, wenn die vorgeschalteten Server das Login- und Rechtemanagement übernehmen.

Für eine bestimmte Variante des Request Smugglings vulnerable Serverkombinationen laut diesem Paper

Auch hier ist es nicht leicht etwas zu tun. Wie immer muss man natürlich seine Server aktuell halten, so gibt es z. B. für Tomcat inzwischen einen Patch für CVE-2021-33037, der auch mit HTTP Request Smuggeling zu tun hat. Aber auf das Verhalten vieler Komponenten, wie z. B. Loadbalancer, hat man wenig bis keinen Zugriff.

Eine Lösung ist es vielleicht die kritischen Entscheidungen einer Applikation – also die Rechte- und Zugriffskontrolle – möglichst weit nach hinten zu verlagern, bis in die Applikationsserver. Das nimmt einem Optimierungsmöglichkeiten, aber dafür ist der Server, der am Ende die Requests verarbeitet, auch derjenige, der entscheidet welche Requests zulässig sind.

Der IE geht – eine kurze Erinnerung an die Browserkriege ⚔

Das die Tagesschau über Software berichtet ist in einer Zeit, in der die IT die Gesellschaft allmählich völlig durchdrungen hat, nicht ungewöhnlich. Aber wenn es um eine so alte Software geht dann doch: Der Internet Explorer geht in Rente und das nach einer 25-jährigen Geschichte.

Logo des Internet Explorers

Ich kann mich nicht mehr erinnern jemals ein aktiver Nutzer des IEs gewesen zu sein und bilde mir heute ein nach ersten Schritten im WWW mit Mosaic im Studium relativ schnell auf den Netscape Navigator gewechselt zu haben, und dann ohne ‚Umweg‘ auf das freie Folgeprodukt Mozilla Firefox. Seit dem Erscheinen von Google Chrome ist dies bis heute mein Hauptwebbrowser.

Aber als Webentwickler kam man lange nicht am Internet Explorer vorbei, jedenfalls für die Zeit, in welcher der IE – insbesondere in der ‚ewigen‘ Version 6 – die absolute Dominanz im Web hatte:

Graphik Browser Wars, Von Wereon - Image:Browser Wars.png, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=1128061
Von Wereon – Image:Browser Wars.png, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=1128061

Bis 2002 hatte Microsoft mit seinem Browserprodukt durch die später von Gerichten bestrafte Bündelung mit dem Windows Betriebssystem den zuvor dominierenden Netscape Browser vom Markt gedrängt, damit den ersten Browserkrieg gewonnen und danach die Weiterentwicklung faktisch eingestellt und so die Fortentwicklung des Webs quasi eingefroren. Für viele Webentwickler*innen war es daher die einfachste Lösung Webseiten zu entwickeln, die sich nur auf diese Webbrowser konzentrierten. Noch heute findet man Seiten mit diesem damals allgegenwärtigem Hinweis:

Webseite mit dem Hinweis 'The layout of these pages is optimized for Internet Explorer 800 x 600'

In Deutschland war die Dominanz nie ganz so stark, insbesondere nicht im Umfeld der Hochschulen, da sich hier viele Verfechter von Open Source Produkten fanden und finden, und daher Firefox teilweise bis heute der Standardwebbrowser ist. Trotzdem konnte es einem auch in den 2010er Jahren noch passieren einem Bankberater gegenüber zu sitzen, der den Kreditvertrag in seiner Bankingsoftware in einer alten Version des Internet Explorers bearbeitete, da gerade im Finanzbereich die proprietäre ActiveX Technologie, die sich nur im IE nutzen ließ, im Einsatz war.

Auch der 2. Browserkrieg ist vorbei

Mit dem Aufstieg von Chrome begann der 2. Browserkrieg, der ebenfalls schon lange beendet ist, wie ein Blick in die heutige Verteilung der Webbrowsernutzung zeigt:

Verteilung der Webbrowser Nutzung

By StatCounter generated image - https://gs.statcounter.com/browser-market-share#monthly-202011-202011-bar, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=96191667
By StatCounter generated image – https://gs.statcounter.com/browser-market-share#monthly-202011-202011-bar, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=96191667

Microsoft hat nach letzten, gescheiterten Versuchen mit einem eigenständigen Browserprodukt die alte Dominanz zu erhalten mit dem aktuellen Edge Browser ebenfalls auf die Chromium Basis aufgesetzt, wie es der Opera Browser bereits seit 2013 tut. Jenseits der Apple Welt sind damit die Chromium-Browser heute ähnlich dominant, wie es vor langer Zeit der IE war. Allerdings ohne den Versteinerungseffekt, nun wird das Web in 6-Wochen-Zyklen weiterentwickelt, bald sogar alle 4 Wochen.

Tomcat 10 bringt EE9 – und den Big Bang weg von javax.servlet.*

Bei der kleinen Docker-Bastelei im Anti-DoS-Valve-Projekt wollte ich das Projekt ‚gerade mal eben‘ auf Tomcat 10 hochziehen und bin direkt über eine wesentliche Änderung gestolpert, die mir bisher entgangen war:

Was bisher

import javax.servlet.*;

war muss nun

import jakarta.servlet.*;

sein 😮 Da sich das mit meinen Gehversuchen mit Docker überschnitt hat es einen Moment gebraucht um zu verstehen, wo eigentlich das Problem lag…

Was ist der Hintergrund

Natürlich das Urheberrecht und Oracle’s Wille die mal mit dem Kauf von SUN an Java gewonnenen Rechte auf keinen Fall Preis zu geben. Die entscheidenden Weichenstellungen sind dabei schon weit vor der Niederlage gestellt worden, die Oracle letztlich Anfang April 2021 in der Auseinandersetzung mit Google über die Java Nutzung in Android erlitten hat. Hier sind ein paar Quellen:

Der Artikel der Eclipse Foundation enthält diese Passage, die das Ende der Verwendung von javax.* ankündigt:

‘..Eclipse and Oracle have agreed that the javax package namespace cannot be evolved by the Jakarta EE community. As well, Java trademarks such as the existing specification names cannot be used by Jakarta EE specifications.’

Selbst der Name Java darf nicht mehr in den Spezifikationen wie JPA verwendet werden, die die Eclipse Foundation weiterentwickelt. Bei der Frage wie es nach EE8 weitergehen kann deutet sich die Entwicklung schon an:

‘What happens beyond Jakarta EE 8?

The guiding principle for Jakarta EE 9 will be to maximize compatibility with Jakarta EE 8 for future versions without stifling innovation.  This will most likely involve two key topics: migration of some or all of the Jakarta EE specification source to a new namespace for future evolution; means to provide backwards compatibility with javax at a binary level, allowing old applications to run on Jakarta 9 implementations with some form of build or runtime tooling.

So while there will be a point in time where future versions of specifications will have to go through a source code incompatible change with respect to the previous javax based packages, this will be a straightforward transformation.’

Eine Frage war es dann ob die Migration weg von javax.* inkrementell erfolgen würde – also nur der Teile, die Veränderungen unterliegen – oder als Big Bang gemacht wird. Die Antwort liefert der vergleichende Blick in die Javadocs der Servlet 4 und 5 APIs:

Der Post Jakarta EE 9 Delivers the Big Bang im Life at Eclipse Blog beschreibt das Vorgehen noch einmal zum Start von EE9. Die Logik dahinter – es wird ein klarer Schnitt gemacht – finde ich durchaus nachvollziehbar. Aber was macht man nun mit Anwendungen, die auf großen Codebasen sitzen und diverse externe Pakete verwenden, die alle noch nicht umgestellt sind?

Was tun mit den Altanwendungen (in Tomcat)

Alles was vor EE9 an Webanwendungen entwickelt wurde ist damit nun plötzlich eine migrationsbedürftige ‚Altanwendung‘. Aber selbst die Befürworter*innen des Big Bangs erkennen an, dass das JEE Ökosystem einfach zu groß ist, als das man innerhalb kürzester Zeit von allen Anbieter*innen von Servern, Anwendungen, Paketen ein Mitziehen erwarten könnte. Es sind also Übergangslösungen gefragt.

In des Migrationshinweisen von Tomcat 10 widmet sich ein eigener Abschnitt dem Thema und es zeigt sich, dass das Tomcat Migration Tool for Jakarta EE, welches im Kern den Eclipse Transformer enthält, hier eingebaut ist und man seine Anwendungen offenbar ohne Umbauten weiterhin deployen kann. Aber nicht mehr in der gewohnten Weise:

Bei einem Test mit einer winzigen JEE Anwendung (nur ein Servlet) in deren pom.xml die Servlet API 4 referenziert wird

                <dependency>
                        <groupId>javax.servlet</groupId>
                        <artifactId>javax.servlet-api</artifactId>
                        <version>4.0.1</version>
                        <scope>provided</scope>
                </dependency>

scheint das Deployment durch Kopieren der WAR-Datei in den <CATALINA_HOME>/webapps-Order zunächst wie gewohnt zu arbeiten, die Datei wird entpackt und die statische Startseite wird im Browser angezeigt. Der Aufruf des Servlets scheitert aber mit einer 404-Meldung, jedoch ohne eine Fehlermeldung in den Tomcats-Logs 🤔

Das Deployment funktioniert erst, wenn man wie in der Migrationshilfe beschrieben einen <CATALINA_HOME>/webapps-javaee-Order anlegt und die WAR Datei dort platziert. Dann passiert beim Start das hier:

Tomcat 10 migriert beim Start eine EE8 Anwendung nach EE9

Tomcat bemerkt die ‚Altanwendung‘ und migriert sie in die neue Welt. Das Ergebnis befindet sich dann im üblichen <CATALINA_HOME>/webapps-Order. Bei der Minianwendung hat das problemlos funktioniert. Die spannende Frage ist dann wie es sich mit komplexeren Anwendungen verhält.

Noch nicht klar geworden ist mir aber ob man bei der Weiterentwicklung von Altanwendungen nun erst einmal auf Tomcat Versionen <10 festgelegt ist, oder ob es auch da einen Weg gibt mit dem aktuellen Tomcat weiter zu machen.

Fazit

Das sich die Eclipse Foundation dazu entschieden hat die Verbindungen zu Oracle und den Teilen von Java, bei denen Oracle sehr viel Wert darauf legt die eigenen Urheberrechtsansprüche zu betonen, ist sicher ein richtiger Schritt. Aber es wird weltweit viel Arbeit machen die betroffenen Systeme auf allen Ebene darauf umzustellen.

Bis sich dieser Aufwand dann gelohnt haben wird, wird viel Zeit ins Land gehen. Und wer weiß ob es nicht Fälle gibt in denen dieser Aufwand das noch fehlende Argument liefert sich von Java im Backend abzuwenden.

Release 1.3.0 des Anti-DoS-Valves – mit Docker

Heute habe ich ein neues Release des Apache Tomcat Valves zur Begrenzung von massenhaften Zugriffen auf Tomcat Server auf Github veröffentlicht. Funktional hat sich dabei nicht viel getan, abgesehen von der Anpassung des Codes an Tomcat 10 und den dort nun anders benannten Servlet API Paketen. Aber dazu schreibe ich noch etwas in einem anderen Post. Die wesentliche Verbesserung liegt hier:

Docker Logo

Im /docker-Unterzeichnis des Projekts findet sich nun eine Docker-Konfiguration, mit der sich sehr einfach ein Tomcat 10 Server mit einkonfiguriertem Valve und einer Testmöglichkeit als Containerinstanz starten lässt. Entweder um das Ganze einmal schnell auszuprobieren, oder um bei eigenen Weiterentwicklungen ohne Basteleien und manuelles Hin- und Herschieben von JARs und Konfigurationen schnell die letzte Version des Valves direkt ausführen zu können.

Ich bin noch nicht so routiniert mit Docker, daher gehe ich hier einmal die Inhalte des /docker-Verzeichnisses durch und falls eine Leserin oder ein Leser dazu Verbesserungsvorschläge hat freue ich mich:

Dockerfile

Es ist nahezu leer:

FROM tomcat:10-jdk16-corretto

Nur das Tomcat 10 Image von Dockerhub wird referenziert. Ich hätte hier schon die angepasste server.xml oder das Valve Jar in das Image bringen können, aber gerade für Entwicklungszwecke erschien es mir zu umständlich jedes Mal ein neues Image zu bauen. Tatsächlich hätte es das Dockerfile im Moment gar nicht gebraucht, es hilft in der jetzigen Form nur die unten beschriebenen Kommandozeilen von späteren Änderungen des verwendeten Tomcat Images zu isolieren.

Falls man aber ein Tomcat Image für produktive Zwecke bauen möchte, in dem das Valve schon enthalten ist, wäre es sicher eine gute Idee die Valve Anpassungen bereits hier zu integrieren und mindestens das Jar schon in das Image aufzunehmen.

README.md

Hier sind die Kommandos enthalten, die es braucht um den Tomcat samt Valve zu starten. Interessant ist dabei eigentlich nur dieses Kommando:

docker run \
   --mount type=bind,source="%cd%"/../target/anti-dos-valve-1.3.0.jar,target=/usr/local/tomcat/lib/anti-dos-valve.jar,readonly  \
   --mount type=bind,source="%cd%"/server.xml,target=/usr/local/tomcat/conf/server.xml,readonly  \
   --mount type=bind,source="%cd%"/advdemo/,target=/usr/local/tomcat/webapps/advdemo/,readonly \
   --name AntiDoSValveDemo \
   -p 8013:8080 \
   -it antidosvalve_demo

In den drei mount-Anweisungen werden drei Dateien/Order aus dem Host-System in den Container abgebildet und überdecken dabei die schon vorhandenen Dateien im Container:

  • JAR: Das Jar, welches sich eins höher im /target-Verzeichnis befindet, wird in das /lib-Verzeichnis des Tomcats im Container gebracht und steht dem Server damit zur Verfügung. Das Jar muss natürlich vorher schon gebaut worden sein
  • server.xml: Hier wird eine angepasste Version der server.xml, die sich im Tomcat Image befindet, in den Container gesetzt. Dadurch werden die Valve Konfigurationen wirksam
  • /advdemo: Dieser Ordner enthält eine JSP – siehe unten – und wird als Webapp eingebracht, die der Tomcat klaglos ausführt

Alle mounts werden als readonly deklariert, damit in keinem Fall der Server im Container etwas zurückschreiben kann. mounts benötigen absolute Pfad, damit die Anweisung trotzdem immer funktioniert wird der aktuelle Pfad eingesetzt. Hier für Windows, für Linux sind entsprechende Anpassungen notwendig.

Es wird ein Portmapping gemacht, dabei wird nicht der sonst übliche Port 8080 verwendet, um nicht in Konflikt mit anderen auf dem Host laufenden Servern zu kommen.

Schließlich wird ein Name vergeben, unter dem sich der Container ansprechen lässt. Das verhindert, dass man einen beendeten Container einfach erneut starten kann und ihn erst entfernen muss. Ich bin mir noch nicht sicher, ob ich das wirklich praktisch finde.

server.xml

Die server.xml Datei, mit der Tomcat 10 Distribution mitgeliefert wird, um 2 Valve Konfigurationen ergänzt. Wenn man alternative Konfigurationen ausprobieren will kann kann man einfach die Datei bearbeiten und den Container neu starten.

/advdemo-Ordner

Hier ist nur eine JSP enthalten, die für die Demonstration des Marking Modes des Valves benötigt wird. Sie wird als eigene Webapp in den Tomcat gebracht und ist dann dort ausführbar.

Schnelle Iterationen

Durch die Containerlösung, die sich in Sekunden hochfährt, ist es einfach neue Versionen des Valves, der server.xml oder auch der JSP auszutesten, deutlich schneller als mir das bisher mit einer separaten Tomcat Instanz möglich war. Auch der rasche Wechsel zwischen unterschiedlichen server.xml Dateien ist einfach, man muss sich nur eine alternative Kommandozeile zurechtlegen. Und dafür ist keine ‚Magic‘ mit in Eclipse und Co. integrierten Tomcats notwendig, alles sind einfache Kommandozeilen, die sich schnell ausführen und und anpassen lassen.

Mir gefällt das gut 😀🐳

Die Tasten an einem ASUS Chromebook ausbauen

Die Vorbesitzer*innen meines aktuellen ASUS C443T Chromebooks haben wohl häufig Chips beim Streaming gegessen, jedenfalls waren einige Tasten sehr schwergängig. Obwohl man unzählige Videos zu Tastaturreparaturen im Netz findet ist mir keins untergekommen, welches die (De)Montage genau dieses Modells zeigt. Daher hier mein Beitrag zum großen Wissensspeicher:

Die Tasten verhalten sich etwas unterschiedlich:

  • Die normalgroßen Tasten sind am oberen Rand eingeklickt, man zieht sie also dort hoch bis sie ausrasten. Das kleine Gerüst darunter ist mit 4 Haken am Grund befestigt, ich konnte es beschädigungslos lösen in dem ich auch am oberen Rand ansetzte
  • Bei den schmalen Tasten am oberen Rand der Tastatur ist es genau umgekehrt, aber das Prinzip identisch
  • Die Leertaste hat eine etwas andere Konstruktion mit zwei Drähten, an denen die Taste eingeklemmt ist. Hier scheint es egal zu sein, von welcher Seite man zieht, aber vielleicht gibt es hier auch spezielles Werkzeug mit dem man weniger den Eindruck hat gleich etwas zu zerbrechen
  • Auch andere große Tasten wie Shift haben zusätzliche Drähte, hier sind weitere Bauformen zu finden

Ich habe hier Hilfsmittel verwendet, die sonst für den Tausch von Handydisplays verwendet werden, also einen kleinen Schraubendreher und ein Plektrum.

Beim Einbauen geht man umgekehrt vor, hängt also die Tasten zuerst auf der Seite ein, in der sie nicht einklicken. Beim Andrücken der kleinen Gerüste muss man etwas darauf achten die Metallhaken nicht zu verbiegen.

Das eKVV erreicht sein 3. Betriebsjahrzehnt

In den BIS News habe ich diesen kurzen Post über das 20. Betriebsjahr des eKVVs eingestellt. Man hätte mehr schreiben können, aber es gab in der Vergangenheit auch schon umfangreichere Texte zu anderen, runden Geburtstagen (10 Jahre Projekt BIS) oder inhaltlichen Meilensteinen (die 2.000.000ste Prüfungsleistung im System). Irgendwann fängt man sich zu wiederholen 😅

Baukräne an der Universität Bielefeld

Und wenn der 20. Geburtstag mitten eine Zeit fällt, in der sich so viel bewegt – der Start des Medizin-Studiengang rückt näher und damit vielfältige Veränderungen im Grundsystem – ist das eher ein Anlass nach vorne zu blicken, als zurück.

Trotzdem … wenn ein technisches System allmählich ein Alter erreicht, in dem man als Mensch endgültig als Erwachsene*r gilt, ist das bemerkenswert, um so mehr wenn die Perspektive nach heutigen Stand ohne Deadline für eine Ablösung oder ein Nachfolgesystem ist.

Am Ende der langen Geschichte des BIS (bis Ende 2016) findet sich ein Abschnitt zur technologischen Zukunftsfähigkeit des Gesamtsystems. Das dort gesagte gilt für mich auch weiterhin: Die Nutzung von Java als Grundtechnologie gibt uns die Handlungsoptionen und das große, lebendige Ökosystem, welches wir für Weiterentwicklungen brauchen. Auch große Überarbeitung wie die aufwändige Umstellung der Oberflächen auf das aktuelle Corporate Design und die damit endlich erfolgende Einführung einer responsiven Darstellung lassen sich bewältigen, die hohen Kosten (in Form von Personalressourcen) entstehen eher durch die Komplexität und den Umfang der BIS Anwendungen und weniger durch die eingesetzte Grundtechnologie.

Im Moment spricht daher nichts dagegen, dass das eKVV in 10 Jahren weiterhin das zentrale System für die Lehrplanung an der Universität Bielefeld ist. Die sich dann mit einem Medizinstudiengang im Vollausbau, vielen neuen Gebäuden und vielleicht auch durch die Nachwirkungen der Corona-Online-Zeit sehr verändert haben wird.

PS.

Beim Schreiben des BIS News Posts habe ich den alten Screenshot des eKVVs aus dem Jahr 2003 herausgesucht:

Screenshot des eKVVs aus dem Jahr 2003

Und irgendwie gefällt mir die Buntheit 😌 und die Läuferin, die wir damals in den Verlauf gesetzt haben. Vielleicht auch einfach nur weil weil der Kontrast zu heutigen Seiten einfach so groß ist.

PPS.

Wer mehr über zur Entstehung des eKVVs lesen möchte: In der Geschichte des Bielefelder Informationssystems bis zum Jahr 2016 findet sich eine Beschreibung.

Endlich: Emacs unter ChromeOS 😆

Screenshot ChromeOS mit Linux Anwendungen

Das ist ein Screenshot aufgefertigt auf dem ChromeBook, das gestern ankam. Das erste Modell hier im Haus, auf dem sich Crostini ausführen läßt. Damit hat ChromeOS Linux Container erhalten und so die Option Tools wie git oder eben Emacs nativ auszuführen. Und Google Drive lässt sich einfach mounten. Sehr schick 😊

Java APIs in Android: Der Rechtsstreit ist entschieden

Die Auseinandersetzungen zwischen Oracle und Google um Google’s Nutzung von Java APIs in Android sind offenbar vorbei: Das Oberste Gericht der USA hat entschieden, dass diese Nutzung unter den Fair Use fällt. Neben IT und Tech Seiten wie Heise und The Verge haben auch SPIEGEL und FAZ direkt darüber berichtet. Das Urteil ist spannend zu lesen:

Fast 11 Jahre vor Gericht

Zusammenfassungen der verschiedenen Etappen dieser Auseinandersetzung zwischen den beiden IT Giganten lassen sich an verschiedenen Stellen im Netz finden, für mich verbindet sich die Anfangsphase noch mit intensiven Diskussionen darüber beim schon lange eingestellten Google+. Dort haben sich naturgemäß die eher Google-freundlichen Diskutanten eingefunden, aber die Frage ob Google sich unrechtmäßig der kreativen Leistung anderer bedient hat, oder ob Oracle mit seinem Versuch Programmierschnittstellen nachträglich als urheberrechtlich geschützte Werke zu interpretieren die Softwarewelt aus ihren gewohnten Angeln hebt, war heiß umstritten. Ich war da eher auf der Seite, die Oracles Klagen strikt ablehnte. Die folgende Karikatur aus dieser Zeit zu den Organisationsstrukturen verschiedener IT Unternehmen ist mir daher direkt wieder eingefallen:

Humoristische Organisationscharts verschiedenen US IT Unternehmen: Apple, Google, Microsoft, Oracle, Facebook, Amazon
Comic von Manu Cornet

Interessante Auszüge aus dem Urteil

Das Urteil kann man hier als PDF vom Heise Verlag abrufen. Es ist durchaus lesenswert und auch ohne umfangreiche juristische Kenntnis durchaus verständlich. Ein paar Abschnitte habe ich mir rauskopiert:

‚To decide no more than is necessary to resolve this case, the Court assumes for argument’s sake that the copied lines can be copyrighted, and focuses on whether Google’s use of those lines was a “fair use.”

Das oberste Gericht hat also die für die IT Welt – insbesondere auch die Open Source Community – wesentliche Frage ob eine API überhaupt ganz grundsätzlich ein Urheberrecht haben kann, nicht entschieden. Und da hatte Oracle in früheren Instanzen einen Etappensieg errungen. Auch wenn die Oracles Niederlage nun vielleicht einen abschreckenden Effekt hat, grundsätzlich ist damit zumindest in den USA wohl mit weiteren Verfahren zu rechnen, in denen API-Nutzungen Anlass zu Gerichtsverfahren geben. Und nicht jede Beklagte ist so mächtig und wohlhabend wie Google.

‚Computer programs differ to some extent from many other copyrightable works because computer programs always serve a functional purpose.‘

Das Gericht hat sich aber Gedanken dazu gemacht, in wie weit das Urheberrecht eigentlich auf Software angewendet werden kann.

‚As a result, this code is different from many other types of code, such as the code that actually instructs the computer to execute a task. As part of an interface, the copied lines are inherently bound together with uncopyrightable ideas (the overall organization of the API) and the creation of new creative expression (the code independently written by Google). Unlike many other computer programs, the value of the copied lines is in significant part derived from the investment of users (here computer programmers) who have learned the API’s system.

Hier macht das Gericht zum ersten, aber nicht zum letzten Mal, einen interessanten Punkt: Eine API – zumindest die, um die es hier konkret geht – gewinnt dadurch an Wert, dass Programmierer*innen sie erlernen und dafür Zeit investieren. Damit wird die Wertgenerierung nicht mehr allein den Erschaffer*innen zugebilligt, sondern jede Java Entwickler*in, die diese APIs gelernt hat, vergrößert durch ihr Investment den Wert der Sprache.

‚Google copied only what was needed to allow programmers to work in a different computing environment without discarding a portion of a familiar programming language.‘

Auch hier wird wieder der Verweis auf das existierende Knowhow von Entwickler*innen gemacht und das es Googles Vorgehensweise diesen ermöglicht habe ihr Wissen nun in einem weiteren Umfeld zu nutzen. Dieses Wissen also wertvoller wurde.

‚Google copied approximately 11,500 lines of declaring code from the API, which amounts to virtually all the declaring code needed to call up hundreds of different tasks. Those 11,500 lines, however, are only 0.4 percent of the entire API at issue, which consists of 2.86 million total lines. In considering “the amount and substantiality of the portion used” in this case, the 11,500 lines of code should be viewed as one small part of the considerably greater whole. As part of an interface, the copied lines of code are inextricably bound to other lines of code that are accessed by programmers. Google copied these lines not because of their creativity or beauty but because they would allow programmers to bring their skills to a new smartphone computing environment.‘

Und noch einmal der Verweis auf die Möglichkeit für Entwickler*innen ihr Knowhow in einer neuen Umgebung zu nutzen. Verbunden mit der Entlastung von Google, die eine vergleichsbare API oder gleich eine ganze Programmiersprache auch leicht hätten selbst entwickeln können (was sie in späteren Jahre mit Dart und Go taten).

‚The fourth statutory factor focuses upon the “effect” of the copying in the “market for or value of the copyrighted work.” §107(4). Here the record showed that Google’s new smartphone platform is not a market substitute for Java SE. The record also showed that Java SE’s copyright holder would benefit from the reimplementation of its interface into a different market

Mir persönlich gefällt, dass das Gericht den positiven Einfluss von Android auf das ganze Java Ökosystem hier honoriert. Schon bei den ersten Diskussionen gab es diesen Punkt, wenn es Oracle wirklich darum gegangen wäre Java zu pushen, dann hätten sie direkt mit Google zusammenarbeiten können. Und offenbar ist im Laufe der Jahre das Argument von Oracle verloren gegangen, wonach Google mit Android das ‚florierende‘ Ökosystem von Java ME Handys vernichtet habe.

Die Entwickler*innen als eigene Partei

Abgesehen von der eigentlichen Urheberrechtsfrage, die vermutlich in anderen Gerichtsverfahren – vielleicht nicht nur in den USA – entschieden wird, finde ich den Aspekt, das wir als Entwickler*innen eine wesentliche Rolle in solchen Erwägungen spielen, sehr spannend:

Wenn wir uns auf eine Sprache / API / Technologie einlassen kostet uns dies Zeit und vielleicht auch Geld und eine Technologie kann sich kaum durchsetzen ohne eine entsprechende Menge von Menschen, die sich damit gut auskennen. Und unsere Interessen sind dabei durchaus anders als die der potentiellen Urheberrechtsinhaber*innen: Für uns ist es attraktiv die Wahl zu haben, zwischen Werkzeugen und zwischen Implementierungen einer API, und jedes neue Feld, in dem wir unsere Kompetenz einsetzen können, ist zunächst einmal gut für uns und den Wert unseres Wissens.

Man wird sehen, ob dieser Aspekt auch in zukünftigen Gerichtsverfahren eine Rolle spielen wird.