die geladenen Elemente auf der "Microsite" von IKEA PAXAuf der deutschen IKEA-Webseite gibt es aktuell eine PAX-“Microsite”. Diese ist echt schick. So bekommt man beispielsweise durch scrollen verschiedene Schrankkombinationen und Befüllungen innerhalb desselben Bildes angezeigt. Auch werden moderne Technologien, wie zum Beispiel jQuery und Modernizr, benutzt.
Was mich dann aber doch etwas staunend zurück ließ ist die Tatsache, dass beim Aufruf der Seite über 1500 HTTP-Requests ausgelöst werden und die damit angeforderten Daten eine Gesamtgröße von über 35MB haben? Srsly? Das geht doch auch besser.

Ursprünglich mochte ich NetworkManager nicht. Grundsätzlich machte er mehr Probleme bei der Handhabung von Netzwerkverbindungen unter Linux, als er löste. Das ist allerdings schon einige Jahre her und spätestens seit der grandiosen Integration von WWAN-Hardware ist er ein richtig brauchbares Hilfsmittel geworden.

Eine Sache, die mir nun fehlte, war die Möglichkeit nach dem verbinden in ein WLAN eine Authentifizierung via Browser zu automatisieren. Nach einer kurzen Suche stellte sich heraus, dass es mit NetworkManager ein leichtes ist, auch das zu automatisieren. Dazu reicht es ein Shell-Skript in /etc/NetworkManager/dispatcher.d/ abzulegen, dass als ersten Parameter den Namen der betroffenen Verbindung und als zweiten Parameter die Statusänderung der Verbindung (up oder down) erwartet. Daraufhin war es ein leichtes, ein kleines Skript zu basteln, dass die Authentifizierung via HTTP übernimmt, nachdem eine bestimmte Verbindung aktiviert wurde:

#!/bin/sh

# network manager connection name
CONN_NAME="sample_wlan"

# check if this script is triggered for the wlan interface
if [ "$1" != "wlan0" ]; then
    exit 0;
fi

# check if the action is the enabling of the interface
if [ "$2" = "up" ]; then
    # check if the connection we want to automate, is active
    if [ "$(nmcli con status | grep -o $CONN_NAME)" = "$CONN_NAME" ]; then
        wget -q --post-data="username=john&password=123456&possible_other_post_parameters=xyz" https://fqdn-of-the-captive-portal.tld/login.html -O - > /dev/null
    fi
fi

Finde den Fehler:

#!/usr/bin/env python

import sys
if sys.version_info.major < 2 or (sys.version_info.major == 2 and sys.version_info.minor < 7):
    print "python <2.7"
else:
    print "python >=2.7"

Auflösung:
Der Ansatz ist eine nette Idee, funktioniert allerdings erst ab Python 2.7, da Python erst seit dem die benannten Parameter .major und .minor kennt. Damit der Code auch mit Python-Versionen kleiner als 2.7 funktioniert, müsste er wie folgt aussehen:

#!/usr/bin/env python

import sys

if sys.version_info[0] < 2 or (sys.version_info[0] == 2 and sys.version_info[1] < 7):
    print "python <2.7"
else:
    print "python >=2.7"

Siehe auch: http://docs.python.org/library/sys.html#sys.version_info

Das sind Kleinigkeiten, auf die man stößt, wenn man versucht ein auf einem System mit Python 2.7 geschriebenes Skript mit Python 2.6 auszuführen. Wäre ja aber langweilig, wenn alles auf Anhieb glatt laufen würde.

Innerhalb der letzten paar Wochen hatte ich das Vergnügen mehrere ejabberd-Instanzen mit vollkommen unterschiedlichen Use-Cases aufsetzen zu dürfen. Abgesehen davon, dass das Format der Konfigurationsdateien von ejabberd ein wenig gewöhnungsbedürftig ist und ejabberd in diversen Fehlerfällen keine sonderlich aussagekräftigen Fehlermeldungen produziert, waren das sehr gute Erfahrungen. Ich war jedes Mal wieder erstaunt, mit wie wenig Anpassungen an der Konfiguration ejabberd das tat, was er tun sollte.
Die Use-Cases will ich euch natürlich auch nicht vorenthalten. Das waren grob die Folgenden:

  • Instanz mit LDAP-Authentifizierung und Shared-LDAP-Roster
  • Instanz ohne S2S, dafür mit HTTP-Binding nach XEP-0124
  • Instanz mit virtuellen Hosts und Authentifizierung über ein externes Skript

Im Jahr 2007 war ich PHP und all die damit verbundenen Nachteile satt und stieß auf der Suche nach einer Alternative zur Webentwicklung auf Python und das damals noch recht junge Webframework Django. Es war Liebe auf den ersten Blick. Während ich mich in Django einarbeitete und die ersten kleinen “Apps” schrieb, hatte ich regelmäßig aha-Effekte, wenn ich sah, wie einfach sich verschiedene Funktionalitäten implementieren ließen und das wievielfache an PHP-Code man für die gleiche Funktionalität gebraucht hätte.
Doch nicht nur für Webentwicklung lässt sich Django wunderbar nutzen. Wie ich damals recht schnell feststellte, lassen sich aufgrund der Modularität von Django, einzelne Komponenten wunderbar eigenständig nutzen.
Zwei Möglichkeiten möchte ich im Folgenden kurz vorstellen.

Für ein Projekt brauchte ich die Möglichkeit statische Webseiten aus einem via Cron laufenden Skriptes zu generieren. Was bot sich also mehr an, als die Templateengine von Django zu verwenden?
Für ein simples Beispiel reichen sogar schon acht Zeilen Code:

#!/bin/env python

from django.conf import settings
from django.template.loader import render_to_string

settings.configure(TEMPLATE_DIRS=('/home/john/project/templates',))
rendered = render_to_string('template.html', { 'foo': 'cookie' })
print rendered

Das dazugehörige Template könnte wie folgt aussehen:

This is a simple template with {{ foo }}.

Das Ganze lässt sich natürlich nicht nur für HTML-Dateien, sondern für jede Art von Textdateien verwenden.
Ein anderes Anwendungsbeispiel ist die Nutzung des Object-Relational Mappers (ORM) von Django, für hübschen Datenbankzugriff aus beliebigen Python-Anwendungen:

#!/bin/env python

from django.conf import settings

settings.configure(DATABASES={
                    'default': {
                        'ENGINE': 'django.db.backends.sqlite3',
                        'NAME': 'database.sqlite'
                    }
})

from django.db import models

class Animal(models.Model):
    species = models.CharField(max_length=32)
    name = models.CharField(max_length=32)
    
    class Meta:
        app_label = 'animals'

Animal(species='dog', name='rex').save()

for i in Entry.objects.all():
    print i.name

Zu obigem Beispiel seien ein paar Punkte angemerkt:

  • Dass der Import der Models nach dem Konfigurieren der Einstellungen kommt ist Absicht. Django benötigt die Einstellungen zum Laden der Models.
  • Die Meta-Klasse mit der Option app_label muss explizit angegeben werden, sofern man den ORM ohne den Rest von Django nutzt.
  • Das obige Beispiel wird so nicht funktionieren, weil keine Datenbank mit entsprechenden Tabellen existiert. Diese müsste man (in diesem Beispiel) auf anderem Wege anlegen.

Wie man sieht, ist Django toll. Und das nicht nur für Webanwendungen, sondern für alles Mögliche, was auf Python basiert. Wollte ich nur mal gesagt haben.

There already exist great tutorials how to setup IPSec for IPv6 using racoon for Internet Key Exchange (IKE) like this one or this one.
But for the usage of IPSec inside one subnet, they miss one point: Inside an IPv6-subnet clients depend on the Neighbor Discovery Protocol (NDP) for receiving Link-Layer-addresses. If NDP isn’t working, clients won’t receive the Link-Layer-address of the target host und won’t therefore be able to send packets to it.
Long story short: If you want to use IPSec for IPv6 in the same subnet, you’ll have to add an exception to enable unencrypted ICMPv6-packets. That problem doesn’t occur with IPv4, because the Address Resolution Protocol (ARP), which is used there for the same purpose, doesn’t rely on IP in contrast to NDP.
I had to search a while to figure that out and finally found the solution there: http://www.oss.sgi.com/archives/netdev/2004-02/msg00684.html.

Apple plant offenbar Werkzeuge zu veröffentlichen, mit denen sich einfach interaktive Bücher für das iPad entwickeln lassen. Insbesondere hat Apple dabei den Gerüchten zufolge interaktive Schulbücher im Auge.
Für Apples Motivation kann ich mir zwei Gründe vorstellen:

  1. Apple möchte Kinder schon früh an seine Geräte gewöhnen und sie so langfristig binden.
  2. Apple möchte die Welt verbessern und Kindern optimale Lernmaterialien zur Verfügung stellen.

Die tatsächliche Motivation ist sicher eine Mischung aus Beidem. Ich höre aber schon die vielen kritischen Stimmen, die nur 1. betrachten und 2. außer Acht lassen. Dabei sind gerade die damit verbundenen Möglichkeiten faszinierend:

  • immer aktuelle Schulbücher
  • Veranschaulichung des Lernstoffes mittels Videos, großflächigen Grafiken und anderen interaktiven Formaten
  • immer parate Schulbücher, ohne dass die Schüler etliche Kilo in Form von Büchern aus Papier durch die Gegend schleppen müssen
  • die Möglichkeit kolloborativer Arbeit, auch von unterschiedlichen Standorten aus

