Zertifikatseigenschaften von FreeRadius prüfen lassen

Ich hab seit einiger Zeit einen FreeRadius-Server um mein WLAN abzusichern und mein VPN Zugang zu regeln. Das System war so konfiguriert, dass der Client ein Zertifikat vorzeigt, einen Tunnel aufbaut und dann via EAP/PAP autorisiert wird. Das Gruppenmanagement übernahm dabei LDAP und die das Passwort wurde via Kerberos geprüft. Alles in allem sehr flexibel aber auch sehr komplex. Vor allem der LDAP Server störte mich doch extrem. Zum einen ist der so ganz anders zu konfigurieren und zu verwalten, als alle anderen Dienst ein meiner Landschaft, zum anderen hab ich ihn nie so richtig verstanden. Kurz der musste weg. Ich wollte aber weiterhin die Option haben, eine Nutzer via VPN auf Subnets „Zugang“ zu lassen aber vom Heimnetz „Sicher“ fern zu halten. Insofern man den aktuellen FreeRadius einsetzt bietet dieser eine sehr elegante Möglichkeit an, dass auf Zertifikatsbasis zu lösen.

Der Grundgedanke: Insofern man der CA wirklich vertraut bzw. die CA selber stellt, kann man davon ausgehen, dass ein Client nur das Zertifikat hat, dass er haben darf. Verlust und Diebstahl wird über eine aktuelle „Revocation Liste“ gelöst. Vertraut man der CA, kann man somit die Zugangsinformationen ins Zertifikat hinterlegen. Zum Beispiel kann man das OU (OrganisationUnit) oder gar das CN Feld nutzen. In meinem Fall, hab ich mich auf das CN Feld bzw den ganzen Zertifikats-Pfad verlassen. Meine Netz ist in verschiedene Bereiche getrennt: Sicher, Gesichert, Offen (Radius entfällt). Alle Clients haben schon jetzt Zertifikate die wie folgt aussehen: hostname.sicher.ca oder bekannter.gesichert.ca. Ich musste den Radius nur noch dazu bekommen, dass ein Client der in das „Sichere“ Netz will auch ein „sicher.ca“-Zertifakt vorweißt.

Umsetzung: Was man vorher braucht, ist ein Radius der TLS beherrscht. Das wird hier beschrieben: Ubuntusers:Wiki – FreeRadius. Läuft der TLS Modus stehen nun eine Reihe von Variablen innerhalb der FreeRadius-Configuraiton zur Verfügung. Eine komplette Liste konnte ich nicht auftreiben aber laut einigen Mailinglisten sind die folgenden Variablen wohl verfügbar:

  • TLS-Cert-Serial
  • TLS-Cert-Expiration
  • TLS-Cert-Issuer
  • TLS-Cert-Subject
  • TLS-Client-Cert-Serial
  • TLS-Client-Cert-Expiration
  • TLS-Client-Cert-Issuer
  • TLS-Client-Cert-Subject

Interessant ist die TLS-Client-Cert-Subject – Variable. Diese stellt das Subject via String zur verfügung. Jetzt muss man nur noch mittels RegExp seine gewünschte Prüfung durchführen. Dass kann dann so aussehen.

authenticate {
  Auth-Type eap {
    eap 
    if ( Huntgroup-Name == 'sicher' && "%{TLS-Client-Cert-Subject}" =~ /\/CN=.*\.sicher\.ca\// ) { 
      ok 
    }
    else {
      reject
    }
  }
}

Die „Huntgroup“ ist eine Eigenschaft die durch beliebige Regeln vorher gesetzt wird. In meinem Fall sieht die Regel so aus:

atlantic   NAS-IP-Address == 10.11.1.2, NAS-Identifier == "sicheres-lan" 

