Bullshit made in germany …

oder „Ich hab jetzt endlich auch ein Konto in der Schweiz“

Zu einer Zeit als mobile Endgeräte noch PDA genannt wurden, entschied ich, wegen eben solch eines Endgerätes, dass ich unbedingt einen IMAP fähigen Mail-Server benötige. Leider hatte man zu dieser Zeit nur zwei Möglichkeiten: selber einen Mail Server betreiben oder Geld für mehr Service bezahlen. (Google Mail war gerade erst im kommen).

Seit diesen Tagen bin ich GMX Pro Kunde. Rückblickend eine verdammt lange Zeit. Ich könnte jetzt einen langen Beitrag darüber schreiben, was GMX und United Internet in Zeiten der Mobilen Endgeräte alles verpennt hat, oder was man als „versierter“ Endnutzer eigentlich erwartet aber belassen wir es bei den Basics. Unzufrieden war ich schon lange mit diesem Verein. Ausschlaggebend für meinen Wechsel weg von GMX war jedoch nur ein Grund: Sicherheit

Ich hab mit entsetzten registriert, wie dilettantisch GMX die letzten Monate agiert hat. Da wird mit großen getöße Angekündigt, dass eine Jahrzehnte alter Standard jetzt umgesetzt wird (Verschlüsselung erzwingen) und dann Versagen sie auf ganzer Linie. Für einen Lacher auf dem 30C3 hat es gereicht. Anstatt sich dann um die Sicherheit ihrer Kunden zu kümmern und endlich ihr WebFronted zu überarbeiten, wird lieber eine Kampagne gegen unliebsame Adblocker gefahren. Das Niveau war erschreckend. Weder vor Scaring noch vor FUD wurde zurückgeschreckt.

Gleichzeitig war das WebFronted von GMX ohne Adblocker, Ghostery und co selbst als zahlender Kunde nicht anzusteuern. Von der Aufmachung nach Bildniveau ganz zu schweigen. Dazu kamen so witzige Sachen wie „nicht abschaltbares Bilderladen beim betrachten von Mails“.

Lange rede kurzer Sinn: ich brauchte einen anderen E-Mail Provider. Eigendeich wollte ich mir selbst einen Server hosten. Kurze die Rahmenbedingen überschlagen:

  • Kosten für eine statische IP (über VPN) – Mein Provider will mir keine statische IP schalten.
  • Mir stehen „nur“ 16/1 Mbit zur Verfügung. Sollte für Mailversand reichen, aber schön ist anders…
  •  Ein Mailserver der öffentlich zugänglich ist, ist eine ganz andere Hausnummer. Vom Pflegen der Spamfilter mal ganz zu schweigen.

Danach hab ich das „Eigenhosting“ für weitere 5 Jahre auf Eis gelegt und mich auf die Suche nach passenden Providern gemacht und bin bei einem kleinen Anbieter in der Schweiz fündig geworden: Kolab Systems.

Zum einen bieten sie ihre Groupware als OpenSource an (was Standard in der Branche zu sein scheint, wenn man gegen Outlook bestehen will), zum anderen betreiben sie einen Mail-Service mit eben dieser Groupware, der all das bietet, was man sich von einem modernen Mail-Provider wünscht:

  • Sicherheit:  Nach bekanntwerden des Hearthbleed – GAUs wurden binnen weniger Stunden die Zertifikate getauscht und die User Informiert. Bei GMX warte ich immer noch auf eine Benachrichtigung.
  • Sicherheit: unverschlüsselt wird nichts angeboten und deren Transportverschlüsselung ist „State of the Art“
  • Datenschutz: Es wird stark auf Anonymität und Sicherheit geachtet. Das FAQ und die Service Beschreibung lesen sich als ob Aluhut-Träger die Zielgruppe sind.
  • Terms of Service die man verstehen kann.
  • Ach und nebenbei voller Support von Mobilen Endgeräten OHNE proprietäre APP (via ActiveSync und Card/Cal-DAV)
  • Synchronisation zwischen verschiedenen Usern
  • Achja und keine Werbung

Müsste ich jetzt nicht alle Dienste auf die neue Mail umstellen, wäre ich im siebten Himmel.

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.

