phoenitydawn

February 20th, 2013

The Next Big Thing

Posted by Dunedan in Computer, Internet

Google hat heute eine Webseite zum schon länger in Entwicklung befindlichen “Project Glass” veröffentlicht. Glass ist platt gesagt eine intelligente Brille mit Kamera und Display, die es erlaubt im alltäglichen Leben ins eigene Sichtfeld zusätzliche Informationen eingeblendet zu bekommen und das eigene Sichtfeld zu filmen.
Auf der Webseite ist unter anderem auch das im Folgenden eingebettete Video zu finden.

Beim anschauen des Videos drängt sich mir förmlich auf, dass Google Glass, sobald es für den Massenmarkt für einen bezahlbaren Preis verfügbar ist (und dafür wird Google sorgen), das Produkt sein wird, nach dem Apple so krampfhaft sucht: The Next Big Thing.

January 2nd, 2013

Rate-Limiting requests to CouchDB using nginx

Posted by Dunedan in Computer

Some time ago I had the requirement to limit the number of requests per IP to a CouchDB-instance. I couldn’t find an option for CouchDB to achieve that, but as communication with CouchDB is based on HTTP-requests I thought that it should be possible to use nginx as reverse proxy with rate-limiting capabilities for CouchDB. The CouchDB-wiki lists some basic steps how to use nginx as reverse proxy, but rate limiting isn’t mentioned there.

Beside the actual rate limiting I noticed that nginx won’t work, because it doesn’t support chunked request-bodies out of the box, which CouchDB seems to rely onto. But to the rescue there is a nginx module called ngx_chunkin, which adds chunkin support to nginx. To get that module in Debian you need to install nginx-extras from the repository (available since squeeze-backports). The configuration of that module is straight forward as described on the wiki page. All you have to do is to put the following code snippet into the server-context of your nginx configuration:

        chunkin on;

        error_page 411 = @my_411_error;
        location @my_411_error {
                chunkin_resume;
        }

Having solved that issue, doing the actual rate limiting was the next step. Therefore nginx ships the module ngx_http_limit_req_module. All I had to do was to configure a zone for the limited requests in the http-context of the configuration:

limit_req_zone $binary_remote_addr zone=couchdb_write:10m rate=10r/s;

and the logic what to rate limit (writing requests in my case) into the server-context:

        location / {
                # POST, PUT, DELETE ... requests will get rate limiting
                if ($request_method !~* GET) {
                        rewrite ^(.*)$ /throttled$1 last;
                }

                proxy_pass       http://127.0.0.1:5985;
                proxy_buffering  off;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location /throttled {
                internal;
                limit_req        zone=couchdb_write burst=10000;
                rewrite /throttled(.*) $1 break;
                proxy_pass       http://127.0.0.1:5985;
                proxy_buffering  off;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

So if you put together the chunkin support and the rate limiting, you’ll get the following piece of configuration for a server which does rate limiting of writing CouchDB-requests using nginx:

limit_req_zone $binary_remote_addr zone=couchdb_write:10m rate=10r/s;

server {
        listen 5984;

        chunkin on;

        error_page 411 = @my_411_error;
        location @my_411_error {
                chunkin_resume;
        }

        location / {
                # POST, PUT, DELETE ... requests will get rate limiting
                if ($request_method !~* GET) {
                        rewrite ^(.*)$ /throttled$1 last;
                }

                proxy_pass       http://127.0.0.1:5985;
                proxy_buffering  off;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location /throttled {
                internal;
                limit_req        zone=couchdb_write burst=10000;
                rewrite /throttled(.*) $1 break;
                proxy_pass       http://127.0.0.1:5985;
                proxy_buffering  off;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

I really enjoyed figuring that out, because it was a lot of fun to be able to use a great tool (nginx) to extend another great tool (CouchDB), because they’re using the same protocol (HTTP).

November 24th, 2012

IKEA PAX “Microsite”

Posted by Dunedan in Internet

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.

July 10th, 2012

Login in Captive Portals automatisieren

Posted by Dunedan in Computer, Linux

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
July 4th, 2012

Spaß mit Python

Posted by Dunedan in Python

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.

May 28th, 2012

ejabberd

Posted by Dunedan in Computer, General

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
May 10th, 2012

Django – Anwendungsmöglichkeiten außerhalb von Webentwicklung

Posted by Dunedan in Programmieren, Python

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.

February 18th, 2012

IPSec and IPv6 in local networks

Posted by Dunedan in Linux

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.

January 17th, 2012

Die Revolution der Schulbücher

Posted by Dunedan in Apple

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.

November 20th, 2011

Spam ohne Opt-Out von 1&1

Posted by Dunedan in Internet

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?

Tags: , , ,