Was folgt ist folgende Prüfung. Wenn eine TLS-Verbindung über einen Zugangspunkt mit der IP 10.11.1.2 und NAS-ID (vorher vereinbart) „sicheres-lan“ ankommt muss das CLientZertifikat auf „*.sicher.ca“ ausgestellt sein. Alles andere wird abgeleht. Mann kann da noch weitere else-Zweige einbauen. Aber das Prinzip bleibt das gleiche.

Servergespeicherte Profile mit unison

Da CSync leider nicht meine Erwartungen erfüllt hat bzw. nicht im Ubuntu-Repository versorgt wird musste ich mich vor ein Weile nach Alternativen umschauen.

Dabei bin ich auf Unison gestoßen. Installiert man es auf Client und Server kann man via ssh sehr schnell große Datenmengen in beide Richtungen abgleichen. Man kann sogar eine Konfliktlösungsstrategie angeben, falls es sowohl auf Server als auch Clients zu Änderungen kam.
Mittels Exclude-List kann man gezielt steuern was übertragen werden soll. Sogar via Regex.

Beispielconfig:

root = /home/myuser
root = ssh://myuser@myserver.local//path/to/storage
batch = true

ignore = Path .unison
ignore = Path .kdevduchain
ignore = Path .kde*/cache-*
ignore = Path .kde*/socket-*
ignore = Path .kde*/tmp-*
ignore = Path .kde/share/apps/amarok/albumcovers
ignore = Path .kde/share/apps/nepomuk
ignore = Path .kde/share/apps/akregator/Archive


ignore = Regex [^\.].* # alle Dateien die nicht mir . beginnen werden ignoriert.

Das ganze kann man ohne Probleme über ein Skript beim Start oder Login automatisieren:

/usr/bin/unison sync_homedir -silent -prefer newer -times

Bleibt nur noch das Problem wie man den ssh-Daemon auf der Server-Seite dazu bekommt ohne weitere Passwortabfrage eine Verbindung zuzulassen. Da gibt es verschiedene Varianten wie z.b. das Public-Key-Verfahren (wobei der keyring automatisch aufgemacht werden muss) oder GSSAPI. Letztere ist relativ bequem einzusetzen, wenn man mal einen Kerberos eingerichtet hat. Dann muss man einfach folgende Konfiguration im SSH Daemon vornehmen.

# Kerberos options
KerberosAuthentication yes
KerberosGetAFSToken yes
KerberosOrLocalPasswd yes
KerberosTicketCleanup yes

# GSSAPI options
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes

Anschließend akzeptiert der SSH Daemon nach einem Neustart auch Kerberos Tickets anstatt ein Password abzufragen.

Aquaero – einmal Lüftersteuerung bitte

Diesmal ein (noch) nicht Linux bezogenes Thema.

Alle Rechner die ich mir in letzter Zeit aufgebaut habe, habe ich immer auch dahin gehend optimiert, möglichst geräuscharm zu sein. Das Spektrum reicht von „kaum Wahrnehmbar“ (HTPC – *grml* Asus…) bis „nicht vermeidbar“ (14 HDDs erzeugen Vibrationen und Wärme…). Immer eine große Hilfe war mir dabei Produkte von Aquacomputer. Da ich mittlerweile ein kleines Vermögen bei der Firma gelassen habe, will ich mal meine Erfahrung für all die Kundtun, die mit dem Gedanken spielen, Produkte von dieser Firma zu erwerben.

Aquacomputer ist eine der wenigen deutschen Firmen die Computerbauteile (im entferntesten Sinne) in Kleinserie für den Endnutzer fertigen. Die Produktpalette von AC dreht sich dabei komplett um das Thema „Wasserkühlung und Steuerung“. Von Pumpen über Radiatoren bis hin zu Steuerungen/Reglern wird alles angeboten was man so braucht. Die Produkte sind alle hochwertig und passgenau verarbeitet, und machen Optisch einiges her. Zu beanstanden hatte ich nie etwas (von fehlenden Schrauben mal abgesehen).

