No advertising, no support, no bug fixes, payment in advance.
— AT&T Unix Policy (1984)

GNU Coreutils

Man stelle sich folgendes Szenario vor. Eine große CSV Datei enthält Datensätze. Eine weitere Datei enthält ~1,5mio IDs die ein Subset der Datensätze darstellen. Gewünscht ist ein File das alle Datensätze des Subsets enthält.

for-loop grep

Die gewohnte Pauschallösung für derartige Probleme. Ganz im Bash-Admin-Stil

1
2
3
$ time for x in $(cat idsubset.txt) ; do
>  grep ^$x dataset.csv
> done > result.csv

Nur leider kommen dabei ganze 1,5 Records pro Sekunde heraus, was alles in allem in über 2 Wochen Rechenzeit endet. IOwait enstand dabei nicht.

GNU parallel

16 Core-Maschine. Einfach härter parallel greppen. GNU parallel hatte ich 2012 einmal ausprobiert.

1
2
3
4
$ cat idsubset.txt | time parallel 'grep -m 1 ^{} dataset.csv' > result.csv
[...]
Command terminated by signal 2
13165.04user 56967.06system 1:23:04elapsed 1406%CPU (0avgtext+0avgdata 40816maxresident)k

Nach knapp 90 Minuten war das gute Stück bei ca. 80% des Files angekommen. Annehmbar, auch wenn die Cores und der RAM der Kiste damit gut beschäftigt waren.

join

Das effizienteste war allerdings join aus den GNU core utilities

1
2
3
4
5
6
7
$ sort idsubset.txt > sidsubset.txt
$ sort dataset.csv > sdataset.csv
$ time join sidsubset.txt sdataset.csv > result.txt
[...]
real    0m38.965s
user    0m36.290s
sys     0m0.991s

Fucking 38 Sekunden. Zwei Dinge sind zu beachten. Sortierung und Formatierung.

Das Field, das zusammengeführt werden soll muss in beiden Files über den gleichen Trenner identifizierbar sein. Zurecht-ge-sed-et©

Beide Files müssen alphabetisch sortiert sein, nicht numerisch. Das ist im wesentlichen dem Algorithmus geschuldet der in join verbaut ist. Linecounts anstelle von Fullscans bei jeder Iteration sind der Trick.

BigData Krams? Lolo. Fucking Coreutils.

Privacy++

“Machste halt mal kurz SSL am Webserver an”. So einfach ists halt leider nicht. Ich habe das so lange nicht in getan, weil weder Logins vorhanden sind noch geheimer Content publiziert wird. Wer möchte kann aber jetzt https://noqqe.de benutzten.

Folgende Dinge haben sich geändert:

  • Google Web Fonts now selfhosted (mit Clemens Skript)
  • Hart kodierte Links mit sed auf relative Links umgestellt. Siehe RFC3986
  • Flattr Button durch statische Variante ersetzt
  • Kein jQuery nachladen von extern mehr
  • Kein Github nachladen mehr
  • Kein Pinboard nachladen mehr
  • ~50MB verwaiste Uploads entfernt
  • Mit wget --spider tote Links entdeckt und korrigiert.
  • Extern gehostete Bilder aus früheren Posts in /uploads/ migriert
  • SSL noqqe.de Zertifikat erstellt
  • Isso Kommentarsystem auf comments.noqqe.de umgezogen und SSL
  • Piwik auf analytics.noqqe.de umgezogen und SSL

Gerade die letzten beiden Punkte waren garnicht so einfach. Für alles was ich sonst so hoste benutze ich meistens die Domain n0q.org. Nur leider möchte mir StartCom kein Zertifikat für diese Domain ausstellen, da sie fürchten ich könnte eine Fakesite für noq.org hosten. Valide Begründung aber doof für mich.

Enlarge your P..GP Key

Mittlerweile ist mein 2048bit PGP Key mit ein paar Signaturen ca. 4 Jahre alt und auch etwas kurz. State of the Art ist wohl 4096bit. Der Migrationspfad auf einen neuen Key.

Sicherung

Sichern des alten Key Environments

$ cp -a ~/.gnupg ~/.gnupg-old

Neuen Key generieren

Wesentlich für einen tollen neuen 4096bit Key ist ausreichend Entropy. Für aus der CPU generierte Entropie, kann havege installiert werden.

