Jitsi Meet Installation


Durch die aktuelle Corona Pandemie sind Videokonferenzen einer der Möglichkeiten, um in Kontakt zu bleiben. Weil einige der Videokonferenz Angebote dubiose Sicherheits- und Privacy-Aspekte haben ist eine Open Source Lösung die man selbst hosten kann eine gute Idee. Seit den Enthüllungen von Edward Snowden kann man ja nicht mehr annehmen dass nicht mitgeschnitten wird, ausser man ist im besten Fall naiv.

Ein Beispiel für eine Anwendung mit einer dubiosen Sicherheits-Historie is Zoom: Soviel ich weiss ist Zoom der einzige Drittanbieter von Software der es geschafft hat, dass seine Software aus Sicherheitsgründen bei einem Sicherheitsupdate des Betriebssystem-Herstellers deinstalliert wurde. Zoom hatte eine Anwendung installiert, die es jeder bösartigen Webseite erlaubte, die Kamera einzuschalten und Video mitzuschneiden. Daraus haben sie in der Folge aber nicht viel gelernt, weil sie vor kurzem dabei erwischt wurden dass sie Benutzerdaten an Facebook weitergegeben haben, auch wenn der Nutzer keinen Facebook-Account hat. Daher kann man diese Anwendung wohl nicht empfehlen.

Sichere Videokonferenzen mit mehr als zwei Teilnehmern sind typischerweise so implementiert, dass Klartext (oder vielleicht besser "Klarvideo"), also unverschlüsseltes Video und/oder Audio am Server vorliegt. Selbst wenn der Browser mit https verbindet und das Audio/Video verschlüsselt versendet wird, wird es am Server ausgepackt und für andere Teilnehmer der Konferenz neu verschlüsselt. Der Grund ist, dass sonst jeder Teilnehmer die Inhalte für jeden anderen Teilnehmer lesbar verschlüsseln müsste. Eine einfach Implementierung würde dabei eine mit der Anzahl der Teilnehmer quadratisch steigende Anzahl von Video/Audio Streams brauchen. Eine besser durchdachte Anwendung würde die Streams so verschlüsseln, dass jeder Teilnehmer sie entschlüsseln kann. Aber diese Variante macht das Hinzufügen oder Entfernen von Teilnehmern der Konferenz schwieriger und wird von den standard Sicherheitsprotokollen für Audio- und Videoverschlüsselung nicht unterstützt (so dass der Schlüsselaustausch auf einem anderen Kanal erfolgen müsste). Dies ist der technische Grund, warum die meisten Videokonferenz-Anwendungen unverschlüsselten Klartext am Server haben. Das macht es für den Betreiber des Servers einfach, mitzuschneiden. Jitsi-Meet ist in dieser Hinsicht nicht verschieden: Auch hier liegt am Server Klartext vor. Aber die gute Nachricht ist, dass man den Server selbst betreiben kann.

Auf der Jitsi-Meet Seite findet man Instruktionen (leider meines Wissens nur in Englisch) um den Installationspfad für Debian oder Ubuntu basierte Linux Installationen um das Jitsi-Meet Repository zu ergänzen. Damit ist es möglich, Jitsi-Meet mit dem üblichen apt-get install jitsi-meet zu installieren.

Sobald das mal gemacht ist, erlaubt die resultierende Jitsi-Meet Instanz allen Usern, neue Konferenzen anzulegen. Für die meisten Installationen möchte man dieses Verhalten nicht haben. Daher gibt es auf der Jitsi-Meet Github Seite Instruktionen um nur einem Moderator das Erzeugen von neuen Konferenzen zu erlauben.

Die in der Anleitung erwähnte Gast-Domain guest.jitsi-meet.example.com braucht nicht im DNS angelegt zu werden, sie wird nur intern für nicht-eingeloggte Benutzer verwendet.

Mit dem aus dieser Anleitung resultierenden Server kann man eigene Video-Konferenzen hosten. Es gibt aber leider ein Problem mit dem Firefox Browser. Dieser verhält sich störend im Zusammenhang mit der Jitsi-Meet Software. Die Details sind in einem Bug-Tracker Ticket beschrieben (leider nur in Englisch). Der Effekt des Bugs ist, dass Audio und Video immer mal wieder nicht funktioren. Leider nicht nur für die Firefox-Benutzer, sondern für alle Teilnehmer sobald es einen Firefox-Benutzer in der Konferenz gibt. Aus diesem Grund ist es eine gute Idee, Benutzern mit Firefox Browser nicht zu erlauben, den Konferenz-Server zu nutzen bis dieser Bug gefixt ist. Wenn man das will, editiert man die Datei /usr/share/jitsi-meet/interface_config.js in der Jitsi-Meet Installation. Es gibt zwei Konfigurations-Einträge, einer mit dem Namen OPTIMAL_BROWSERS enthält in der Default-Konfiguration auch den firefox. Ein weiterer Eintrag namens UNSUPPORTED_BROWSERS ist in der Standardeinstellung leer. Um Firefox-Nutzer von der Konferenz auszuschließen wird der firefox Eintrag von OPTIMAL_BROWSERS nach UNSUPPORTED_BROWSERS verschoben.