IMG_20130223_13_57_39Besonders zu erwähnen ist die Aquaero 5. Diese „Lüftersteuerung“ setzt sich von ihrer Konkurrenz vor allem durch ihre Konfigurierbarkeit aus. Preislich liegt sie mit anderen Produkten auf einer Linie, ich hab aber keine andere Steuerung gefunden die so viele Regelungsmöglichkeiten bietet. 8 Temperatursensoren (die einzige Eingangsgröße die Einfluss auf Ausgangswerte nehmen kann) können direkt angeschlossen werden, wer mehr braucht, kann sich Erweiterungsmodule dazu stecken. Vier Lüfter kann die Steuereinheit direkt Versorgen (auch das kann man erweitern). Leider nur einen davon im PWM – Modus. Alle Ausgänge sollen 1,65 A bieten. Man kann also mehre als nur einen Lüfter pro Kanal antreiben. Kaufgrund und vor allem Empfehlenswert ist für mich aber die Steuereinheit selber. Es werden fünf Reglertypen angeboten, wobei jeder der angebotenen Hardwareausgänge angesteuert werden kann (LED, Lüfter, PWM-Leistungsausgänge):

  • Vorgabewert: Ausgang mit x% Leistung
  • Zweipunkt Regler: bei Temp x1 einschalten und bei Temp x2 auschalten.
  • Kurveregelung: bei Temp X -> Leistung y
  • Sollwert/PID-Regler: Versucht die eingestellte Temperatur zu „halten“.
  • LED-Regler: Kennt drei Bereiche (zu kalt, optimal, zu heiß) und kann entsprechend drei Ausgänge ansteuern.

IMG_20130223_13_54_43Der PID-Regler hat es mir angetan. Kurz und knapp: wenn man den PID Regler richtig einstellt, das braucht eine Weile, werden die Lüfter nur dann hochgedreht wenn sie gebraucht werden, anschließend wird die Lüfterleistung und Temperatur auf den Sollwert „eingeschwungen“ (im wahrsten sinne des Wortes). Dies hat z.B gerade bei „AlwaysOn“ Festplatten den Vorteil, dass man die optimale Betriebstemperatur einstellt und halten kann. Das ist materialschonend und erhöht die Lebenserwartung. Meine Serverplatten werden seit zwei Jahren konstant im Bereich 35 bis 40°C gehalten, unabhängig ob sie gerade belastet werden oder in Ruhe sind. Auch Schwankungen der Außentemperatur können bis zu einem gewissen Grad gut kompensiert werden.
Die AE5 wird in mehreren Versionen angeboten. Meine präferierte Version war eigentlich die LT Version. Bei dieser Version bekommt man nur eine Platine ausgeliefert. Parametriert und überwacht wird die AE5 via USB. Eigendlich ideal für Server die remote Verwaltet werden und HTPCs die keine 5 1/2 Zoll Slot zu verschenken habe. Leider wird von Aquacomputer kein Linux Support geliefert, so dass man zwingend Windows braucht um die AE5 initial zu konfigurieren. Die anderen beiden Versionen werden mit Display und Bedienknöpfen samt Edelstahl-Einbaurahmen geliefert. Die teuerste Version bringt gleich noch eine IR-Tasturvernbedienung mit.

Verbaut habe ich die AE5 drei mal. Einmal eine LT in meinem HTPC, wo zwei kleine Lüfter so geregelt werden, so dass das eigentlich „lüfterlose“ Board AT5IONT sich nicht über 60 Grad aufheizt. Die AE5 dafür zwar auf den ersten Blick oversized , im nach hinein ist es meiner Meinung nach das schwierigste Setup. Der HTPC steht im Wohnraum und darf kein Geräusch von sich geben. Die AE5 war die einzige Steuerung, für die ich kein Laufwerkslot brauchte und die Lüfter quasi Stufenlos Aussteuern kann. Dies gelingt ohne Probleme. Einmal korrekt eingerichtet, verrichtet die AE5 ihren dienst seit gut einem Jahr ohne ein Aufhäulen eines Lüfters oder abrauchen des Boards.

