Nachbearbeiten digitaler Quellen von Archive.org

Das Internet Archive Archive.org ist um die Langzeitarchivierung digitaler Daten bemüht und bietet seine Archivalien der Öffentlichkeit frei an. So findet man im Internet Archive die digitalen Kopien vieler gescannter Bücher deren Urheberschutz abgelaufen ist. Darunter sind viele Perlen der deutschen Klassiker, aber auch viele naturwissenschaftliche Klassiker wie bspw. Humboldt etc. Die Qualität der angeboten Scans schwankt dabei erheblich, teilweise fehlen ganze Seiten oder sind unleserlich, Gesamtwerke sind nicht immer vollständig. Eine andere Schwäche besteht darin, dass die bereitgestellten PDF- bzw. DJVU-Dateien oftmals durch starke Komprimierung aus den originalen Scandaten erzeugt wurden, weshalb ihre Anzeigequalität gegenüber den Originaldaten teilweise erheblich zurücksteht, was wiederum ihren Gebrauchswert als Ebook schmälert. Zumindest der letztgenannte Mangel kann behoben werden, sofern die originalen Daten zur Verfügung stehen. Was in diesem Fall zu tun ist, um bessere Resultate bei der Erzeugung von DJVU-Dateien zu erhalten, soll im folgenden erläutert werden:

Als Beispiel dient hier der Scan (unter Archive.org) einiger Postkarten mit Kupferstichen von Albrecht Dürer die der Verlag F.A. Ackermann in München herausbrachte. Der eingebettet Betrachter auf Archive.org zeigt die Stiche noch in einer ansprechenden Qualität an, die Überraschung erlebt man erst, wenn man sich eine Kopie als PDF- oder DJVU-File herunterlädt. Die feinen Details der Stiche sind durch die starke Kompression der angebotenen Dateien nicht mehr sichtbar. Glücklicherweise sind auf Archive.org in der Regel auch die Originaldaten der Scans vorhanden, gebündelt in einem TAR-Archiv tragen sie die Endung ..._orig_jp2.tar. Bei diesen Daten handelt es sich jedoch um die unbeschnittenen Daten, auch sind die Bilder in ihrer Lage noch nicht korrigiert. Die beschnittenen und ordentlich orientierten Bilder liegen oft in einem ZIP-Archiv mit der Endung ..._jp2.zip vor – falls nicht, muss man sich selbst an die Arbeit machen.

In unserem Beispiel mit Dürers Kupferstichen liegt jedoch das entsprechende ZIP-Archiv vor. Die JPEG-2000-Dateien des ZIP-Archivs müssen nun zuerst in ein etwas konventionelleres Format überführt werden, prinzipiell sollte man natürlich ein verlustfreies Format wählen, um keine weiteren Details zu verlieren. Ich benutze hier j2k_to_image aus der openjpeg-Suite. Anschließend sollte man die Bilder noch etwas nachschärfen, dazu benutze ich das Kommandozeilentool ImageMagick. Zum schärfen wird die Methode der unscharfen Maskierung (unsharp mask) eingesetzt, um Farbartefakte zu vermeiden wird das Bild vorher in den HSI-Farbraum zerlegt, von den Komponenten Hue, Saturation und Value (oder Intensität) wird nur die letztere, also das Bild mit der Intensität geschärft. Anschließend führt man die drei Komponenten wieder in ein einziges Bild im sRGB-Farbraum zusammen. Nun können die Bilder einzeln in ein DJVU-File überführt werden. Dabei sollte man auf eine Vorgabe der Qualität durch die Optionen -percent oder -decibel verzichten. Natürlich sind die DJVU-Dateien in der Regel deutlich größer als die auf Archive.org liegenden, sie haben aber auch eine deutlich höhere Qualität und letztlich zählt ja vor allem diese (Speicher wird ohnehin immer billiger).

Im folgenden Bild (Ausschnitt aus Dürers St. Christophorus) wurde zum Vergleich einmal ein Bildausschnitt aus dem ursprünglich heruntergeladenen PDF-File (links), dem nachgeschärften Bild aus dem ZIP-Archiv (rechts) gegenübergestellt. Die fein aufgelösten Strukturen des Stichs im rechten Bild rechtfertigen den Aufwand:

Vergleich

Das folgende Shell-Skript erledigt nun die vorher besprochenen Schritte:

# Konvertiere JPEG2000 nach PPM (kompl. Verzeichnis):
j2k_to_image -ImgDir . -OutFor ppm
# 
for i in `ls -1 *.ppm`;
do
# Separiere jedes Bild in H-, S- und I-Bestandteile 
convert $i -colorspace HSI -separate separate_HSI_%d.ppm
# Schärfe die I-Komponente
mogrify -unsharp 1.2x1.2+5+0 separate_HSI_2.ppm
# Führe die HSI-Bestandteile wieder in einem sRGB-File zusammen
convert separate_HSI_?.ppm  -set colorspace HSI -combine -colorspace sRGB $i
# Räume auf
rm separate_HSI_?.ppm
# Erzeuge ein DJVU-File
c44 $i $i.djvu
done
# Erzeuge einen DJVU-Container für alle Seiten
djvm -c dürer.djvu *.ppm.djvu

IPython-Notebooks in einem WordPress-Blog veröffentlichen

Wie in einem vorangegangen Artikel erwähnt, bieten IPython-Notebooks hervorragende Möglichkeiten Arbeiten zu publizieren. Einfügungen können als $\LaTeX$-Code oder durch MathJax vorgenommen werden, Bild- und Videomaterial kann ebenso wie Audiosequenzen in die Notebooks aufgenommen werden. Ein Thema lässt sich so auf sehr ansprechende, multimediale Weise darstellen.
Um eine Notebook-Datei für eine Veröffentlichung in ein gängiges Format zu konvertieren, ruft man auf der Kommandozeile folgendes auf:

> ipython nbconvert --to html input.ipynb

Man erhält ein statisches HTML-Dokument aus dem Notebook input.ipynb, durch Angabe von pdf, latex etc. können selbstverständlich auch andere Formate erzeugt werden.
Ein auf diese Weise erstelltes HTML-Dokument lässt sich nun ohne großen Aufwand in einem WordPress-Blog einfügen. Dazu wird lediglich ein Plugin benötigt, welches HTML-Code direkt im Editor einfügen kann. Hier wird die Vorgehensweise anhand des Plugins EmbedIt Pro beschrieben:

EmbedIt Pro:
Embed any HTML code (Youtube, UStream or whatever HTML) in a post, page or widget, deciding precisely where to embed it, either on-the-fly from custom fields OR from your saved HTML Code Snippets. Super easy for newbies but powerful for developers, since it supports not only shortcodes but PHP functions too to return or display the snippets in your templates.

Nach der Installation des Plugins findet man im Dashboard den Punkt HTML Snippets. Wählt man dort Add New kann man nun den HTML-Code auf der vorgesehenen Fläche einfügen (zum bsp. durch vorherige Selektion mit der Maus). Bestätigt man den Code durch klicken auf Veröffentlichen, erhält man einen Shortcode, der direkt im zu erstellenden Artikel eingefügt werden kann.

Ohne weitere Nachbearbeitung kann man mit dem beschriebenen Workflow seine IPython-Notebooks in einem WordPress-Blog veröffentlichen, dies spart Zeit und erhöht die gestalterische Qualität der Publikation.

IP-Adresse eines Android-Geräts ermitteln

Mit Android-Bordmitteln kann man lediglich die IP-Adresse der Wlan-Schnittstelle feststellen (unter Einstellungen->Wlan->Erweitert). Benötigt man die IP-Adresse einer anderen Netzwerkschnittstelle bietet sich folgender Weg an: Herstellung eines Zugang zum Phone über ssh (bspw. mit der App ConnectBot), anschließend kann auf der Kommandozeile mit dem ip-Befehl die IP-Adressen vorhandener Schnittstellen abgefragt werden:

> ip addr show

Bzw. wenn nur ip4-Adressen interessieren und man evtl. noch mit grep die gewünschten Schnittstelle aussortieren will:

> ip -o -4 addr show

Es werden keine root-Rechte benötigt!

PDFs komprimieren