Mit diesem Setup habe ich nun einen laufenden Konferenz-Server wo ich nicht dubiosen Online-Angeboten bezüglich Sicherheit und Privacy vertrauen muss.

Kein Sound nach Upgrade auf Debian Buster


Vor kurzem habe ich meinen Desktop-Rechner auf Debian Buster upgegradet. Nachdem ich auf diesem Rechner nich sehr oft Audio-Ausgabe brauche habe ich erst nach einiger Zeit gemerkt, dass die Audio-Ausgabe nicht funktionierte.

Symptome: Das Tool pavucontrol zeigte nur ein Dummy Gerät

pacmd list-cards

Zeigte nur:

0 card(s) available.

Der speaker-test lief wie gewohnt (die typischen Meldungen) aber keine Audio-Ausgabe.

In alsamixer konnte ich die Intel Soundkarte finden und Änderungen an den Einstellungen machen. Der Linux-Kernel hatte also offensichtlich die Soundkarte erkannt. Aber alle anderen Programme verweigerten die Zusammenarbeit. Bei einer Web-Suche habe ich dann auf askubuntu folgendes gefunden:

https://askubuntu.com/questions/1085174/no-sound-after-upgrade-to-18-10-only-a-dummy-device-is-shown

Das schlägt vor den timidity-daemon zu entfernen. Und nach einer schnellen Eingabe von:

% sudo dpkg --purge timidity-daemon
(Reading database ... 541273 files and directories currently installed.)
Removing timidity-daemon (2.14.0-8) ...
Purging configuration files for timidity-daemon (2.14.0-8) ...
Processing triggers for systemd (241-7~deb10u3) ...

Fing alles sofort zu funktionieren an: Das noch laufende pavucontrol erkannte sofort das neue Device und ich konnte wieder Audio ausgeben wie gewohnt.

Auf der Suche nach einem generellen Modell für Übertragungsleitungen


Ich bin derzeit auf der Suche nach einer guten Formel für Übertragungsleitungen die ziemlich beliebige Strukturen haben können sollen. Ein Projekt wäre ein Richtkoppler, ein anderes die Simulation einer Log-Periodic Antenne. Als ich versucht habe, das Modell einer Zweiband Log-Periodic Antenne [1], ursprünglich von Günter Lindemann, DL9HCG [2] (sk) entwickelt, zu simulieren, war das Modell nicht besonders gut: Das Stehwellenverhältnis war höher als beschrieben. Die Originalantenne hat zwei quadratische Träger, aber NEC2 unterstützt nur runde Leiter, daher wurde die Antenne mit runden Leitern simuliert.

Um die Antenne mit Übertragungsleitungen (die von NEC2 unterstützt werden) neu zu simulieren war ich auf der Suche nach einer Formel für die Impedanz von zwei quadratischen Leitern die als Übertragungsleitung wirken. Ich entdeckte den "Transmission Line Calculator" von Hartwig Harm (wieder) [3] über seinen Artikel im Funkamateur [4]. Aber sein Modell unterstützt (noch?) nicht die Parameter für zwei quadratische Leiter. Harm verwendet atlc2 zur Schätzung der Parameter seines Modells. Die Software atlc2 ist eine Reimplementierung von Dave Kirkby's Arbitrary transmission line calculator (der als Source-Code verfügbar ist und bei einigen Linux Distributionen mitkommt) [5] aber zumindest für runde Leiter bekomme ich Fehler von ein paar Prozent wenn ich einen runden Leiter gegenüber einer Wand modelliere die auch von Harm berichtet werden [3]. Nachdem atlc keine Leiter im Freiraum unterstützt, muss man Wände in sehr großer Entfernung vorsehen wenn man das modelliert.

Auf der Suche nach einer Formel entdeckte ich Owen Duffy's Arbeit [6] (über die Neu-Implementierung seines Rechners von Serge Y. Stroobandt, ON4AA [7] der Duffy zitiert). Er verwendet auch atlc [5] um die Parameter eines Modells zu berechnen. Wenn ich die Werte aus Duffy's Rechner in Harm's Modell stecke, bekomme ich einen K-Faktor von 1.65, allerdings stimmen die ersten beiden Werte schlecht überein (der erste Wert für d = 10 und D = 15, also D/d = 1.5 weicht um 6.4% ab, für D = 20 immer noch um 1.5%). Weil Duffy selbst erwähnt dass "Werte unter etwa 100 Ω wahrscheinlich unterschätzt werden" [6] vertraue ich dem Modell von Harm etwas mehr für diese niedrigen Werte, habe aber keine Messungen gemacht und verstehe Duffy's Argument bezüglich des Proximity Effekts nicht wirklich, weil das Modell von atlc ja größeninvariant ist (es verwendet nur D/d über ein Pixel-Modell des Leitungsquerschnitts). Aber nachdem man wohl dem Modell von atlc auch nicht ganz vertrauen kann, ist wohl die erreichbare Genauigkeit mal ausreichend.

