So
Feb
01
2009
Benchmarking mit ab und autobench
Vor kurzem habe ich ein wenig zum Thema Benchmarking geschrieben. Dieses Thema ist für viele Entwickler ein Buch mit sieben Siegeln. Deswegen hier ein paar erklärende Worte, wie man auf einfache Art und Weise eine aussagekräftige Messung inklusive vorzeigbarem Graphen für den eigenen Webserver generieren kann.
Das Problem
Niemand weiß so recht, wie schnell ein Webserver eigentlich ist und wie viele Anfragen er verarbeiten kann, bis er zusammenbricht. Abwarten, bis der GAU eintritt, ist die schlechteste Variante, dem Problem zu begegnen. Besser ist es, einen Benchmark durchzuführen, um die Skalierfähigkeit eines Servers einschätzen zu können. Antwortet des Server zu langsam auf Anfragen, bleiben eventuell Besucher fern und es wäre an der Zeit, über Lastverteilung oder einen dickeren Server nachzudenken.
Der einfachste Ansatz: ab
Jeder Apache-Webserver bringt von Hause aus ab mit. ab funktioniert denkbar einfach (Eingabe im Terminal/Kommandozeile/Shell):
ab -c 20 -n 100 http://127.0.0.1/
In diesem Fall werden 20 gleichzeitige Benutzer (concurrent requests) mit 100 Anfragen (number of requests) an den Webserver unter der Adresse 127.0.0.1 geschickt1. In diesem Fall wird die index.html meines lokalen Webservers ausgeliefert, was in der Regel schnell ablaufen dürfte. Die Ausgabe von ab bestätigt dies:
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)…..done
| Server Software: | Apache/2.2.9 |
| Server Hostname: | 127.0.0.1 |
| Server Port: | 80 |
| Document Path: | / |
| Document Length: | 1456 bytes |
| Concurrency Level: | 20 |
| Time taken for tests: | 0.081 seconds |
| Complete requests: | 100 |
| Failed requests: | 0 |
| Write errors: | 0 |
| Total transferred: | 186000 bytes |
| HTML transferred: | 145600 bytes |
| Requests per second: | 1240.46 [#/sec] (mean) |
| Time per request: | 16.123 [ms] (mean) |
| Time per request: | 0.806 [ms] (mean, across all concurrent requests) |
| Transfer rate: | 2253.19 [Kbytes/sec] received |
Connection Times (ms)
| min | mean | [+/-sd] | median | max | |
| Connect: | 0 | 0 | 0.3 | 0 | 1 |
| Processing: | 10 | 15 | 4.9 | 13 | 29 |
| Waiting: | 3 | 14 | 5.1 | 13 | 29 |
| Total: | 10 | 15 | 5.0 | 13 | 29 |
Percentage of the requests served within a certain time (ms)
50% 13
66% 14
75% 15
80% 19
90% 25
95% 27
98% 29
99% 29
100% 29 (longest request)
Diesen Test kann man nun mehrfach durchführen und den Wert für -c jeweils anpassen. Von -c 10 bis -c 150 oder noch weiter. Aus den erhaltenen Werten läßt sich nun ein Diagramm in Excel oder OOo.
Wenn es dem Apachen zu viele Anfragen werden, schaltet er einfach ab (Connection reset by peer):
Macintosh:~ stephan$ ab -c 150 -n 2000 http://127.0.0.1/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 200 requests
Completed 400 requests
Completed 600 requests
Completed 800 requests
Completed 1000 requests
Completed 1200 requests
Completed 1400 requests
Completed 1600 requests
apr_socket_recv: Connection reset by peer (54)
Total of 1688 requests completed
Kurzer Exkurs in die Konfiguration des Apache
Warum wurde die Verbindung zurückgesetzt? Die Lösung findet sich (für den Apache 2.x unter Mac OS X 10.5.6) in der Datei /etc/apache2/extra/httpd-mpm.conf
<IfModule mpm_prefork_module> StartServers 1 MinSpareServers 1 MaxSpareServers 10 MaxClients 150 MaxRequestsPerChild 0 </IfModule>
Wenn der Wert für -c über dem Wert von MaxClients gesetzt wird, reagiert der Webserver per Definition nicht mehr auf diese Benutzer. Allerdings ist die Anzahl der Anfragen pro Client hier nicht begrenzt. Eine genaue Auseinandersetzung mit den Einstellungsmöglichkeiten und der Performanceoptimierung von Webservern ist jedoch nicht das Thema hier, sondern das Messen der Performance.
Komfortables Benchmarking mit autobench
Auf dem Mac kann man autobench unter anderem mit den MacPorts installieren:
$ sudo port install autobench
Zur Erzeugung von Graphen ist außerdem das Programm gnuplot notwendig:
$ sudo port install gnuplot
Ich vermute, dass die Installation von gnuplot nicht ganz korrekt verläuft, da bench2graph (in einem späteren Arbeitsschritt) unter OS X nicht funktioniert.
Die Funktionsweise von autobench
autobench ist ein Perl-Skript, welches httperf mit ansteigender Anzahl an Abfragen startet und die wesentlichen Ergebnisse in einer Komma- (csv) oder Tabulator-separierten (tsv) Datei abspeichert. Diese Datei wiederum kann als Grundlage für Graphen genutzt werden.
Das Prinzip ist also ähnlich wie bei einer Testreihe mit ab. Allerdings sieht man bereits an der Konfiguration, dass httperf bzw. autobench dem Benutzer etwas mehr abverlangt.
Konfiguration von autobench
.autobench.conf im Heimverzeichnis des Anwenders beinhaltet die Standardkonfiguration von autobench. Auf den ersten Blick zeigt sich ein deutlicher Unterschied zur Arbeit mit ab: Es können zwei Server konfiguriert (host1 und host2). Da hier jedoch nur ein Server getestet werden soll, konfiguriere ich nur host1. Die wesentlichen und in unserem Beispiel relevanten Einstellungen sehen wie folgt aus:
host1 = localhost uri1 = / port1 = 80 low_rate = 10 high_rate = 200 rate_step = 10 num_conn = 5000 num_call = 10 timeout = 5 output_fmt = tsv
autobench schickt also Anfragen an den Server localhost (127.0.0.1) auf Port 80 an die dort hinterlegte Startseite (in diesem Fall index.html). Begonnen wird mit 10 gleichzeitigen Verbindungen (low_rate) und 10 Anfragen (num_call) bei insgesamt 5000 Verbindungen für den einzelnen Testlauf (num_con). Pro Testlauf wird nun die Anzahl gleichzeitiger Verbindungen um 10 (rate_step) erhöht, bis sie 200 (high_rate) erreicht. Wenn der Webserver nicht innerhalb von 5 Sekunden (timeout) antwortet, so wird dies von autobench als Fehler gewertet. Das Ergebnis wird im tsv-Format (output_fmt) ausgegeben.
Ein Testlauf mit autobench
Es gibt prinzipiell zwei Möglichkeiten, autobench aufzurufen. Einerseits so, dass die Ergebnisse dargestellt werden und andererseits so, dass die Ergebnisse in einer Datei protokolliert werden. Gibt man auf der Kommandozeile keine expliziten Parameter an, dann werden die Einstellungen der .autobench.conf genutzt.
$ autobench —single_host —file bench.tsv
Mit —single_host wird autobench angewiesen, nur die Einstellungen für host1 zu verwenden, der Parameter —file zeigt an, dass die Ergebisse in die Datei bench.tsv geschrieben werden sollen.
Je nach Konfiguration heißt es jetzt ein bißchen warten. Wer gerne sehen möchte, was passiert, kann entweder auf der Konsole zusehen oder eine zweite Shell öffnen und dem Logfile beim Wachsen zusehen:
$ tail -f bench.tsv
Graphen mit bench2graph
Im Normalfall ist der nächste Schritt nach dem eigentlichen Test die Aufbereitung der Ergebnisse. Unter Mac OS X ist es mir leider nicht gelungen, mit gnuplot und bench2graph die tsv-Datei zu verarbeiten. Es kam immer dieselbe Fehlermeldung:
$bench2graph bench2.tsv result.ps
-n Enter the title :
Der Titel meines Benchmarking Graphen
-n plot
^
“gnuplot.cmd”, line 8: invalid command
Da ich kein Experte für gnuplot bin, habe ich einen einfachen (Um-)Weg gewählt (unter Ubuntu funktionierte die Erstellung des Graphen einwandfrei).
1 Natürlich muss der Wert für -c immer kleiner als der von -n sein, sonst gäbe es Benutzer, die keine Anfragen stellen würden und der Befehl in sich wird sinnlos.
Sa
Jan
17
2009
Benchmarking und Load-Tests von Webservern
Help! My boss wants me to load test our web app titelt die Dokumentation von jMeter, dem vermutlich bekanntlichtesten Werkzeug für die Analyse von Webserverleistung. Ein kurzer Blick offenbart recht schnell, dass man nicht mal eben so nebenbei einen Lasttest eines Webserver bzw. einer Webseite durchführen kann, und sofort aussagekräftige Werte hat.
Wichtigste Frage, bevor überhaupt ein Test stattfinden kann, ist, für wie viele Benutzer ein Server dimensioniert wurde und wie viele Benutzer durchschnittlich erwartet werden. Es gibt bei den Tests einen Unterschied zwischen Benchmarking und Lasttests. Bei einem Benchmark will man herausfinden, wie schnell ein Server antworten kann. Das kennt manch einer aus den Balkendiagrammen, die die Geschwindigkeit neuer Computer gegenüber denen aus dem Vorjahr darstellen. Lasttests hingegen werden häufig auch genutzt um herauszufinden, ab wann ein Server in die Knie geht, wo eine Leistungsgrenze ist. Ähnlich wie beim Sporttest beim Arzt, wenn man mit hochrotem Kopf auf dem Ergometer sitzt und gegenüber der Sprechstundenhilfe nicht zugeben will, dass man eigentlich schon seit 85 Watt Belastung außer Puste war, aber dennoch den Ehrgeiz hat, auch die 185 noch für fünf Minuten zu überstehen.
Die Interpretation der Ergebnisse ist mitunter etwas schwierig, muss man sich vor dem Test doch im Klaren sein, was man eigentlich messen möchte. Einerseits kann es also darum gehen, eine Aussage über die Leistungsfähigkeit eines Systems zu treffen. Das würde in etwa so klingen:
Im Schnitt kann der Server eine Million Anfragen am Tag abarbeiten, vorausgesetzt, dass sie sich exakt gleich über den Tag verteilen und auch keine komplexeren Anfragen, als jene aus dem Test darstellen.
Andererseits kann man aber auch einen Lasttest verwenden, um zu sehen, wo eventuell Fehler in der Programmierung einer Seite oder der Konfiguration von Serverkomponenten sind. Wo liegen die Schwachstellen eines Systems: in der Datenbank, der Anwendungslogik oder am Load-Balancer davor?
Es sollte jedem klar sein, dass ein Leistungstest nur dann sinnvoll ist, wenn ein Server nicht bereits produktiv eingesetzt wird. Führt man im Live-Betrieb einen Lasttest zum Beispiel gegen amazon.de durch, dann heißt das DOS und ist nicht legal (es sei denn natürlich, dass man der Eigentümer von amazon.de wäre, aber dann wäre es tatsächlich hirnverbrannt, seine eigene Seite vorsätzlich abzuschießen).
Ganz abgesehen davon sind die Testergebnisse auch überhaupt nicht aussagekräftig, da ja die anderen Anfragen nicht gesteuert werden und somit der Statistik entkommen.
Anleitungen für das Testen von Webseiten gibt es zuhauf im Internet. Load testing for webservers von Lukas Beeler sei hier stellvertretend genannt. Aber einen Test durchzuführen, ohne sich mit dem zu testenden System zumindest ansatzweise auszukennen, ist wenig zielführend.
Die verfügbaren Werkzeuge sind zahlreich. Neben apache benchmark und siege gibt es natürlich auch noch Programme, die komplexere Testszenarien unterstützen. Hierzu zählt beispielsweise Selenium.
Eine (etwas veraltete) Übersicht über Linux Test Tools bei SourceForge bildet generel einen ganz guten Einstieg ins Thema Testing unter Linux-Systemen.
Prinzipiell ist es mittlerweile nahezu ein Kinderspiel geworden, die verfügbaren Programme zum Test zu nutzen und ein paar Zahlen zu generieren. Allerdings ist die Interpretation der Ergebnisse nicht ganz leicht und abhängig von der Testkonstellation. Mit ein wenig Geduld und Spucke kann man sich aber sehr einfach in das Thema einarbeiten und dann auch aussagekräftige Analysen von Servern und Seiten durchführen.
Softwareliste:
Weiterführende Links:
- Performance testing with JMeter
- Easy Site Benchmarking 1.04
- project: benchsid – automate benchmarks with siege, ab, and httperf using shell scripts
- Load testing for webservers von Lukas Beeler
- Testing eZ Publish with Selenium
- eZ Publish Performance Optimization Part 1 of 3: Introduction and Benchmarking
So
Mai
04
2008
Praktische Hashes of Arrays
Einer der recht häufig besuchten Artikel hier im Blog ist Hashes of Arrays oder Hashes of Hashes. Allem Anschein nach besteht noch immer großes Interesse an praktischen Beispielen für deren Anwendung in Perl. Dem soll nun Rechnung getragen werden.
Die Aufgabe:
Meine MP3- (und inzwischen AAC-)Sammlung ist mittlerweile recht groß. Leider sind auch die Lautstärkeschwankungen zwischen zwei Alben ziemlich ausgeprägt, so dass ich mittels aacgain eine Anpassung vornehmen möchte1.
Der Code:
| # | Code |
|---|---|
| 0001 | #!/usr/bin/perl -w |
| 0002 | # aacgain.pl benoetigt ein ausfuehrbares aacgain im pfad |
| 0003 | # v1 - 02.05.2008 - initial release |
| 0004 | print "### aacgain.pl ###\n"; |
| 0005 | use strict; |
| 0006 | use DirHandle; |
| 0007 | use Cwd; |
| 0008 | use File::Find; |
| 0009 | |
| 0010 | # Variablendeklaration |
| 0011 | my ( %directories, @files, $current_directory, $options, $command ); |
| 0012 | |
| 0013 | &show_help |
| 0014 | if $ARGV[0] =~ /^(help|-h|h|--help|\?|-\?)/; # zeige Hilfetext wenn notwendig |
| 0015 | |
| 0016 | @ARGV = qw(.) |
| 0017 | unless @ARGV; # suche im Startverzeichnis, wenn nichts anderes angegeben wurde |
| 0018 | $options = '-a -k'; # Album-Modus, kein clipping, 89db (Standardeinstellung) |
| 0019 | |
| 0020 | # Finde alle Songs im angegebenen Verzeichnis inkl. Unterverzeichnisse |
| 0021 | find( \&find_songs, @ARGV ); |
| 0022 | |
| 0023 | &process_files; |
| 0024 | |
| 0025 | sub find_songs { |
| 0026 | return |
| 0027 | unless /(\.m4a|\.mp3)/; # finde nur Dateien, mit entsprechender Endung |
| 0028 | $current_directory = cwd; |
| 0029 | push( @{ $directories{$current_directory} }, $_ ); |
| 0030 | } |
| 0031 | |
| 0032 | sub process_files { |
| 0033 | foreach my $key ( keys %directories ) { |
| 0034 | @files = qw//; |
| 0035 | foreach ( @{ $directories{$key} } ) { |
| 0036 | push @files, $key . '/' . $_; |
| 0037 | } |
| 0038 | $command = 'aacgain ' . $options; # konstruiere den aacgain-Befehl |
| 0039 | foreach (@files) { |
| 0040 | $command .= ' ' . "\"$_\""; |
| 0041 | } |
| 0042 | print qx($command); # fuehre aacgain aus und zeige die Ausgabe |
| 0043 | } |
| 0044 | } |
| 0045 | |
| 0046 | sub show_help { |
| 0047 | print "aacgain.pl erlaubt die Mehrfachbearbeitung von MP3/AAC-Dateien.\n"; |
| 0048 | print "Hierzu werden alle Unterverzeichnisse nach Dateien durchsucht.\n"; |
| 0049 | print "Songs innerhalb eines Ordners werden als Album behandelt.\n"; |
| 0050 | print "Syntax: perl aacgain.pl <Verzeichnisname>\n"; |
| 0051 | exit; |
| 0052 | } |
| 0053 |
Dies ist ein recht kurzes Beispiel, wie Hashes of Arrays genutzt werden können. Im Hash %directories werden die Verzeichnisse hinterlegt, in denen Songs (mit den Endungen mp3 oder m4a) gefunden wurden. Entscheidend ist Zeile 29, die Speicherung der Suchergebnisse:
Hier werden die gefundenen Songs in ein Array gepusht, welches innerhalb eines Hashes existiert. Der Key des Hashes ist der Speicherort der Musikdateien, Inhalt des Verzechnisses ist ein Array aus den gefundenen Dateinamen.
Die eigentliche Verarbeitung der Songs erfolgt in zwei foreach-Schleifen.
Für jedes Verzeichnis (=Element des Hashes) sollen die darin enthaltenen Dateien (=Elemente des Arrays) verarbeitet werden. Das Kommando hat folgende Syntax:
aacgain -a -k /path/to/song1 /path/to/song2
Um etwaige Leerzeichen im Pfad- oder Songnamen zu unterstützen werden die Dateinamen in Anführungszeichen gesetzt. Eine Rückmeldung von aacgain wird durch die qx in Verbindung mit print ermöglicht.
Damit ich das Programm auch in der nächsten Woche noch verstehen kann, gibt es eine minimale Hilfefunktion und großzügige Kommentare im Quelltext.
1 Ja, mir ist bewusst, dass man dieses Problem auch mit MacMP3Gain lösen kann, aber mit Perl macht es mehr Spaß. aacgain kann man auf dem Mac übrigens mit MacPorts einfach und schnell selbst kompilieren.
Do
Jun
07
2007
Remotezugriff auf OpenWrt-Router (Updated)
Lange Zeit hatte ich einen Account bei dyndns. Dadurch konnte ich meinen Rechner zuhause trotz DSL aus dem Internet ansprechen. Die dynamisch vergebene IP-Adresse wurde automatisch durch eine Helferapplikation bei dyndns mit einem URL verbunden.
Inzwischen bin ich weg von dyndns, ich brauche es eigentlich auch gar nicht. Dank meines Asus-Routers mit OpenWrt kann ich zeitgesteuert meine IP-Adresse zuhause in eine Textdatei auf meinem gemieteten Webspace schreiben lassen. Dadurch kann ich von überall auf Router und meinen Rechner zuhause (sofern er eingeschaltet ist) zugreifen.
Ziel: Der Router soll periodisch seine IP-Adressen auslesen und in eine Textdatei auf einem FTP-Account schreiben.
Der erste Schritt, ist die Installation einiger Pakete auf dem Router, damit ein Upload möglich ist. Prinzipiell geht es auch via ftp, ich bevorzuge jedoch curl.
ipkg install curl
Als nächstes lege ich ein Skript an, welches für das Auslesen und Hochladen der IP-Infos zuständig ist: /mnt/usb/usr/bin/publish_ip.sh
#!/bin/sh
date > /tmp/ip
ifconfig vlan1 | grep -v inet6 | grep inet | cut -f2 -d: | awk '{print $1}' >> /tmp/ip
curl -T /tmp/ip -u username:password ftp://ftp.webspace.de/ip/inet_addr
Zeile 1 ist die Shebang, in Zeile 2 wird ein aktueller Zeitstempel in die Datei /tmp/ip geschrieben. Zeile 3 führt das Programm ifconfig aus und sucht dort nach der IP-Adresse, indem die Ausgabe von ifconfig via grep durchforstet, mittels cut zurechtgestutzt und anhand von awk ausgegeben wird. Das Ergebnis wird an die Datei /tmp/ip angehangen. In Zeile 4 sorgt curl dafür, dass die Textdatei via ftp auf den Webspace kopiert wird. Das geht natürlich auch mit ftp oder anderen ftp-fähigen Werkzeugen.
Nicht vergessen: Die Datei muss ausführbar sein:
chmod +x /mnt/usb/usr/bin/publish_ip.sh
Dann wird ein Cronjob eingerichtet. Wenn Cron bereits läuft, ist alles gut, alternativ muss es eingerichtet werden:
Eine Datei namens /etc/init.d/S61 muss mit dem folgenden Inhalt angelegt werden (dies sollte via Webinterface auch automatisch gehen):
#!/bin/sh
crond -c /etc/crontabs -b
Diese Datei muss ausführbar gemacht werden:
chmod +x /etc/init.d/S61crond
Dann folgt entweder ein Neustart oder der Aufruf des crond-Startskripts:
sh /etc/init.d/S61crond
Das Anlegen des Cronjobs kann unter anderem durch den Befehl “crontab -e” erfolgen. Folgende Zeile füge ich hinzu:
59 4 * * * /mnt/usb/usr/bin/publish_ip.sh
Somit wird jeden Morgen gegen 5 Uhr Uhr das Skript ausgeführt und die IP-Adresse auf den Webspace geladen. Das Ergebnis sieht in etwa so aus:
Sun Jun 10 04:59:01 CEST 2007 26.134.211.32
Die IP-Adresse des Routers im Internet am 10. Juni um 04:59 Uhr ist also 26.134.211.32.
Um den Komfort noch etwas zu erhöhen, könnte das kleine Skript publish_ip.sh ebensogut eine HTML-Seite generieren, die anhand eines Meta-Tags im Head der Seite eine automatische Weiterleitung vornimmt:
<meta http-equiv="Refresh" content="5; url=127.0.0.1">
Update für Kamikaze: Um die aktuelle WAN-IP herauszufinden, lautet das Kommando
ifconfig eth0.1 | grep -v inet6 | grep inet | cut -f2 -d: | awk '{print $1}' >> /tmp/ip
Do
Mai
31
2007
OpenWRT auf Asus WL-500g Premium
Seit Anfang Mai habe ich einen WLAN-Router von Asus, den WL-500g Premium, natürlich mit einem freien Betriebssystem: OpenWRT. Der Router verfügt neben vier Netzwerkports, 32 MB RAM und einer schicken Antenne über zwei USB 2.0 Ports, an welche man einen Drucker oder USB-Speicher anschließen kann. Ich habe derzeit nur einen alten 512 MB USB-Stick angeschlossen, da der Drucker in einem anderen Zimmer steht.
Die Installation von OpenWRT 0.9, Codename White Russian war dank der guten Dokumentation vergleichsweise einfach, Image downloaden, flashen, warten, neustarten, fertig. Als nächstes dann die Konfiguration und erste Schritte, bis hin zur Einbindung des USB-Speichers.
Upgrade der Firmware
Die Erst-Installation des Images erfolgte via Windows XP (Asche auf mein Haupt) mit dem Firmware Restoration Tool von Asus. Die installierte Firmware ist openwrt-brcm-2.4-squashfs.trx.
Nach längerem Warten – lieber eine Minute zu lang als zu kurz – habe ich den Router neu gestartet.
Der erste Bootvorgang
Nach dem ersten Boot funktionierte bereits der Betrieb via Kabel einwandfrei. Dank DHCP hatte der Asus eine Verbindung zum Kabelmodem, welches seinerseits mit dem Internet verbunden war.
Zunächst ging es darum, den Administrationszugang abzusichern.
Administrationszugang via ssh
Via telnet auf den Router (192.168.1.1), dort via passwd das Passwort für den ssh-Zugang gesetzt, anschließend den Router neu gestartet mittels reboot.
Anmerkung: steht vor der Zeile stephan$, so ist der Befehl auf dem Rechner einzugeben, an dem der Benutzer gerade angemeldet ist, steht dort root@OpenWrt, so ist der Befehl auf dem Router einzugeben. Es wird davon ausgegangen, dass der Router unter der Adresse 192.168.1.1 zu erreichen ist.
stephan$ telnet 192.168.1.1
root@OpenWrt:~# passwd
Changing password for root
Enter the new password (minimum of 5, maximum of 8 characters)
Please use a combination of upper and lower case letters and numbers.
Enter new password:
Re-enter new password:
Password changed.
root@OpenWrt:~# reboot
Es kann ein klein wenig dauern, doch dann kann man via ssh auf den Router zugreifen, das Passwort ist das zuvor eingestellte:
stephan$ ssh root@192.168.1.1
Da ich von meinem Rechner aus gerne ohne Eingabe eines Passwortes auf den Router gelangen möchte, folgt die Konfiguration der Public Key Authentication. Falls noch kein dsa-Schlüsselpaar vorhanden ist, wird dieses mittels
stephan$ ssh-keygen -t dsa
erzeugt. Dann muss der Key auf den Router kopiert werden:
stephan$ scp ~/.ssh/id_dsa.pub root@192.168.1.1:/tmp
Der Schlüssel muss noch zu den Authorized Keys hinzugefügt werden:
root@OpenWrt:~# cd /etc/dropbear
root@OpenWrt:~# cat /tmp/id_*.pub >> authorized_keys
root@OpenWrt:~# chmod 0600 authorized_keys
Eventuell sollte man bei Problemen in der Datei ~/.ssh/known_hosts eine eventuell vorhandene Zeile, die mit 192.168.1.1 beginnt entfernen.
Aktualisierung des Images und Einrichtung WLAN
Die folgenden Befehle sind auf der Kommandozeile einzugeben. Hiermit wird die Paketverwaltung aktualisiert bzw. benötigte Pakete werden installiert. Die Meldung Successfully terminated ist eine Erfolgsmeldung.
root@OpenWrt:~# ipkg update
root@OpenWrt:~# ipkg install ntpclient
root@OpenWrt:~# ipkg install nas
root@OpenWrt:~# nvram set wl0_akm=psk psk2
root@OpenWrt:~# nvram set wl0_crypto=aes+tkip
root@OpenWrt:~# nvram set wl0_wpa_psk =MeinePassphraseFürDasWLAN
root@OpenWrt:~# nvram commit
X-Wrt
X-Wrt als Alternative zum bestehenden Webinterface bietet sich an, es reicht aus, auf der Webseite des Projekts die Adresse des Router einzugeben, das Update läuft automagisch.
USB-Unterstützung
Die fragmentarische Kurzfassung:
root@OpenWrt:~# ipkg install kmod-usb2
root@OpenWrt:~# ipkg install kmod-usb-storage
root@OpenWrt:~# ipkg install kmod-ext2
root@OpenWrt:~# ipkg install fdisk
root@OpenWrt:~# ipkg install e2fsprogs
root@OpenWrt:~# ipkg install swap-utils
Durch den Aufruf von dmesg lässt sich erkennen, welche Bezeichnung der USB-Stick hat, in meinem Fall /dev/scsi/host0/bus0/target0/lun0
root@OpenWrt:~# fdisk /dev/scsi/host0/bus0/target0/lun0/part1
Mittels fdisk lege ich eine Partition an, die später unter /mnt/usb/ eingehangen werden soll.
root@OpenWrt:~# echo ‘/dev/scsi/host0/bus0/target0/lun0/part1 /mnt/usb ext2 defaults 0 0’ > /etc/fstab
Links
- Opennet Firmware/Asus Erstinstallation
- DropbearPublicKeyAuthenticationHowto
- OpenWRT als alternative Firmware für den Linksys WRT54GL
- How to setup secure 802.1x WPA2 enterprise wireless lan on a linksys WRT54G / GS Revision 4
- OpenWRT – PUG Penguin User Group
- OpenWrt Storage Howto
- Wie kann ich einen USB Speicher Stick als Partition mit OpenWrt nutzen?
- Wie kann ich OpenWrt vom USB Stick booten?
- OpenWRT: Installing ipkg packages to /opt
Do
Apr
19
2007
Subversion unter Mac OS X benutzen
In diesem Tutorial geht es darum, wie man mittels MacPorts (ehemals darwinports) und Mac OS X 10.4.3 einen Subversion-Server einrichtet, der prinzipiell via Internet von jedem Rechner zugänglich ist, aber nur von bestimmten Nutzern tatsächlich benutzt werden kann. Benötigt werden
- ein Computer mit Mac OS X (10.4.3 kam bei diesem Tutorial zum Einsatz)
- ein Internetzugang
- Grundlagenkenntnisse in Terminal.app
- sowie in der Versionsverwaltung
Benötigte Software installieren
darwinports
darwinports ermöglichen die Installation von Softwarepaketen mitsamt ihren Abhängigkeiten. Subversion benötigt nebenbei noch einen Webserver (Apache 2) mit dem mod_dav_svn Modul. Damit die Installation einfacher und bequemer verläuft, kommt das Portsystem zum Einsatz.
Auf der Webseite der darwinports (darwinports.opendarwin.org) befindet sich eine recht gute Erklärung, wie die Paketverwaltung zu installieren ist.
Subversion und der Apache
Sobald die darwinports-Infrastruktur steht, kann Subversion installiert werden. Hierzu werden Administratorrechte benötigt. Der Befehl lautet:
sudo port install subversion +mod_dav_svn
Für die nächsten Minuten gibt es nichts zu tun als abzuwarten. Wenn die Installation erfolgreich war, zeigt sich in etwa folgendes Bild:

Repository anlegen
Zur Arbeit mit Subversion wird ein Repository benötigt. Dieses kann prinzipiell an jeder beliebigen Stelle angelegt werden, da in diesem Beispiel das Repository nur über den Webserver angesprochen werden soll, erzeugen wir es an einem eher unauffälligen Ort: /usr/local/repos. Zuerst muss das Verzeichnis repos mit einem einzigen Befehl angelegt werden:
sudo mkdir /usr/local/repos
Das Repository wird anhand des Programms svnadmin erzeugt:
sudo svnadmin create /usr/local/repos
Jetzt fehlen nur noch Daten im Repository. Ich lege einen Ordner auf dem Desktop an, der importiert werden soll:

Zuerst wird der zu importierende Ordner angegeben, dann die Adresse des Repositorys. Jeder Commit bekommt eine Notiz, in diesem Fall lautet sie: “Eins”:
sudo svn import /Users/stephan/Desktop/stephan/ file:///usr/local/repos -m "Eins"
Da niemand außer dem Webserver (also dem User namens www) Zugriff auf das Repository haben muss, weisen wir die Rechte entsprechend zu:
sudo chown -R www /usr/local/repos/
Apache 2 konfigurieren
Die Konfiguration des Webservers ist zwar etwas umständlicher als die bisherigen Schritte, aber auch nicht weiter kompliziert. Eine Textdatei muss editiert und eine Passwortdatei angelegt werden.
Zunächst wird die Datei httpd.conf angelegt und im Editor geöffnet:
cd /opt/local/apache2/conf
sudo cp httpd.conf.sample httpd.conf
sudo vi httpd.conf
Anstelle des Editors vi kann auch jeder andere Texteditor (Textmate, Textwrangler, Smultron, jEdit) benutzt werden.
Zuerst ändern wir den Port, auf dem der Apache auf Anfragen wartet. Der voreingestellte Port 80 wird vom in Mac OS X enthaltenen Webserver bereits benutzt, also lassen wir Apache 2 auf dem alternativen Webserverport 8080 laufen. Die Zeile
Listen 80
muss geändert werden in:
Listen 8080
Desweiteren muss nach der Zeile
LoadModule dav_module modules/mod_dav.so
folgende Zeile hinzugefügt werden:
LoadModule dav_svn_module modules/mod_dav_svn.so
Am Ende der Datei müssen die Einstellungen für den Zugriff des Webservers auf das Subversion Repository hinzugefügt werden. In diesem Beispiel soll das Repository unter der Adresse http://127.0.0.1:8080/svn erreichbar sein, hierzu dient die Location-Anweisung:
<Location /svn> DAV svn SVNPath /usr/local/repos AuthType Basic AuthName "Stephans Subversion" AuthUserFile /etc/svn-auth-file Require valid-user </Location>
Der Titel des Repositorys lautet “Stephans Subversion”. Zugriff erhalten nur User, deren Login und Passwort in der Datei /etc/svn-auth-file gespeichert sind.
Passwortschutz für Repository einrichten
Wir wollen das Repository für zwei User zugänglich machen. Diese heissen stephan und fred. Um den ersten User anzulegen, benötigen wir htpasswd mit den Optionen c und m:
sudo htpasswd -cm /etc/svn-auth-file stephan
Nun muss das entsprechende Passwort zweimal eingeben werden.
Für jeden weiteren Benutzer lautet der Befehl:
sudo htpasswd -m /etc/svn-auth-file fred
Die Option -c zur Erzeugung einer neuen Datei ist überflüssig, sobald /etc/svn-auth-file existiert. Um die bestehende Datei also nicht zu überschreiben, muss sie bei allen weiteren Usern weggelassen werden.
Apache 2 starten
Es gibt zwei Möglichkeiten, den Apache 2 Webserver zu starten: manuell oder bei jedem Systemstart. Manuell lässt er sich starten durch
sudo /opt/local/apache2/bin/apachectl start
Die zweite Möglichkeit bedarf derzeit (darwinports < 1.2) noch etwas Handarbeit.
Das Verzeichnis /opt/local/etc/StartupItems/apache2 muss in das Verzeichnis /Library/StartupItems kopiert werden. Dann muss in der Datei /etc/hostconfig angegeben werden, dass apache2 beim Systemstart gestartet wird. Dies geschieht anhand der Zeile:
APACHE2=-YES-
Beim nächsten Neustart wird Mac OS X eine Meldung bezüglich fehlerhafter Sicherheitseinstellungen ausgeben, diese lassen sich auf Knopfdruck korrigieren. Daraufhin folgt ein weiterer Neustart und schon ist das System betriebsbereit.
Arbeiten mit Subversion
Jetzt ist das Repository einsatzbereit. Mittels der Kommandozeile im Terminal lassen sich jetzt Dateien ein- und auschecken. Etwas komfortabler geht die Versionsverwaltung mit einem Werkzeug wie svnX. Da svnX nicht von einer darwinports-Installation ausgeht, muss noch der Pfad zum ausführbaren Programm svn in den Einstellungen angepasst werden:

Quellen
Version Control with Subversion
Subversion lokal unter Mac OS X