Vor dem Versenden einer großen PDF-Datei als Email-Anhang, sollte man versuchen sie mit Hilfe eines Postscript-Interpreters zu verkleinern. Dies schont nicht nur upload-Volumen, es verringert auch die Gefahr, dass die Email wegen evtl. Restriktion von Mailservern nicht zugestellt wird. Das auf praktisch allen Systemen verfügbare Programm Ghostscript meistert diese Aufgabe zuverlässig.
Über die Option -dPDFSETTINGS kann man dabei die Darstellungsqualität und damit die Größe der erzeugten Dateien bestimmen:

  • /screen wählt die schlechteste Auflösung,
  • /ebook wählt eine mittlere Auflösung,
  • /printer wählt eine hohe Auflösung,
  • /prepress wählt eine sehr hohe Auflösung aus.

Mit den beiden zuletzt genannten Auflösungsstufen wird man in der Regel keine erheblich Kompression gegenüber der Ausgangsdatei erreichen, mit den erstgenannten Angaben jedoch schon – teils signifikant, jedoch um den Preis stark verlustbehafteter Kompression von enthaltenen Bildern. Man muss gegebenenfalls etwas herumspielen, um bei noch akzeptabler Qualität die gewünschte Verringerung der Dateigröße zu erzielen. Mit folgender Kommandozeile

> gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.5 -dPDFSETTINGS=/printer -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.pdf input.pdf

wird Ghostscript mit vernünftigen Optionen gestartet. Weitere Optionen und Erläuterungen findet man auf der Website von Ghostscript.

IPython Notebook

Das IPython Notebook ist eine web-basierte, interaktive Plattform, um Programmcode, Text, mathematische Formeln und grafische Ausgaben in einem einzelnen Dokument zu vereinen. Notebooks sind normale Dateien, die einfach in andere Formate wie HTML oder PDF etc. umgewandelt werden können. Außerdem können einzelne Notebooks der Öffentlichkeit als statische Webseite zugänglich gemacht werden ohne das der Betrachter etwas zusätzlich installieren muß. Weitere Informationen zu den umfangreichen Möglichkeiten von IPython und Notebooks erhält man auf der IPython-Homepage[ 1].

Um Notebooks nutzen zu können, ruft man in einer Konsole das Kommando

ipython notebook --no-browser

auf, dies startet den lokalen Notebook-Server. In einem Web-Browser kann man sich nun über

IPython Notebook in Google Chrome

IPython Notebook in Google Chrome

http://127.0.0.1:8888 mit dem Server verbinden und gelangt zum IPython Dashboard, von wo aus ein neues oder bestehendes Notebook ausgewählt werden kann. Im Notebook selbst hat man nun über eine Navigationsleiste Zugriff auf verschiedene Funktionen: Der Punkt Cell gestattet z.B. eine Zelle als Markdown auszuwählen. Eine solche Zelle dient der Dokumentation des Kodierungsprozesses und bietet dafür ausgefeilte Möglichkeiten an. So kann Text mit beliebigem HTML-Code formatiert werden, Bilder und andere Multimedia-Inhalte über html5-Elemente eingefügt und mathematische Formeln in $\LaTeX$-Notation angegeben werden. Der Punkt Help bietet Links zur Onlinehilfe von Python, IPython, NumPy, SciPy, MPL und SymPy an.

Über Magics können bestimmte Funktionen auch nach dem Start des Kernels noch unterstützt werden, die ein spezielles Setup für eine reibungslose Zusammenarbeit mit IPython erfordern und deshalb eigentlich beim Aufruf von IPython in der Kommandozeile übergeben werden müssen. Statt des Kommandozeilenaufrufs:

ipython notebook --no-browser --matplotlib inline

können durch Aufruf des Magics %matplotlib inline die Plot-Funktionen auch nachträglich unterstützt werden. Die Angabe des Backends inline bettet statische Bilder innerhalb des Notebooks ein, statt ein separates, interaktives Fenster zu öffnen.

Interaktive Python Sitzungen speichern

Ein großer Vorteil interpretativer Skriptsprachen ist die Möglichkeit Code interaktiv zu testen. Das Sichern einer Sitzung der klassischen Python-Shell ist durch das readline-Modul möglich, welches durch import readline zur Verfügung steht. Durch readline.write_history_file wird der aktuelle Verlauf (History) per Voreinstellung in die Datei ~/.history geschrieben, man kann aber auch einen eigenen Dateinamen angeben. Zurückgelesen wird das ganze dann durch readline.read_history_file. Weiteres ist der Dokumentation zu entnehmen.