Daneben kommen noch zwei weitere AE5 mit Display in meinem Server als auch meinem Desktop PC zum Einsatz. Beide Setups sind nicht weiter erwähnenswert. Beim Server werden insgesamt 6 Lüfter Zonenweise so aus gesteuert, dass die oben erwähnte Betriebstemperatur der Platten gehalten wird. Im Desktop kann die AE5 ihr vorgesehenes Potential auspielen und neben 4 Lüftern auch noch eine ganze Wasserkühlung mit überwachen. Auch dieses System wird wie Vorgesehen ohne Lärm auf den vorgesheen Temperaturen gehalten.

Aquastream quer verbautAquastream und Aqualis aufrecht verbautNeben der AE5 ist noch die Aquastream XT-Pumpe als „intelligentes Bauteil“ erwähnenswert. Diese gibt es in drei Varianten. Bautechnisch handelt es sich immer um die gleiche Pumpe, es werden per Software nur neue Steuerfeatures freigeschaltet. Die kleinste Variante agiert „nur“ als Regelbare Pumpe. Die Pumpfrequenz kann von 50Hz (leiser als das Festplattenbrummen) bis 75Hz (höhrbar/vergleichbar mit guten CPU Lüfter). Die Pumpe kann dabei via Aquabus an die AE5 angeschlossen und über diese Konfiguriert und Überwacht werden. Die beiden teureren Versionen bietet dann noch manuelle bzw. temperaturgesteuerte Lüftersteuerung.

OpenWrt im Langzeittest

Ich hab seit einer geraumen Zeit OpenWRT im Einsatz und will hier mal meine Meinung zu dieser „Linux-Distribution“ kundtun.

Bei OpenWRT handelt es sich wie DD-WRT um eine aus dem WRT54G-Basissystem entstandene, auf Router ausgerichtete Firmware. Viele weitere Projekte wie z.b Freifunk bauen auf OpenWRT auf.

Was zeichnet OpenWRT nun gegenüber anderen Router-Firmwares aus, was macht es empfehlenswert? Kurz und knapp: es ist ein „echtes“ Linux. Soll heißen, man hat ein schreibbares  Root-Dateisystem, vollen Zugriff auf /dev, /etc und alle Änderungen überleben einen Reboot. Man kann sämtliche Hilfs- und Automatisierungsfunktionen abschalten bzw. deinstallieren und ggf. auf einem „nackten“ System aufsetzen. Mittels des Paketmanagers opkg kann man bequem fast alles nachinstallieren was man so braucht, wenn mal etwas fehlt kann man es sich auch selber ein Paket bauen. Alles in allem ein Eldorado. Kniffelige Setups lassen sich relativ unkompliziert Umsetzen, Dinge die mit anderen Firmwares nicht funktionieren (VLAN  Konfiguration pro Port) sind mit OpenWRT ohne größeren Aufwand umgesetzt. All das hat dafür gesorgt, dass OpenWRT momentan auf allen meinen Routern im Einsatz ist.

Es gibt aber auch Schattenseiten. Die große Funktionsvielfalt geht meist mit einem Konfigurationswust einher. Bei OpenWRT versucht man das über eine einheitliche Konfigurationsschnittstelle  abzufangen (UCI). Dabei gibt es unter /etc/config eine reihe von Konfigfiles die immer „gleich“ gestaltet sind. Diese werden mittels Paketabhängiger Scriptes dann in die eigentlichen Konfigurationsfiles umgesetzt. Aus der WLAN-Config Datei /etc/config/wireless wird zb das /tmp/hostapd.conf erzeugt und anschließend der hostapd Dienst hochgefahren. Dieses Verfahren hat drei Schwächen. Wenn der Paketverwalter keine UCI Unterstützung vorsieht, ist man wieder mit der Hand am arm unterwegs. Manchmal wird sowohl UCI als auch die eine eigene Konfiguration benötigt, dann wird es schnell unübersichtlich. In seltenen Fällen empfinde ich das UCI Interface komplizierter als die ursprüngliche Konfigurationsmethoden. Die UCI-Firewall Konfig schmeiße ich immer als erstes runter und setzte mir alles selber mit iptables-befehlen auf.