Apple ist nicht das erste Unternehmen mit dieser Idee, aber ich bin mir sicher, dass es das erste Unternehmen sein wird, dass damit in der Masse Erfolg hat. Das ist schade, weil Apple Nachteile wie ein geschlossenes Ökosystem mit sich bringt, aber andererseits haben andere Projekte, die das gleiche Potenzial gehabt hätten, dieses bislang nicht umgesetzt. So hat beispielsweise One Laptop per Child seinen Fokus primär auf Entwicklungsländer und Schwellenländer gelegt, statt ihn auch auf Industrieländer zu legen.

Ich bin gespannt, was Apple am kommenden Donnerstag vorstellen wird und wie sich das Themengebiet rund um digitale Lehrmaterialien in Zukunft entwickelt. Es bleibt zu hoffen, dass Apples Engagement in diesem Markt auch andere Anbieter wachrüttelt und so zur “digitalen Revolution” in Schulen führen wird.

Wegen altem DSL-Vertrag und neuem DSL-Vertrag hatte ich in letzter Zeit einigen Kontakt mit 1&1. Da waren etliche Sachen dabei, wo man einfach nur den Kopf schütteln kann, aber ich habe nicht die Nerven, das noch mal schriftlich zusammen zu fassen.

Eine Sache möchte ich aber doch erwähnen. So erhielt ich vor kurzem per E-Mail Spam Werbung von 1&1 für “Die Homepage Ihres Lebens“. Ich fragte mich zwar, warum ich überhaupt von 1&1 Werbung bekomme, da ich dem sicher nie zugestimmt habe, aber hielt in der E-Mail brav nach einem Link zum austragen für weitere Werbung Ausschau. Den fand ich dann auch in Form folgenden Abschnittes:

Wenn Sie unsere Kundeninformationen nicht mehr wünschen, können Sie
sich aus dem Verteiler austragen: http://www.1und1.de/rapidunjoin

So weit, so gut. Spannend wird es erst, wenn man sieht, was passiert, wenn man die Seite öffnet (und das kann jeder von euch selbst ausprobieren). Dann kommt nämlich folgende schöne Meldung:

Lieber Kunde,

wie gewünscht haben wir Ihre E-Mail-Adresse aus dem Verteiler herausgenommen.

Da die URL keinerlei Informationen über die eigene E-Mail-Adresse enthält, hätte ich mit einem Formular zum eintragen der E-Mail-Adresse gerechnet, aber nicht mit einer solchen Meldung, bei der offensichtlich ist, dass nichts aus irgendeinem Verteiler heraus genommen wurde. Wie auch? 1&1 weiß ja nicht, welche E-Mail-Adresse entfernt werden soll.

Wie kommt es, dass sich ein so großes Unternehmen wie 1&1 so was leisten kann? Schreien da nicht genügend Kunden auf oder was?

Am Wochenende sorgte der Chaos Computer Club (CCC) für Aufsehen, indem er eine Analyse einer staatlichen Computerüberwachungssoftware, dem so genannten “Bundestrojaner”, veröffentlichte. Besonders brisant: Die analysierte Software ist aufgrund eines Beschlusses des Bundesverfassungsgerichts von 2008 verfassungswidrig.
Wer technisch versiert ist, dem empfehle ich ein Lesen der amüsanten Analyse des CCC: http://www.ccc.de/system/uploads/76/original/staatstrojaner-report23.pdf. Allen anderen sei folgendes Video empfohlen, dass die gewonnenen Erkenntnisse kurz und leicht verständlich zusammen fasst:

Nutzt man Firefox mit Tor als Proxy und hat ein System, dass neben IPv4 auch mittels IPv6 an das Internet angebunden ist, macht Firefox standardmäßig beim aufrufen von Webseiten mit AAAA-Records einfach nichts. Prinzipiell auch logisch, da Tor aktuell noch kein IPv6 unterstützt. Irritierend ist das trotzdem, da man keinerlei Rückmeldung erhält warum Firefox nichts macht. Lösen lässt sich diese Problematik, in dem man in Firefox über about:config bei DNS-Anfragen die Abfrage von AAAA-Records deaktiviert:

network.dns.disableIPv6 = true

Dies sollte man allerdings nur tun, wenn man Tor als Proxy nutzt, da Firefox durch diese Konfigurationsänderung IPv6 nicht benutzt.

Edit: Natürlich tritt das Problem auch mit jedem anderen Proxy, der kein IPv6 unterstützt, auf.