Ich habe die geschätzten Impedanzwerte für die beiden quadratischen Träger der Antenne noch nicht in ein neues Modell gesteckt – aber es scheint zumindest dass die Impedanz der Träger deutlich über den 50 Ω der echten Antenne liegt.

Netzwerkausfall kurz nach Reboot mit Debian Buster


Kürzlich habe ich eine existierende virtuelle Maschine mit Debian (die unter KVM läuft) auf Debian Buster (das neueste Stable Release zur Zeit des Entstehens dieses Blog-Eintrags) hochgezogen.

Nach dem Reboot schien alles OK zu sein, aber kurz nach dem Reboot (etwa nach 10 Minuten) war die Maschine nicht mehr erreichbar. Nach einem weiteren Reboot passierte das selbe wieder.

Ich habe dann VNC eingeschaltet (die Host-Maschine auf der die VM läuft ist in einer gehosteten Infrastruktur die ich nur über Netzwerk erreichen kann, daher musste ich den VNC-Port auf meine lokale Maschine zum Testen bringen) und stellte fest, dass die Maschine lief – aber ohne Netzwerkverbindung. Das Netzwerk-Interface war oben aber hatte keine IPv4 Adresse.

Weitere Untersuchungen zeigten, dass die Maschine mit einer falschen Zeit hochkam (eine Stunde nach der aktuellen Zeit, also die Uhr war in der Zukunft) und dass die Zeit von ntp um eine Stunde zurückgestellt wurde sobald dieser hochkam. Aus dem Log:

Jan 22 19:19:35 tux4 dhclient[351]: DHCPOFFER of 10.33.33.4 from 10.33.33.254
...
Jan 22 19:19:36 tux4 ntpd[391]: ntpd 4.2.8p12@1.3728-o (1): Starting

Jan 22 19:19:36 tux4 ntpd[420]: kernel reports TIME_ERROR: 0x41: Clock Unsynchronized
Jan 22 18:19:47 tux4 ntpd[420]: receive: Unexpected origin timestamp 0xe1d310c2.72d51f2c does not match aorg 0000000000.00000000 from server@XX.XXX.XXX.XXX xmt 0xe1d302b3.0dae523c

Im letzten Log-Eintrag ist die Zeit um eine Stunde früher als bei dem Log-Eintrag davor!

Daher war mein nächster Schritt, die dhcp leases Datei in /var/lib/dhcp/dhclient.eth0.leases zu checken:

renew 3 2020/01/22 18:39:54;
rebind 3 2020/01/22 18:44:51;
expire 3 2020/01/22 18:46:06;

Aha, das Lease war ausgelaufen. Offensichtlich konnte der ISC dhcp Server dem Interface die IP Adresse entziehen sobald das Lease ausgelaufen war, aber konnte dieses nicht rechtzeitig erneuern (vermutlich wäre das dann eine Stunde später passiert wenn die Uhr wieder die Zeit erreicht hätte die sie vor dem Zurückstellen hatte). Es sieht so aus als ob der ISC dhcp Server zwei unterschiedliche Mechanismen verwendet um die beiden Events zu timen: Für den einen Event der beim Auslaufen des Lease passiert funktioniert der Mechanismus auch wenn die Zeit zurückgestellt wird (vgl. den obigen Auszug aus dem leases file, die Zeiten dort sind richtig, nicht eine Stunde in der Zukunft). Für den anderen Mechanismus beim Lease-Erneuern nicht. Ich habe mir den Code nicht angesehen um rauszufinden, warum das so ist.

Was war nun die Ursache der falschen Zeit? Es stellte sich heraus dass ich diese Maschine schon immer so konfiguriert hatte dass sie in localtime (CET ist eine Stunde weiter als UTC) lief. Also war dieser Fehler schon immer drin. Das oben beschriebene Problme trat aber erst mit Debian Buster auf.

Inzwischen starte ich diese Maschine in UTC und alles funktioniert wie erwartet. Ich verwende direkt KVM, die korrekte Option ist:

-rtc base=utc

Zweiter SPI Chipselect für den Orange-Pi Zero


Vor kurzem habe ich versucht, ein TPM-Modul von Infineon das für den Raspberry-Pi entwickelt ist auf dem Orange-Pi Zero zum Laufen zu bekommen. Der Chipselect des TPM-Moduls ist hart verdrahted mit dem Chipselect 1 (mit einem 0 Ω Widerstand der auf ein vorgesehenes Lötpad umgelötet werden könnte um den Chipselect 0 zu verwenden).

Der Orange-Pi hat das gleiche Anschlussschema wie der Raspberry-Pi aber verwendet SPI-1 (statt SPI-0 auf dem Raspi) auf den Anschlüssen 19 (MOSI), 21 (MISO), 23 (CLK) und 24 (CS-0, der von der Hardware unterstützte Chipselect). Chipselect CS-1, der auf dem Raspi ein nativer vom SPI-Controller unterstützter Chipselect ist, ist ein normaler GPIO (PA10) auf dem Orange-Pi Zero. Der SPI-Treiber für den H2 Allwinner Prozessor im Linux-Kernel sollte eigentlich normale GPIOs als zusätzliche Chip-Selects verwenden können. Das hat in meinem Fall nicht funktioniert.