Was noch Problematisch ist, ist der  Upgrade/Deploy-Prozess. Es gibt verschiedene Varianten OpenWRT auf seinen Router zu bekommen. Einmal die „stable“ Images, dann den Entwickler-Images und zu guter letzt kann man sich aus dem Entwickler-Repo auch das latest-Image zusammenbauen. Die komfortabelste Variante ist ein stable-Image. Diese wird über die gesamte zeit mit Packages versorgt. Das Entwickler-Image (trunk) benötigt man, wenn die eigene Hardware noch nicht von dem stable-Image unterstützt wird. Hier hat man mit zwei Problemen zu rechnen. Zum einen fliegen Pakete aus dem Repo einfach raus. Das würde einen normalerweise erst bei der nächsten stable-Version (mit Vorwarnung) ereilen. Das zweite Problem ist, sobald die Entwicklerversion auf einen neuen Kernel setzt, werden die module entsprechend hochgezogen. Will man ein Paket aktualisieren steht nun ein komplettes Router flashen an. Nach dem flashen hat man quasi wieder einer jungfräulichen Router. Einzig ein paar vor definierte Ordner und Dateien (inkl /etc)  werden erhalten. Pakete und Anpassungen muss man manuell nachziehen. Das macht die Fernwartung ein wenig kniffelig.

Das sind aber auch die einzigen Probleme, die ich mit dieser Distri hatte. Ansonsten sind in ca einem Jahr betrieb keine einziger störender Effekt aufgetreten. Die ganze Zeit liefen die Router stabil und ohne nennenswerten Konfiguration/Administrationsaufwand.

Moneyplex auf Ubuntu 12.04 64bit mit PCSC-Treiber

Wer Moneyplex mit auf einem 64Bit system betreibt, wird das ein oder andere Mal verärgert feststellen, dass es immer noch keine native 64 Bit Version des Programms gibt. Um es zu starten muss man unter Ubuntu schon immer das ia32-libs Package installieren. Will man dann auch noch den kartenleser via PC/SC-Treiber ansprechen (oder muss es, weill der Herrsteller nur solche Treiber ausliefert) musste man im 10.04 LTS basteln. Mittlerweile kann man einfach die benötigte Library im 32 Modus nachinstallieren. Einfach das Paket libpcsclite1:i386 nachinstallieren, Moneyplex neustarten und zb den Reiner-SCT ohne gefrickel ansteuern.

So nun muss matrica nur noch eine 64Bit Version raus bringen, dann bin ich 100% zufrieden 😉

Ubuntu Upgrade / Neuinstallation mit geringer Downtime

Wenn man den Ubuntu LTS auf einem Server einsetzt hat mein ein relativ ruhiges Leben. Es gibt kaum wartungsaufwand, da sich die Updates automatisch einspielen (wenn man das will), nur ab und an sollte man den Rechner neustarten.

Will man die Maschine jedoch auf die neue Version hochziehen ist Arbeit angesagt. Ob man nun das Upgrade macht oder ein blankes System aufspielt. Beides kostet Zeit und eine Downtime. Kann man ein ersatzsystem sein eigenen nennen oder eine Weile auf die Services verzichten ist das keine Problem, leider ist dem selten so.

In meinem Fall geht ohne meinen Ubuntu-Server gar nichts und für eine komplettes Spiegelsystem hab ich weder Geld noch Platz. Ich brauchte einen Weg um die Downtime für die gesamte Familie auf unter 4 Stunden zu drücken. Kurz der WLAN Wecker sollte am nächsten Morgen wieder wecken. (Ubuntu-Server = Radius, MediaStorage und MediaServer)