IPSec/L2TP VPN mit OpenWRT

Da ich mehrere Android Geräte in Benutzung habe die ich nicht „rooten“ darf und dennoch einen VPN Tunnel in mein Heimnetzwerk brauche, hatte ich das „Vergnügen“ mich mit IPSec/L2TP – Tunneln auseinander zu setzten. Android bietet native aktuell vier VPN-Varianten an: PPP, L2TP, IPSec/L2TP (PSK), IPSec/L2TP (Certificate)

PPTP fällt aus, da der Android-Client nur primitive Authentifizierungen anbietet, welche als leicht angreifbar gelten. L2TP ist nur ein Layer2-Tunnel-Protokoll um darüber wiederum ein PPP-Tunnel aufzubauen. Da L2TP selber nicht Verschlüsselt ist das ganze nur so sicher wie der PPP Tunnel. Bei welchem wieder nur primitive Authentifizierungen angeboten wird. Bleibt als letzte Alternative nur den L2TP-Tunnel via eines IPSec Tunnel zu sichern. Sowohl die PSK (PreSharedKey) als auch zertifikatsbasierte Lösung sollten hinreichend sicher sein.

Damit beginnt aber auch schon der Ärger.  IPSec-Gateways findet man nur in wenigen SOHO Geräten vorkonfiguriert (z.b. einigen Fritzboxen) und das aus gutem Grund. Das Zusammenspiel Clients, Netze, Netzanbieter und IPSec läuft nicht so reibungslos wie es sollte. Dazu gleich mehr.

OpenWRT bietet gleich mehrere IPSec und L2TP Dienste an. Ich hab mich für den StrongSwan4 – Daemon als IPSec Dienst entschieden. Da dieser auch IKEv2 anbietet, in der Hoffnung dass dies vom auf Android eingesetzten Racoon-Daemon auch mal genutzt wird.

Des weiteren komm der xl2tp-Daemon oder der standardmäßig installierte ppp-Daemon zum Einsatz.

Bevor man die Sache angeht sollte man folgendes beachten um sich viel Zeit und Ärger zu ersparen: Das fehleranfälligste an einem IPSec/L2TP-VPN ist der IPSec-Anteil. Man sollte diesen also getrennt testen. Als sinnvoll hat es sich gezeigt, den Zielrouter mal vom Netz ab zu klemmen, die Firewall abzuschalten und plain den xl2tp-Daemon im Zusammenspiel mit dem PPP-Daemon zu testen. Das ganze geht einfach von der Hand und ist robust und stressfrei.

Danach kann man den IPSec Tunnel via PSK hochziehen und im internen Netz testen. Anschließend kann man ggf noch Zertifikate zur Authorisierung nutzen. Erst wenn das alles im internen Netz klappt sollte man Versuchen von „Außen“ auf das VPN zuzugreifen. Es empfiehlt sich an dieser Stelle für die Mobilen Devices einen LogReader zu installieren. Für Android ist das die App aLogcat. Leider gibt der racoon-Daemon nur in die Logfiles aus warum er einen Tunnel wieder zu macht oder warum er erst gar keinen aufbauen will.