Ich habe also zuerst versucht rauszufinden, ob irgendwas mit meiner Device-Tree Konfiguration nicht stimmt oder ob ich einen zusätzlichen Fix für die SPI-Initialisierung brauch. Diese Suche ist in einer Diskussion im Armbian Forum dokumentiert. Es hat sich dann herausgestellt, dass meine Device-Tree Konfiguration OK war, der folgende Ausschnitt zeigt ein Device-Tree Overlay das ich derzeit verwende um den GPIO PA10 vom Orange-Pi Zero als zweiten Chipselect CS1 zu verwenden:

// Enable CS1 on SPI1 for the orange pi zero
/dts-v1/;
/plugin/;

/ {
    fragment@0 {
        target = <&pio>;
        __overlay__ {
            spi1_cs1: spi1_cs1 {
                pins = "PA10";
                function = "gpio_out";
                output-high;
            };
        };
    };

    fragment@1 {
        target = <&spi1>;
        __overlay__ {
            status = "okay";
            pinctrl-names = "default", "default";
            pinctrl-1 = <&spi1_cs1>;
            /* PA10 GPIO_ACTIVE_HIGH (last 0) */
            cs-gpios = <0>, <&pio 0 10 0>;
        };
    };
};

Aber in der Praxis wird die Taktleitung (CLK) des SPI-Bus auf High gesetzt bevor der SPI-Transfer gestartet wird. Dies sieht man im folgenden Oszilloskop Bildschirmabzug für den eingebauten Chipselect CS0:

/wp-content/uploads/2019/native-cs0.bmp

Die Taktleitung (Blau) geht auf High bevor der Transfer startet und dann auf Low sobald der Chipselect (Gelb) auf Low geht. Der Chipselect ist Aktiv Low, die Daten auf MISO/MOSI, nicht gezeigt im Oszilloskop-Bild, werden bei Taktleitung High abgetastet. Das kann einige Geräte verwirren sollte aber in den meisten Fällen funktionieren.

Das Bild schaut anders aus wenn man den zweiten Chipselect CS1 verwendet. In diesem Fall geht der Takt (Blau) auch auf High bevor der Transfer startet aber geht nicht auf Low wenn der Chipselect (Gelb) auf Low geht. Das ist ein Problem weil Takt auf High bedeutet dass der SPI Slave den Bus (MOSI) an diesem Punkt abtastet. Dadurch werden alle übertragenen Bits um ein Bit nach rechts geshiftet und der SPI Slave empfängt nur Müll.

/wp-content/uploads/2019/additional_cs1.bmp

Als ich das gesehen habe, habe ich mich an einen Patch auf der SUNXI spidev Seite erinnert, der das Problem fixt, dass die Taktleitung auf High geht bevor der SPI-Transfer startet (Siehe am Ende dieser Seite unter der Überschrift "HIGH on SCK line right before transfer"). Also habe ich den Patch eingespielt.

Im nächsten Oszilloskop-Bild – CS1 wieder in Gelb und Takt in Blau – sieht man dass die Taktleitung nicht vor dem Transfer auf High geht. Von dem Verhalten von CS0 (dem nativen Chipselect) habe ich kein Oszilloskop-Bild gemacht, weil CS0 dauern auf Low bleibt: Er ist auf Low bevor der SPI Bus initialisiert wird und bleibt auf Low sobald der Transfer startet. Der Wackler der Taktleitung vor dem Transfer wie im ersten Oszilloskop-Bild vor Anwendung des Patches zeigt sich nicht mehr.

/wp-content/uploads/2019/working_cs1.bmp

Ich habe vor den Original-Autor des Patches auf der SUNXI spidev Seite zu überzeugen, diesen Patch auf der Kernel Mailingliste zu posten, weil ohne diesen Patch der zweite Chipselect nicht funktioniert. Falls mir das nicht gelingt (bis jetzt habe ich keine Antwort bekommen) werde ich selbst versucht, den Patch in den Kernel zu bekommen.

Blog zu eine statischen Site-Generator umgezogen


Ich bin mit meinem Blog endlich zu einem statischen Site-Generator umgezogen. Die Auswahlkriterien waren:

  • Unterstützung von ReStructuredText als Markup-Sprache

  • Ein "responsive design"

Weil ich vorher Wordpress (WP) hatte war einer der Vorteile des statischen Website-Generators Nikola, den ich jetzt verwende, dass Nikola WP aus dem WP XML-Backup Format (aktuelle Version 1.2) importieren kann.

Der WP-Importer kann nach HTML oder MD (Markdown) konvertieren. Die Konversion nach MD hat bei mir zu viele Artefakte erzeugt, so dass ich das HTML-Format verwende. Im konvertierten HTML musste ich ein Bild in der Größe beschränken und Bildunterschriften von WP an einigen Stellen ausbessern (scheint so dass der Konverter die Bildunterschriften WP: caption nicht unterstützt). Sonst war die Konvertierung in Ordnung.

Die Konvertierung der Kommentare war allerdings mehr Aufwand: Der Konverter produziert .wpcomment Dateien, eine für jeden Kommentar. Diese brauchen das static_comments Plugin für Nikola.