Benutzt man IPython, so stehen die Magics %save und %loadpy bereit. Durch die Angabe von

%save testlauf 1-20

werden die Zellen 1 bis 20 in die Datei testlauf.py (die Endung .py wird automatisch angefügt) geschrieben.

Erstellen von Wachstumskurven mit Gnuplot

Hinweise auf den Gesundheits- und Ernährungszustand von Kindern- und Jugendlichen können sich durch die Messung anthropometrischer Merkmale und deren Einordnung in Perzentilkurven, die die Verteilung der Körpermaße in einer Referenzpopulation wiederspiegeln, ergeben. Eine aktuelle Studie zur Gesundheit von Kindern und Jugendlichen[ 1] liefert solche Perzentilkurven ausgewählter Körpermaße von Kindern und Jugendlichen im Alter von 3 Monaten bis 17 Jahren.
Als individuelle Datenquelle können die Ergebnisse der kinderärztlichen Untersuchungen, die im Mutterpass dokumentiert sind, herangezogen werden. Es gibt insgesamt 9 Vorsorgeuntersuchungen, angefangen von der U1 direkt am Tag der Geburt, bis hin zur U9 im 5 Lebensjahr, bzw. bis zu 4 Monaten später. Bei allen Vorsorgeuntersuchungen wird in der Regel auch das Gewicht und die Körpergröße erfasst. Darüber hinaus sollte man diese Körpermaße in regelmäßigen Abständen auch selbst erfassen. Oft erinnern die Kinder selbst an die Messungen, da sie ab einem gewissen Lebensalter an ihrem eigenen Wachstum Interesse zeigen. Für die Darstellung der gemessenen Daten soll die skriptgesteuerte Plottersoftware Gnuplot, die unter freier Lizenz für alle gängigen Betriebssysteme verfügbar ist, verwendet werden. Die Aufbereitung der Daten für Gnuplot ist denkbar einfach: In einer Textdatei werden spaltenweise Messzeitpunkt, Körpergröße in cm und Körpergewicht in Gramm, jeweils durch Leerzeichen oder Tabulator getrennt erfasst. In Zeile 4 des folgenden kleinen Gnuplot-Skripts wird dem Programm mitgeteilt, dass es sich bei den Daten für die x-Achse um Datumsangaben handelt, die folgende Zeile beschreibt das Format, in dem das Datum vorliegt. Das Höchstalter des zu untersuchenden Kindes muß gegebenfalls in Zeile 15 als oberer Grenzwert des Darstellungsbereichs angepasst werden. Dabei zählt nur die Dekade des Jahrtausends als Kindesalter (Gnuplot repräsentiert Zeitangaben intern als Sekunden seit dem 01.01.2000). Mein Skript geht von den Daten zweier Kinder aus, die in den Dateien "bruno.dat" und "felix.dat" gespeichert sind. In diesen Dateien ist der Zeitpunkt der Messung natürlich durch das reale Datum vermerkt. Da die Daten aber über das Alter des Kindes abgetragen werden sollen, muss in Zeile 45 und 46 das Datum der Messung entsprechend verschoben werden, so dass die Geburt mit dem Datum 01.01.2000 zusammenfällt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/gnuplot 
#
set encoding utf8
set xdata time
set timefmt "%d.%m.%Y"
set xtics rotate by -45
set format x "%b/%y"
 
set termoption dash
set size ratio 0.7 1.0, 1.0; set origin 0.0, 0.0
set ylabel "Körpergröße [cm]"
set xlabel "Alter [Jahre]" offset screen 0,-0.02
#####################################
# Als Endpunkt das Höchstalter eintragen:
set xrange ['01.01.2000':'01.01.2009']
set ytics mirror
unset y2label
unset y2range
unset y2tics
set format x "%y"
set mxtics 12
set key left
set key screen 0.1,0.9
 
set style line 1 lt 1 lc rgb "red" lw 3
set style line 2 lt 1 lc rgb "grey" lw 1
set style line 3 lt 1 lc rgb "black" lw 1
set style line 4 lt 1 lc rgb "green" lw 1
 