$ cat /proc/sys/kernel/random/entropy_avail
> 153
$ aptitude install havege
$ /etc/init.d/havege start
$ cat /proc/sys/kernel/random/entropy_avail
> 1649

und anschliessend den Key erstellen

$ gpg --gen-key

Der interaktive Dialog sollte einen eigentlich halbwegs verständlich durch die Generierung führen.

Alten Key revoken

Beim Revoken des alten Keys, ist es sinnvoll die korrekte Begründung auszuwählen. In meinem Fall Ersetzung durch einen neuen Key, also superseded.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ gpg --gen-revoke oldkeyid

Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
  0 = No reason specified
  1 = Key has been compromised
  2 = Key is superseded
  3 = Key is no longer used
  Q = Cancel
(Probably you want to select 1 here)
Your decision? 2
Enter an optional description; end it with an empty line:
> replaced by newkeyid
>
Reason for revocation: Key is superseded
replaced by newkeyid

Heraus fällt ein Public-Key Block, der in einer Datei importiert werden kann.

$ gpg --import revoke.txt

Migration

Auf meinem alten Key befinden sich wie gesagt ein paar Unterschriften. Auch deswegen macht es Sinn den neuen Key mit dem Alten zu unterschreiben.

$ gpg --default-key oldkeyid --sign-key newkeyid

Dadurch wird nicht nur die Referenzkette gebildet, sondern auch gleich nachvollziehbar, dass der neue Key wirklich der Nachfolger meiner “originalen” KeyID ist.

Keyserver aktualisieren

Wenn der alte Publickey nun revoked ist, kann es auf den Keyserver geladen werden.

$ gpg --list-key oldkeyid
$ gpg --send-keys oldkeyid

Genauso der neue Publickey.

$ gpg --list-key newkeyid
$ gpg --send-keys newkeyid

Nacharbeiten

  • Default Key in der gpg.conf ändern default-key newkeyid
  • PGP Plugin in mutt (oder Mailclient) updaten
  • Zum Austausch des Fingerprints fürs einfaches Signing, gibt es im Debian Paket signing-party die entsprechende key2ps Tools. Diese kann dann zum PDF umgewandelt und ausgedruckt werden.
1
2
3
$ aptitude install signing-party ghostscript
$ gpg-key2ps -p a4 CDA4B775 > key.ps
$ ps2pdf key.ps
  • Signatur im Mailclient updaten
  • Informationen auf der Website updaten
  • caff Konfiguration anpassen

Analog BitCoin Ticker

BitCoin. Cheffinnen von Trading-Sites werden tot in Wohnungen gefunden. Ein Magic the Gathering Online Exchange geht insolvent. FlexCoin gehackt.

Der Kurs zeigt sich trotzdem relativ unbeeindruckt, was mich irgendwie verblüfft. Egal. Es macht momentan Spass BitCoin zu verfolgen. Gerade die “Suche” nach Satoshi Nakamoto.

2011 bastelte ich einen Megabitmeter und als er mir letztens wieder in die Hände fiel, dachte ich mir hey, BitCoins<–>Dollar anzeigen lassen!

Im Endeffekt hole ich mir nur mit etwas Python (schlechtes Python, btw) den aktuellen Kurs vom letzten halbwegs stabilen BitCoin Trader Bitstamp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/python

import json
import urllib2
import math
import time

# configure
url = "https://www.bitstamp.net/api/ticker/"
analogmeter = "/dev/ttyUSB0"

# runtime loop
while True:

    # parse api json result
    data = json.load(urllib2.urlopen(url))
    value = math.floor(float(data["last"]))
    value = str(int(value)) + '\n' # use ALL the data types

    # write to usb device
    f = open(analogmeter, 'w')
    f.write(value)
    f.close()

    # wait until the next refresh
    time.sleep(60)

OpenBSD nginx Logrotate

Seit mittlerweile fast 3 Releases setze ich OpenBSD auf meinem Housing-Server ein. Ich mag das OS immernoch sehr gerne. Die WTF-Rate bei Software ist hier denkbar niedrig. Ganz ohne gehts aber leider auch nicht.

Unter OpenBSD ist newsyslog für die Logrotation verantwortlich. Das gut abgehangene Stück Software ist wie immer toll dokumentiert und funktioniert. Nur leider ignoriert es Wildcards