Die generierten Dateien brauchen eine Spezifikation des Compilers (der aus dem Text in der Datei HTML erzeugt) innerhalb jeder Kommentar-Datei. Ich habe als Compiler ReStructuredText verwendet, die Direktive dafür ist:

.. compiler: rest

Wenn man ReStructuredText verwendet, muss man natürlich HTML Entities die im Kommentar-Text verwendet werden, editieren.

Zusätzlich braucht das static_comments Plugin ein Setup von Lokalisierungs-Strings die im zugehörigen Template verwendet werden. Es wird in der Dokumentation zwar erwähnt, dass man diese erzeugen muss, allerdings wird nicht erwähnt wie und wo das zu geschehen hat. Ich habe dazu ein Github Issue eröffnet.

In meinem alten WP Blog markiert WP Links in Blog Kommentaren, sowohl in der URL des Kommentar-Autors als auch Links innerhalb des Kommentar-Textes mit rel=external nofollow. Dieses Verhalten wollte ich beibehalten und habe daher das Jinja-Template, das mit static_comments mitkommt, geändert und in einem weiteren Github Issue dokumentiert. Das funktioniert wenn der Kommentar-Autor eine Autoren-URL angegeben hat. Bis jetzt habe ich keinen Weg gefunden, ein rel=nofollow auch in Links innerhalb des Kommentar-Textes, wie sie von ReStructuredText erzeugt werden, zu generieren. Daher werden alle Links innerhalb von Kommentaren derzeit von Suchmaschinen ausgewertet (Ich habe verifiziert dass das keine bösen Dinge tut in diesem Fall). Für Menschen die von WP konvertieren und mehr Kommentare haben als ich in meinem Blog kann potentiell großer Aufwand entstehen.

Ich hoffe dass in in nächster Zeit wieder mehr zum bloggen komme, jetzt wo die grausliche WP-Markupsprache keine Entschuldigung mehr ist :-)

Peer Production License


Recently discussions about new licensing models for open cooperative production have come up (again). This discussion resurrects the “Peer Production License” proposed in 2010 by John Magyar and Dmytri Kleiner [1] which is also available on the p2pfoundation website [2] although it’s not clear if the latter is a modified version. The license is proposed by Michel Bauwens and Vasili Kostakis accompanied by a theoretical discussion [3] why such a license would enhance the current state of the art in licensing. The proposal has already sparked criticism in form of critical replies which I will cite in the following where appropriate.

The theoretical argument (mostly base on marxist theories I don’t have the patience to dig into) boils down to differentiating “good” from “bad” users of the licensed product. A “good” user is a “workerowned business” or “workerowned collective” [2] while a “bad” user seems to be a corporation. Note that the theoretical discussion seems to allow corporate users who contribute “as IBM does with Linux. However, those who do not contribute should pay a license fee” [3] (p.358). I’ve not found a clause in the license that defines this contribution exception. Instead it makes clear that “you may not exercise any of the rights granted to You in Section 3 above in any manner that is primarily intended for or directed toward commercial advantage or private monetary compensation”. Finally it is made clear “for the avoidance of doubt” that “the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License” [2].

With the cited clauses above the “new” license is very similar to a Creative Commons license with a non-commercial clause as others have already noted [4] (p.363). Although the missing clauses in the license for a contribution exception for non-workerowned collectives or businesses is probably only an oversight — Rigi [5] (p.396) also understands the license this way — this is not the major shortcoming.

For me the main point is: who is going to be the institution to distinguish “good” from “bad” users of the product, those who have to pay and those who don’t? The license mentions a “collecting society” for this purpose. Whatever this institution is going to be, it might be a “benevolent dictator” [6] at the start but will soon detoriate into a real dictatorship. Why? As the software-focused “benevolent dictator for life” Wikipedia article [7] notes, the dictator has an incentive to stay benevolent due to the possibility of forking a project, this was first documented in ESRs “Homesteading the Noosphere” [8]. Now since our dictator is the “Licensor [who] reserves the exclusive right to collect such royalties” [2] there are other, monetary, incentives for forking a project which has to be prevented by other means covered in the license. Collection of royalties is incompatible with the right to fork a project. We have an “owner” who decides about “good” vs. “bad” and uses a license to stay in power. A recipe for desaster or — as a friend has put it in a recent discussion “design for corruption” [9].

Other problems are the management of contributions. As Meretz has already pointed out, “only people can behave in a reciprocal way” [4] (p.363). Contributors are people. They may belong to one instution that is deemed “good” by the dictator at one point and may later change to an institution that is deemed “bad” by the dictator. So a person may be excluded from using the product just because they belong to a “bad” institution. Take myself as an example: I’m running an open source business for ten years “primarily intended for or directed toward commercial advantage or private monetary compensation” [2]. I guess I wouldn’t qualify for free use of a “peer production license” licensed product. One of the reasons for success of open source / free software like Linux was that employees could use it for solving their day-to-day problems. This use often resulted in contributions, but only after using it for some time.

