Möchten Sie jetzt wissen, wie eine Antwort von einem echten Webserver aussieht, dann werfen Sie einmal einen Blick in die Ausgabe des Befehls wget --spider -S "https://www.zeit.de/index". Das ist ein Spider-Request von Wget, bei dem es nur darum geht, die Antwort eines Servers herauszufiltern. Der informiert in der ersten Zeile mit HTTP/1.1 200 OK, dass er mit einer HTTP-Anforderung zufrieden ist. Mit weiteren Zeilen in Form von Wertepaaren (etwa Connection: keep-alive, Content-Length:) sendet er zusätzliche Informationen oder Anweisungen zurück.
Es scheint sich bei diesem Dienst auch um einen gut abgesicherten Webserver zu handeln, denn er gibt nicht preis, um was für ein Server-Programm es sich genau handelt. Viele Server outen sich an dieser Stelle zum Beispiel als Server: nginx – nicht ratsam, weil es Angreifern die Arbeit erleichtert. Rein technisch gesehen ist die Information auch gar nicht notwendig.
FIFO-Datei
Netcat steht auf nahezu jedem Linux-System zur Verfügung und lässt sich mit etwas Kreativität für viele Zwecke verwenden, wobei es auch seine Grenzen hat. Basisoperationen im Netzwerk lassen sich damit gut emulieren, komplexe Interaktionen dagegen nur schwer oder gar nicht. Den Plan, Apache oder Nginx mit Netcat Konkurrenz machen zu wollen, muss man definitiv aufgeben.
Wenn Sie möchten, dass Netcat dauerhaft an einem Port lauscht und auch verschiedene Antworten versenden kann, müssen Sie es in einer Schleife mit einer FIFO-Datei kombinieren. Das Kürzel FIFO steht für das Prinzip “first in, first out”. Die Informationen kommen also in derselben Reihenfolge wieder aus der Datei, in der sie hineingeschrieben wurden [3]. Listing 3 stellt das exemplarisch dar. Später zeigen wir noch eine Möglichkeit, diese Schleife per Log-Funktion zu optimieren.
Listing 3
Netcat-Antwort
while true; do antworten < $FIFO_GET | netcat -l $HTTP_GET_PORT > $FIFO_GET done
Die FIFO-Datei sorgt dabei für eine bessere Kommunikation zwischen Netcat und der Funktion antworten, die Listing 4 zeigt. Netcat lauscht am angegebenen Port und schreibt in die FIFO-Datei. Auf der linken Seite der Pipe sehen Sie den Aufruf der Funktion, die die Anfrage des Browsers aus der FIFO-Datei herausliest. Sie wertet sie aus und schickt dann durch die Pipe hindurch eine passende Antwort zu Netcat zurück, die einen HTML-Header und HTML-Daten enthält. Die Funktion antworten entscheidet, was an den Browser zurückgegeben wird.
Listing 4
FIFO-Datei
function antworten () {
read get_or_post adresse httpversion
if [ ${#adresse} = 1 ]; then
list_dir
elif [ ${#adresse} -gt 1 ]; then
return_file $adresse
fi
}
Diese Variante stellt bereits eine ziemlich leistungsfähige Lösung dar. Beträgt die Länge der Browser-Anfrage 1 (Zeile 3), dann lautet sie /, falls nicht (Zeile 5), dann soll eine Datei aus dem Root-Verzeichnis wiedergegeben werden. Um den Webserver dazu zu veranlassen, dass er die im Root-Ordner enthaltenen Dateien wiedergibt, genügt erst einmal ein ganz schlichtes ls Verzeichnis. Das Resultat gilt es dann aber noch in passenden HTML-Code einzubetten, damit der Browser etwas damit anfangen kann und auch Links funktionieren (Abbildung 2). Anderenfalls käme keine richtige Interaktion zwischen dem Server und dem Browser zustande. Um eine Auflistung eines Verzeichnisses in HTML-Code umzuwandeln, empfiehlt sich der Einsatz des Stream-Editors Sed [4].

Abbildung 2: Der selbst gebaute Webserver liefert jetzt den Inhalt des Root-Verzeichnisses als Listing aus.
Listing 5 zeigt die Funktionen, die für die Rückgabe des Inhalts des Root-Ordners und auch einzelner Seiten darin sorgen. Die Ausgabe des Verzeichnisinhalts übernimmt in der Funktion list_dir (ab Zeile 1) ein einfacher Ls-Befehl, dessen Resultat Sed dann in lupenreines HTML verwandelt. Die durch die Funktion aus Listing 2 erzeugten Dateien, die im Root-Ordner liegen, enthalten bereits HTML-Code. Der Server gibt sie über die Funktion return_file ab Zeile 19 mit einem passenden Header an den Browser zurück.
Listing 5
Ausgaben
function list_dir () {
local ausgabe=$( ls --hide=upload -1 $HTTP_HOME | sed -r '
1 i<html><head><meta charset="utf-8"><title>Inhalt</title></head>\
<body style="margin: 45px; font-family: sans-serif">
s#(.*)#<li><a href="http://1">\1</a></li>#
$ a</body></html>
' )
local content_length="Content-Length: $( cat <<<$ausgabe | wc --bytes )"
cat <<<$ausgabe | sed '
1 i HTTP/1.1 200 OK
1 i Server: Dein GET-SERVER
1 i Connection: close
1 i '"$content_length"'\n
'
}
function return_file () {
inhalt=$( cat ${HTTP_HOME}/${1:1} )
if [[ $? -eq 0 ]]; then
laenge=$( cat <<<${inhalt} | wc --bytes )
cat <<<${inhalt} | sed -r '
1 i HTTP/1.1 200 OK
1 i Server: Dein GET-SERVER
1 i Connection: close
1 i Content-Length: '"$laenge"'\n'
else
cat <<-FEHLER
HTTP/1.1 404 Not Found
Connection: close
Content-Length: 44
Die angeforderte Seite gibt es leider nicht!
FEHLER
fi
}
Dadurch, dass Netcat in der Schleife fortlaufend für Anfragen zur Verfügung steht und einen Header sowie das passende HTML dazu versendet, meint ein Browser im lokalen Netzwerk es mit einem echten Webserver zu tun zu haben.
Es kann aber auch der Fall auftreten, dass der Anwender im Browser manuell eine Seite anfordert, die es gar nicht gibt. Das führt zum berüchtigten Fehler 404, den Sie bestimmt schon einmal im Web gesehen haben [5]. Auch der Eigenbau-Webserver kann mit diesem Feature aufwarten. Falls der Cat-Befehl in der ersten Zeile der Funktion return_file (Zeile 20) einen Fehler auslöst, wird der Else-Zweig ab Zeile 28 ausgeführt. Im Webbrowser erscheint dann die Meldung, dass die angefragte Seite nicht existiert.
POST-Anfragen
Im Gegensatz zu GET-Anfragen, bei denen der Webbrowser Dateien heruntergeladen möchte, gibt es auch POST-Anfragen, die ein Browser an einen Webserver senden kann. Stellen Sie sich das so vor, als wollten Sie etwas auf einem Social-Media-Portal posten. Sie geben Text, Bilder oder auch Videos in eine dafür vorgesehene Box ein und drücken anschließend auf Posten. Der jeweilige Inhalt wird dann zum Server hochgeladen und erscheint anschließend auf Ihrem Profil. Unser einfacher Server verfolgt erst einmal nur den Zweck, Dateien von einem Browser aus hochzuladen und im Ordner uploads/ zu speichern.





