Open Source im professionellen Einsatz

Shellskripte aus der Stümper-Liga - Folge 12: Ausgabe ins Netz umleiten

Bash Bashing

Eigentlich ist die Bash nicht als Tool für Netzwerkprogramme bekannt, obwohl sich einfache Protokolle damit gut implementieren lassen. Meist stellen Wrapper wie Netcat die Verbindung zum Netzpartner her. Mit kluger Ausgabeumleitung und einem überraschenden Pseudodevice geht das aber auch mit Bordmitteln.

Niemand ist vom Bash Bashing gefeit: In dieser Folge trifft es das Linux-Magazin selbst. Im Heft 09/10 rief die Redaktion ihre Leser auf, Bots zu entwickeln, die um die Wette würfeln sollten [1]. Um das erdachte Netzwerkprotokoll zu demonstrieren, druckte sie ein Beispiel ab, das sein Eingaben von Stdin holte und das seine Antworten auf die Standardausgabe schrieb. Ein Beispiel dafür ist der Bot von Leser Patrick Engel. Er nannte ihn augenzwinkernd selbstkritisch "Karl der Mittelmäßige" und entwickelte dazu den Demo-Bot weiter (siehe Listing 1).

Listing 1: Karl der
Mittelmäßige

01 #!/bin/bash
02 
03 name=karldermittelmaessige
04 nextsave=16
05 
06 while read command a1 a2 a3; do
07    case $command in
08       HELO)
09          echo "AUTH $name Ich bin bereit!"
10         ;;
11       TURN)
12          echo "Spielstand ${a1}:${a2}" >&2
13          if (($a1 >= $nextsave));; then
14            echo "SAVE Das reicht erstmal ..."
15            if (($nextsave >= 30)); then
16               nextsave=50
17            else
18               let nextsave=(50+$a1)/2
19            fi
20            active=0
21          else
22            echo "ROLL Auf gut Glück!"
23            active=1
24          fi
25         ;;
26       THRW)
27          if [ "$active" = "1" ]; then
28             echo "Ich würfle eine $a1." >&2
29             if [ "$a1" = "6" ]; then
30                echo "Du bist dran!" >&2
31                active=0
32             fi
33          else
34             echo "Du würfelst eine $a1." >&2
35             if [ "$a1" = "6" ]; then
36                echo "Ich bin dran!" >&2
37                active=1
38             fi
39          fi
40         ;;
41       WIN|DEF)
42          echo "Spielende: $command" >&2
43          exit 0
44         ;;
45       *)
46          echo "Unbekannt: $command" >&2
47         ;;
48    esac
49 done

Der Wettbewerb fand jedoch im Netzwerk auf einem dafür vorgesehenen Server statt. Um die Verbindung zu diesem herzustellen, schlug der Artikel vor, das Bash-Skript in den Aufruf von

nc -e Skript Host Port

einzubetten. Das sorgt dafür, zunächst eine TCP-Verbindung zu Host auf Port zu etablieren. Sobald »nc« den klassischen Drei-Wege-Handshake erledigt hat, verbindet er den Socket, mit der Standardein- und ausgabe. Anschließend überlädt sich der laufende Prozess mit dem »Skript«, das der Option »-e« folgt (siehe Abbildung 1).

Abbildung 1: Netcat fügt Netzverbindungen zu Shellskripten hinzu. Die Bash kann das sogar von Haus aus.

Abbildung 1: Netcat fügt Netzverbindungen zu Shellskripten hinzu. Die Bash kann das sogar von Haus aus.

Da Linux beim Überladen von Prozessen mit einem Systemaufruf der »exec()«-Familie seine Dateideskriptoren weitervererbt, darf das neue Programm im alten Prozessgewand nun einfach Daten ausgeben. Die landen dann automatisch beim Netzwerkserver. Die Eingabeseite funktioniert äquivalent, weil sich ein Socket, ist er erst einmal aufgebaut, bei einfachen Schreib- und Leseoperationen ziemlich ähnlich wie ein Deskriptor auf einer lokalen Datei oder einer Named Pipe verhält.

Externe Prozesse sparen

Aufmerksame Codepuristen und Bash-Kenner merkten nach ein paar Tagen per Wettbewerbs-Wiki [2] an, dass der zusätzliche Aufruf von »nc« gar nicht nötig sei und damit manches Problem gar nicht erst auftrete. So gibt es sich unterschiedlich verhaltende Versionen von Netcat, wie das Tool ursprünglich hieß. Seine Open-BSD-Variante etwa kennt die nützliche Option »-e« gar nicht. Neben »nc« selbst kennen die Distributionen dann auch noch »netcat«, »ncat« als Spin-off vom Nmap-Projekt sowie »socat« als Implementation mit Zusatzfunktionen. Wem das zu konfus ist, darf sich auch mit der Bash alleine zufriedengeben.

Die enthält nämlich schon seit vielen Jahren eine Kuriosität: Wer etwa versucht, die Datei »/dev/tcp/wettbewerb.linux-magazin.de/3333« zu öffnen, den verbindet die Bash nicht etwa mit einer speziellen Datei im Geräteverzeichnis, sondern der erhält einen Socket, an dessen anderer Seite der angegebene Host mit dem spezifizierten Port hängt [3]. Wer das einmal ausprobieren möchte oder gerade keinen Webbrowser zur Hand hat, gibt auf seiner Kommandozeile

echo -n "GET / HTTP/0.9nrnr" > 
 /dev/tcp/linux-magazin.de/80

ein. Das schickt eine etwas antiquierte, aber noch funktionierenden HTTP-Anfrage an den Server von Linux-Magazin Online und bittet um die Startseite »/«. Die Option »-n« von »echo« unterdrückt abschließende Newlines, denn Webserver erwarten hier typischerweise neben dem Newline »n« noch ein Carriage Return »r«, an dieser Stelle in HTTP sogar zwei Sequenzen davon.

Bidirektionale Verbindungen

Wer bei diesem Aufruf einen Fehler oder Warnung erhält, kommt leider nicht in den Genuss dieser Funktion. Ältere Versionen gaben antworten dann schlicht mit »No such file or directory«, weil es die Datei ja nicht gibt, modernere Versionen informieren den Anwender mit der Meldung »network operations not supported«, wenn die Bash nicht mit dem Flag »--enable-net-redirections« übersetzt ist. Debian beispielsweise deaktiviert die Funktion recht schnöde und weist in der Datei »/usr/share/doc/bash/README.Debian.gz« darauf hin, dass der Effekt mitunter unerwartete Effekte erzeugt.

Die Anfrage an den Webserver hat einen Schönheitsfehler: Er zeigt die Antwort nicht an. Zwar nimmt »cat < /dev/tcp/linux-magazin.de/80« lesenden Kontakt mit dem Server auf, allerdings erzeugt dazu eine neue, unabhängige Verbindung. Um denselben Socket sowohl zum Lesen wie zum Schreiben zu öffnen, ist ein anderer, nur selten in Skripten gelesener Trick notwendig.

Diesen Artikel als PDF kaufen

Als digitales Abo

Als PDF im Abo bestellen

comments powered by Disqus

Ausgabe 07/2013

Preis € 6,40

Insecurity Bulletin

Insecurity Bulletin

Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...

Linux-Magazin auf Facebook