#####################################################
# Darstellung der Körperlänge über dem Kindesalter
#
# Sekunden/Tag = 86400
# Differenz der Geburtsdatumsangaben in Tagen = 962
# Differenz zwischen Brunos Geburtstag und 1.1.2000 in Tagen = 1660
# Verschiebe die Zeitangaben, so dass sie am 1.1.2000 starten.
 
plot "KiGGS-Referenzperzentile-Länge.dat" using 1:5 title "Perzentile P50 (KiGGS 2003-06)" ls 1 smooth csplines, \
     "" using 1:6 title "Perzentile P75" ls 2 smooth csplines, \
     "" using 1:4 t "Perzentile P25" ls 2 smooth csplines, \
     "" using 1:7 title "Perzentile P90" ls 3 smooth csplines, \
     "" using 1:3 t "Perzentile P10" ls 3 smooth csplines, \
     "" using 1:8 title "Perzentile P97" ls 4 smooth csplines, \
     "" using 1:2 t "Perzentile P3" ls 4 smooth csplines, \
     "bruno.dat" using (timecolumn(1)-1660*86400):2 title "Bruno Körpergröße" with linespoints  4, \
     "felix.dat" using (timecolumn(1)-(963+1660)*86400):2 title "Felix Körpergröße" with linespoints 5
 
set term svg fsize 8
set output "kurven-l.svg"
replot
 
pause -1

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
set ylabel "BMI [kg/m²]"
 
plot "KiGGS-Referenzperzentile-BMI.dat" using 1:5 title "Perzentile P50 (KiGGS 2003-06)" ls 1 smooth csplines, \
     "" using 1:6 title "Perzentile P75" ls 2 smooth csplines, \
     "" using 1:4 t "Perzentile P25" ls 2 smooth csplines, \
     "" using 1:7 title "Perzentile P90" ls 3 smooth csplines, \
     "" using 1:3 t "Perzentile P10" ls 3 smooth csplines, \
     "" using 1:8 title "Perzentile P97" ls 4 smooth csplines, \
     "" using 1:2 t "Perzentile P3" ls 4 smooth csplines, \
     "bruno.dat" using (timecolumn(1)-1660*86400):($3/1000.0)/($2/100.0)**2 title "Bruno BMI" with linespoints  4, \
     "felix.dat" using (timecolumn(1)-(963+1660)*86400):($3/1000.0)/($2/100.0)**2 title "Felix BMI" with linespoints 5
 
set term svg fsize 8
set output "kurven-bmi.svg"
replot
 
pause -1

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
set ylabel "Gewicht [kg]"
 
plot "KiGGS-Referenzperzentile-Gewicht.dat" using 1:5 title "Perzentile P50 (KiGGS 2003-06)" ls 1 smooth csplines, \
     "" using 1:6 title "Perzentile P75" ls 2 smooth csplines, \
     "" using 1:4 t "Perzentile P25" ls 2 smooth csplines, \
     "" using 1:7 title "Perzentile P90" ls 3 smooth csplines, \
     "" using 1:3 t "Perzentile P10" ls 3 smooth csplines, \
     "" using 1:8 title "Perzentile P97" ls 4 smooth csplines, \
     "" using 1:2 t "Perzentile P3" ls 4 smooth csplines, \
     "bruno.dat" using (timecolumn(1)-1660*86400):($3/1000.0) title "Bruno Gewicht" with linespoints  4, \
     "felix.dat" using (timecolumn(1)-(963+1660)*86400):($3/1000.0) title "Felix Gewicht" with linespoints 5
 
set term svg fsize 8
set output "kurven.svg"
replot
 
pause -1

Die Dateien KiGGS-Referenzperzentile-Länge.dat, KiGGS-Referenzperzentile-Gewicht.dat und KiGGS-Referenzperzentile-BMI.dat mit der Angabe der Referenzperzentilen zu Größe, Gewicht und BMI, auf Grundlage der oben erwähnten Studie, stehen zum Download bereit.

Tunnelblick

Einrichtung eines ssh-Tunnels durch das Internet zwischen einem Android-Smartphone und einem Linux-Host.

Firewall-Mechanismen

Nutzt man unterwegs mit seinem Smartphone einen öffentlichen Hotspot, so besteht die Gefahr, dass der Datenverkehr durch den Betreiber ausgewertet, also auch evtl. unverschlüsselt gesendete Daten mitgelesen und missbraucht werden. Nun besteht prinzipiell die Möglichkeit, auf dem heimischen PC, der über einen Breitbandanschluß mit dem Internet verbunden ist, einen sshd zu installieren und den Datenverkehr des Smartphones über einen ssh-Tunnel zum heimischen PC zu leiten.
Oft schützen die Provider der Breitbandanschlüsse ihre Kunden jedoch durch eine Firewall vor unerwünschten Zugriffen aus dem Internet. Während man auf die Firewall des heimischen Routers normalerweise vollen administrativen Zugriff hat, ist dies naturgemäß bei der Firewall des Providers nicht der Fall. Dies bedeutet, dass die vom heimischen PC angebotenen Server-Dienste nicht aus dem Internet erreichbar sind (es sei denn, das die providerseitige Firewall die Ports dafür standardmäßig offen hält, was selten der Fall ist). Nun muß prinzipiell jede Firewall auch Pakete von außen hereinlassen und zwar die Antwortpakete zu Anfragen an Web- und Mailserver etc. die der Nutzer durch Browser oder Email-Clients an die Server im Internet richtet. Damit die Firewall entscheiden kann, ob ein Paket von außerhalb die Antwort auf ein ausgehendes Paket ist, wird im Router Buch darüber geführt, welcher interne Rechner mit welchem Rechner außerhalb kommuniziert und welche Ports dabei angesprochen wurden.

Die Rolle von Vermittlungsservern

Um nun eine Client-Server-Kommunikation durch eine restriktive Firewall hindurch zu ermöglichen, bedient man sich eines Vermittlungsservers: Beide Kommunikationspartner, also Server und Client nehmen periodisch Kontakt mit dem Vermittlungsserver auf. Somit kennt dieser die IP-Adressen der Teilnehmer und die Ports auf denen sie zu kommunizieren wünschen. Will ein Teilnehmer nun die Verbindung aufnehmen, meldet er diesen Wunsch beim Vermittlungsserver an, erhält von ihm die IP-Adresse und den Port der Gegenstelle und kann nun seine Anfrage losschicken. Diese wird zwar von der Firewall der Gegenstelle verworfen, aber der Router von dem die Anfrage stammt wartet dennoch auf die Antwort. Der Vermittlungsserver teilt nun der Gegenstelle die Daten der Anfrage mit und läßt sie antworten. Das Antwortpaket passiert nun die auf Antwort wartende Firewall und nun können beide Kommunikationspartner ohne den Vermittlungsserver weiter Daten austauschen. Dieses Verfahren ist auch unter dem Begriff Hole Punching bekannt. Eine grobe Simulation dieser Arbeitsweise mit einfachen Netzwerktools zeigt ein Artikel in der c’t und erläutert diese Problematik ausführlicher.

NeoRouter Mesh und Co.

Ein prominentes Beispiel eines solchen Vermittlungsservers ist Skype. Es gibt jedoch auch Anbieter, die Vermittlungsdienste für allgemeinere Aufgaben bereitstellen. Einer von ihnen ist die Firma NeoRouter Inc.. Der Einsatz ihres Dienstes NeoRouter Mesh zum Aufbau eines ssh-Tunnels zwischen Smartphone und einem hinter einer Firewall verborgenen Linux-Hosts, der einen Proxy für den Internetzugriff bereitstellt, soll hier demonstriert werden. Die folgende Vorgehensweise benötigt keine Root-Rechte auf dem Smartphone, dieses muß also nicht gerootet werden.

Schritt für Schritt

Auf der Herstellerseite der Firma NeoRouter Inc. kann man die notwendige Mesh Domain und den Account beantragen. Anschließend kann die Software für die verschiedenen Endgeräte auf der Download-Seite heruntergeladen und installiert werden.
Auf dem Linux-Host, der als Server dienen soll, wird nach der Installation nrserver gestartet. Anschließend kann die App NeoRouter Mesh auf dem Android-Smartphone aufgerufen werden.

Konfiguration der App NeoRouter Mesh