1
2
3
4
# logfile_name      owner:group     mode count size when  flags
/var/cron/log       root:wheel  600  3     10   *     Z
/var/www/logs/*.log             644  7     *    *     Z "kill -s USR1 `cat /var/run/nginx.pid`"
/var/www/logs/error.log         644  7     *    24    Z "kill -s USR1 `cat /var/run/nginx.pid`"

Einen Testlauf mit dry-run lässt sich starten mit

1
2
3
$ newsyslog -nv
/var/cron/log <3Z>: size (KB): 2.28 [10] --> skipping
/var/www/logs/error.log <7Z>: age (hr): 1 [24] --> skipping

Unter FreeBSD enthält die newsyslog Version das Flag G.

G indicates that the specified logfile_name is a shell pat-
tern, and that newsyslog(8) should archive all filenames
matching that pattern using the other options on this
line. See glob(3) for details on syntax and matching
rules.

Unter oBSD ist dieser Modus leider nicht verfügbar. Was für Lösungen sind also möglich? Ich hab mich vorerst dafür entschieden die Liste der Entries mit einem Einzeiler zu generieren.

1
$ for x in $(ls -1 /var/www/logs/*.log) ; do echo -e "$x\t\t" '644  7     *    24    Z' ; done

und beim letzten Eintrag den entsprechenden nginx reload Command anfügen.

1
2
3
4
5
6
7
8
# logfile_name           owner:group mode count size when  flags
/var/cron/log            root:wheel  600  3     10   *     Z
/var/www/logs/vhost1_access.log      644  7     *    24    Z
/var/www/logs/vhost2_access.log      644  7     *    24    Z
/var/www/logs/vhost3_access.log      644  7     *    24    Z
/var/www/logs/vhost4_access.log      644  7     *    24    Z
/var/www/logs/vhost5_access.log      644  7     *    24    Z
/var/www/logs/vhost6_access.log      644  7     *    24    Z "kill -s USR1 `cat /var/run/nginx.pid`"

Ich kann mir nicht vorstellen, dass ich der Einzige mit diesem Problem bin, daher bin ich auf alternative Vorschläge gespannt. Selber ein Skript schreiben ist mir zu fehleranfällig und aufwändig, logrotate ist nicht paketiert. FreeBSD scheint newsyslog auch durch rsyslog ersetzt zu haben.

Obskures aus der Software Entwicklung

Heisenbug

Aus der aktuellen Situation heraus suggerierte mir “Heisenbug” eher einen Methamphetamin kochenden Walter White. Bei näherer Betrachtung geht es aber doch um den Wissenschafter Werner Heisenberg. Abgeleitet von der Heisenbergschen Unschärferelation besagt Heisenbug, dass sobald Debugging-Methoden ergriffen werden, der Bug im Programm nicht mehr nachvollziehbar wird.

Auch andere Wissenschaftler bekommen ihre Referenzen. Siehe Bohrbug, Mandelbug und Schrödinbug

STONITH

STONITH hatte ich bereits vertwittert.

Shoot The Other Node In The Head

Ein Konzept das bei hochverfügbaren Setups das Verhalten anderer Nodes im Fehlerfall eines Nachbarn beschreibt. Und das sehr unmissverständlich.

It is Easier to Ask for Forgiveness than Permission

Dieses Motto wird folgender guten Dame zugeschrieben.

Grace Hopper, die auch den Spitznamen “Grandma COBOL” trägt. Exception-Handling:

1
2
3
4
try:
    ham = spam.eggs
except AttributeError:
    handle_error()

…anstelle von if-Conditions:

1
2
3
4
if hasattr(spam, 'eggs'):
    ham = spam.eggs
else:
    handle_error()

Der Coding-Stil floss in allerlei Sprachen ein. Unter anderem Python.

Shotgun Debugging

Das sogenannte “Shotgun Debugging” ist eine (zurecht) verkannte Methodik mit Bugs fertig zu werden. Statt strukturellem Vorgehen werden wild mit der Präzision einer Schrotflinte Einstellungen/Codepassagen geändert ohne deren Auswirkung vorherzusehen.

The Mythical Man-Month

Wer in der IT sein Geld verdient, wird das kennen. Verzögerungen bei einem Projekt sind nicht selten. Zusätzliche Entwickler zum richtigen Zeitpunkt zum Projekt holen dagegen sehr.

Adding manpower to a late software project makes it later.

Darum gehts in dem Buch The Mythical Man-Month.

Planning Poker

Ein Kollege klärte mich diese Woche über Planning Poker auf. Ein typischer Kandidat aus dem fast schon esoterischen Umfeld von Scrum und anderen bewusstseinserweiterden Optimierungsmethoden im Software Development.

Kurz zusammengefasst, geht es darum Tasks mit Karten (von 1-100) nach eigenem Ermessen auf ihre Schwierigkeit zu bewerten. So entstehen Working-Slots und Arbeitsverteilung, da man sich selbst einschätzen kann. A la “In einer Woche kann ich ca. 70 Punkte bewältigen”. Egal ob das nun 7x 10er Probleme oder 1x 70 sind. Sehr tolles Prinzip.

The Airplane Rule

Die Flugzeug Regel ist eine Versinnbildlichung für das KISS Prinzip

A twin-engine airplane has twice as many engine problems as a single-engine airplane

Quellen: Werner Heisenberg, Grace Hopper, Planning Poker Cards, List of software development philosophies, Hackers Dictonary von Eric Raymond

RSA Implementation in Bash

Teil 2 der Serie Crypto in Bash implementieren, heute: RSA. Schon vor Längerem hatte ich mal ROT13 in purem Bash geschreiben, einfach um zu sehen wies funktioniert.

Auf dem #30c3, den ich letzte Woche besuchen durfte, ging es natürlich auch viel, viel um Crypto. Die Do’s and Dont’s sozusagen. Ein Vortrag war dabei besonders nett, da er als eine Art Leitfaden zu verstehen war, wie man es nicht machen sollte. Unter anderem RSA/AES selbst implementieren. Das hab ich dann aber einfach mal gemacht.

Basic RSA

Der Code ist so einfach wie nur irgendwie möglich gestaltet, um ihn verständlich zu halten. Ich habe deshalb bewusst auf Funktionen und Sanity Checks verzichtet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
p=37    # prime 1
q=89    # prime 2
e=25    # public key
d=2281  # private key
msg=$1  # the message
max=$((p * q)) # calc max for flattening

# show original message
echo "orig msg: $msg"

# encrypt message
i=$msg
for x in $(seq 2 $e); do
    msg=$((msg*i))      # multiply
    msg=$((msg%max))    # flatten
done
echo "encr msg: $msg"

# decrypt message
i=$msg
for x in $(seq 2 $d); do
    msg=$((msg*i))      # multiply
    msg=$((msg%max))    # flatten
done
echo "decr msg: $msg"

Manchem mag auffallen, wie im Debian-Stil ziemlich statischer “Zufall” im Header kodiert ist. Für den Anfang ist das okay um zu verstehen wie RSA so tickt.

1
2
3
4
$ ./rsa.bash 999
orig msg: 999
encr msg: 2146
decr msg: 999

RSA + Privkey Generierung

Was im obigen Beispiel passiert ist, ist natürlich sehr trivial, da die Keys vordefiniert sind und hinten hinaus die allerwenigste Magie passiert. Der interessante Teil ist eher die Schlüsselgenerierung.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
p=$1    # prime
q=$2    # prime
msg=$3  # the message
max=$((p * q)) # calc max for flattening
phi=$(((p-1)*(q-1))) # calc phi
pubprimes=( 1901 1907 1913 1931 1933 1949 1951 1973 1979 \
  7841 7853 7867 7873 7877 7879 7883 7901 7907 7919 \
  127  131  137  139  149  151  157  163  167  173 \
  6311 6317 6323 6329 6337 6343 6353 6359 6361 6367 \
  2221 2237 2239 2243 2251 2267 2269 2273 2281 2287 )

# choose random prime for pubkey e
e=${pubprimes[$RANDOM % ${#pubprimes[@]}]}

# extended euclid algorithm. borrowed and simplified from
# https://sites.google.com/site/algorithms2013/home/number-theory/extended-gcd-bash
function ext_euclid_algo() {
    agcd=$1
    b=$2
    x=0
    lastx=1
    y=1
    lasty=0
    while [ $b != 0 ]; do
        tempb=$b
        tempx=$x
        tempy=$y

        quotient=$(($agcd / $b))
        b=$(($agcd - $(($b * $(($agcd / $b))))))
        x=$(($lastx-$(($quotient*$x))))
        y=$(($lasty-$(($quotient*$y))))

        agcd=$tempb
        lastx=$tempx
        lasty=$tempy
    done

    echo $((lastx+$2))
}

# calculate private key
d=$(ext_euclid_algo $e $phi)

# print key environment
echo "pub: $e"
echo "priv: $d"
echo "phi: $phi"
[...]
letzter Teil wie oben
[...]

Worauf ich außerdem verzichtet habe ist die Auswahl einer richtigen/anständigen Primzahl für den Publickey, da das Problem weder logisch noch programmatisch besonders reizvoll ist. Zumindest was den RSA Scope angeht. Im RNG Scope natürlich eine ganz andere Geschichte.

Usage des Skripts hat sich nun auch von nur der Message hin zu Primzahl1, Primzahl2, Message erweitert.

1
2
3
4
5
6
7
$ ./rsa.bash 911 43 8234
pub: 1913
priv: 21977
phi: 38220
orig msg: 8234
encr msg: 33207
decr msg: 8234

Das gesamte Skript gibts nochmal auf Github. Bei Fehlern in der Implementierung freue ich mich über Kommentare, aber bitte keine “da oben ist eine Timing Attacke möglich”-Comments. Ich patche hier nicht OpenSSL. Was dieses mal mehr gilt, als beim ROT13 Skript: Nicht für Dinge benutzen.

On Hackernews

Eigentlich wollte ich nur Acrylamid ausprobieren. Ich evaluierte neue Software wegen des ständigen Fuckups mit Octopress und RVM.

Ich lud also Acrylamid herunter, spielte damit herum, bastelte eine Demo Site mit etwas Layout Änderungen. Content bestand anfangs aus ein paar random Texten und “/dev/null” im Header. Irgendwann formte sich der Inhalt aber zu etwas Rundem und ich dachte, egal jetzt kauf ich mir die Domain zum entstandenen Text. devnull-as-a-service.com. Ein kleines Spass Projekt am Rande schadet ja keinem.

Als ich dann fertig war und es vertweetete, freute ich mich noch, dass die Site von @slith76 erwähnt wurde. Legte mich aber dann schlafen.

Als ich am nächsten Morgen aufwachte sah das alles irgendwie anders aus. Ein Blick in Piwik in der S-Bahn zeigte mir über 20.000 Visit. O_o. Dann wurde es etwas verrückt; was folgt ist eine stichpunktartige Zusammenfassung.

Facts

  • die Zugriffszahlen des 1. Monats
  • 127.326 Visits
  • 438.461 Page Views (Actions)
  • 1.249.375 GET Requests (4.385 MB)
  • 97.318 POST Requests

  • ~2 Stunden #1 auf HackerNews (Ranking)
  • Zugriffe aus 118 verschiedenen Ländern

Reaktionen

Als Response zu der Site bekam ich insgesamt ~40 Emails unter anderem:

  • Jemand schrieb eine Wrapper Library für Linux via LD_PRELOAD
  • 3 Job/Praktika Anfragen bzgl. der Carreers-Page
  • Ergänzungsvorschläge bzgl. des HTTP Methodenverhaltens
  • Kooperationsanfrage des Dienstes ZAAS (/dev/zero as a Service)
  • 4 lustige Supportanfragen bzgl. des offerierten Serivces
  • 3 (ironisch gemeinte?) Jobangebote irgendwo in China-World
  • Requestete Features: Kerberos, SOAP Interface, 10GE Interface für die Enterprise Appliance, Sharding Support, “is it webscale?”)
  • anderer related Content via Mail wie

  • paar Dankes und/oder “LOL” Mails
  • *.gif bei SecurityReactions
  • 16 Github Issues
  • 10 Pull Requests

Wohin hat sich die Site verbreitet?

Wie alles anfing lässt sich nur sehr schwer rekonstruieren. Nicht das ich es nicht versucht hätte, aber über mehrere Tweets und andere Socialmedia Kanäle zu vergraphen hätte viel Aufwand bedeutet.

  • HackerNews 271 Points \o/
  • Reddit Ich bin nicht sonderlich Redditaffin, die Kommentare sind aber teils lesenswert. 785 Upvotes \o/
  • Twitter Insgesamt gab es 990 Tweets die einen Link zu DAAS enthielten. Die Twitter Suche dazu erheitert mich immer wieder :)
  • Heise Security hat DAAS in einem Wochenrückblick erwähnt
  • Habrahabr Ist scheinbar eine lustige Russische Tech-News-Site von der immens viele Menschen kamen. Scheinbar grosses Ding da.

  • Top Referrer als Graph

Schlechte Entscheidungen die ich traf

Es ist eine grundsätzliche Frage wie sehr man ein neues Projekt over-engineert. Hielt die Aufwand/Nutzen Relation für angemessen, über ein paar Dinge ärgere ich mich aber trotzdem.

  • Ich hätte das OpenFiles Limit in OpenBSD für nginx anpassen sollen. So kam es dazu dass bei Lastspitzen sporadisch 500er Fehler geworfen wurden.
  • Flattr. Mal ein Projekt bei dem es sinnvoll gewesen wäre Flattr zu integrieren
  • RFC 863 Discard Service nicht gleich zu nennen. Habe nicht gezählt wie oft, wurde aber gefühlt 10.000 mal an mich herangetragen.

Gute Entscheidungen die ich traf

  • Plain Files bzw. Static Content deployed. In PHP oder etwas ähnlichem serverseitig Generiertem wäre ich viel früher hart hingeflogen, als durch die OpenFiles Limitierung.
  • Kein gif auf der Startseite einbinden. Gifs benutze sich sehr gerne in Dingen die ich ins Internet stelle. Das hier nicht zu tun war unter dem Aspekt meines limitiert zur Verfügung stehenden Traffics eine sehr gute Entscheidung
  • Die maximale POST-Size in nginx nicht aufzubohren. Es stellte sich heraus das echt viele Leute Daten POSTeten.
  • Einrichtung einer separaten Mailadresse unter Contact, da dort nun auch schon wieder echt viel Spam ankommt.
  • Source auf GitHub zu stellen

Rückwirkend muss ich sagen, es war mal eine Erfahrung wert :) Ich wundere mich auch immernoch wie wenig Kritik oder “mhhh lahm” Comments kamen. Genauswenig wie Kommentare über das schlechte HTML oder das schlechte Layout. Was auch immer. Ich hatte Spass. A lot.

Fixing Windows Font Rendering

Seit ich auf der Arbeit Windows nutzen muss, störe ich mich am Font der systemweit irgendwie “ausgefranzt” wirkt. Ausgefranzt ist natürlich ein total professionell klingendes Wort, man könnte von irgendwas mit Anti-Aliasing sprechen aber dazu hab ich mich genau nicht schlau gelesen.

Das erste Thema, auf das man stößt wenn man nach Font Rendering unter Microsofts Betriebssystem schlauließt heisst ClearType, doch egal wie viel ich damit herumgespielt hatte, kam dabei nicht heraus was ich mir vorstellte. Nach wie vor brößliger Font.

Dann fand ich nach etwas längerem Herumgoogeln gdipp. Das Tool stellt, je nach Einstellung Windows Service, eine DLL oder einen Registry Eintrag zur Verfügung und ersetzt damit die vom OS bereitgestellte Font-Rendering-Engine. Mittel der Wahl ist die Installation des Windows Services.

Dann sieht auch gleich alles Systemweit schön aus. Outlook und sogar das Cygwin Terminal.

Ich blogge über Windows Themen. Fühle mich jetzt Enterprise-Ready©.

Isso - Ich schrei sonst

posativ hat neben seinem in Python geschriebenen Static Site Generator acrylamid seit kurzem auch sein eigenes Kommentarsystem wiederbelebt. Isso – Ich schrei sonst. Die Alternative zu Disqus die auch hier im Blog bisher zum Einsatz kam setzt auf Python auf, ist einfach einzubauen und sogar alle alten Disqus Kommentare lassen sich importieren. Für die User bedeutet das konkret kein Traffic mehr zu Gravatar, Disqus und keine lustige Registrierungen nötig. Privacy!

Abweichend von der Anleitung die auf Debian/Ubuntu Systeme abziehlt ist die Installation dank guter Python Packages unter OpenBSD easy.

1
2
$ sudo pkg_add py-pip
$ sudo pip install isso

Der Rest läuft dann genauso, wie unter anderen Distributionen auch. Zusätzlich habe ich noch ein kleines Daemon Skript für OpenBSD geschrieben, damit das neue Kommentarsystem auch schön automatisch startet.

Viel Spaß beim Ausprobieren von Isso!