Wie eingangs erwähnt gibt es mehrere Stolpersteine. Es war mir z.b. nicht möglich eines meiner Geräte dazu zu bewegen, den IPSec Tunnel aufzubauen. Das lies sich aber zweifelsfrei auf das Netzsegment zurückführen. Eine SIM-Karte des gleichen Netzanbieters aus einem anderen Gerät (anderes Netzsegment) eingewechselt und schon konnte der Tunnel aufgebaut werden. Es scheint Probleme beim Zusammenspiel Racoon – open/strong-Swan zu geben wenn mehrfaches „NAT“ing zum Einsatz kommt.[1. Quelle: http://www.mail-archive.com/users@lists.strongswan.org/msg02787.html]

Diesen Widrigkeiten zum Trotz kann man das ganze relativ leicht auf OpenWRT oder Ubuntu wie folgt einrichten:

Man benötigt  als Pakete den PPP-Daemon, XL2TP-Daemon und StrongSwan.

Configuration – /etc/ppp/options.xl2tpd

#Das wird nur gebraucht für radius-anbindung
plugin radius.so 
radius-config-file /etc/ppp/radius.conf
avpair NAS-Identifier=l2tp-vpn 
avpair NAS-Port=1

auth
#ggf für testzwecke noauth
#für debugging dump

lock
noccp
novj
novjccomp
nopcomp
noaccomp

ms-dns DNS-Server-IP

refuse-chap
require-pap

Hinweis ich erzwinge das unsichere PAP weil der IPSec-Tunnel via Zertifikaten gesichert ist (sehr schwer zu brechen, eigene CA) und FreeRadius für alles andere Klartextpasswörter im Zugriff braucht. Das muss man ggf. an seine Anforderungen anpassen!

Configuration xl2tp – Achtung hier verwende ich keine Authentifizierung. Das überlasse ich IPSec und PPPd
/etc/xl2tpd/xl2tpd.conf

[global]
port = 1701
;auth file = /etc/xl2tpd/xl2tp-secrets
access control = no
ipsec saref = no ;wichtig SAREF funktioniert nicht mit StrongSwan
;folgende zielen für debuggin einkommentieren
;debug avp = yes
;debug network = yes
;debug packet = yes
;debug state = yes
;debug tunnel = yes

[lns default]
exclusive = yes
ip range = 10.0.100.5-10.0.100.50
hidden bit = no
local ip = 10.0.100.1
length bit = yes
refuse authentication = yes
name = IpSec-Tunnel
ppp debug = no
pppoptfile = /etc/ppp/options.xl2tpd

Nun zu IPSec

config setup
        strictcrlpolicy=no #Für ein kleines Setup wird keine RevokationList verwaltet...
        plutodebug=none
        nat_traversal=yes #anschalten wenn man mit NAT(ted) Clients rechnet.
        virtual_private=%v4:10.0.0.0/8,%v4:192.168.99.0/24,%v4:!192.168.100.0/24
        charonstart=no #noch brauchen wir kein IKEv2
        #protostack=netkey
conn NAT-Tunnel
    authby=rsasig #Authentisierung via Zertifikaten
    pfs=no
    compress=no
    rekey=no 
    keyingtries=3
    type=transport
    auto=add
    left=%defaultroute
    leftcert=mycert.pem
    leftid=@mydomain
    leftrsasigkey=%cert
    leftsendcert=always
    leftprotoport=17/1701
    right=%any
    rightsubnet=vhost:%no,%priv
    rightprotoport=17/%any 
    rightrsasigkey=%cert
    rightca=%same #Wichtig das sorgt dafür dass alle Zertifikate die von der gleichen CA unterschrieben wurden wie das LeftCert angenommen wurden.
    keyexchange=ikev1 #ikev2 ist Standard auf ikev1 downgraden, da Android mit ikev1 reinkommt.

Anschließend sollte man sich noch vor der Dummheit der Nutzer und Clients schützen. Wenn der Racoon unter Andoid die Verbindung abbricht, versucht es der L2TP-Daemon dennoch aufzubauen. Die Verbindungsverwaltung bemerkt das zwar und beendet die Verbindung sofort, dummerweise wurden schon die Authentisierungs-Daten im Klartext gesendet. (Nein auch MS-Chap-v2 zählt als Klartext). Ein Angreifer kann so gezielt (über NAT) ein kurzes Downgrade erzwingen, die Daten abgreifen und dann selber ohne IPSec einen L2TP-Tunnel aufbauen.
Um das zu verhindern muss man IPTables dazu bringen Verbindungen für Port 1701(L2TP) nur dann anzunehmen, wenn diese über IPSec reingekommen sind. Früher war das einfach, da gab es ein ipsec-Device, heute muss man über die mangle-Table rann. Das ganze sieht dann wie folgt aus

iptables -A INPUT -p udp --dport 500 -j ACCEPT #IPSec kommt immer über port 500 rein
iptables -A INPUT -p esp             -j ACCEPT # Encapsulated Security Payload - IPSec Protokoll
iptables -A INPUT -p ah              -j ACCEPT #Authentication Header - IPSec Protokoll

iptables -t mangle -A PREROUTING -p esp -j MARK --set-mark 1 # Der eigendliche Paylod kommt über das ESP protokol, alle Pakete markieren.
iptables -A INPUT -m mark --mark 1 -p udp --dport 1701 -j ACCEPT #alle Pakete die markiert wurden und an 1701 gehen werden akzeptiert.

Mittels dieser Regel lehnt der Gateway alle L2TP Pakete ab, die nicht über IPSec gesichert wurden.

ics dhcp hostname direktive wird ignoriert.

Ich hatte bei mir das Problem, dass bei aktiven DNS-Update durch den DHCP Server „illegale“ DNS-Namen in meine dynamische Zone eingetragen wurden. Irgendein Witzbold muss sich bei Google wohl gedacht haben, dass „android_{MAC}“ ein wunderbar einfacher Hostname ist und den ein User nie ändern will.

Dummerweise wird dieser von keinem DNS Server standardmäßig akzeptiert. Man muss zu mindestens das „Sperrverhalten“ abschalten. Ich entschied mich dafür im DHCP Server ein Hostname zu definieren. Der wurde aber geflissentlich ignoriert. Das Snippet das standardmäßig als „on-commit“ Hook hinterlegt ist greift auf „option host-name“ zu anstatt auf „config-option host-name“.

Ich hab es wie folgt angepasst und in meine dhcpd.conf eingefügt

on commit {
  option server.ddns-hostname =
        pick (config-option host-name,option fqdn.hostname, option host-name);
  option server.ddns-domainname = config-option domain-name;
  option server.ddns-rev-domainname = "in-addr.arpa.";
}

Android – BitmapFactory und OutOfMemory-Exception

OutOfMemory-Exceptions sind immer eine unangenehme Sache. Trehten sie einmal auf, kann man nicht mehr reagieren. Das Programm wird einfach vom Stack geworfen und dem User eine unschöne Fehlermeldung vorgesetzt. Für den Entwickler ist die Fehlersuche langwierig, da das vermeintliche „Opfer“ selten der Verursacher ist. Der produzierte StackTrace ist schlicht unbrauchbar.

Die OOM-Exceptions trehten gehäuft im zusammenhang mit der BitmapFactory auf. Der Grund ist einfach, Bilder brauchen viel Platz…

Wenn man im Web nach Beispielen  für eine Bilder-Galerie sucht, bekommt man eigentlich immer das gleiche Beispiel. Ein paar kleine Bilder, lokale Resourcen, werden über eine Klasse die von BaseAdapter abgeleitet an ein über-gelagertes UI-Element gereicht. um dort zur Anzeige gebracht zu werden.

Bringt man jedoch Bilder auf einem Tablet zur Anzeige, werden schon die Bild-Dimensionen größer, nicht nur die Auflösungen. Auf einem 10 Zoll Tablet mit 1280×800 und mehr Bildpunkten braucht ein Bild in VollBild-Auflösung oder mehr schon mehrere MegaByte Ram, alleine zum Vorhalten der Bildinformationen. Dank der komprimierung brauchen Bilder als File wesentlich weniger Speicher, als die dann Tatsächlich im Ram belegen. Ein JPEG in 1920*1080 Aufgelöst und 500KB Dateigröße braucht mehr als 6MB Ram. Ein paar solcher Bilder im Ram abgelegt und die Dalvik-VM grüßt mit einer OutOfMemory-Exception.

Dazu kommt Fall einer Web Galerie die Bilder nicht lokal vorhanden sind, sondern bei Bedarf von einem WebServer geladen werden. Was einfach klingt, stellte sich schnell als vermeintliches Memory-Leak heraus. Im Grunde dreht sich alles um folgende Methode:

public View getView(int position, View cachedView, ViewGroup parent);

Mit dieser Methode werden die Views/darzustellenden Bilder zur Laufzeit abgefragt. Im einfachsten Fall sind das ImageViews die ein Bitmap auf den Bildschirm zeichnen.

Der augenscheinlichste Ansatzpunkt zum Speicher sparen ist, dass man eine vorher benutze View zur „Wiederverwendung“ übergeben bekommt (cachedView). Die CachedView kann man auch benutzen, der Resourcengewinn ist bei großen Bildern aber nicht „von Interesse“. In Anbetracht der xMB pro Bild, kommt es auf die paar Byte für die ImageView Struktur kaum an. Kommt jedoch ein AsyncTask zum ein Einsatz, um die Bilddaten „im Hintergrund“ herunterzuladen und in ein Bitmap zu decodieren, dann ist diese cachedView immens wichtig. Slided der User schneller durch die Galerie, als die Bilder aus dem Netz herunter geladen werden können, werden AsyncTask erzeugt, die „sinnlos“ Bilder im Hintergrund herunter laden und decodieren. Bei kleinen Bildern und einem Lokalen Cache, ist das nicht mal schlecht. Einmal gecached, werden die Bilder das nächste mal aus der lokalen Quelle geladen. Bei den großen Bildern frisst das parallele Decodieren schlicht zu viel Speicher.

Bei der GalDroid-Entwicklung hat es sich nicht als sinnvoll herausgestellt, die Anzahl der Threads zu kontrollieren. Der overhead, die Downloads zu queuen, stand in keinem Verhältnis zum Nutzen oder der Wartezeit des Users. Ich hab mir in der CachedView einfach den Task gemerkt, der das Bild herunterlädt und diesen bei Bedarf abgebrochen. So sind bei einer VollBild-Anzeigen selten mehr als vier Bilder parallel in Bearbeitung.

Eine Ausnahme gibt es noch: Ist das Layout des UI-Elements nicht statisch fixiert, werden die Dimension geändert, oder hängen die Dimensionen gar von den darzustellenden Inhalt ab, wird das 0-te Element mehrfach abgefragt um die benötigten Dimension zu bestimmen. Das ist in sofern übel, da es 5-7 mal hinter einander passierte, ohne das jeweils eine cachedView übergeben wird. Wieder: bei kleinen Bildern unschön, bei großen Bildern grüßt die OutOfMemory-Exception.

Das Problem kann man umgehen, in dem man mehr speichert. Bei der GalDroid wird einfach ein Feld von WeakReferences angelegt, in dem jedes je angefragte ImageView gespeichert wird. Die Logik ist simpel – wird ein Element mehrfach kurz hinter einander abgefragt, sollte es in diesem Speicher zu finden sein. Wird es länger Zeit nicht genutzt, räumt der GC auf und die WeakReference zeigt auf NULL.

Sollte nach diesen Maßnahmen immer noch OOM-Exceptions auftreten, kann man noch Bitmap.recycle aufrufen, sobald eine ImageView aus dem Sichtbereich des Users verschwindet. Das ist aber „frickelig“, da nicht immer klar ist, wann etwas „nicht mehr gesehen werden kann“. Das Recycle gibt sofort den Speicher des Bitmaps wieder frei, ohne den GC aufzurufen. Allerdings muss man so jedes mal das Bitmap neu laden, wenn es wieder in den Sichtbereich kommt.

Sollte das alles nicht helfen, kann man auf den Allocation Tracker zurückgreifen. Dieses Tool ist in dem ADT für Eclipse enthalten und listet jedes erstellte Objekt zur Laufzeit auf.

GalDroid – Gallery 3 für Tablets

Da es mich ein wenig genervt hat, dass es keine einfach Anbindung der Gallery 3 für Android Honeycomb gibt, hab ich mich selber mal hingesetzt und was zusammen geschustert. Das ganze ist ab heute im Market verfügbar.


Available in Android Market

Die Entwicklung ging relativ einfach von der Hand jedoch bin ich über einige grundlegende Sachen gestolpert, die ich in einigen Beiträgen in den nächsten Tagen vertiefen werde.

Für alle interessierten, den SourceCode gibt es hier: https://github.com/raptor2101/GalDroid

Android – App bekommt kein Zugriff aufs Internet

Da ich gerade meine ersten Gehversuche in der Android-Entwicklung mache, bin ich auch gleich in eine fiese Falle getappt.

Android hat ein „schickes“ Rechtemanagement. Jede App/Anwendung bekommt einen eigenen User und diesem wird über das Manifest das recht auf Ressourcen zugeteilt. Soweit so bekannt. Ich ging davon aus, dass wenn eine Ressource angesprochen wird, die nicht freigegeben ist, eine entsprechende SecurityException geworfen wird. Dem ist leider nicht so.

Die DalvikVM lässt die Anwendung einfach ins Leere laufen. In meinem Fall hatte ich vergessen anzumelden, dass meine App zugriff aufs Netz benötigt. Die Folge war eine IOException mit dem Hinweis „Unable to resolve host “<mein dnsname>” No address associated with hostname“. Es hat ne Weile gebraucht, biss ich die Ursache gefunden hatte. Es bedarf eines Eintrages in der Manifest.xml

<uses-permission android:name="android.permission.INTERNET" />

EGroupware und SyncML im Einsatz

Wer ein mobiles Gerät mit Android seit eigen nennt, wird schnell feststellen, dass nur zwei sinnvolle Sync-Optionen vorgesehen sind: Google(Mail/Konto) und Exchange. Wer wie ich ersteres nicht hat und auch nicht will und für letzteres kein Sinn sieht (OpenXchange ist die OpenSource Alternative) der muss etwas suchen um seine Kalender, Kontakte und ToDo-List zu synchronisieren.

Seit einiger Zeit kristallisiert sich SyncML  als „Transportstandart“ für genau diese Aufgabe heraus. Der Vorteil dieses offenen Standards liegt auf der Hand. Es gibt verschiedene Backends und Frontends, die alle in unterschiedlicher Kombination miteinander Synchronisieren können. Dieser Artikel geht auf beides ein.

Mein Setup sieht wie folgt aus:

  • mehrere Thunderbird Endgeräte – mobil wie stationär
  • mehrere mobile Endgeräte mit verschieden OS Typen (Symbian, Android, usw)
  • Outlook/Exchange (Arbeitsrechner)
  • Ubuntu-Server als zentrale Datenhalde.

Das Frontend

Recht schnell bin ich auf Funambol gestoßen. Diese Firma bietet Sync-Tools für alle möglichen Plattformen, einen SyncML-Server und einen CloudService. Funambol betreibt dabei das typische OpenSource – Geschäfftsmodel. Code und Tools kostenlos, den Service und einige Features gibt’s gegen Bares. Aber das stört nicht. Zum einen gibt es den FunambolServer (SyncML) als installpacket zum anderen kann man auch auf andere SyncML-Angbote zurückgreifen. Das Backend ist frei konfigurierbar. Mein Fazit nach zwei Wochen mit Funambol im Test:

  • Thunderbird: Erst einmal muss man das Plugin finden. Dazu muss man sich das Plugin entweder selber bauen oder unter www.memotoo.com ein vorkompiliertes Paket herunter laden. Einmal installiert funktioniert alles wie man es sich vorstellt. Adressbücher, Kalender und Task werden ordnungsgemäß synchronisiert.
  • Android: Auch hier gibt es eine Funambol-Applikation kostenlos im markten. Einmal installiert, legt es ein neues „Synchronisations-Konto“ an. Es existiert neben Exchange und Google-Mail dann noch eine weite SyncQuelle, die sich schön in die Android-Oberfläche einbindet. Aufbau der Applikation und Funktonumfang entspricht den Standart Funambol Desktop-Client mit einer Ausnahme: auf dem Android gibt es (noch) keine Task. Es gibt noch keine Task-App die mit Funambol koppelt – leider.
  • Outlook: hier gibt es ein offizielles Plugin das ebenfalls einwandfrei funktioniert.

Eine Einschränkung gibt es jedoch: Funambol scheint beim syncen „marker“ in die jeweiligen Kalendereinträge zu machen (id). Wird der Kalender aber nicht lokal gespeichert sondern ebenfalls synchronisiert oder gar über Netzwerk eingebunden (Exchange/ICS/CalDav) gehen diese Informationen verloren. Der Client ist scheinbar nicht mehr in der Lage, Einträge die vom Server kommen zuzuordnen, mit der unschönen Folge das Dubletten entstehen. Bei meinem Outlook muss ich auf eine veraltete Funambol Version (8.72) setzten, weile nur noch diese den „One-Way“ Modus unterstützt. Dabei überträgt der Client (wahlweise) nur Zum Server oder Empfängt nur vom Server.

Das Backend

Funambol bietet auch einen SyncML Server.  Bei diesem handelt es sich um ein Java – basierten Server samt Konfiguration. Im ersten Überblick wirkte das alles ein wenig „unübersichtlich“ und wenig strukturiert aus. Ich muss aber gestehen das ich mir den Server nur ganze 2 Stunden angeschaut habe. Nebenher hatte ich mir noch ein EGroupware Server aufgesetzt und direkt verglichen. Diesen Vergleich hat der Funambol-Server aus folgenden Gründen verloren:

  • Funambol setzt eine eigene Server-Struktur auf. Dieser Server braucht einen Port den ich durch meine FW Routen muss und so weiter. Auf meinen Server läuft aber schon ein Apache. Egroupware nutzt diesen, so fällt der Mehraufwand weg.
  • Funambol setzt sein eigenes DB-Backend ein. Die wollen gesichert werden. EGroupware kann alle DB-Backends ansprechen, die PHP beherrscht. Standardmäßig komm MySQL zum Einsatz.
  • Und mein Totschlag-Argument: Funambol kann man (noch) nicht aus einer apt-Quelle installieren. Man muss sich also selber kümmern ob und wie man das ganze aktuell hält. EGroupware gibt es als Paket aus den offiziellen quellen.

Bei Egroupware handelt es sich ebenfalls um eine OpenSource-Projekt mit kommerziellen Grundgerüst. Die Community-Edition gibt es kostenlos, den Service muss man kaufen. Man kann das Paket direkt aus den offiziellen Quellen beziehen (die sind veraltet) oder man greift auf Quellen des Herstellers zurück. Dieser bietet für fast alle Debian/Ubuntu-Verianten die quellen an.

Standardmäßig wird EGroupware so installiert das es ein Anwendung unter „http://localhost/egroupware“ gibt. Das kann man wie gewohnt über die Apache-configs umbiegen und anpassen. Die geführte Installation in der Webanwendung gestaltet sich ein wenig hackelig. Das ist bedingt durch den Umstand, dass EGroupware für große Mittelständler gedacht ist. Es unterstützt Domänenkonzepte, Mailserver, verschiedenste Authentifizierungen usw Für den Zweck der einfachen „Ein Mann Synchronisierung“ ein wenig oversized aber es gibt schlimmeres.

Einmal installiert und eingerichtet zeigt sich EGroupware sehr aufgeräumt und übersichtlich. Besonders hervor gestochen haben folgende Funktionen:

  • Es gitb unterschiedlichste Sync-Schnittstellen für ein und das selbe. Zum Beispiel kann der Kalender unter ./calendar oder calendar angesprochen werden. Jede dieser Schnittstellen kann man ein eigenes Konflikt-Management vorgeben.
  • Es wird die WebDav – Schnittstelle angeboten. Hat man Festrechner, die immer mit dem Server verbunden sind, kann man die Kalender bequem mittels WebDav einbinden. Insofern die Kalender der „Kollegen“ freigegeben sind kann man sogar die einbinden. Der Link sieht dann so aus: https://egroupware/groupdav.php/<username>/calendar
  • Legt man einen Eintrag im Kalender an und hinterlegt dabei einen Gesprächspartner (E-Mail) gleicht Egroupware automatisch mit der internen Kontakt-Liste ab und macht entsprechende Einträge bzw. versendet E-Mails
  • Sowohl IMAP als auch POP Server werden unterstützt, auch SMTP wird angeboten – Es muss aber kein Mail-Server angegeben werden!
  • Das WebEnd-ist ansprechend und übersichtlich.

Fazit

Seit zwei Wochen synchronisiere ich erfolgreich zwischen allen meinen Geräten. Von der kleinen Outlook-Einschränkung mal abgesehen funktioniert das Problemlos. Besonders das Feature, dass meine Freundin jederzeit sehen kann, wie meine geschäftlichen Termine liegen bzw. mir von zu Hause Termine „rein knallen“ kann, erleichtert mir ein wenig das leben. Der Verwaltungsaufwand hält sich in Grenzen, da fast alles aus den Mail-Clients her raus gelöst werden kann. Eine klare Empfehlung an alle die ihre Kontaktdaten,Kalender und Aufgaben lieber nicht in der Cloud speichern wollen aber dennoch auf den SyncService nicht verzichten wollen.

Weitere Links: