seeseekey.net - Invictus Deus Ex Machina

Vor einigen Tagen begegneten mir einige Dateien, deren Inhalts größtenteils aus der Zeichenfolge EF BF BD EF BF BD EF BF BD (hexadizimal) bestand. Eigentlich sollte in den entsprechenden Dateien binäre Daten enthalten sein. Damit stellte sich nun die Frage: Was war passiert?

EF BF BD EF BF BD EF BF BD EF BF BD EF BF BD EF BF BD EF BF BD EF BF BD EF BF BD

Auf den ersten Blick sah das ganze so aus, als ob ein Großteil der Datei durch Datenmüll ersetzt wurde. Schaut man sich die Zeichenfolge allerdings genauer an, so wird man feststellen das sich die Folge EF BF BD immer und immer wieder wiederholt. Bei dieser Zeichenfolge handelt es sich um die hexadezimale Schreibweise des Unicode-Zeichens für den Replacement Character welcher meist durch eine Raute mit einem Fragezeichen (�) dargestellt wird.

Eindeutiger wäre das Problem gewesen, wenn die erzeugten Dateien mit der Zeichenfolge EF BB BF begonnen hätte. Dabei handelt es sich um das Byte Order Mark für eine UTF-8 kodierte Datei. Damit wäre gleich klar geworden, das die enthaltenen Daten nicht zu einer Datei mit binären Inhalten passen. Doch wie sind diese Dateien nun entstanden? Der Ursprung der Dateien ist in einer Java-Applikation zu finden, welche diese Dateien erstellt. Diese kopierte die Daten von A nach B, im Quelltext (man ignoriere das fehlende try with resources) könnte das so ausgesehen haben:

FileInputStream fileInputStream  = new FileInputStream("binary.dat");
FileWriter fileWriter = new FileWriter("binary-copied.dat");

int byteData;

while ((byteData = fileInputStream.read()) != -1) {
    fileWriter.write(byteData);
}

fileInputStream.close();
fileWriter.close();

Hier wird ein FileInputStream geöffnet und dieser Stück für Stück mit einem FileWriter in die Zieldatei geschrieben. Genau an dieser Stelle entsteht das Problem – der FileWriter ist nämlich ein zeichenbasierter Writer, das bedeutet das sämtliche Zeichen, die mit diesem geschrieben werden, kodiert werden. Wenn nun bei dieser Kodierung ein Zeichen gefunden wird, welches nicht im Unicode abgebildet werden kann, so erhält dieses Zeichen den Wert EF BF BD – besagter Replacement Character. Damit ist dann auch erklärt warum die binären Dateien hauptsächlich nur noch aus diesen Zeichen bestanden. Die echten Daten wurden beim Kopiervorgang größtenteils schlicht und ergreifend in den Replacement Character konvertiert, da sich für diese Daten keine Entsprechung im Unicode fand.

Den freien Suchserver Elasticsearch kann man, wie das Wort Suchserver es dezent andeutet, als Server betreiben. Allerdings ist es manchmal nicht gewünscht einen dedizierter Server zu betreiben. In einem solchen Fall kann man den Elasticsearch-Server in eine Java-Applikation einbetten. Der sicherlich häufigste Fall für eine solche Einbettung ist dabei die Nutzung zu Testzwecken (z.B. Unit-Tests zum Test der Suchergebnisse). Im ersten Schritt sollte in das Java-Projekt die entsprechende Abhängigkeit zum Projekt hinzugefügt werden. In diesem Beispiel wird dabei auf einem auf Maven basierenden Projekt ausgegangen – in diesem muss die pom.xml entsprechend erweitert werden:

<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>2.3.4</version>
</dependency>

Damit wurde Elasticsearch dem Projekt hinzugefügt. Nun muss der eigentliche Server im Java-Projekt gestartet werden. Dafür werden nur wenige Zeilen Quellcode benötigt:

Settings.Builder elasticsearchSettings = Settings.settingsBuilder()
    .put("http.enabled", "true")
    .put("path.data", "data")
    .put("path.home", "home");

Node node = nodeBuilder()
    .local(true)
    .settings(elasticsearchSettings.build())
    .node();

In diesem Beispiel werden im ersten Schritt die Einstellungen für Elasticsearch definiert. Dabei wird unter anderem der HTTP-Modus aktiviert. Wenn dieser deaktiviert ist, ist die Kommunikation per HTTP nicht mehr möglich. Stattdessen kann dann nur noch die Kommunikation über das Transport-Interface genutzt werden. Dieses Interface wird im Normalfall für die interne Kommunikationen zwischen einzelnen Elasticsearch-Clustern genutzt – allerdings ist eine Nutzung mit dem Elasticsearch-Java-Client ebenfalls möglich. Mit dem aktivierten Modus, ist die Entwicklung einfacher (z.B. für den Einsatz von Analyse-Tools) und die Konfiguration näher an der Praxis. Standardmäßig horcht der Elasticsearch-Server dabei auf dem Port 9200 – in diesem Beispiel wäre er über die URL:

http://localhost:9200

erreichbar. Nachdem die Einstellungen angelegt wurden, werden diese dem NodeBuilder übergeben, welcher schlussendlich den Elasticsearch-Server hochfährt. Nachdem dieser hochgefahren wurde, kann die Nutzung des selben beginnen.

Wenn man Let’s Encrypt Zertifikate erzeugt, so landen diese im Ordner /etc/letsencrypt/. Die Rechte sind dabei so gewählt das nicht privilegierte Prozesse auf diese Zertifikate nicht zugreifen können. Läuft nun z.B. ein Server mit solchen Rechten, so kann er das Zertifikat nicht ohne weiteres nutzen. Um diesem Umstand zu beseitigen sollte eine neue Nutzergruppe angelegt werden:

groupadd tls-certificates

Dieser Gruppe wird nun der Nutzer hinzugefügt, welcher den Serverdienst betreibt:

usermod -a -G tls-certificates git

Damit wird der Nutzer git der Gruppe tls-certificates hinzugefügt. Nun müssen nach der Zertifikatsgenerierung die Berechtigungen angepasst werden:

#!/bin/sh
service gogs stop
letsencrypt renew --agree-tos
chgrp -R tls-certificates /etc/letsencrypt
chmod -R g=rX /etc/letsencrypt
service gogs start

In diesem Skript wird im ersten Schritt der Service gestoppt. Anschließend werden neue Zertifikate erzeugt und die Berechtigungen angepasst. Damit kann die Gruppe tls-certificates auf die Zertifikate zugreifen. Danach wird der Service wieder gestartet, was nun dank Zugriff auf die Zertifikate ohne Probleme funktioniert.

Möchte man bestimmte Seiten innerhalb eines WordPress umleiten, so gibt es neben der Möglichkeit dies über den Server zu tun, eine Reihe von Plugins. Für einen Einsteiger könnte die verwendete Syntax der meisten Plugins teilweise zu kompliziert (man denke nur an reguläre Ausdrücke und ähnliches) sein.

Simple 301 Redirects

Simple 301 Redirects

Einfacher kann diese Aufgabe mit dem WordPress-Plugin Simple 301 Redirects erledigt werden. Mit Hilfe des Plugins können einfach Umleitungen angelegt werden. Dabei werden Wildcards durch das *-Zeichen unterstützt und sind somit auch dem Einsteiger nutzbar. Das Plugin ist freie Software und unter der GPL2 (und neuer) lizenziert.

Preis: Kostenlos

Mit Hilfe des Befehls dd ist es unter Linux und vielen anderen unixoiden Systemen möglich, eine Festplatte mit Nullen zu überschreiben. Ist die Festplatte dabei z.B. als sda im System registriert, so funktioniert das Überschreiben mit folgendem Befehl:

dd if=/dev/zero of=/dev/sda

Je nach Festplattengröße kann der Vorgang dabei durchaus einige Stunden in Anspruch nehmen.

Ein REST-API von Hand entwickelt, benötigt eine Dokumentation, ein entsprechenden Server und eventuell einige Clients als Referenz. Einfacher wird es mit einem Framework wie Swagger. Unter Zuhilfenahme der Beschreibungssprache YAML können mit Hilfe des Frameworks REST-APIs, Dokumentation, Server und Clients generiert werden.

Der Swagger Editor

Der Swagger Editor

Doch Swagger versteht sich nicht nur als Framework, sondern auch als Spezifikation. Begonnen wurde mit der Entwicklung bereits im 2010; die Swagger Specification trägt seit Anfang Januar 2012 offiziell den Namen OpenAPI Specification und beschreibt eine maschinenlesbare Interfacedefinitionen einer REST-API. Ähnliches wurde unter anderem schon mit WSDL und WADL versucht – alles Konzepte bzw. Beschreibungsprachen welche an ihren eigenen Limitationen gescheitert sind und wenn überhaupt nur noch sporadisch genutzt werden.

Betreut und weiterentwickelt wird die Spezifikation nun von der Open API Initiative, zu der namenhafte Firmen wie Google, PayPal, IBM, Atlassian und Microsoft gehören. Die Spezifikation als solche ist freie Software und auf GitHub zu finden. Sie ist unter der Apache Lizenz lizenziert. Aktuell ist die Spezifikation in der Version 2.0 veröffentlicht.

Auf der offiziellen Webseite von Swagger findet sich ein Editor, mit welchem APIs definiert werden können und anschließend exportiert werden können. Der Editor kann dabei Server unter anderem in den Sprachen bzw. für die Framworks Haskel, Jax-RS, Node.js, Python, Rails und PHP erzeugen. Bei den Clients ist die Auswahl noch größer. Diese können in C#, HTML, Dart, Go, Groovy, Java, Javascript, Objective C, Perl, PHP, Ruby, Scala, Swift und vielen weiteren Sprachen erzeugt werden.

Neben dem Editor kann für die Erzeugung von Clients auch der Swagger Codegen genutzt werden. Dabei handelt es sich um eine Java-Anwendung um die Clients lokal auf dem eigenen Rechner zu erzeugen. Der Editor und viele weitere Tools rund um Swagger sind ebenfalls auf GitHub zu finden. – auch diese sind freie Software, welche unter der Apache Lizenz stehen.

Wenn man unter Linux eingehende und abgehende Pakete kontrollieren, umleiten oder blockieren möchte, so kann man für diese Aufgabe iptables nutzen. Das Problem an iptables ist das es relativ kompliziert in der Anwendung ist.

Damit man hier nicht im Regen steht, gibt es (neben vieler anderer Firewall-Lösungen für Linux) die uncomplicated firewall kurz ufw. Technisch gesehen handelt es sich bei ufw um ein Frontend für iptables. Seit der Version 8.04 (Hardy Hedon) ist ufw ein Bestandteil der Ubuntu-Distribution. Neben Ubuntu ist ufw unter anderem auch für Debian verfügbar. Installiert werden kann ufw mittels des Befehls:

apt-get install ufw

Standardmäßig ist ufw deaktiviert, so das die Installation im ersten Schritt keinerlei Auswirkungen hat. Den aktuellen Status sowie die definierten Regeln können dabei mittels:

ufw status

eingesehen werden. Das könnte dann z.B. so aussehen:

Status: Aktiv

Zu                   Aktion      Von
--                   ------      ---
8080/tcp             DENY        Anywhere                                
22/tcp               ALLOW       Anywhere                            
22/tcp (v6)          ALLOW       Anywhere (v6)

Ist der Status auf inaktiv gesetzt, so muss ufw erst mit dem Befehl:

ufw enable

aktiviert werden. Hierbei muss man beachten das eine unbedachte Aktivierung von ufw dazu führen kann das man sich aus dem Rechner aussperrt. Dies liegt daran das am Anfang keinerlei Regeln definiert sind – so werden Pakete an Port 22 ignoriert; dies führt dazu das keine Verbindung per SSH möglich ist. Um dem vorzubeugen sollte eine Regel für SSH definiert werden, bevor ufw aktiviert wird:

ufw allow 22/tcp

Bei dieser Schreibweise handelt es sich um die vereinfachte Form zum Anlegen einer Regel. Neben allow, sind dabei auch die Werte deny und reject möglich. Während bei allow die Pakete passieren können, werden sie bei deny blockiert – im Gegensatz dazu wird bei reject der Absender darüber informiert das die Pakete abgelehnt wurden. Möchte man komplexere Regeln definieren nutzt man ufw nach folgendem Schema:

ufw allow proto tcp from any to 127.0.0.1 port 1234

Damit werden alle Verbindungen per TCP von beliebigen IP-Adressen an die spezifizierte IP-Adresse weitergeleitet. Als Port wird als Eingangs- und Zielport Port 1234 genutzt. Die Regeln welche ufw verwaltet werden in drei Dateien gespeichert:

/etc/ufw/before.rules
/var/lib/ufw/user.rules
/etc/ufw/after.rules

Abgearbeitet werden die Regeln in der Reihenfolge wie oben angegeben – somit könnte eine Regel in der user.rules-Datei definiert sein, welche anschließend von einer anderen Regel in der after.rules-Datei überschrieben wird. Die selbst definierten Regeln sind dabei in der user.rules zu finden. Neben dem Anlegen ist es natürlich auch möglich Regeln wieder zu löschen. Für obige SSH-Regel würde das dabei so aussehen:

ufw delete allow 22/tcp

Daneben ist es möglich ufw auf die Standardeinstellungen zu setzen. Dazu dient der Befehl:

ufw reset

Alle Regeln werden dabei auf die Standardeinstellungen zurückgesetzt. Für die bestehenden Regeln wird ein Backup im Verzeichnis /etc/ufw/ angelegt. Möchte man ufw wieder deaktivieren, so nutzt man den Befehl:

ufw disable

Beim beschriebenen reset-Befehl wird ufw ebenfalls deaktiviert. Damit sind die grundlegenden Konfigurationsschritte erklärt – für die weitergehende Konfiguration empfiehlt sich der entsprechende Artikel bei ubuntuusers.

Wenn man Dateien mit dem Midnight Commander von A nach B kopiert kann es passieren das man mit der Fehlermeldung:

Cannot chown target directory

konfrontiert wird. Das Problem ist das beim Kopieren die Attribute der Dateien ebenfalls übernommen werden. Dazu kopiert der Midnight Commander die Datei zum Zielort und versucht anschließend die Attribute anzupassen. Hierbei kann es passieren, das das Ziel die Anpassung der Attribute nicht unterstützt – dies führt zu besagtem Fehler.

Der Midnight Commander beim kopieren

Der Midnight Commander beim kopieren

Umgehen lässt sich der Fehler in dem im Kopierdialog der Punkt Attribute sichern deaktiviert wird. Damit werden die Dateien nur noch kopiert; eine Attributänderung findet nicht mehr statt.

Vor einiger Zeit hatte ich einen Twitter-Bot entwickelt welcher als Datenquelle unter anderem die Wikipedia nutzt. Dazu nutzt der Bot unter anderem eine Bibliothek um auf die MediaWiki-API zuzugreifen. Nun stellte ich fest das die Nutzung der API in diesem Fall allerdings überdimensioniert war. Stattdessen ist es möglich sich für eine beliebige MediaWiki-Seite denn Quelltext anzeigen zu lassen. Die URL sieht dabei wie folgt aus:

https://de.wikipedia.org/wiki/Machinima?action=raw

Durch den Parameter action=raw wird der Quelltext anstatt des HTML-Renderings ausgegeben und kann somit ausgewertet werden.

Unter Umständen kann es unter Ubuntu, oder anderen Distributionen basierend auf Debian passieren, das ein apt-get Vorgang fehlschlägt. Dies kann sich darin äußern das apt-get nicht mehr genutzt werden kann – stattdessen bekommt man folgende Meldung zu sehen:

E: Could not get lock /var/lib/dpkg/lock - open (11 Resource temporarily unavailable)
E: Unable to lock the administration directory (/var/lib/dpkg/) is another process using it?

Hintergrund ist das dpkg Sperrdateien mit dem Name lock anlegt und sie nach getaner Arbeit wieder entfernt. Bei plötzlichen Unterbrechungen wie z.B. einem Stromausfall kann es passieren das die Dateien nicht mehr entfernt werden. Lösen kann man das Problem indem man die entsprechenden Sperrdateien entfernt:

rm /var/lib/dpkg/lock
rm /var/lib/apt/lists/lock
rm /var/cache/apt/archives/lock

Abschließend sollte dpkg bzw. apt-get wieder ohne Probleme funktionieren.