Mal etwas, das nichts mit dem Lab zu tun hat: mein IRC-Client. Ich nutze seit Jahren WeeChat , und wie bei fast allem auf meinen Maschinen gilt auch hier — nichts wird von Hand zusammengeklickt, alles ist reproduzierbar. WeeChat samt Konfiguration kommt deshalb aus einem Home-Manager -Modul und verbindet sich ausschließlich mit meinem Bouncer.
WeeChat als Nix-Modul#
Der Client soll auf jeder meiner Maschinen identisch dastehen — gleiche Plugins, gleiche Skripte, gleiche Tastenbelegung. Genau dafür ist Nix gemacht. Mein Modul baut WeeChat über pkgs.weechat.override mit exakt den Bausteinen, die ich brauche, und nicht mehr:
1weechat = pkgs.weechat.override {
2 configure = { availablePlugins, ... }: {
3 plugins = [ (availablePlugins.python.withPackages (_ps: [ ])) ];
4 scripts = with pkgs.weechatScripts; [ autosort weechat-grep ];
5 };
6};
Das Python-Plugin und die beiden Skripte —
autosort
zum automatischen Einsortieren der Buffer und weechat-grep zum Durchsuchen der Logs — sind damit Teil des Build-Outputs, nicht etwas, das ich nach der Installation noch nachziehen müsste.
Die Konfiguration selbst lege ich deklarativ ab, indem das Modul den ./config-Baum nach ~/.config/weechat spiegelt:
1xdg.configFile.weechat = {
2 source = lib.cleanSourceWith { src = lib.cleanSource ./config; };
3 recursive = true;
4};
Das Ergebnis: Ein frisch ausgerolltes System hat sofort meinen kompletten WeeChat — Build und irc.conf, buflist.conf, trigger.conf und der ganze Rest. Aktiviert wird das Ganze über einen einzigen Schalter, fr0st.apps.weechat.enable.
Eingeklinkt am Bouncer#
Hier kommt der zweite Teil ins Spiel. WeeChat verbindet sich nie direkt mit Libera.Chat oder hackint, sondern immer nur mit meinem ZNC-Bouncer . Dieser hält die eigentlichen Netzwerk-Verbindungen dauerhaft offen — und routet sie, wie im verlinkten Beitrag beschrieben, über Tor.
Der Trick steckt in der ZNC-typischen Syntax des Passwort-Feldes: Beide „Server“ in meiner irc.conf zeigen auf dieselbe Bouncer-Adresse, und allein das Passwort entscheidet, in welches Netz ZNC die Verbindung weiterreicht — <znc-user>/<netz>:<passwort>:
1libera.addresses = "${sec.data.bnc_addr}"
2libera.password = "ff0x/libera:${sec.data.bnc_pass}"
3libera.capabilities = "server-time,znc.in/server-time-iso,znc.in/self-message"
4
5hackint.addresses = "${sec.data.bnc_addr}"
6hackint.password = "ff0x/hackint:${sec.data.bnc_pass}"
Aus Sicht von WeeChat sind das zwei Server-Verbindungen; tatsächlich landen beide am selben Bouncer, der sie auf die richtigen Netze auffächert. Die znc.in-Capabilities sorgen dafür, dass beim Verbinden die gepufferte History samt korrekter Zeitstempel nachgespielt wird — ich steige also genau dort wieder ein, wo ich aufgehört habe.
irc.conf, sondern als ${sec.data.*} aus WeeChats eigenem secured-data-Store (sec.conf), der mit einer Master-Passphrase verschlüsselt ist. So kann der Config-Baum bedenkenlos versioniert werden.Fazit#
Zwei einfache Ideen, die zusammen erstaunlich bequem sind: Der Client ist ein reproduzierbares Nix-Artefakt, das auf jeder Maschine identisch erscheint, und die Netzwerk-Logik liegt nicht im Client, sondern im Bouncer. Ich starte WeeChat, eine einzige verschlüsselte Verbindung pro Eintrag geht zum Bouncer — und ich bin sofort wieder in allen Kanälen, als wäre ich nie weg gewesen.