Was es dazu braucht ist ein Software-Raid (Mirror) eine zweite Maschine und eine Virtuelle-Umgebung die eine physikalische Platte „durchreichen“ kann.

Der Trick ist einfach. Man baut im laufenden Betrieb eine der Mirror-Platten aus. Das kann jeh nach Konfiguration (kein HotSwap, „umbauarbeiten“ notwendig) eine kurze Downtime bedeuten. Anschließend schließt man die Platte an einem anderen Rechner an und haut ein VM-Host seiner wahl drauf. Dieser sollte direkt mit Physikalischen Platten umgehen können. (VMWare, VirtualBox) Nun muss man nur noch eine VM erzeugen und anschließend von der Platte booten. In meinem Fall funktionierte das tadellos. Der virtuelle „Server“ meckerte zwar eine defekten Raid und fehlendes Netzwerk an, aber das ließ sich schnell beheben.

Ab diesem moment kann man in aller Sehlenruhe sein Upgrade einspielen oder gleich den ganzen Server neu aufsetzen.

Anschließen muss man nur die eigentliche Hardware runterfahren. Die noch aktive Platte ausbauen und (ganz wichtig) die RAID-Header-Informationen löschen (mdadm –zero-superblock). Die „VM“-Platte wieder in den Rechner einbauen durchstarten und hoffen dass man alles richtig eingerichtet hat. Wenn alles klappt bootet der Rechner ohne murren durch, man richtet den RAID wieder ein und hat eine Downtime von unter einer Stunde.

XBMC unter 12.04

Im Rahmen meines Wechsels von Ubuntu 10.04 bis 12.04 musste als erstes mein HTPC dran glauben. Das ganze ging recht Problemlos von statten. Einzig der NoDM hatte Probleme bereitet. NoDM erwartet den XServer unter /usr/bin/X. Ubuntu 12.04 stellt selbigen aber (ohne Link) unter /usr/bin/Xorg zur Verfügung. Da musste mit einem Link nachgeholfen werden.

Danach lief sofort XBMC hoch, ohne weitere Probleme. Danach begann jedoch die Detailarbeit.

Wie gehabt muss nachgeholfen werden, wenn man vie XBMC den Rechner runter fahren möchte. Dazu bedarf es der Packete policykit-1, upower und acpi-support.

sudo aptitude install policykit-1 upower acpi-support

anschließend müssen dem XBMC-User die entsprechenden Rechte eingeräumt werden:
File /var/lib/polkit-1/localauthority/50-local.d/xbmc-actions.pkla

[Actions for xbmc user]
Identity=unix-user:xbmc-user
Action=org.freedesktop.upower.*;org.freedesktop.consolekit.system.*;org.freedesktop.udisks.*
ResultAny=yes
ResultInactive=yes
ResultActive=yes

Danach kann man über die entsprechenden Menüs/Kommandos aus XBMC heraus den Rechner Ausschalten, Schlafen legen oder in den Hibernate schicken.

Um den Rechner wieder aufzuwecken bedurfte es eines weiteren Kniffs. Die Schnittstelle, wie man ein USB Device für das Aufwecken markiert hat sich verändert. Ich musste es wie folgt erweitern:

#!/bin/sh
echo "USB0" > /proc/acpi/wakeup
echo "USB2" > /proc/acpi/wakeup
echo enabled > /sys/bus/usb/devices/3-1/power/wakeup
echo enabled > /sys/bus/usb/devices/usb1/power/wakeup
echo enabled > /sys/bus/usb/devices/usb2/power/wakeup
echo enabled > /sys/bus/usb/devices/usb3/power/wakeup
echo enabled > /sys/bus/usb/devices/usb4/power/wakeup

Interessanterweise war die „Breitbandfreigabe“ nur für den Suspend nötig. Um aus den Hibernate aufzuwachen reichte es das 3-1 Device zu „enablen“. Ich hab das Script auch nicht mehr in der rc.local verlink sondern lasse es vor und nach jeden Suspend/Hibernate ausführen, indem es unter /etc/pm/sleep.d abgelegt wurde.