Konfiguration der App NeoRouter Mesh


Nach der Authentifizierung sollte die App den Linux-Host nun unter My Computers auflisten. Tippt man länger auf den Host, zu dem der Tunnel aufgebaut werden soll, öffnet sich ein Auswahlfenster und man kann nun den Dienst ssh 22 auswählen. Durch diese Auswahl richtet die App eine Port-Weiterleitung vom Port 32973 des lokalen Hosts (also des Smartphones) zum Port 22 des entfernten ausgewählten Linux-Host ein (bzw. teilt sie diesen Wunsch dem Vermittlungsserver mit).

ConnectBot: ein ssh-client für Android

Nun kann die ssh-App ConnectBot gestartet werden. Aus einer Dropdown-Liste kann man die Dienste ssh, telnet und local auswählen.

Konfiguration der App ConnectBot

Konfiguration der App ConnectBot

Wir wählen ssh (local gestattet die Einrichtung eines ssh-Zugangs zum Smartphone) und geben im Eingabefenster siegel@localhost:32973 als Ziel ein. Wir erinnern uns, daß durch NeoRouter Mesh eine Weiterleitung vom lokalen Port 32973 zum Port 22 des Linux-Hosts eingerichtet wurde. Nachdem man auf dem Linux-Host angemeldet wurde, kann man in der Werkzeugleiste (ganz unten rechts) den Punkt Port-Weiterleitung aufrufen.

Einrichten einer Port-Weiterleitung mit ConnectBot

Einrichten einer Port-Weiterleitung mit ConnectBot

Hier kann man unter Vergabe eines Spitznamen eine Weiterleitung vom Typ Lokal mit dem Quellport: 8080 zum Ziel localhost:3128 einrichten. Der Port 3128 ist der Standard-Port des Proxy-Programms squid, welches auf dem Linux-Host installiert und konfiguriert werden mußte. Bei der Auswahl des Quellports ist zu bedenken, dass unter Unix-artigen Betriebssystemen (also auch unter Android) nur root Dienste betreiben darf, die Portnummern kleiner 1024 benötigen (sogenannte Systemports).

Der Proxy-Server squid

Wie bereits erwähnt, muß auf dem Linux-Host ein Proxy-Server eingerichtet werden. Nach dessen Installation sind in der Datei /etc/squid/squid.conf noch einige Kleinigkeiten einzutragen. So muß dem Proxy noch ein Name über das Schlüsselwort visible_hostname zugewiesen werden, dieser kann beliebig gewählt werden. Außerdem muß das Disk Cache Directory durch das Schlüsselwort cache_dir bezeichnet werden und es sollte die Zeile http_access deny to_localhost in der Config-Datei vorhanden sein. Im übrigen ist die Datei squid.conf sehr gut kommentiert und man muss eigentlich nur den dort gemachten Empfehlungen folgen. Vor dem ersten Start von squid ist die Cache-Verzeichnisstruktur durch den Aufruf von squid -z anzulegen. Nun kann man mit squid -NCd1 den Dämon probeweise starten, ohne ihn in den Hintergrund zu schicken. So kann man evtl. Fehlermeldungen besser beobachten. Später kann man den Dämon dann durch /etc/init.d/squid start aktivieren. Für weitere Konfigurations-Details sei auf den Eintrag bei selflinux.org und das HOWTO der Seite www.linuxhomenetworking.com verwiesen.

Eintrag des Proxy-Servers im Browser

Um nun durch den eingerichteten Tunnel über den Linux-Host surfen zu können, muß in Opera (Chrome für Android unterstützte zum Verfassungszeitpunkt des Artikels die Angabe eines Proxy-Servers noch nicht) auf dem Smartphone die Adresse des Proxy-Servers angegeben werden. Dies kann durch Aufruf von opera:config geschehen.

Mit Opera die Benutzung eines Proxy-Servers einrichten

Mit Opera die Benutzung eines Proxy-Servers einrichten

Als HTTP-Server muß dann 127.0.0.2:8080 eingetragen werden, denn der lokale Port 8080 wird ja durch die mit ConnectBot eingerichtete Port-Weiterleitung an den Proxy-Port 3128 des fernen Linux-Host weitergereicht. Nach dem Speichern dieser Angaben und einem Neustart von Opera, wird nun jede Anfrage von Opera durch den Tunnel an den Proxy weitergeleitet.