Which leads to the next problem: The license tries to force “good” behaviour. But you must first prove to be “good” by contributing before you’re eligible for using the product. As noted by Rigi the “GPL stipulated reciprocity does not fit into any of these forms [usually known to economists (my interpretation)]” [5] (p.398) because a contributor always gets more (e.g. a working software package) than his own contribution. This exactly is one if not the main reason people are motivated to contribute. Openness creates more ethical behaviour than a license that tries to force ethics. Force or control will destroy that motivation as exemplified in the Linus vs. Tanenbaum discussion where Tanenbaum stated:

If Linus wants to keep control of the official version, and a group of eager beavers want to go off in a different direction, the same problem arises. I don’t think the copyright issue is really the problem. The problem is co-ordinating things. Projects like GNU, MINIX, or LINUX only hold together if one person is in charge. During the 1970s, when structured programming was introduced, Harlan Mills pointed out that the programming team should be organized like a surgical team–one surgeon and his or her assistants, not like a hog butchering team–give everybody an axe and let them chop away.
Anyone who says you can have a lot of widely dispersed people hack away on a complicated piece of code and avoid total anarchy has never managed a software project. [10] (Post 1992-02-05 23:23:26 GMT)

To which Linus replied:

This is the second time I’ve seen this “accusation” from ast, who feels pretty good about commenting on a kernel he probably haven’t even seen. Or at least he hasn’t asked me, or even read alt.os.linux about this. Just so that nobody takes his guess for the full thruth, here’s my standing on “keeping control”, in 2 words (three?):
I won’t.
[10] (Post 1992-02-06 10:33:31 GMT)

and then goes on to explain how kernel maintenance works (at the time).

What becomes clear from this discussion is that the main focus of chosing a license is to attract contributors — preventing others from appropriating a version or influencing derived works is only secondary. Many successful open source projects use licenses that are more permissive than the GNU General Public License GPL Version 2 [11], and the new Version 3 of the GPL [12] which is more restrictive sees less use. The programming language Python is a prominent example of a successful project using a more permissive license [13]. Armin Ronacher documents in a blog post [14] that there is a trend away from the GPL to less restricitive licenses. This is also confirmed statistically by other sources [15].

One reason for this trend is the growing mess of incompatible licenses. One of the ideas of open source / free software is that it should be possible to reuse existing components in order not to reinvent the wheel. This is increasingly difficult due to incompatible licenses, Ronacher in his essay touches the tip of the iceberg [14]. License incompatibility has already been used to release software under an open source license and still not allowing Linux developers to incorporate the released software into Linux [14].

Given the reuse argument, adding another incompatible license to the mix (the proposed Peer Production License is incompatible with the GPL and probably other licenses) is simply insane. The new license isn’t even an open source license [16] much less fitting the free software definition [17] due to the commercial restrictions, both definitions require that the software is free for any purpose.

When leaving the field of software and other artefacts protected by copyright we’re entering the field of hardware licensing. Hardware unlike software is not protected by copyright (with the exception of some artefacts like printed circuit boards, where the printed circuit is directly protected by copyright). So it is possible for private or research purposes to reverse-engineer a mechanical part and print it on a 3D printer. If the part is not protected by a patent, it is even legal to publish the reverse-engineered design documents for others to replicate the design. This was shown in a study for UK law by Bradshaw et. al. [18] but probably transcends to EU law. Note that the design documents are protected by copyright but the manufactured artefact is not. This has implications on the protection of open source hardware because this finding can be turned around. A company may well produce an open source design without contributing anything back, even a modified or improved design which is not given back to the community would probably be possible.

Hardware could be protected with patents, but this is not a road the open source community wants to travel. The current state in hardware licensing seeks to protect users of the design from contributors who later want to enforce patents against the design by incorporating clauses where contributors license patents they hold for the project. This was pioneered by the TAPR open hardware license [19] and is also reflected in the CERN open hardware license [20].

To sum up: Apart from the inconsistencies in the theoretical paper [3] and the actual license [2] I pointed out that such a license is a recipe for corruption when money is involved due to the restrictions of forking a project. In addition the license would hamper reuse of existing components because it adds to the “license compatibility clusterfuck” [14]. In addition it won’t protect what it set out to protect: Hardware artefacts — except for some exceptions — are not covered by copyright and therefore not by a license. We can only protect the design but the production of artefacts from that design is not subject to copyright law.

Last not least: Thanks to Franz Nahrada for inviting me to the debate.