Ein letzer Kniff war nötig damit sich das DVD-Laufwerk nach dem mounten auswerfen lies. Dazu musste ich in der /lib/udev/ruled.d/60-cdrom_id.rules die folgende Zeile ändern.

IMPORT{program}="cdrom_id --lock-media $tempnode"

So sollte es aussehen, dann lässt sich das Laufwerk jederzeit öffnen.

IMPORT{program}="cdrom_id $tempnode"

Quellen:

Zwei Jahre Ubuntu 10.04 – Zeit für einen Wechsel

Seit dem 29 April 2010 betreibe ich meinen HomeServer mit Ubuntu LucidLynx. Danach hab ich suxesive meine ganze Rechner auf den Langläufer umgestellt. Die folgenden zwei Jahren waren die ruhigsten in meiner ganzen Zeit, die ich mit Computern zu tun hab.

In der ganzen Zeit ereilten mich nur zwei „schwere Fehler“ (GAUs) die ich nicht auf meine eigene Dummheit zurückführen konnte. Gleich zu beginn Zerschoss mir der GRUB-Installer mein verschlüsseltes Storage indem der Bootsektor den Kryptoheader überschrieben hat obwohl ich eine andere Platte als Bootloader-Ziel angegeben habe. Der zweite GAU ereignete sich durch ein defektes Update, der die Netbook-Version unbenutzbar machte.

Beide Fehler liesen jedoch mit überschaubarem Aufwand beheben. Alle weiteren Fehler waren auf die eigene Dummheit zurückzuführen. Alles in allem hat sich der LTS-Release als sehr robust erwiesen. Jetzt wird es Zeit Abschied zu nehmen und auf die neue Version umzusteigen, hoffentlich werden die folgenden 2 Jahre genauso entspannt wie die bisherigen.

Android: Multithreading mit AsyncTask und Deadlocks

Wenn man für Android Anwendungen entwickelt kommt man sehr schnell mit dem AsyncTask in Kontakt. Immer dann, wenn etwas länger dauern kann, soll man diese Klasse benutzten, so der Tenor in fast allen Tutorials, Blog-Einträgen und Offiziellen Developer-Guides. Was seltener zur Sprache kommt ist folgender Umstand: unterschiedliche AsyncTask-Instanzen sind nicht unabhängig voneinander.  Standardmäßig laufen alle AsnycTask auf einem „Executor“, einem ThreadPool. Jeh nach AndroidVersion ist dieser auf Serielle Verarbeitung eingestellt (ein WorkerThread) oder stellt fünf WorkerThreads bereit.

Als Entwickler kann man dies aber auch vorgeben oder gleich einen eigenen ThreadPool mitgeben. Das Problem bleibt aber das gleiche: man kommt wahnsinnig schnell in die Versuchung zwei AsyncTask logisch zu verschalten oder aus einem Task einen mehrere Task zu erzeugen und auf deren Ergebnisse zu werten (scatter – gather). Die Anzahl der WorkerThreads legt nun fest wie schnell das ganze in die Hose geht. Bei einem WorkerThread braucht es solange bis der erste „wartende“ AsyncTask anfängt zu warten, danach kommt kein andere AsyncTask mehr zum Zug. Bei zwei oder mehr WorkerThreads kann es immer gut gehen oder zu der Situation kommen, dass alle Threads auf Tasks warten die noch gar nicht ausgeführt werden. Ein klassisches logisches DeadLock. Die Anwendung „hängt“, Android bekommt es nicht mit, weil der UI Thread nicht blockiert ist und der User schimpft.

Das ganze kann man umgehen indem man nicht „unbegrenzt“ auf ein Ergebnis wartet (AsyncTask.get mit Zeitspanne aufrufen), die Abhängigkeiten anderes gestaltet oder mehrere unterschiedliche ThreadPools verwendet. Das Grundproblem ist aber, ein einmal erzeugter AsyncTask(.execute) wird genau einmal ausgeführt. Man kann ihn nicht vom Stack nehmen, nicht wieder einqueuen oder sonst wie an der Ausführungsreihenfolge drehen.