Hat man bspw. bei dem Dienst no-ip für seine eigene, vom Provider dynamisch zugeteilte IP-Adresse einen Domainnamen eingerichtet, so lassen sich unter diesem Domainnamen nun auch Seiten aus dem Internet aufrufen. Da sich hinter der vom Provider vergebenen IP-Adresse normalerweise der heimische Router verbirgt, man aber mit dem Domainnamen eigentlich einen Rechner hinter dem eigenen Router (also im eigenen lokalen Netz) erreichen möchte, ist im Router eine entsprechende Port-Weiterleitung (oft unter dem Menü-Punkt Virtueller Server erreichbar) zu dem gewünschten Rechner und Port zu konfigurieren. Handelt es sich zum Beispiel um eine Webcam und ist für diese im eigenen Router eine entsprechende Port-Weiterleitung konfiguriert, so könnte eine Abfrage des gerade sichtbaren Bildes z.B. durch http://dcs-900.no-ip.org:8080/IMAGE.JPG erfolgen, wenn der bei no-ip registrierte Domainname dcs-900.ni-ip.org lautet und in der Webcam der Port 8080 als Dienstport konfiguriert wurde.

Screenshots auf dem Samsung Galaxy Nexus

Das Android-Handy Samsung Galaxy Nexus bietet eine einfache Möglichkeit zur Anfertigung von Screenshots an: Gleichzeitiges Drücken der Lautstärke-Leiser-Taste und der Power-Taste bis eine verkleinerte Darstellung des Screenshots erscheint. Der Screenshot wird unter /sdcard/Pictures/Screenshots/ im png-Format abgelegt.

Konfiguration zertifikatbasierter SSH-Zugänge

SSH bietet die Möglichkeit der Zugangs-Authentifizierung mittels öffentlicher Schlüssel (Public Key Authentication). Bei der konventionellen Zugangskontrolle durch Username und Passwort liegt die Schwachstelle beim Passwort, läßt es sich erraten, so ist der Zugang hergestellt.
Bei der zertifikatbasierten Zugangskontrolle wird durch das Dienstprogramm ssh-keygen ein Schlüsselpaar, bestehend aus einem öffentlichen und einem privaten Schlüssel, erzeugt. Anschließend verbleibt der private Schlüssel auf dem Client, während der öffentliche Schlüssel auf den Server übertragen wird. Schlüssel lassen sich prinzipiell schwieriger kompromittieren als Kennwörter. Ein weitere Vorteil dieser Methode ist, daß sie (entsprechende Konfiguration vorausgesetzt) den Zugang ohne Benutzerinteraktion herstellen kann, zusätzlich läßt sie sich als einzig legitime Art der Anmeldung (Authentifizierung) festlegen. Der private Schlüssel wird üblicherweise nochmals mit einer Passphrase gesichert (von Passphrase spricht man, da sie aus mehreren Worten bestehen kann). Diese wird dann beim Zugang abgefordert. Um die Angabe der Passphrase nicht bei jedem Zugang vornehmen zu müssen, läuft normalerweise ein ssh-agent, der die Angabe der Passphrase stellvertretend übernimmt.
Die Anmeldung erfolgt nun sinngemäß etwa folgendermaßen: Auf dem Client wird mittels des hier vorhandenen privaten Schlüssels eine Signatur erzeugt, diese wiederum kann der Server mit dem bei ihm hinterlegten öffentlichen Schlüssel des Client prüfen.

Praxis:

Erzeugen des privaten und öffentlichen Schlüssels (der Option -t wird der Typ des Schlüssels übergeben, die möglichen Werte nennt die Manualseite):
# ssh-keygen -t rsa

Es entstehen Dateien mit den Schlüsselpaaren:
~/.ssh/id_rsa und ~/.ssh/id_rsa.pub.

Die *.pub-Dateien können nun auf den Server kopiert werden und dort an ~/.ssh/authorized_keys angehängt werden, diesen Schritt übernimmt das Dienstprogramm ssh-copy-id:

# ssh-copy-id -i ~/.ssh/id_rsa.pub user@server