[1] Dymtri Kleiner, The Telekommunist Manifesto. Network Notebooks 03, Institute of Network Cultures, Amsterdam, 2010.
[2] (1, 2, 3, 4, 5, 6) Dymtri Kleiner, Peer Production License, 2010. Copy at p2pfoundation.org (Not sure if this is the original license by Kleiner or a modification)
[3] (1, 2, 3) Michel Bauwens and Vasilis Kostakis. From the communism of capital to capital for the commons: Towards an open co-operativism. tripleC communication capitalism & critique, Journal for a Global Sustainable Information Society, 12(1):356-361, 2014.
[4] (1, 2) Stefan Meretz. Socialist licenses? A rejoinder to Michel Bauwens and Vasilis Kostakis. tripleC communication capitalism & critique, Journal for a Global Sustainable Information Society, 12(1):362-365, 2014.
[5] (1, 2) Jakob Rigi. The coming revolution of peer production and revolutionary cooperatives. A response to Michel Bauwens, Vasilis Kostakis and Stefan Meretz. tripleC communication capitalism & critique, Journal for a Global Sustainable Information Society, 12(1):390-404, 2014.
[6] Wikipedia, Benevolent dictatorship, accessed 2014-05-27.
[7] Wikipedia, Benevolent dictator for life, accessed 2014-05-27.
[8] Eric S. Raymond, Homesteading the Noosphere 1998-2000.
[9] Michael Franz Reinisch, private communication.
[10] (1, 2) Andy Tanenbaum, Linus Benedict Torvalds. LINUX is obsolete, discussion on USENIX news, reprinted under the title The Tanenbaum-Torvalds Debate in Open Sources: Voices from the Open Source Revolution, 1999. The discussion was continued under the subject “Unhappy campers”.
[11] GNU General Public License version 2. Software license, Free Software Foundation, 1991
[12] GNU General Public License version 3. Software license, Free Software Foundation, 2007
[13] Python Software Foundation. History and License 2001-2014
[14] (1, 2, 3, 4) Armin Ronacher, Licensing in a Post Copyright World, Blog entry, Jul 2013
[15] Matthew Aslett, On the continuing decline of the GPL. Blog entry, December 2011
[16] Bruce Perens, The Open Source Definition, Online document, Open Source Initiative, 1997
[17] Free Software Foundation, The free software definition. Essay, 2001-2010
[18] Simon Bradshaw, Adrian Bowyer, and Patrick Haufe, The intellectual property implications of low-cost 3D printing. SCRIPTed — A Journal of Law, Technology & Society 7(1):5-31, April 2010.
[19] John Ackermann, TAPR open hardware license version 1.0, Tucson Amateur Packet Radio, May 2007
[20] Javier Serrano, CERN open hardware license v1.1, Open Hardware Repository, September 2011

Migrating to GIT with Reposurgeon


I’ve recently worked a lot with reposurgeon, a tool by Eric S. Raymond to do surgery on version control data. With this tool it is possible to migrate from almost any version control system to almost any other version control system — although these days the most feature-complete system is GIT which is the recommended and best supported target system (and the only one I’ve tested). It comes with a migration guide, the DVCS migration HOWTO.

Beyond just converting data, reposurgeon can be used to clean up artefacts, the simplest of which is to reformat commit comments to conform to established standards on GIT commit messages.

My conversion of the history of the pyst project, a python library to connect to different network interfaces of the Asterisk telephony engine, is a good example of what can be done with reposurgeon. The project, originally started by Karl Putland with version control at the time in CVS, was later taken over by Matthew Nicholson who used Monotone for version control. When I took over maintenance in 2010, I used Subversion. So we had three separate source code repositories in different version control systems. No effort was ever made to convert the version history from one system to another, so each new maintainer imported the last release version into the new version control system and continued from there.

Fortunately, Monotone has a GIT export feature and reposurgeon can natively read the other two formats. So I used separate reposurgeon scripts to clean up the three repositories and then used the reposurgeon graft command to unite them into one. The Subversion repo started with release 0.2 but there had been some commits after 0.2 in Monotone (which were later merged in Subversion) so the commits after 0.2 were put on a branch in the new repository. The last step then was to write out the resulting repository in GIT fast-export format and import into a GIT repository.

What artefacts did I clean up? Let me give two examples, both of which are problems I have when using Subversion.

Subversion doesn’t have the concept of a tag like other version control systems have. Instead tags are emulated by copying the to-be-tagged content to a new location in the repository, effectively creating a new branch, it’s just a naming convention that this is called a tag.

The first example deals with last-minute changes when doing a release: It’s not possible in Subversion to really remove a tag as in other systems. So when doing a release in GIT and something in the release process doesn’t work (not having created a release yet), as long as we didn’t push our changes to the public repository we can still move the release tag. This isn’t possible in Subversion. So I frequently have the situation that a release tag isn’t just one commit but several and the changes are either merged from the trunk to the tag-branch or the other way round from the tag-branch to the trunk. An example of a commit on a tag (r22 “fix PACKAGE definition for SF release”) and subsequent merge back to trunk can be seen in the following illustration created with the graph command of reposurgeon. The tag, originally Subversion commit r21 has already been tagified by reposurgeon. But the commit on the tag is now on the branch V_0_3.

First example

This can be fixed with reposurgeon with the following commands:


debranch V_0_3 trunk
[/^V_0_3\//] paths sup
:70 unmerge
:70 tagify –canonicalize
tag emptycommit-23 delete
tag V_0_3-root rename V_0_3
tag V_0_3 move :69

This puts the branch V_0_3 back onto the trunk and creates a new subdirectory V_0_3 there. Then this subdirectory is removed with the paths reposurgeon command. We then make the merge commit a normal commit with only one predecessor with unmerge and create a tag from this new commit which is possible because it doesn’t change any files. Finally we delete the tag just created and rename and move the V_0_3 tag.

The second example involves accidental commits on a release tag. This frequently happens to me when using Subversion for doing a release and happens as follows:

  • Create new tag by copying to a subdirectory in tags
  • Switch to this new tag using svn switch
  • Do the release
  • Forget to switch back to trunk
  • Come back later, do some accidental commits on the tag
  • Merge accidental changes back to trunk
  • Revert the changes on the tag

An example of this problem can be seen in the following figure.
Second example

This example is from my svnpserver project and shows a series of commits on the V_0_4 tag. Just before the next release I noticed, merged the commits from the tag to trunk, and reverted the erroneous commits on the tag. This is fixed with reposurgeon as follows:

:14063 delete
debranch V_0_4 trunk
[/^V_0_4//] paths sup
tag V_0_5-root rename V_0_5
tag V_0_5 move :14061
:14062 unmerge
:14062 tagify –canonicalize
tag emptycommit-4734 delete

First we delete the commit that reverts the changes on the tag. Then we move the commits from the tag to trunk and remove the resulting path prefix V_0_4. The new V_0_5 tag is moved to the last commit on what was previously the last commit on the tag because we’re going to eliminate the merge-commit next: First we make the merge commit a normal commit by removing the earlier ancestor using unmerge. The last step is to convert this commit into a tag (which is possible because it now doesn’t modify anything) and remove that resulting tag.

Modifying history is usually a bad idea when converting repositories. After all, the version control system is here to preserve the history. My rule is to remove artefacts of the used version control system that would never have occurred with another system. All the problems above would have been avoided by using, e.g., GIT in the first place: With GIT we can simply move a tag (if we haven’t pushed yet) and the erroneous commits on the tag could never have happened because we don’t have to switch branches for doing a release with GIT, so forgetting to switch back from the branch is not possible.

So by using reposurgeon we now have a GIT repository for pyst that spans the entire history of the project united from three different version control systems in use over the duration of the project.

ICMPv6 and prefixes


In IPv4 the address assignment is coupled with the assignment of a subnet-mask — which means the insertion of a route to the given subnet.

In IPv6 address assignment is separate from on-link determination, for this an interface maintains a list of prefixes. All addresses matched by these prefixes are directly reachable. In addition routers may issue ICMPv6 redirects and the target of such a redirect is also on-link even if not contained in a known prefix of the interface.

Unfortunately the dhclient from ISC doesn’t get this right, so I spent some time to learn why a prefix I wanted for an interface, which is different from /64, didn’t work. It turns out, dhclient always configures an interface with a /64 subnet mask and associated route.

RFC4861 on IPv6 Neighbor Discovery later updated by RFC5942 “IPv6 Subnet Model: The Relationship between Links and Subnet Prefixes” makes clear that such prefixes may only be set by the following means (RFC5942, p.4)

The Prefix List is populated via the following means:

  • Receipt of a valid Router Advertisement (RA) that specifies a prefix with the L-bit set. Such a prefix is considered on-link for a period specified in the Valid Lifetime and is added to the Prefix List. (The link-local prefix is effectively considered a permanent entry on the Prefix List.)
  • Indication of an on-link prefix (which may be a /128) via manual configuration, or some other yet-to-be-specified configuration mechanism.

And makes clear this also holds for DHCPv6 (RFC5942, p.7):

The assignment of an IPv6 address — whether through IPv6 stateless address autoconfiguration [RFC4862], DHCPv6 [RFC3315], or manual configuration — MUST NOT implicitly cause a prefix derived from that address to be treated as on-link and added to the Prefix List. …

It even lists the bug if dhclient under the heading “Observed Incorrect Implementation Behavior” (RFC5942, p.8):

… An address could be acquired through the DHCPv6 identity association for non-temporary addresses (IA_NA) option from [RFC3315] (which does not include a prefix length), or through manual configuration (if no prefix length is specified). The host incorrectly assumes an invented prefix is on-link. This invented prefix typically is a /64 that was written by the developer of the operating system network module API to any IPv6 application as a “default” prefix length when a length isn’t specified…

And code inspection (client/dhc6.c, line 3844 dhcp-4.3.0a1) shows the value is really hard-coded in dhclient:

/* Current practice is that all subnets are /64′s, but
 * some suspect this may not be permanent.
 */
client_envadd(client, prefix, “ip6_prefixlen”,
              “%d”, 64);
client_envadd(client, prefix, “ip6_address”,
              “%s”, piaddr(addr->address));

I’ve filed a bug-report (#35178, not the first one I discovered later as the bug-tracker doesn’t seem to be public, the reporter of the Debian bug also has submitted a report) and hope this will be fixed. The bug is present also in older versions, for example isc-dhcp-4.2.2 in Debian stable (wheezy). Debian also has a bug-report that references RFC 5942 which exists since 2012 (RFC 5942 is from 2010).

The fix would probably be to hard-code the netmask /128 for the newly-assigned address and leave the configuration to ICMPv6 router advertisements (see RFC4861).

I hope this will finally be fixed as dhcp is the only autoconfiguration mechanism in IPv6 that can handle netmasks different from /64 (on Ethernet, there may be other layer-2 protocols with a different interface identifier length for stateless autoconfiguration).