Glücklicherweise stellt Google die Klasse im Rahmen seiner OpenSource-Strategie die AsyncTask-Quelldatei zur Verfügung, so dass man sich relativ einfach seine eigene AsyncTask-Variante nach eigenem Bedarf zusammenbauen kann.

Ich hab das z.B gemacht um einen dedizierten Thread zu haben, bei dem immer wieder Task eingequeued werden können und sequenziell in einer definierten Reihenfolge (FIFO) abgearbeitet werden.

Sources: RepeatingTask

Grundsätzlich bleibt aber gültig: wer Multithreading betreibt, weiß was er da tut oder kommt in die Hölle.

LVM – Rolling Mirror

Rolling Backups sind eine beliebte Variante um zum einen alle BackupMedien gleich-verteilt zu ab zu nutzen und zum anderen mehrere Backupversionen zur Verfügung zu haben. Diese Arbeitsweise wird jedoch mit zunehmender Speichergröße unpraktisch. Ein Fullbackup ist bei 2TB nicht mehr Täglich möglich (6-8 Stunden IO nur durch Backup). Bei inkrementellen Backups ist das Wiederherstellen einzelner Dateien zeitaufwändiger.

Ein guter Kompromiss sind Tools wie „rdiff-backup“. Diese bietet quasi ein Full und Inkrementell Backup  in einem rutsch an. Da nur Änderungen geschrieben werden, bleibt die Dauer des einzelne Backuplaufes kurz und da immer ein FullBackup gehalten wird, kann man ohne Umwege auf die „aktuellste“ Version zurückgreifen. Nur wenn man auf ältere Versionen zurückgreifen will, muss man „ein bisschen“ Rechenzeit einplanen.

Jedoch muss bei rdiff-backup immer der letzte aktuelle Stand als Backup vorliegen. Tauscht man einfach platten durch, kann man beim „einlegen“ einer neuen Platte nicht mehr auf die alten Daten zugreifen. Mann muss die neue Platte also vorher mit den alten Daten bespielen.

Die Idee: Man richtet kurzzeitig einen Mirror zwischen HDD n und HDD n+1 ein. Die Syncronistation beeinflusst das Gesamtsystem kaum, da es sich Backupplatten handelt. Das Backup bleibt über die gesamte Zeit verfügbar, es können also weitere Inkrements gespeichert werden. Die Syncronisationsdauer spielt also keine Rolle. Ist der Mirror hergestellt entfernt man HDD n aus dem System und legt sie in einer anderen „Brandzone“ ab. HDD n+1 übernimmt jetzt die aktive Backupphase. Das kann man so lange treiben bis einem Entweder die Platten ausgehen oder man die gewünschte Datensicherheit/Speicherdauer erreicht hat.

Zum umsetzen kann man LVM nutzen. Das Backupdevice muss jedoch von Anfang schon ein LVM-Device sein.

Als erstes initialisiert man einen Mirror. In Fall wird dem Logischen Device vgBackup/lvBackup die Platte /dev/sda hinzugefügt.

pvcreate  #ggf  zu für die LVM Nutzung vorbereiten.
vgextend diskGroup  #Diskgruppe erweitern
lvconvert -m 1 diskGroup/logcalDevice  --corelog --type mirror -b
lvs #hiermit kann der Sync-Status abgefragt werden.

Nun muss der Spiegel aufgebrochen werden. Normalerweise kann man die Platte einfach so entfernen (HotSwap) wenn kein IO stattfindet. Wenn man sichergehen will, mountet man das Device mal kurz read only.

Anschließend werden ein Haufen fehlermeldungen auftrehten die auf die Fehlende Platte hinweisen. Die wird man mit folgendem Befehl los:

vgreduce --removemissing diskGroup --force