diff --git a/krebs/1systems/hotdog/config.nix b/krebs/1systems/hotdog/config.nix
index c0fa38284..a100e414d 100644
--- a/krebs/1systems/hotdog/config.nix
+++ b/krebs/1systems/hotdog/config.nix
@@ -1,7 +1,3 @@
-# Edit this configuration file to define what should be installed on
-# your system.  Help is available in the configuration.nix(5) man page
-# and in the NixOS manual (accessible by running ‘nixos-help’).
-
 { config, lib, pkgs, ... }:
 
 {
diff --git a/krebs/1systems/news/config.nix b/krebs/1systems/news/config.nix
new file mode 100644
index 000000000..e4059e579
--- /dev/null
+++ b/krebs/1systems/news/config.nix
@@ -0,0 +1,36 @@
+{ config, lib, pkgs, ... }:
+
+{
+  imports = [
+    <stockholm/krebs>
+    <stockholm/krebs/2configs>
+
+    <stockholm/krebs/2configs/ircd.nix>
+    <stockholm/krebs/2configs/go.nix>
+
+    #### NEWS ####
+    <stockholm/krebs/2configs/ircd.nix>
+    <stockholm/krebs/2configs/news.nix>
+  ];
+
+  krebs.build.host = config.krebs.hosts.news;
+
+  boot.isContainer = true;
+  networking.useDHCP = false;
+  krebs.bindfs = {
+    "/var/lib/htgen-go" = {
+      source = "/var/state/htgen-go";
+      options = [
+        "-M ${toString config.users.users.htgen-go.uid}"
+      ];
+      clearTarget = true;
+    };
+    "/var/lib/brockman" = {
+      source = "/var/state/brockman";
+      options = [
+        "-M ${toString config.users.users.brockman.uid}"
+      ];
+      clearTarget = true;
+    };
+  };
+}
diff --git a/krebs/1systems/puyak/config.nix b/krebs/1systems/puyak/config.nix
index 19cf22280..1e0687ba7 100644
--- a/krebs/1systems/puyak/config.nix
+++ b/krebs/1systems/puyak/config.nix
@@ -19,14 +19,6 @@
     <stockholm/krebs/2configs/binary-cache/nixos.nix>
     <stockholm/krebs/2configs/binary-cache/prism.nix>
 
-    ### Krebs ###
-    <stockholm/krebs/2configs/go.nix>
-
-    #### NEWS ####
-    <stockholm/krebs/2configs/ircd.nix>
-    <stockholm/krebs/2configs/news.nix>
-
-
     ### shackspace ###
     # handle the worlddomination map via coap
     <stockholm/krebs/2configs/shack/worlddomination.nix>
diff --git a/krebs/2configs/news-host.nix b/krebs/2configs/news-host.nix
new file mode 100644
index 000000000..82360a670
--- /dev/null
+++ b/krebs/2configs/news-host.nix
@@ -0,0 +1,12 @@
+{
+  krebs.sync-containers.containers.news = {
+    peers = [
+      "shodan"
+      "mors"
+      "styx"
+    ];
+    hostIp = "10.233.2.101";
+    localIp = "10.233.2.102";
+    format = "plain";
+  };
+}
diff --git a/krebs/2configs/news.nix b/krebs/2configs/news.nix
index f40997f82..a492b0782 100644
--- a/krebs/2configs/news.nix
+++ b/krebs/2configs/news.nix
@@ -1,4 +1,4 @@
-{ pkgs, ... }:
+{ config, pkgs, ... }:
 
 {
   services.rss-bridge = {
@@ -22,7 +22,6 @@
     "d /var/lib/brockman 1750 brockman nginx -"
   ];
 
-  systemd.services.brockman.environment.BROCKMAN_LOG_LEVEL = "DEBUG";
   krebs.brockman = {
     enable = true;
     config = {
@@ -36,4 +35,54 @@
       bots = {};
     };
   };
+
+  krebs.reaktor2.news = {
+    hostname = "localhost";
+    port = "6667";
+    nick = "brockman-helper";
+    plugins = [
+      {
+        plugin = "register";
+        config = {
+          channels = [
+            "#all"
+            "#aluhut"
+            "#news"
+          ];
+        };
+      }
+      {
+        plugin = "system";
+        config = {
+          hooks.PRIVMSG = [
+            {
+              activate = "match";
+              pattern = "^(?:.*\\s)?\\s*brockman-helper:\\s*([0-9A-Za-z._][0-9A-Za-z._-]*)(?:\\s+(.*\\S))?\\s*$";
+              command = 1;
+              arguments = [2];
+              commands = {
+                add-telegram.filename = pkgs.writeDash "add-telegram" ''
+                  if [ "$#" -ne 1 ]; then
+                    echo 'usage: brockman-helper: add-telegram $telegramname'
+                    echo "$#"
+                    exit 1
+                  fi
+                  echo "brockman: add t_$1 http://rss.r/?action=display&bridge=Telegram&username=$1&format=Mrss"
+                '';
+                search.filename = pkgs.writeDash "search" ''
+                  if [ "$#" -ne 1 ]; then
+                    echo 'usage: brockman-helper: search $searchterm'
+                    echo "$#"
+                    exit 1
+                  fi
+                  ${pkgs.curl}/bin/curl -Ss "https://feedsearch.dev/api/v1/search?url=$1&info=true&favicon=false" |
+                    ${pkgs.jq}/bin/jq '.[].url'
+                '';
+              };
+            }
+          ];
+        };
+      }
+    ];
+  };
 }
diff --git a/krebs/2configs/syncthing.nix b/krebs/2configs/syncthing.nix
new file mode 100644
index 000000000..31e33ad5e
--- /dev/null
+++ b/krebs/2configs/syncthing.nix
@@ -0,0 +1,15 @@
+{ config, pkgs, ... }: with import <stockholm/lib>; let
+  mk_peers = mapAttrs (n: v: { id = v.syncthing.id; });
+
+  all_peers = filterAttrs (n: v: v.syncthing.id != null) config.krebs.hosts;
+  used_peer_names = unique (flatten (mapAttrsToList (n: v: v.devices) config.services.syncthing.declarative.folders));
+  used_peers = filterAttrs (n: v: elem n used_peer_names) all_peers;
+in {
+  services.syncthing = {
+    enable = true;
+    configDir = "/var/lib/syncthing";
+    declarative = {
+      devices = mk_peers used_peers;
+    };
+  };
+}
diff --git a/lass/3modules/bindfs.nix b/krebs/3modules/bindfs.nix
similarity index 79%
rename from lass/3modules/bindfs.nix
rename to krebs/3modules/bindfs.nix
index 5c8df8dc5..7e3730e86 100644
--- a/lass/3modules/bindfs.nix
+++ b/krebs/3modules/bindfs.nix
@@ -1,9 +1,9 @@
 with import <stockholm/lib>;
 { config, pkgs, ... }:
 let
-  cfg = config.lass.bindfs;
+  cfg = config.krebs.bindfs;
 in {
-  options.lass.bindfs = mkOption {
+  options.krebs.bindfs = mkOption {
     type = types.attrsOf (types.submodule ({ config, ... }: {
       options = {
         target = mkOption {
@@ -28,6 +28,13 @@ in {
           type = types.listOf types.str;
           default = [];
         };
+        clearTarget = mkOption {
+          description = ''
+            whether to clear the target folder before mounting
+          '';
+          type = types.bool;
+          default = false;
+        };
       };
     }));
     default = {};
@@ -41,6 +48,9 @@ in {
       path = [ pkgs.coreutils ];
       serviceConfig = {
         ExecStartPre = pkgs.writeDash "bindfs-init-${name}" ''
+          ${optionalString mount.clearTarget ''
+            rm -rf '${mount.target}'
+          ''}
           mkdir -p '${mount.source}'
           mkdir -p '${mount.target}'
         '';
diff --git a/krebs/3modules/brockman.nix b/krebs/3modules/brockman.nix
index 55e8255b4..32aa3489b 100644
--- a/krebs/3modules/brockman.nix
+++ b/krebs/3modules/brockman.nix
@@ -1,5 +1,5 @@
-{ pkgs, lib, config, ... }:
-with lib;
+{ pkgs, config, ... }:
+with import <stockholm/lib>;
 let
   cfg = config.krebs.brockman;
 in {
@@ -13,6 +13,7 @@ in {
       home = "/var/lib/brockman";
       createHome = true;
       isNormalUser = false;
+      uid = genid_uint31 "brockman";
     };
 
     systemd.services.brockman = {
diff --git a/krebs/3modules/default.nix b/krebs/3modules/default.nix
index 8c620a4e2..e7d04ead8 100644
--- a/krebs/3modules/default.nix
+++ b/krebs/3modules/default.nix
@@ -11,6 +11,7 @@ let
       ./apt-cacher-ng.nix
       ./backup.nix
       ./bepasty-server.nix
+      ./bindfs.nix
       ./brockman.nix
       ./buildbot/master.nix
       ./buildbot/slave.nix
@@ -51,6 +52,7 @@ let
       ./secret.nix
       ./setuid.nix
       ./shadow.nix
+      ./sync-containers.nix
       ./tinc.nix
       ./tinc_graphs.nix
       ./urlwatch.nix
@@ -90,8 +92,10 @@ let
           @ IN SOA dns19.ovh.net. tech.ovh.net. (2015052000 86400 3600 3600000 86400)
                                 IN NS     ns19.ovh.net.
                                 IN NS     dns19.ovh.net.
-                                IN A      192.30.252.154
-                                IN A      192.30.252.153
+                                IN A      185.199.108.153
+                                IN A      185.199.109.153
+                                IN A      185.199.110.153
+                                IN A      185.199.111.153
         '';
         };
     };
diff --git a/krebs/3modules/krebs/default.nix b/krebs/3modules/krebs/default.nix
index d0648418f..4a1b56084 100644
--- a/krebs/3modules/krebs/default.nix
+++ b/krebs/3modules/krebs/default.nix
@@ -92,6 +92,37 @@ in {
       ssh.privkey.path = <secrets/ssh.id_ed25519>;
       ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICxFkBln23wUxt4RhIHE3GvdKeBpJbjn++6maupHqUHp";
     };
+    news = {
+      ci = true;
+      nets = {
+        retiolum = {
+          ip4.addr = "10.243.0.5";
+          aliases = [
+            "news.r"
+            "go.r"
+            "rss.r"
+          ];
+          tinc.pubkey = ''
+            -----BEGIN PUBLIC KEY-----
+            MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9PY6t6P1ytgo8qYL2QDc
+            cgPezX8yGmA0nuTyCUPtXbWyWee9HnzYqekzJYvBHwgBDvZ8UhLZTCXD15agDfaf
+            cbzd4uM5bCDgqI8sezzD95tqj7mzvIEurIShDXYSWC6YRat1h1Opp86JngBJRvHZ
+            Gb6NAyfnr4v2eyMrmH9/j+sECxjCAaC5QLpJWyoDPilFU8dXBarmiZNYYlXQt1pn
+            yxZSF5pElmrdiZ6vlKlnEHwFtExm1gv63ZjAlusrXM+bKMvdVKRnhahq76A5VXjc
+            kbOhQi+wYGaVK4jB2a1UilmKYh1wKLE7HULoHDRrqEe4jemNZg+JOBPTU+jM/JzM
+            XdPy0KAMxHOUZCe8IX0LgF1snVaMF05Qkoe3QKr0YJ3KTD7UdsJpa1Br216Z/w2f
+            koz+cRn/Z/8TO8SIRKvy5TfXeH+ra6rp/CvwryNlNL4FB+25LFDkJtLIZGqAsz3G
+            vRXUiGN4l1FR4TbX7XaK2rvIlA/+4isJ02bBdnZhe7kmuuBeECyPaR1+Ui6pElXe
+            ZamnxTAmj86Q8pDx6Wn2cg8YAJlVV3UCfhda34DZokJmmmKucGupg/6Xt0Bhm9d5
+            exNrTIDG3lXTxmg2mfiZJeg/fsnalvtN0j/VB+NmmKzie+ZohMK4nUfslq8o5CO9
+            j7ZLmZzm062GzX0RenxNkwUCAwEAAQ==
+            -----END PUBLIC KEY-----
+          '';
+        };
+      };
+      ssh.privkey.path = <secrets/ssh.id_ed25519>;
+      ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHl5cDF9QheXyMlNYIX17ILbgd94K50fZy7w0fDLvZlo ";
+    };
     onebutton = {
       cores = 1;
       nets = {
@@ -131,8 +162,6 @@ in {
             "brockman.r"
             "build.puyak.r"
             "cgit.puyak.r"
-            "go.r"
-            "rss.r"
           ];
           tinc.pubkey = ''
             -----BEGIN RSA PUBLIC KEY-----
diff --git a/krebs/3modules/lass/default.nix b/krebs/3modules/lass/default.nix
index a4586bed4..c5cf5cb15 100644
--- a/krebs/3modules/lass/default.nix
+++ b/krebs/3modules/lass/default.nix
@@ -44,6 +44,7 @@ in {
           matrix              60 IN A      ${config.krebs.hosts.prism.nets.internet.ip4.addr}
           paste               60 IN A      ${config.krebs.hosts.prism.nets.internet.ip4.addr}
           radio               60 IN A      ${config.krebs.hosts.prism.nets.internet.ip4.addr}
+          jitsi               60 IN A      ${config.krebs.hosts.prism.nets.internet.ip4.addr}
           streaming           60 IN A      ${config.krebs.hosts.prism.nets.internet.ip4.addr}
         '';
       };
@@ -685,6 +686,7 @@ in {
       };
       ssh.privkey.path = <secrets/ssh.id_ed25519>;
       ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII3OpzRB3382d7c2apdHC+U/R0ZlaWxXZa3GFAj54ZhU ";
+      syncthing.id = "JAVJ6ON-WLCWOA3-YB7EHPX-VGIN4XF-635NIVZ-WZ4HN4M-QRMLT4N-5PL5MQN";
     };
   };
   users = rec {
@@ -699,6 +701,11 @@ in {
       pubkey = builtins.readFile ./ssh/blue.rsa;
       pgp.pubkeys.default = builtins.readFile ./pgp/blue.pgp;
     };
+    lass-green = {
+      mail = "lass@green.r";
+      pubkey = builtins.readFile ./ssh/green.ed25519;
+      pgp.pubkeys.default = builtins.readFile ./pgp/green.pgp;
+    };
     lass-mors = {
       mail = "lass@mors.r";
       pubkey = builtins.readFile ./ssh/mors.rsa;
diff --git a/krebs/3modules/lass/pgp/green.pgp b/krebs/3modules/lass/pgp/green.pgp
new file mode 100644
index 000000000..96b2b38e4
--- /dev/null
+++ b/krebs/3modules/lass/pgp/green.pgp
@@ -0,0 +1,40 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQGNBGAMS3EBDACzbsaP9nhJ8GrAk5JLlz+ruDbEGuvJXvh+spVq9i9TCCGAraPo
+z8Tmgsw6SJhJMW/170OZJ+GMMEDRpRbvh8tLZ0jsTIwINasRjC68tF9dgjjPZdNN
+cVOpFw4Wf4ueMmoEG/9Xyehm+YEJFTj5wul2uJtfj5NJB43daDn4e3ieGExd+zE0
+FTP4yAmxVMbN4BiyZPX7CxeTzJS0g4aVnMq9RqtYbxd1Uv++LmPh1ZkEyNNKItfC
+nRFeZzjhnmD7LvwsixE2ENnbiL9Ho7Mc4C7kRKSJ+LvXH6ChJJtDy9ApVA+u90i5
+Rd7y9rdzFY+NCHusWg0/U/t2FoLc/hRa0eLE1KFtzWzH35TMl8R/7NrPztTwT/fH
+xt3qSiwMUvH9X9TGvh5N0WwqgtEe6mpZvpq+4gyOiyA+EwE73rnxG2DzmM6CFHyo
+Qm/OOfjuFH+l0PkAqti+f41SqlEOiOAAFzgz7gaTdJ8gXs8piOGxk4U5EK/p1OTW
+4e6DrxqcxmHgoAUAEQEAAbQMbGFzc0BncmVlbi5yiQHUBBMBCAA+FiEE6Ed5jGI3
+gop09K1NMwheLc2Sjz0FAmAMS3ECGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwEC
+HgECF4AACgkQMwheLc2Sjz0otwv+I8Sw0ENqy6SsrZSGDtmhAouCeTIUseRQ66tp
+UFnxDVPYhhdM2ubTtIqOfx20Xdy/7N/POyYMJ5VR+IaFcB9wUlrhdjwUlCtoUipx
+EycZloccMPGySxAxR3Kcy/SFzUKWwQ10/mfSQg/4+vYayZNuSvEpviMEZn0prpmw
+jwFJcHOu0NL+7eYULMdit1BDaZfBaAu/otKn18878+0hVimyjW27564uXtJYnbf1
+hUVGvPLaSo74XBFra+kujcA3zIjWiPn6dRA5dzLrRRkb30Unl1+0a9QwY3wd3vCV
+UHWSgDNaV+o7yPTuxoMsfrxHPAc3JlaKM6ka/EdK04tbgMH/N7FHXqDqCEIBWML4
+1/+HxkP2UW59zLefQwvBqWcF6bA7kgHGhIDkg1yg7ygP0t2mH6ktuEAYYr24BFx7
+b8nK/jhK+rp3LomLTLQ6e/6mikfoDr636sB1/Bc+pTdWsJnuQTzaWBDloVEr/2hz
+/K5+wH2kgSKaWYUtaR6wiMbVKq3HuQGNBGAMS3EBDAC1xQNCJD3hlnihHBv7jxfH
+CI5HdnUEh1eP8mUKjSE+Z0xGEMq8Z9sbTHQxtDdmC4ZOq1Kkt2LmtQQQAIH+Qnu6
+RYFOAPRmegouIxg4S3eTPZhZRo1ZqCphqbL2mQ9ifNrG3VVvQGXNvjo3Cuwj0uzx
+EDtOilKEtHZhG0cfehGV+nO1n/g50EQMC7JkFWnryxVL8i4l3KstOdj+LcIT6c27
+EE2fzOUekeltBHGRFSM1Yzmn2lxruuK4I8zoiqak2St1788ay//F9tiZPfhWRb6+
+DF+JgRLCXatqTJppPpkui1irw6jN5ZabjyS7GBtH+5wpnvuMEMr484OXEg17VnCd
+Tx/RTLyjfffDtTkC4M7oiAr5SUbkJjVkEuwjxp1N19epD8gzrBQC2W7XKM3z+mtG
+ZLJtiW5hM+QylMv7VWxbQ21ObJmUqBQUZLPlpl3dlGU/ILw3U4urBibD9oPT2QAX
+J6Db/STyl6w0bzRbMJmaEM4P0FcdEKTuw7tOpl5zBUkAEQEAAYkBtgQYAQgAIBYh
+BOhHeYxiN4KKdPStTTMIXi3Nko89BQJgDEtxAhsMAAoJEDMIXi3Nko89yc8MAJKg
+M5lbA/PJYlIju/qWKWt7yZbsIGuDfmuKfYftjXDOqskEqDyYgr31Txd43bWM6Ec7
+gb5JVmtzvLull0/KRwMcKAFNTXIYcb3jKpanwWRgHQlt/D6zlQula73WxwNUlZWl
+Q8FCWjGa2hC8oKlTbtzm5osdcK+YhlpTpK5y4Mrg0f9Rcd297ygFQSDInpGq7ILY
+sFat3HU7w9oPp9Q5RS8/EmrvAx1kFj9mZRs4L9inJJnHFpb1R6snojcKPwEyIWBi
++PFZ6ns296FjW9C+Ci7C+aaAzVDM7NAwU0/EhWeDKKHITU3Zaz4gnShesKBiVxhI
+JQNFCjWlnc+o3RqbAhDQhlwFrCZWUxQi1qWy4U88IYqR9hxV0eNtGSRmwnGCT9RV
+Nxb6CjtmHpgUmzyvwBpBJya8bLYu5tCKnUodtFiq/poxEfI5WrP6pu5l648AwuPa
+ioovprweDWs38Q8wd/SuoaUtIoj378UDXq8acFvHHnOS/bBBfAE9tutY1ycJdg==
+=Fg3f
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/krebs/3modules/lass/ssh/green.ed25519 b/krebs/3modules/lass/ssh/green.ed25519
new file mode 100644
index 000000000..1aa7b1801
--- /dev/null
+++ b/krebs/3modules/lass/ssh/green.ed25519
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIOJfTJ37hWYTYLWY6egshmvigPfRF0Sa4N11gmphMLm lass@green
diff --git a/lass/3modules/sync-containers.nix b/krebs/3modules/sync-containers.nix
similarity index 94%
rename from lass/3modules/sync-containers.nix
rename to krebs/3modules/sync-containers.nix
index ca81458a9..d31022d3a 100644
--- a/lass/3modules/sync-containers.nix
+++ b/krebs/3modules/sync-containers.nix
@@ -1,6 +1,6 @@
 with import <stockholm/lib>;
 { config, pkgs, ... }: let
-  cfg = config.lass.sync-containers;
+  cfg = config.krebs.sync-containers;
   paths = cname: {
     plain = "/var/lib/containers/${cname}/var/state";
     ecryptfs = "${cfg.dataLocation}/${cname}/ecryptfs";
@@ -8,6 +8,7 @@ with import <stockholm/lib>;
   };
   start = cname: {
     plain = ''
+      :
     '';
     ecryptfs = ''
       if ! mount | grep -q '${cfg.dataLocation}/${cname}/ecryptfs on /var/lib/containers/${cname}/var/state type ecryptfs'; then
@@ -28,6 +29,7 @@ with import <stockholm/lib>;
   };
   stop = cname: {
     plain = ''
+      :
     '';
     ecryptfs = ''
       ${pkgs.ecrypt}/bin/ecrypt unmount ${cfg.dataLocation}/${cname}/ecryptfs /var/lib/containers/${cname}/var/state
@@ -37,7 +39,7 @@ with import <stockholm/lib>;
     '';
   };
 in {
-  options.lass.sync-containers = {
+  options.krebs.sync-containers = {
     dataLocation = mkOption {
       description = ''
         location where the encrypted sync-container lie around
@@ -90,6 +92,10 @@ in {
 
   config = mkIf (cfg.containers != {}) {
     programs.fuse.userAllowOther = true;
+    # allow syncthing to enter /var/lib/containers
+    system.activationScripts.syncthing-home = ''
+      ${pkgs.coreutils}/bin/chmod a+x /var/lib/containers
+    '';
 
     services.syncthing.declarative.folders = (mapAttrs' (_: ctr: nameValuePair "${(paths ctr.name).${ctr.format}}" ({
       devices = ctr.peers;
@@ -153,6 +159,8 @@ in {
 
         if [ -h /var/lib/containers/${ctr.name}/var/src/nixos-config ] && (! ping -c1 -q -w5 ${ctr.name}.r); then
           ${pkgs.nixos-container}/bin/nixos-container run ${ctr.name} -- nixos-rebuild -I /var/src switch
+        else
+          ${(stop ctr.name).${ctr.format}}
         fi
       '')
       (pkgs.writeDashBin "stop-${ctr.name}" ''
diff --git a/krebs/5pkgs/haskell/brockman.nix b/krebs/5pkgs/haskell/brockman.nix
index c6d01edc7..5f1166a25 100644
--- a/krebs/5pkgs/haskell/brockman.nix
+++ b/krebs/5pkgs/haskell/brockman.nix
@@ -1,24 +1,26 @@
 { mkDerivation, aeson, aeson-pretty, base, bloomfilter, bytestring
-, conduit, containers, directory, feed, filepath, hslogger
-, html-entity, http-client, irc-conduit, lens, network
-, optparse-applicative, random, safe, stdenv, text, wreq
+, case-insensitive, conduit, containers, directory, feed, filepath
+, hslogger, html-entity, http-client, irc-conduit, lens, network
+, optparse-applicative, random, safe, stdenv, text, time, timerep
+, wreq
 , fetchFromGitHub
 }:
 mkDerivation rec {
   pname = "brockman";
-  version = "3.0.0";
+  version = "3.2.3";
   src = fetchFromGitHub {
     owner = "kmein";
     repo = "brockman";
     rev = version;
-    sha256 = "08yla9q2mjd7znpasfwsdqzc3dp2vcvg53x9p4vlx4g7jr3dw3yp";
+    sha256 = "1qbjbf0l1ikfzmvky4cnvv7nlcwi2in4afliifh618j0a4f7j427";
   };
   isLibrary = false;
   isExecutable = true;
   executableHaskellDepends = [
-    aeson aeson-pretty base bloomfilter bytestring conduit containers
-    directory feed filepath hslogger html-entity http-client
-    irc-conduit lens network optparse-applicative random safe text wreq
+    aeson aeson-pretty base bloomfilter bytestring case-insensitive
+    conduit containers directory feed filepath hslogger html-entity
+    http-client irc-conduit lens network optparse-applicative random
+    safe text time timerep wreq
   ];
   license = stdenv.lib.licenses.mit;
 }
diff --git a/krebs/5pkgs/simple/ecrypt/default.nix b/krebs/5pkgs/simple/ecrypt/default.nix
new file mode 100644
index 000000000..f83f8cfe7
--- /dev/null
+++ b/krebs/5pkgs/simple/ecrypt/default.nix
@@ -0,0 +1,111 @@
+{ pkgs, lib }:
+
+#usage: ecrypt mount /var/crypted /var/unencrypted
+pkgs.writers.writeDashBin "ecrypt" ''
+  set -euf
+
+  PATH=${lib.makeBinPath (with pkgs; [
+    coreutils
+    ecryptfs
+    gnused
+    gnugrep
+    jq
+    mount
+    keyutils
+    umount
+  ])}
+
+  # turn echo back on if killed
+  trap 'stty echo' INT
+
+  case "$1" in
+    init)
+      shift
+      mkdir -p "$1" "$2"
+
+      # abort if src or dest are not empty
+      if [ -e "$1"/.cfg.json ]; then
+        echo 'source dir is already configured, aborting'
+        exit 1
+      elif ls -1qA "$2" | grep -q .; then
+        echo 'destination dir is not empty, aborting'
+        exit 1
+      else
+        # we start and exit ecryptfs-manager again to circumvent a bug where mounting the ecryptfs fails
+        echo 4 | ecryptfs-manager
+        stty -echo
+        printf "passphrase: "
+        read  passphrase
+        stty echo
+        sig=$(echo "$passphrase" | ecryptfs-add-passphrase | grep 'Inserted auth tok' | sed 's/.*\[\(.*\)\].*/\1/')
+        mount -t ecryptfs \
+          -o ecryptfs_unlink_sigs,ecryptfs_fnek_sig="$sig",ecryptfs_key_bytes=16,ecryptfs_cipher=aes,ecryptfs_sig="$sig" \
+          "$1" "$2"
+
+        # add sig to json state file
+        jq -n --arg sig "$sig" '{ "sig": $sig }' > "$1"/.cfg.json
+      fi
+      ;;
+
+    mount)
+      shift
+      if ! [ -e "$1"/.cfg.json ]; then
+        echo '.cfg.json missing in src'
+        exit 1
+      fi
+      old_sig=$(cat "$1"/.cfg.json | jq -r .sig)
+
+      # check if key is already in keyring, otherwise add it
+      
+      if keyctl list @u | grep -q "$old_sig"; then
+        echo 'pw already saved'
+      else
+        # we start and exit ecryptfs-manager again to circumvent a bug where mounting the ecryptfs fails
+        echo 4 | ecryptfs-manager
+        stty -echo
+        printf "passphrase: "
+        read  passphrase
+        stty echo
+        new_sig=$(echo "$passphrase" | ecryptfs-add-passphrase | grep 'Inserted auth tok' | sed 's/.*\[\(.*\)\].*/\1/')
+
+        # check if passphrase matches sig
+        if [ "$old_sig" != "$new_sig" ]; then
+          echo 'passphrase does not match sig, bailing out'
+          new_keyid=$(keyctl list @u | grep "$new_sig" | sed 's/\([0-9]*\).*/\1/')
+          keyctl revoke "$new_keyid"
+          keyctl unlink "$new_keyid"
+          exit 1
+        fi
+      fi
+
+      sig=$old_sig
+      keyid=$(keyctl list @u | grep "$sig" | sed 's/\([0-9]*\).*/\1/')
+      if (ls -1qA "$2" | grep -q .); then
+        echo 'destination is not empty, bailing out'
+        exit 1
+      else
+        mount -i -t ecryptfs \
+          -o ecryptfs_passthrough=no,verbose=no,ecryptfs_unlink_sigs,ecryptfs_fnek_sig="$sig",ecryptfs_key_bytes=16,ecryptfs_cipher=aes,ecryptfs_sig="$sig" \
+          "$1" "$2"
+      fi
+      ;;
+
+    unmount)
+      shift
+
+      sig=$(cat "$1"/.cfg.json | jq -r .sig)
+      keyid=$(keyctl list @u | grep "$sig" | sed 's/\s*\([0-9]*\).*/\1/')
+
+      umount "$2" || :
+      keyctl revoke "$keyid"
+      keyctl unlink "$keyid"
+      ;;
+
+    *)
+      echo 'usage:
+        ecrypt init /tmp/src/ /tmp/dst/
+        ecrypt mount /tmp/src/ /tmp/dst/
+        ecrypt unmount /tmp/src/ /tmp/dst/
+      '
+  esac
+''
diff --git a/krebs/5pkgs/simple/realwallpaper/default.nix b/krebs/5pkgs/simple/realwallpaper/default.nix
index 56a7dfb98..e55454a08 100644
--- a/krebs/5pkgs/simple/realwallpaper/default.nix
+++ b/krebs/5pkgs/simple/realwallpaper/default.nix
@@ -192,18 +192,15 @@ pkgs.writers.writeDashBin "generate-wallpaper" ''
     fi
 
     # create marker file from json
-    if [ -s marker.json ]; then
-      jq -r 'to_entries[] | @json "\(.value.latitude) \(.value.longitude) image=krebs.png"' marker.json > marker_file
-      echo 'position=sun image=sun.png' >> marker_file
-      echo 'position=moon image=moon.png' >> marker_file
-      echo 'position=mercury image=mercury.png' >> marker_file
-      echo 'position=venus image=venus.png' >> marker_file
-      echo 'position=mars image=mars.png' >> marker_file
-      echo 'position=jupiter image=jupiter.png' >> marker_file
-      echo 'position=saturn image=saturn.png' >> marker_file
-      echo 'position=uranus image=uranus.png' >> marker_file
-      echo 'position=neptune image=neptune.png' >> marker_file
-    fi
+    echo 'position=sun image=sun.png' > marker_file
+    echo 'position=moon image=moon.png' >> marker_file
+    echo 'position=mercury image=mercury.png' >> marker_file
+    echo 'position=venus image=venus.png' >> marker_file
+    echo 'position=mars image=mars.png' >> marker_file
+    echo 'position=jupiter image=jupiter.png' >> marker_file
+    echo 'position=saturn image=saturn.png' >> marker_file
+    echo 'position=uranus image=uranus.png' >> marker_file
+    echo 'position=neptune image=neptune.png' >> marker_file
 
     # generate moon
     xplanet -body moon --num_times 1 -origin earth \
@@ -227,6 +224,24 @@ pkgs.writers.writeDashBin "generate-wallpaper" ''
         shade=15
       ''}
 
+    xplanet --num_times 1 --geometry $xplanet_out_size \
+      --output xplanet-marker-output.png --projection merc \
+      -config ${pkgs.writeText "xplanet-marker.config" ''
+        [earth]
+        "Earth"
+        map=daymap-final.png
+        night_map=nightmap-final.png
+        cloud_map=clouds.png
+        cloud_threshold=1
+        cloud_gamma=10
+        marker_file=marker_file
+        shade=15
+      ''}
+
+    if [ -s marker.json ]; then
+      jq -r 'to_entries[] | @json "\(.value.latitude) \(.value.longitude) image=krebs.png"' marker.json >> marker_file
+    fi
+
     xplanet --num_times 1 --geometry $xplanet_out_size \
       --output xplanet-krebs-output.png --projection merc \
       -config ${pkgs.writeText "xplanet-krebs.config" ''
@@ -248,6 +263,13 @@ pkgs.writers.writeDashBin "generate-wallpaper" ''
         mv realwallpaper-tmp.png realwallpaper.png
     fi
 
+    # trim xplanet output
+    if needs_rebuild realwallpaper-marker.png xplanet-marker-output.png; then
+      convert xplanet-marker-output.png -crop $out_geometry \
+        realwallpaper-marker-tmp.png
+        mv realwallpaper-marker-tmp.png realwallpaper-marker.png
+    fi
+
     if needs_rebuild realwallpaper-krebs.png xplanet-krebs-output.png; then
       convert xplanet-krebs-output.png -crop $out_geometry \
         realwallpaper-krebs-tmp.png
diff --git a/krebs/krops.nix b/krebs/krops.nix
index 608e46df1..aeb2413a4 100644
--- a/krebs/krops.nix
+++ b/krebs/krops.nix
@@ -28,6 +28,7 @@
       git = {
         ref = (lib.importJSON ./nixpkgs.json).rev;
         url = https://github.com/NixOS/nixpkgs;
+        shallow = true;
       };
     };
     stockholm.file = toString ../.;
@@ -67,6 +68,13 @@
     target = "root@${target}/var/src";
   };
 
+  # usage: $(nix-build --no-out-link --argstr name HOSTNAME --argstr target PATH -A populate)
+  populate = { target, force ? false }: pkgs.populate {
+    inherit force;
+    source = source { test = false; };
+    target = lib.mkTarget target;
+  };
+
   # usage: $(nix-build --no-out-link --argstr name HOSTNAME --argstr target PATH -A test)
   test = { target }: pkgs.krops.writeTest "${name}-test" {
     force = true;
diff --git a/krebs/nixpkgs-unstable.json b/krebs/nixpkgs-unstable.json
index e478709b8..321fafac6 100644
--- a/krebs/nixpkgs-unstable.json
+++ b/krebs/nixpkgs-unstable.json
@@ -1,9 +1,9 @@
 {
   "url": "https://github.com/NixOS/nixpkgs",
-  "rev": "f211631c1cb3e94828c7650b5d12c1e5a89e0e16",
-  "date": "2021-01-07T19:50:35+02:00",
-  "path": "/nix/store/2zymxp9iq6xvxy5wjc411iws2kk3c8z4-nixpkgs",
-  "sha256": "0r085j42991qcbzx4l0hnwlsxw016y4b7r821s4qxvqnvwr9lxar",
+  "rev": "f217c0ea7c148ddc0103347051555c7c252dcafb",
+  "date": "2021-01-21T09:50:34+01:00",
+  "path": "/nix/store/8srlzkkvbvlg4g585g9iyzd3ryiilm8a-nixpkgs",
+  "sha256": "0cyksxg2lnzxd0pss09rmmk2c2axz0lf9wvgvfng59nwf8dpq2kf",
   "fetchSubmodules": false,
   "deepClone": false,
   "leaveDotGit": false
diff --git a/krebs/nixpkgs.json b/krebs/nixpkgs.json
index 9c450582c..97afb10f8 100644
--- a/krebs/nixpkgs.json
+++ b/krebs/nixpkgs.json
@@ -1,9 +1,9 @@
 {
   "url": "https://github.com/NixOS/nixpkgs",
-  "rev": "0cfd08f4881bbfdaa57e68835b923d4290588d98",
-  "date": "2021-01-08T17:43:56+01:00",
-  "path": "/nix/store/c3rhsa326ylk4hm146nmfrfmxcpqflyb-nixpkgs",
-  "sha256": "1srd9p37jmrsxgvrxvlibmscphz5p42244285yc5piacvrz1rdcc",
+  "rev": "a058d005b3cbb370bf171ebce01839dd6ff52222",
+  "date": "2021-01-23T17:41:51-05:00",
+  "path": "/nix/store/6ps307ghgrp10q3mwgw4lq143pmz0h25-nixpkgs",
+  "sha256": "154mpqw0ya31hzgz9hggg1rb26yx8d00rsj9l90ndsdldrssgvbb",
   "fetchSubmodules": false,
   "deepClone": false,
   "leaveDotGit": false
diff --git a/lass/1systems/archprism/config.nix b/lass/1systems/archprism/config.nix
deleted file mode 100644
index 0a2ab1611..000000000
--- a/lass/1systems/archprism/config.nix
+++ /dev/null
@@ -1,54 +0,0 @@
-{ config, lib, pkgs, ... }:
-with import <stockholm/lib>;
-
-{
-  imports = [
-    <stockholm/lass>
-    <stockholm/lass/2configs/retiolum.nix>
-    <stockholm/lass/2configs/libvirt.nix>
-    { # TODO make new hfos.nix out of this vv
-      boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
-      users.users.riot = {
-        uid = genid_uint31 "riot";
-        isNormalUser = true;
-        extraGroups = [ "libvirtd" ];
-        openssh.authorizedKeys.keys = [
-          "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6o6sdTu/CX1LW2Ff5bNDqGEAGwAsjf0iIe5DCdC7YikCct+7x4LTXxY+nDlPMeGcOF88X9/qFwdyh+9E4g0nUAZaeL14Uc14QDqDt/aiKjIXXTepxE/i4JD9YbTqStAnA/HYAExU15yqgUdj2dnHu7OZcGxk0ZR1OY18yclXq7Rq0Fd3pN3lPP1T4QHM9w66r83yJdFV9szvu5ral3/QuxQnCNohTkR6LoJ4Ny2RbMPTRtb+jPbTQYTWUWwV69mB8ot5nRTP4MRM9pu7vnoPF4I2S5DvSnx4C5zdKzsb7zmIvD4AmptZLrXj4UXUf00Xf7Js5W100Ne2yhYyhq+35 riot@lagrange"
-        ];
-      };
-
-      # TODO write function for proxy_pass (ssl/nonssl)
-
-      krebs.iptables.tables.filter.FORWARD.rules = [
-        { v6 = false; precedence = 1000; predicate = "-d 192.168.122.179"; target = "ACCEPT"; }
-      ];
-      krebs.iptables.tables.nat.PREROUTING.rules = [
-        { v6 = false; precedence = 1000; predicate = "-d 46.4.114.243"; target = "DNAT --to-destination 192.168.122.179"; }
-      ];
-    }
-    <stockholm/lass/2configs/container-networking.nix>
-    {
-      services.taskserver = {
-        enable = true;
-        fqdn = "lassul.us";
-        listenHost = "::";
-        listenPort = 53589;
-        organisations.lass.users = [ "lass" "android" ];
-      };
-      krebs.iptables.tables.filter.INPUT.rules = [
-        { predicate = "-p tcp --dport 53589"; target = "ACCEPT"; }
-      ];
-    }
-    {
-      krebs.iptables.tables.filter.INPUT.rules = [
-        { predicate = "-p udp --dport 60000:61000"; target = "ACCEPT";}
-      ];
-    }
-  ];
-
-  krebs.build.host = config.krebs.hosts.archprism;
-  services.earlyoom = {
-    enable = true;
-    freeMemThreshold = 5;
-  };
-}
diff --git a/lass/1systems/archprism/physical.nix b/lass/1systems/archprism/physical.nix
deleted file mode 100644
index 36de7dc17..000000000
--- a/lass/1systems/archprism/physical.nix
+++ /dev/null
@@ -1,77 +0,0 @@
-{ config, lib, pkgs, ... }:
-{
-  imports = [
-    ./config.nix
-    {
-      boot.kernelParams = [ "net.ifnames=0" ];
-      networking = {
-        defaultGateway = "46.4.114.225";
-        # Use google's public DNS server
-        nameservers = [ "8.8.8.8" ];
-        interfaces.eth0 = {
-          ipAddress = "46.4.114.247";
-          prefixLength = 27;
-        };
-      };
-      # TODO use this network config
-      networking.interfaces.eth0.ipv4.addresses = [
-        {
-          address = config.krebs.build.host.nets.internet.ip4.addr;
-          prefixLength = 27;
-        }
-        {
-          address = "46.4.114.243";
-          prefixLength = 27;
-        }
-      ];
-      #networking.defaultGateway = "46.4.114.225";
-      #networking.nameservers = [
-      #  "8.8.8.8"
-      #];
-      #services.udev.extraRules = ''
-      #  SUBSYSTEM=="net", ATTR{address}=="08:60:6e:e7:87:04", NAME="et0"
-      #'';
-    }
-    {
-      imports = [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix> ];
-
-      networking.hostId = "fb4173ea";
-      boot.loader.grub = {
-        devices = [
-          "/dev/sda"
-          "/dev/sdb"
-        ];
-        splashImage = null;
-      };
-
-      boot.initrd.availableKernelModules = [
-        "ata_piix"
-        "vmw_pvscsi"
-        "ahci" "sd_mod"
-      ];
-
-      boot.kernelModules = [ "kvm-intel" ];
-
-      sound.enable = false;
-      nixpkgs.config.allowUnfree = true;
-      time.timeZone = "Europe/Berlin";
-
-      fileSystems."/" = {
-        device = "rpool/root/nixos";
-        fsType = "zfs";
-      };
-
-      fileSystems."/home" = {
-        device = "rpool/home";
-        fsType = "zfs";
-      };
-
-      fileSystems."/boot" = {
-        device = "/dev/disk/by-uuid/b67c3370-1597-4ce8-8a46-e257ca32150d";
-        fsType = "ext4";
-      };
-
-    }
-  ];
-
-}
diff --git a/lass/1systems/blue/config.nix b/lass/1systems/blue/config.nix
index f6dc23d20..c4286cca3 100644
--- a/lass/1systems/blue/config.nix
+++ b/lass/1systems/blue/config.nix
@@ -9,8 +9,8 @@ with import <stockholm/lib>;
 
     <stockholm/lass/2configs/blue.nix>
     <stockholm/lass/2configs/syncthing.nix>
+    <stockholm/lass/2configs/sync/sync.nix>
     <stockholm/lass/2configs/sync/decsync.nix>
-    <stockholm/lass/2configs/sync/weechat.nix>
   ];
 
   krebs.build.host = config.krebs.hosts.blue;
diff --git a/lass/1systems/daedalus/config.nix b/lass/1systems/daedalus/config.nix
index bd559944a..d84502b3f 100644
--- a/lass/1systems/daedalus/config.nix
+++ b/lass/1systems/daedalus/config.nix
@@ -6,7 +6,6 @@ with import <stockholm/lib>;
     <stockholm/lass>
 
     <stockholm/lass/2configs/retiolum.nix>
-    <stockholm/lass/2configs/backup.nix>
     <stockholm/lass/2configs/nfs-dl.nix>
     {
       # bubsy config
diff --git a/lass/1systems/green/config.nix b/lass/1systems/green/config.nix
index 0b4b50ee4..fbd2d223f 100644
--- a/lass/1systems/green/config.nix
+++ b/lass/1systems/green/config.nix
@@ -9,13 +9,80 @@ with import <stockholm/lib>;
     <stockholm/lass/2configs/mail.nix>
 
     <stockholm/lass/2configs/syncthing.nix>
+    <stockholm/lass/2configs/sync/sync.nix>
     <stockholm/lass/2configs/sync/decsync.nix>
     <stockholm/lass/2configs/sync/weechat.nix>
+
+    <stockholm/lass/2configs/bitlbee.nix>
+    <stockholm/lass/2configs/IM.nix>
+    <stockholm/lass/2configs/muchsync.nix>
+    <stockholm/lass/2configs/pass.nix>
   ];
 
   krebs.build.host = config.krebs.hosts.green;
 
-  #networking.nameservers = [ "1.1.1.1" ];
+  users.users.mainUser.openssh.authorizedKeys.keys = [
+    config.krebs.users.lass-android.pubkey
+    "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICMe23IAHn4Ow4J4i8M9GJshqvY80U11NKPLum6b1XLn" # weechat ssh tunnel
+  ];
 
-  #time.timeZone = "Europe/Berlin";
+  krebs.bindfs = {
+    "/home/lass/.weechat" = {
+      source = "/var/state/lass_weechat";
+      options = [
+        "-M ${concatMapStringsSep ":" (u: toString config.users.users.${u}.uid) [ "syncthing" "mainUser" ]}"
+        "--create-for-user=${toString config.users.users.syncthing.uid}"
+      ];
+    };
+    "/home/lass/Maildir" = {
+      source = "/var/state/lass_mail";
+      options = [
+        "-M ${toString config.users.users.mainUser.uid}"
+      ];
+    };
+    "/home/lass/sync" = {
+      source = "/var/state/lass_sync";
+      options = [
+        "-M ${concatMapStringsSep ":" (u: toString config.users.users.${u}.uid) [ "syncthing" "mainUser" ]}"
+        "--create-for-user=${toString config.users.users.syncthing.uid}"
+      ];
+    };
+    "/var/lib/bitlbee" = {
+      source = "/var/state/bitlbee";
+      options = [
+        "-M ${toString config.users.users.bitlbee.uid}"
+      ];
+      clearTarget = true;
+    };
+    "/home/lass/.ssh" = {
+      source = "/var/state/lass_ssh";
+      options = [
+        "-M ${toString config.users.users.mainUser.uid}"
+      ];
+      clearTarget = true;
+    };
+    "/home/lass/.gnupg" = {
+      source = "/var/state/lass_gnupg";
+      options = [
+        "-M ${toString config.users.users.mainUser.uid}"
+      ];
+      clearTarget = true;
+    };
+  };
+
+  systemd.services."bindfs-_home_lass_Maildir".serviceConfig.ExecStartPost = pkgs.writeDash "symlink-notmuch" ''
+    sleep 1
+    mkdir -p /home/lass/notmuch
+    chown lass: /home/lass/notmuch
+    ln -sfTr /home/lass/notmuch /home/lass/Maildir/.notmuch
+
+    mkdir -p /home/lass/notmuch/muchsync
+    chown lass: /home/lass/notmuch/muchsync
+    mkdir -p /home/lass/Maildir/.muchsync
+    ln -sfTr /home/lass/Maildir/.muchsync /home/lass/notmuch/muchsync/tmp
+  '';
+
+  krebs.iptables.tables.nat.PREROUTING.rules = [
+    { predicate = "-i eth0 -p tcp -m tcp --dport 22"; target = "ACCEPT"; precedence = 101; }
+  ];
 }
diff --git a/lass/1systems/icarus/physical.nix b/lass/1systems/icarus/physical.nix
index bd74c29f3..837872bf5 100644
--- a/lass/1systems/icarus/physical.nix
+++ b/lass/1systems/icarus/physical.nix
@@ -51,12 +51,10 @@
     (1,     48,     60)
     (2,     50,     61)
     (3,     52,     63)
-    (6,     60,     65)
-    (7,     80,     85)
-    (127,   90,     32767)
+    (6,     60,     85)
+    (7,     80,     90)
+    (127,   89,     32767)
   '';
 
   services.logind.lidSwitch = "ignore";
-  services.logind.lidSwitchDocked = "ignore";
-
 }
diff --git a/lass/1systems/littleT/config.nix b/lass/1systems/littleT/config.nix
index eee23ee60..adf8aeeb1 100644
--- a/lass/1systems/littleT/config.nix
+++ b/lass/1systems/littleT/config.nix
@@ -7,6 +7,7 @@ with import <stockholm/lib>;
 
     <stockholm/lass/2configs/retiolum.nix>
     <stockholm/lass/2configs/blue-host.nix>
+    <stockholm/lass/2configs/green-host.nix>
     <stockholm/lass/2configs/syncthing.nix>
   ];
 
diff --git a/lass/1systems/morpheus/config.nix b/lass/1systems/morpheus/config.nix
index 79fbe4c97..79d4f528d 100644
--- a/lass/1systems/morpheus/config.nix
+++ b/lass/1systems/morpheus/config.nix
@@ -4,6 +4,9 @@ with import <stockholm/lib>;
   imports = [
     <stockholm/lass>
     <stockholm/lass/2configs/retiolum.nix>
+
+    <stockholm/lass/2configs/syncthing.nix>
+    <stockholm/lass/2configs/green-host.nix>
   ];
 
   krebs.build.host = config.krebs.hosts.morpheus;
diff --git a/lass/1systems/mors/config.nix b/lass/1systems/mors/config.nix
index b03d95c49..95b688590 100644
--- a/lass/1systems/mors/config.nix
+++ b/lass/1systems/mors/config.nix
@@ -18,28 +18,28 @@ with import <stockholm/lib>;
     <stockholm/lass/2configs/steam.nix>
     <stockholm/lass/2configs/wine.nix>
     <stockholm/lass/2configs/git.nix>
-    <stockholm/lass/2configs/virtualbox.nix>
     <stockholm/lass/2configs/fetchWallpaper.nix>
     <stockholm/lass/2configs/mail.nix>
     <stockholm/krebs/2configs/ircd.nix>
     <stockholm/lass/2configs/logf.nix>
     <stockholm/lass/2configs/syncthing.nix>
-    <stockholm/lass/2configs/otp-ssh.nix>
-    <stockholm/lass/2configs/c-base.nix>
+    <stockholm/lass/2configs/sync/sync.nix>
     <stockholm/lass/2configs/sync/decsync.nix>
     <stockholm/lass/2configs/sync/weechat.nix>
+    #<stockholm/lass/2configs/c-base.nix>
     <stockholm/lass/2configs/br.nix>
     <stockholm/lass/2configs/ableton.nix>
-    <stockholm/lass/2configs/starcraft.nix>
     <stockholm/lass/2configs/dunst.nix>
     <stockholm/lass/2configs/rtl-sdr.nix>
-    <stockholm/lass/2configs/backup.nix>
     <stockholm/lass/2configs/print.nix>
-    <stockholm/lass/2configs/blue-host.nix>
     <stockholm/lass/2configs/network-manager.nix>
     <stockholm/lass/2configs/nfs-dl.nix>
-    #<stockholm/lass/2configs/hardening.nix>
-    <stockholm/lass/2configs/ppp.nix>
+    <stockholm/lass/2configs/green-host.nix>
+    <stockholm/krebs/2configs/news-host.nix>
+    <stockholm/lass/2configs/ppp/x220-modem.nix>
+    <stockholm/lass/2configs/ppp/umts-stick.nix>
+    # <stockholm/lass/2configs/remote-builder/morpheus.nix>
+    # <stockholm/lass/2configs/remote-builder/prism.nix>
     {
       krebs.iptables.tables.filter.INPUT.rules = [
         #risk of rain
diff --git a/lass/1systems/prism/config.nix b/lass/1systems/prism/config.nix
index f63c6a05a..6f61ea57e 100644
--- a/lass/1systems/prism/config.nix
+++ b/lass/1systems/prism/config.nix
@@ -118,6 +118,7 @@ with import <stockholm/lib>;
     <stockholm/lass/2configs/iodined.nix>
     <stockholm/lass/2configs/paste.nix>
     <stockholm/lass/2configs/syncthing.nix>
+    <stockholm/lass/2configs/green-host.nix>
     <stockholm/lass/2configs/reaktor-coders.nix>
     <stockholm/lass/2configs/ciko.nix>
     <stockholm/lass/2configs/container-networking.nix>
@@ -137,23 +138,18 @@ with import <stockholm/lib>;
         enable = true;
       };
     }
-    {
-      lass.ejabberd = {
-        enable = true;
-        hosts = [ "lassul.us" ];
-      };
-      krebs.iptables.tables.filter.INPUT.rules = [
-        { predicate = "-p tcp --dport xmpp-client"; target = "ACCEPT"; }
-        { predicate = "-p tcp --dport xmpp-server"; target = "ACCEPT"; }
-      ];
-    }
     {
       imports = [
         <stockholm/lass/2configs/realwallpaper.nix>
       ];
-      services.nginx.virtualHosts."lassul.us".locations."= /wallpaper.png".extraConfig = ''
-        alias /var/realwallpaper/realwallpaper.png;
-      '';
+      services.nginx.virtualHosts."lassul.us".locations = {
+        "= /wallpaper-marker.png".extraConfig = ''
+          alias /var/realwallpaper/realwallpaper-marker.png;
+        '';
+        "= /wallpaper.png".extraConfig = ''
+          alias /var/realwallpaper/realwallpaper.png;
+        '';
+      };
     }
     {
       users.users.jeschli = {
@@ -282,8 +278,9 @@ with import <stockholm/lib>;
       services.murmur = {
         enable = true;
         bandwidth = 10000000;
+        registerName = "lassul.us";
+        autobanTime = 30;
       };
-      services.murmur.registerName = "lassul.us";
       krebs.iptables.tables.filter.INPUT.rules = [
         { predicate = "-p tcp --dport 64738"; target = "ACCEPT";}
         { predicate = "-p udp --dport 64738"; target = "ACCEPT";}
@@ -354,6 +351,8 @@ with import <stockholm/lib>;
             palo.pubkey
             "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDB0d0JA20Vqn7I4lCte6Ne2EOmLZyMJyS9yIKJYXNLjbLwkQ4AYoQKantPBkTxR75M09E7d3j5heuWnCjWH45TrfQfe1EOSSC3ppCI6C6aIVlaNs+KhAYZS0m2Y8WkKn+TT5JLEa8yybYVN/RlZPOilpj/1QgjU6CQK+eJ1k/kK+QFXcwN82GDVh5kbTVcKUNp2tiyxFA+z9LY0xFDg/JHif2ROpjJVLQBJ+YPuOXZN5LDnVcuyLWKThjxy5srQ8iDjoxBg7dwLHjby5Mv41K4W61Gq6xM53gDEgfXk4cQhJnmx7jA/pUnsn2ZQDeww3hcc7vRf8soogXXz2KC9maiq0M/svaATsa9Ul4hrKnqPZP9Q8ScSEAUX+VI+x54iWrnW0p/yqBiRAzwsczdPzaQroUFTBxrq8R/n5TFdSHRMX7fYNOeVMjhfNca/gtfw9dYBVquCvuqUuFiRc0I7yK44rrMjjVQRcAbw6F8O7+04qWCmaJ8MPlmApwu2c05VMv9hiJo5p6PnzterRSLCqF6rIdhSnuOwrUIt1s/V+EEZXHCwSaNLaQJnYL0H9YjaIuGz4c8kVzxw4c0B6nl+hqW5y5/B2cuHiumnlRIDKOIzlv8ufhh21iN7QpIsPizahPezGoT1XqvzeXfH4qryo8O4yTN/PWoA+f7o9POU7L6hQ== lhebendanz@nixos"
             "AAAAB3NzaC1yc2EAAAADAQABAAABgQC4ECL9NSCWqs4KVe+FF+2BPtl5Bv5aQPHqnXllCyiESZykwRKLx6/AbF5SbUAUMVZtp9oDSdp28m3BvVeWJ/q7hAbIxUtfd/jp+JBRZ8Kj6K5GzUO7Bhgl/o0A7xEjAeOKHiYuLjdPMcFUyl6Ah4ey/mcQYf6AdU0+hYUDeUlKe/YxxYD6202W0GJq2xGdIqs/TbopT9iaX+sv0wdXDVfFY72nFqOUwJW3u6O2viKKRugrz/eo50Eo3ts7pYz/FpDXExrUvV9Vu/bQ34pa8nKgF3/AKQHgmzljNQSVZKyAV8OY0UFonjBMXCBg2tXtwfnlzdx2SyuQVv55x+0AuRKsi85G2xLpXu1A3921pseBTW6Q6kbYK9eqxAay2c/kNbwNqFnO+nCvQ6Ier/hvGddOtItMu96IuU2E7mPN6WgvM8/3fjJRFWnZxFxqu/k7iH+yYT8qwRgdiSqZc76qvkYEuabdk2itstTRY0A3SpI3hFMZDw/7bxgMZtqpfyoRk5s= philip@shiki11:15 <Profpatsch> AAAAB3NzaC1yc2EAAAADAQABAAABgQC4ECL9NSCWqs4KVe+FF+2BPtl5Bv5aQPHqnXllCyiESZykwRKLx6/AbF5SbUAUMVZtp9oDSdp28m3BvVeWJ/q7hAbIxUtfd/jp+JBRZ8Kj6K5GzUO7Bhgl/o0A7xEjAeOKHiYuLjdPMcFUyl6Ah4ey/mcQYf6AdU0+hYUDeUlKe/YxxYD6202W0GJq2xGdIqs/TbopT9iaX+sv0wdXDVfFY72nFqOUwJW3u6O2viKKRugrz/eo50Eo3ts7pYz/FpDXExrUvV9Vu/bQ34pa8nKgF3/AKQHgmzljNQSVZKyAV8OY0UFonjBMXCBg2tXtwfnlzdx2SyuQVv55x+0AuRKsi85G2xLpXu1A3921pseBTW6Q6kbYK9eqxAay2c/kNbwNqFnO+nCvQ6Ier/hvGddOtItMu96IuU2E7mPN6WgvM8/3fjJRFWnZxFxqu/k7iH+yYT8qwRgdiSqZc76qvkYEuabdk2itstTRY0A3SpI3hFMZDw/7bxgMZtqpfyoRk5s= philip@shiki"
+            mic92.pubkey
+            qubasa.pubkey
           ];
         };
       };
@@ -412,42 +411,6 @@ with import <stockholm/lib>;
         ];
       };
     }
-    { #macos mounting of yellow
-      krebs.iptables.tables.filter.INPUT.rules = [
-        { predicate = "-i wiregrill -p tcp --dport 139"; target = "ACCEPT"; }
-        { predicate = "-i wiregrill -p tcp --dport 445"; target = "ACCEPT"; }
-        { predicate = "-i wiregrill -p udp --dport 137"; target = "ACCEPT"; }
-        { predicate = "-i wiregrill -p udp --dport 138"; target = "ACCEPT"; }
-      ];
-      users.users.smbguest = {
-        name = "smbguest";
-        uid = config.ids.uids.smbguest;
-        description = "smb guest user";
-        home = "/home/share";
-        createHome = true;
-      };
-      services.samba = {
-        enable = true;
-        enableNmbd = true;
-        shares = {
-          download = {
-            path = "/var/download/finished";
-            "read only" = "yes";
-            browseable = "yes";
-            "guest ok" = "yes";
-          };
-        };
-        extraConfig = ''
-          guest account = smbguest
-          map to guest = bad user
-          # disable printing
-          load printers = no
-          printing = bsd
-          printcap name = /dev/null
-          disable spoolss = yes
-        '';
-      };
-    }
   ];
 
   krebs.build.host = config.krebs.hosts.prism;
diff --git a/lass/1systems/shodan/config.nix b/lass/1systems/shodan/config.nix
index 9e01396bc..7695e637b 100644
--- a/lass/1systems/shodan/config.nix
+++ b/lass/1systems/shodan/config.nix
@@ -13,19 +13,18 @@ with import <stockholm/lib>;
     <stockholm/lass/2configs/programs.nix>
     <stockholm/lass/2configs/wine.nix>
     <stockholm/lass/2configs/bitcoin.nix>
-    <stockholm/lass/2configs/backup.nix>
     <stockholm/lass/2configs/blue-host.nix>
+    <stockholm/lass/2configs/green-host.nix>
+    <stockholm/krebs/2configs/news-host.nix>
     <stockholm/lass/2configs/nfs-dl.nix>
-    <stockholm/lass/2configs/gg23.nix>
-    <stockholm/lass/2configs/hass>
-    <stockholm/lass/2configs/br.nix>
     <stockholm/lass/2configs/fetchWallpaper.nix>
     <stockholm/lass/2configs/home-media.nix>
+    <stockholm/lass/2configs/syncthing.nix>
+    <stockholm/lass/2configs/sync/sync.nix>
   ];
 
   krebs.build.host = config.krebs.hosts.shodan;
 
   services.logind.lidSwitch = "ignore";
   services.logind.lidSwitchDocked = "ignore";
-
 }
diff --git a/lass/1systems/skynet/config.nix b/lass/1systems/skynet/config.nix
index 507ccd14d..4da4dffb8 100644
--- a/lass/1systems/skynet/config.nix
+++ b/lass/1systems/skynet/config.nix
@@ -6,6 +6,7 @@ with import <stockholm/lib>;
 
     <stockholm/lass/2configs/retiolum.nix>
     <stockholm/lass/2configs/blue-host.nix>
+    <stockholm/lass/2configs/green-host.nix>
     <stockholm/lass/2configs/power-action.nix>
     <stockholm/lass/2configs/syncthing.nix>
     {
diff --git a/lass/1systems/styx/config.nix b/lass/1systems/styx/config.nix
index 4c3ae1411..016d1480f 100644
--- a/lass/1systems/styx/config.nix
+++ b/lass/1systems/styx/config.nix
@@ -12,14 +12,17 @@ with import <stockholm/lib>;
     <stockholm/lass/2configs/browsers.nix>
     <stockholm/lass/2configs/programs.nix>
     <stockholm/lass/2configs/nfs-dl.nix>
-    # <stockholm/lass/2configs/gg23.nix>
-    # <stockholm/lass/2configs/hass>
+    <stockholm/lass/2configs/gg23.nix>
+    <stockholm/lass/2configs/hass>
+    <stockholm/lass/2configs/green-host.nix>
+    <stockholm/krebs/2configs/news-host.nix>
     # <stockholm/lass/2configs/br.nix>
     <stockholm/lass/2configs/fetchWallpaper.nix>
     <stockholm/lass/2configs/home-media.nix>
-    # <stockholm/lass/2configs/syncthing.nix>
-    # <stockholm/lass/2configs/sync/sync.nix>
+    <stockholm/lass/2configs/syncthing.nix>
+    <stockholm/lass/2configs/sync/sync.nix>
     # <stockholm/lass/2configs/idc.nix>
+    <stockholm/lass/2configs/ppp/umts-stick.nix>
   ];
 
   krebs.build.host = config.krebs.hosts.styx;
@@ -27,6 +30,8 @@ with import <stockholm/lib>;
   krebs.iptables.tables.filter.INPUT.rules = [
     { predicate = "-p tcp --dport ${toString config.services.smokeping.port}"; target = "ACCEPT"; }
   ];
+  krebs.power-action.enable = mkForce false;
+
   services.smokeping = {
     enable = true;
     targetConfig = ''
diff --git a/lass/1systems/styx/physical.nix b/lass/1systems/styx/physical.nix
index a3899f87d..ae0cdf489 100644
--- a/lass/1systems/styx/physical.nix
+++ b/lass/1systems/styx/physical.nix
@@ -31,4 +31,9 @@
 
   nix.maxJobs = lib.mkDefault 4;
   powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
+
+  services.udev.extraRules = ''
+    SUBSYSTEM=="net", ATTR{address}=="3c:7c:3f:7e:e2:39", NAME="et0"
+    SUBSYSTEM=="net", ATTR{address}=="00:e0:4c:78:91:50", NAME="int0"
+  '';
 }
diff --git a/lass/1systems/xerxes/config.nix b/lass/1systems/xerxes/config.nix
index 8c4362865..22c80b4da 100644
--- a/lass/1systems/xerxes/config.nix
+++ b/lass/1systems/xerxes/config.nix
@@ -11,6 +11,7 @@
     <stockholm/lass/2configs/programs.nix>
     <stockholm/lass/2configs/network-manager.nix>
     <stockholm/lass/2configs/syncthing.nix>
+    <stockholm/lass/2configs/sync/sync.nix>
     <stockholm/lass/2configs/games.nix>
     <stockholm/lass/2configs/steam.nix>
     <stockholm/lass/2configs/wine.nix>
diff --git a/lass/1systems/yellow/config.nix b/lass/1systems/yellow/config.nix
index d400697d7..1afad003c 100644
--- a/lass/1systems/yellow/config.nix
+++ b/lass/1systems/yellow/config.nix
@@ -9,30 +9,21 @@ with import <stockholm/lib>;
 
   krebs.build.host = config.krebs.hosts.yellow;
 
-  system.activationScripts.downloadFolder = ''
-    mkdir -p /var/download
-    chown transmission:download /var/download
-    chown transmission:download /var/download/finished
-    chmod 775 /var/download
-  '';
-
-  users.users.download = { uid = genid "download"; };
   users.groups.download.members = [ "transmission" ];
-  users.users.transmission.group = mkForce "download";
 
   systemd.services.transmission.bindsTo = [ "openvpn-nordvpn.service" ];
   systemd.services.transmission.after = [ "openvpn-nordvpn.service" ];
-  systemd.services.transmission.postStart = ''
-    chmod 775 /var/download/finished
-  '';
   services.transmission = {
     enable = true;
+    group = "download";
+    downloadDirPermissions = "775";
     settings = {
       download-dir = "/var/download/finished";
       incomplete-dir = "/var/download/incoming";
       incomplete-dir-enable = true;
+      rpc-bind-address = "0.0.0.0";
       message-level = 1;
-      umask = "002";
+      umask = 18;
       rpc-whitelist-enabled = false;
       rpc-host-whitelist-enabled = false;
     };
@@ -172,7 +163,7 @@ with import <stockholm/lib>;
     client
     dev tun
     proto udp
-    remote 185.230.127.27 1194
+    remote 91.207.172.77 1194
     resolv-retry infinite
     remote-random
     nobind
@@ -195,6 +186,7 @@ with import <stockholm/lib>;
     fast-io
     cipher AES-256-CBC
     auth SHA512
+
     <ca>
     -----BEGIN CERTIFICATE-----
     MIIFCjCCAvKgAwIBAgIBATANBgkqhkiG9w0BAQ0FADA5MQswCQYDVQQGEwJQQTEQ
diff --git a/lass/2configs/IM.nix b/lass/2configs/IM.nix
new file mode 100644
index 000000000..b79af3b49
--- /dev/null
+++ b/lass/2configs/IM.nix
@@ -0,0 +1,45 @@
+with (import <stockholm/lib>);
+{ config, lib, pkgs, ... }:
+
+{
+  imports = [
+    ./bitlbee.nix
+  ];
+
+  systemd.services.chat = let
+    tmux = pkgs.writeDash "tmux" ''
+      exec ${pkgs.tmux}/bin/tmux -f ${pkgs.writeText "tmux.conf" ''
+        set-option -g prefix `
+        unbind-key C-b
+        bind ` send-prefix
+
+        set-option -g status off
+        set-option -g default-terminal screen-256color
+
+        #use session instead of windows
+        bind-key c new-session
+        bind-key p switch-client -p
+        bind-key n switch-client -n
+        bind-key C-s switch-client -l
+      ''} "$@"
+    '';
+  in {
+    description = "chat environment setup";
+    after = [ "network.target" ];
+    wantedBy = [ "multi-user.target" ];
+
+    restartIfChanged = false;
+
+    path = [
+      pkgs.rxvt_unicode.terminfo
+    ];
+
+    serviceConfig = {
+      User = "lass";
+      RemainAfterExit = true;
+      Type = "oneshot";
+      ExecStart = "${tmux} -2 new-session -d -s IM ${pkgs.weechat}/bin/weechat";
+      ExecStop = "${tmux} kill-session -t IM";
+    };
+  };
+}
diff --git a/lass/2configs/backup.nix b/lass/2configs/backup.nix
deleted file mode 100644
index f5c241785..000000000
--- a/lass/2configs/backup.nix
+++ /dev/null
@@ -1,14 +0,0 @@
-{ config, lib, ... }:
-with import <stockholm/lib>;
-
-{
-  users.users.backup = {
-    useDefaultShell = true;
-    home = "/backups";
-    createHome = true;
-    group = "syncthing";
-    openssh.authorizedKeys.keys = with config.krebs.hosts; [
-      blue.ssh.pubkey
-    ];
-  };
-}
diff --git a/lass/2configs/binary-cache/server.nix b/lass/2configs/binary-cache/server.nix
index 9b91035a8..101dd045f 100644
--- a/lass/2configs/binary-cache/server.nix
+++ b/lass/2configs/binary-cache/server.nix
@@ -6,6 +6,7 @@
   services.nix-serve = {
     enable = true;
     secretKeyFile = config.krebs.secret.files.nix-serve-key.path;
+    port = 5005;
   };
 
   systemd.services.nix-serve = {
diff --git a/lass/2configs/bitlbee.nix b/lass/2configs/bitlbee.nix
index 1220fa0cd..d8f1ae888 100644
--- a/lass/2configs/bitlbee.nix
+++ b/lass/2configs/bitlbee.nix
@@ -10,6 +10,10 @@ with (import <stockholm/lib>);
       pkgs.bitlbee-steam
       pkgs.bitlbee-discord
     ];
-    libpurple_plugins = [ pkgs.telegram-purple ];
+    libpurple_plugins = [
+      # pkgs.telegram-purple
+      pkgs.tdlib-purple
+      # pkgs.purple-gowhatsapp
+    ];
   };
 }
diff --git a/lass/2configs/browsers.nix b/lass/2configs/browsers.nix
index eafab400c..00a5d2db0 100644
--- a/lass/2configs/browsers.nix
+++ b/lass/2configs/browsers.nix
@@ -7,7 +7,6 @@
     enable = true;
     extensions = [
       "cjpalhdlnbpafiamejdnhcphjbkeiagm" # ublock origin
-      "ihlenndgcmojhcghmfjfneahoeklbjjh" #cVim
     ];
   };
 }
diff --git a/lass/2configs/codimd.nix b/lass/2configs/codimd.nix
index e55090de9..d29a65210 100644
--- a/lass/2configs/codimd.nix
+++ b/lass/2configs/codimd.nix
@@ -12,8 +12,9 @@ with import <stockholm/lib>;
     '';
   };
 
-  services.codimd = {
+  services.hedgedoc = {
     enable = true;
+    configuration.allowOrigin = [ "*" ];
     configuration = {
       db = {
         dialect = "sqlite";
diff --git a/lass/2configs/default.nix b/lass/2configs/default.nix
index 1cf421fed..7b6f01148 100644
--- a/lass/2configs/default.nix
+++ b/lass/2configs/default.nix
@@ -3,7 +3,6 @@ with import <stockholm/lib>;
 {
   imports = [
     ./binary-cache/client.nix
-    ./backup.nix
     ./gc.nix
     ./mc.nix
     ./vim.nix
@@ -22,6 +21,7 @@ with import <stockholm/lib>;
           openssh.authorizedKeys.keys = [
             config.krebs.users.lass-mors.pubkey
             config.krebs.users.lass-blue.pubkey
+            config.krebs.users.lass-green.pubkey
             config.krebs.users.lass-yubikey.pubkey
           ];
         };
@@ -40,6 +40,7 @@ with import <stockholm/lib>;
           openssh.authorizedKeys.keys = [
             config.krebs.users.lass-mors.pubkey
             config.krebs.users.lass-blue.pubkey
+            config.krebs.users.lass-green.pubkey
             config.krebs.users.lass-yubikey.pubkey
           ];
         };
diff --git a/lass/2configs/exim-retiolum.nix b/lass/2configs/exim-retiolum.nix
index 1ee8d843e..589e17551 100644
--- a/lass/2configs/exim-retiolum.nix
+++ b/lass/2configs/exim-retiolum.nix
@@ -3,7 +3,12 @@
 with import <stockholm/lib>;
 
 {
-  krebs.exim-retiolum.enable = true;
+  krebs.exim-retiolum = {
+    enable = true;
+    system-aliases = [
+      { from = "root"; to = "lass"; }
+    ];
+  };
   krebs.iptables.tables.filter.INPUT.rules = [
     { predicate = "-i retiolum -p tcp --dport smtp"; target = "ACCEPT"; }
   ];
diff --git a/lass/2configs/git.nix b/lass/2configs/git.nix
index edec2dcb4..e6aeca5d1 100644
--- a/lass/2configs/git.nix
+++ b/lass/2configs/git.nix
@@ -97,6 +97,10 @@ let
     populate = {
       cgit.section = "software";
     };
+    reaktor2 = {
+      cgit.desc = "irc bot";
+      cgit.section = "software";
+    };
     stockholm = {
       cgit.desc = "take all the computers hostage, they'll love you!";
       cgit.section = "configuration";
@@ -109,6 +113,10 @@ let
       cgit.desc = "Good Music collection + tools";
       cgit.section  = "art";
     };
+    workadventure-nix = {
+      cgit.desc = "Nix packaging for workadventure";
+      cgit.section = "deployment";
+    };
     xmonad-stockholm = {
       cgit.desc = "krebs xmonad modules";
       cgit.section = "configuration";
@@ -142,9 +150,6 @@ let
           nick = config.krebs.build.host.name;
           channel = "#xxx";
           # TODO define refs in some kind of option per repo
-          refs = [
-            "refs/heads/master"
-          ];
           server = "irc.r";
           verbose = config.krebs.build.host.name == "prism";
         }}
diff --git a/lass/2configs/green-host.nix b/lass/2configs/green-host.nix
index 1f17c78c8..355daba9c 100644
--- a/lass/2configs/green-host.nix
+++ b/lass/2configs/green-host.nix
@@ -4,16 +4,26 @@
     <stockholm/lass/2configs/container-networking.nix>
     <stockholm/lass/2configs/syncthing.nix>
   ];
-  lass.sync-containers.containers.green = {
+  krebs.sync-containers.containers.green = {
     peers = [
       "icarus"
       "shodan"
       "skynet"
       "mors"
+      "morpheus"
       "littleT"
+      "styx"
     ];
     hostIp = "10.233.2.15";
     localIp = "10.233.2.16";
     format = "ecryptfs";
   };
+
+  services.borgbackup.jobs.sync-green = {
+    encryption.mode = "none";
+    paths = "/var/lib/sync-containers/green/ecryptfs";
+    repo = "/var/lib/sync-containers/green/backup";
+    compression = "auto,lzma";
+    startAt = "daily";
+  };
 }
diff --git a/lass/2configs/hass/default.nix b/lass/2configs/hass/default.nix
index 78379ba1c..3cd6e0ebf 100644
--- a/lass/2configs/hass/default.nix
+++ b/lass/2configs/hass/default.nix
@@ -13,7 +13,9 @@ with import ./lib.nix { inherit lib; };
     { predicate = "-i int0 -p tcp --dport 1883"; target = "ACCEPT"; } # mosquitto
     { predicate = "-i docker0 -p tcp --dport 1883"; target = "ACCEPT"; } # mosquitto
     { predicate = "-i int0 -p tcp --dport 8123"; target = "ACCEPT"; } # hass
+    { predicate = "-i int0 -p tcp --dport 1337"; target = "ACCEPT"; } # hass
     { predicate = "-i retiolum -p tcp --dport 8123"; target = "ACCEPT"; } # hass
+    { predicate = "-i retiolum -p tcp --dport 1337"; target = "ACCEPT"; } # hass frontend
     { predicate = "-i wiregrill -p tcp --dport 8123"; target = "ACCEPT"; } # hass
   ];
 
@@ -47,6 +49,7 @@ with import ./lib.nix { inherit lib; };
     };
     config = {};
     sun.elevation = 66;
+    shopping_list = {};
     discovery = {};
     frontend = {};
     mqtt = {
@@ -81,7 +84,6 @@ with import ./lib.nix { inherit lib; };
       (tasmota_s20 "Stereo Anlage" "stereo")
     ];
     mobile_app = {};
-    hue = {};
     weather = [
       {
         platform = "openweathermap";
diff --git a/lass/2configs/hass/lib.nix b/lass/2configs/hass/lib.nix
index 9281a19ec..1f9f9945d 100644
--- a/lass/2configs/hass/lib.nix
+++ b/lass/2configs/hass/lib.nix
@@ -23,7 +23,7 @@ rec {
   };
 
   friendly_names =
-    lib.mapAttrs' (n: v: lib.nameValuePair "light.${v}_light" { friendly_name = "l.${n}"; }) lights //
+    lib.mapAttrs' (n: v: lib.nameValuePair "light.${v}" { friendly_name = "l.${n}"; }) lights //
     lib.mapAttrs' (n: v: lib.nameValuePair "binary_sensor.${v}_update_available" { friendly_name = "s.${n}_up"; }) switches.dimmer //
     lib.mapAttrs' (n: v: lib.nameValuePair "binary_sensor.${v}_update_available" { friendly_name = "i.${n}_up"; }) sensors.movement //
     lib.mapAttrs' (n: v: lib.nameValuePair "binary_sensor.${v}_update_available" { friendly_name = "l.${n}_up"; }) lights //
@@ -41,11 +41,11 @@ rec {
     lib.mapAttrs' (n: v: lib.nameValuePair "sensor.${v}_illuminance" { friendly_name = "i.${n}_lux"; }) sensors.movement //
     {};
 
-  detect_movement = sensor: light: delay:
+  detect_movement = name: sensor: light: delay:
   let
-    id = "${sensor}_${light}";
+    id = name;
     sensor_ = "binary_sensor.${sensor}_occupancy";
-    light_ = "light.${light}_light";
+    light_ = "light.${light}";
   in {
     input_boolean."${id}" = {
     };
@@ -71,7 +71,6 @@ rec {
       # }
       {
         alias = "movement reset timer ${id}";
-        hide_entity = true;
         trigger = {
           platform = "state";
           entity_id = sensor_;
@@ -87,7 +86,6 @@ rec {
       }
       {
         alias = "movement on ${id}";
-        # hide_entity = true;
         trigger = {
           platform = "state";
           entity_id = "binary_sensor.${sensor}_occupancy";
@@ -124,7 +122,6 @@ rec {
       }
       {
         alias = "movement off ${id}";
-        hide_entity = true;
         trigger = {
           platform = "state";
           entity_id = sensor_;
@@ -144,7 +141,6 @@ rec {
       }
       {
         alias = "movement override ${id}";
-        hide_entity = true;
         trigger = {
           platform = "state";
           entity_id = light_;
@@ -164,7 +160,6 @@ rec {
       }
       {
         alias = "movement expired ${id}";
-        hide_entity = true;
         trigger = {
           platform = "event";
           event_type = "timer.finished";
@@ -186,11 +181,10 @@ rec {
     ];
   };
 
-  lightswitch = switch: light: {
+  lightswitch = name: switch: light: {
     automation = [
       {
-        alias = "lightswitch ${switch} turn on light ${light}";
-        hide_entity = "true";
+        alias = "lightswitch ${name} turn on";
         trigger = {
           platform = "mqtt";
           topic = "zigbee/${switch}";
@@ -225,15 +219,14 @@ rec {
           {
             service = "light.turn_on";
             data_template = {
-              entity_id = "light.${light}_light";
+              entity_id = "light.${light}";
               brightness = "{{ trigger.payload_json.brightness }}";
             };
           }
         ];
       }
       {
-        alias = "lightswitch ${switch} turn off light ${light}";
-        hide_entity = "true";
+        alias = "lightswitch ${name} turn off";
         trigger = {
           platform = "mqtt";
           topic = "zigbee/${switch}";
@@ -254,7 +247,7 @@ rec {
         action = {
           service = "light.turn_off";
           data_template = {
-            entity_id = "light.${light}_light";
+            entity_id = "light.${light}";
           };
         };
       }
diff --git a/lass/2configs/hass/rooms/bett.nix b/lass/2configs/hass/rooms/bett.nix
index 48a1f72d7..026c5722c 100644
--- a/lass/2configs/hass/rooms/bett.nix
+++ b/lass/2configs/hass/rooms/bett.nix
@@ -3,7 +3,7 @@ with import ../lib.nix { inherit lib; };
 
 {
   services.home-assistant.config = lib.mkMerge [
-    (lightswitch switches.dimmer.bett lights.bett)
+    (lightswitch "bett" switches.dimmer.bett lights.bett)
   ];
 
   # lass.hass.love = {
diff --git a/lass/2configs/hass/rooms/essen.nix b/lass/2configs/hass/rooms/essen.nix
index eeb3d30d2..293935f65 100644
--- a/lass/2configs/hass/rooms/essen.nix
+++ b/lass/2configs/hass/rooms/essen.nix
@@ -3,7 +3,7 @@ with import ../lib.nix { inherit lib; };
 
 {
   services.home-assistant.config = lib.mkMerge [
-    (detect_movement sensors.movement.essen lights.essen 10)
-    (lightswitch switches.dimmer.essen lights.essen)
+    (detect_movement "essen" sensors.movement.essen lights.essen 70)
+    (lightswitch "essen" switches.dimmer.essen lights.essen)
   ];
 }
diff --git a/lass/2configs/hass/rooms/nass.nix b/lass/2configs/hass/rooms/nass.nix
index 7e6298738..b23ba86cd 100644
--- a/lass/2configs/hass/rooms/nass.nix
+++ b/lass/2configs/hass/rooms/nass.nix
@@ -3,8 +3,8 @@ with import ../lib.nix { inherit lib; };
 
 {
   services.home-assistant.config = lib.mkMerge [
-    (detect_movement sensors.movement.nass lights.nass 100)
-    (lightswitch switches.dimmer.nass lights.nass)
+    (detect_movement "nass" sensors.movement.nass lights.nass 100)
+    (lightswitch "nass" switches.dimmer.nass lights.nass)
   ];
 }
 
diff --git a/lass/2configs/mail.nix b/lass/2configs/mail.nix
index 98affdd83..4682865c6 100644
--- a/lass/2configs/mail.nix
+++ b/lass/2configs/mail.nix
@@ -21,6 +21,26 @@ let
     account default: prism
   '';
 
+  notmuch-config = pkgs.writeText "notmuch-config" ''
+    [database]
+    path=/home/lass/Maildir
+
+    [user]
+    name=lassulus
+    primary_email=lassulus@lassul.us
+    other_email=lass@mors.r;${concatStringsSep ";" (flatten (attrValues mailboxes))}
+
+    [new]
+    tags=unread;inbox;
+    ignore=
+
+    [search]
+    exclude_tags=deleted;spam;
+
+    [maildir]
+    synchronize_flags=true
+  '';
+
   msmtp = pkgs.writeBashBin "msmtp" ''
     ${pkgs.coreutils}/bin/tee >(${pkgs.notmuch}/bin/notmuch insert +sent) | \
       ${pkgs.msmtp}/bin/msmtp -C ${msmtprc} "$@"
@@ -207,7 +227,7 @@ let
     set sidebar_short_path
     set sidebar_folder_indent
     set sidebar_visible = yes
-    set sidebar_format = '%B%?F? [%F]?%* %?N?%N/? %?S?%S?'
+    set sidebar_format = '%D%?F? [%F]?%* %?N?%N/? %?S?%S?'
     set sidebar_width   = 20
     color sidebar_new yellow red
 
@@ -232,6 +252,7 @@ let
   };
 
 in {
+  environment.variables.NOTMUCH_CONFIG = toString notmuch-config;
   environment.systemPackages = [
     msmtp
     mutt
diff --git a/lass/2configs/muchsync.nix b/lass/2configs/muchsync.nix
new file mode 100644
index 000000000..b09bf579b
--- /dev/null
+++ b/lass/2configs/muchsync.nix
@@ -0,0 +1,40 @@
+with (import <stockholm/lib>);
+{ config, pkgs, ... }:
+
+{
+  systemd.services.muchsync = let
+    hosts = [
+      "mors.r"
+      "green.r"
+      "blue.r"
+    ];
+  in {
+    description = "sync mails";
+    environment = {
+      NOTMUCH_CONFIG = config.environment.variables.NOTMUCH_CONFIG;
+    };
+    after = [ "network.target" ];
+
+    restartIfChanged = false;
+
+    path = [
+      pkgs.notmuch
+      pkgs.openssh
+    ];
+
+    startAt = "*:*"; # run every minute
+    serviceConfig = {
+      User = "lass";
+      Type = "oneshot";
+      ExecStart = pkgs.writeDash "sync-mails" ''
+        set -euf
+
+        /run/current-system/sw/bin/nm-tag-init 2>/dev/null
+        ${concatMapStringsSep "\n" (host: ''
+          echo syncing ${host}:
+          ${pkgs.muchsync}/bin/muchsync -s 'ssh -CTaxq -o ConnectTimeout=4' --nonew lass@${host} || :
+        '') hosts}
+      '';
+    };
+  };
+}
diff --git a/lass/2configs/nfs-dl.nix b/lass/2configs/nfs-dl.nix
index 91b026455..eeab732ba 100644
--- a/lass/2configs/nfs-dl.nix
+++ b/lass/2configs/nfs-dl.nix
@@ -13,9 +13,9 @@
       "x-systemd.device-timeout=1"
       "x-systemd.idle-timeout=1min"
       "x-systemd.requires=retiolum.service"
-      "x-systemd.requires=wpa_supplicant.service"
       "user"
       "_netdev"
+      "soft"
     ];
   };
 }
diff --git a/lass/2configs/ppp/umts-stick.nix b/lass/2configs/ppp/umts-stick.nix
new file mode 100644
index 000000000..64551a2b3
--- /dev/null
+++ b/lass/2configs/ppp/umts-stick.nix
@@ -0,0 +1,33 @@
+{ pkgs, ... }: {
+
+  # usage: pppd call stick
+
+  environment.etc."ppp/peers/stick".text = ''
+    /dev/ttyUSB0
+    460800
+    crtscts
+    defaultroute
+    holdoff 10
+    lock
+    maxfail 0
+    noauth
+    nodetach
+    noipdefault
+    passive
+    persist
+    usepeerdns
+    connect "${pkgs.ppp}/bin/chat -f ${pkgs.writeText "default.chat" ''
+      ABORT "BUSY"
+      ABORT "NO CARRIER"
+      REPORT CONNECT
+      "" "ATDT*99#"
+      CONNECT
+    ''}"
+  '';
+
+  environment.systemPackages = [
+    pkgs.ppp
+  ];
+
+}
+
diff --git a/lass/2configs/ppp.nix b/lass/2configs/ppp/x220-modem.nix
similarity index 84%
rename from lass/2configs/ppp.nix
rename to lass/2configs/ppp/x220-modem.nix
index 9cc7568a5..d6facb724 100644
--- a/lass/2configs/ppp.nix
+++ b/lass/2configs/ppp/x220-modem.nix
@@ -1,8 +1,8 @@
 { pkgs, ... }: {
 
-  # usage: pppd call default
+  # usage: pppd call x220
 
-  environment.etc."ppp/peers/default".text = ''
+  environment.etc."ppp/peers/x220".text = ''
     /dev/ttyACM2
     921600
     crtscts
diff --git a/lass/2configs/radio.nix b/lass/2configs/radio.nix
index 8c95b535d..707cc8459 100644
--- a/lass/2configs/radio.nix
+++ b/lass/2configs/radio.nix
@@ -200,7 +200,7 @@ in {
         ${pkgs.mpc_cli}/bin/mpc idle player > /dev/null
         ${pkgs.mpc_cli}/bin/mpc current -f %file%
       done | while read track; do
-        listeners=$(${pkgs.iproute}/bin/ss -Hno state established '( sport = :8000 )' | wc -l)
+        listeners=$(${pkgs.iproute}/bin/ss -Hno state established 'sport = :8000' | wc -l)
         echo "$(date -Is)" "$track" | tee -a "$HISTORY_FILE"
         echo "$(tail -$LIMIT "$HISTORY_FILE")" > "$HISTORY_FILE"
         ${write_to_irc} "playing: $track listeners: $listeners"
@@ -275,7 +275,7 @@ in {
     user = {
       name = "radio";
     };
-    script = ''
+    script = ''. ${pkgs.writeDash "radio" ''
       case "$Method $Request_URI" in
         "GET /current")
           printf 'HTTP/1.1 200 OK\r\n'
@@ -303,7 +303,7 @@ in {
           exit
         ;;
       esac
-    '';
+    ''}'';
   };
 
   services.nginx = {
diff --git a/lass/2configs/realwallpaper.nix b/lass/2configs/realwallpaper.nix
index e0cb37f67..c3054d3af 100644
--- a/lass/2configs/realwallpaper.nix
+++ b/lass/2configs/realwallpaper.nix
@@ -28,6 +28,9 @@ in {
     locations."/realwallpaper-krebs.png".extraConfig = ''
       root /var/realwallpaper/;
     '';
+    locations."/realwallpaper-video.mp4".extraConfig = ''
+      root /var/realwallpaper/archive;
+    '';
   };
 
   krebs.iptables = {
diff --git a/lass/2configs/sync/sync.nix b/lass/2configs/sync/sync.nix
new file mode 100644
index 000000000..bee1d03ac
--- /dev/null
+++ b/lass/2configs/sync/sync.nix
@@ -0,0 +1,13 @@
+{
+  services.syncthing.declarative.folders."/home/lass/sync" = {
+    devices = [ "mors" "icarus" "xerxes" "shodan" "green" "blue" ];
+  };
+  krebs.permown."/home/lass/sync" = {
+    file-mode = "u+rw,g+rw";
+    owner = "lass";
+    group = "syncthing";
+    umask = "0002";
+    keepGoing = true;
+  };
+}
+
diff --git a/lass/2configs/sync/weechat.nix b/lass/2configs/sync/weechat.nix
index ccbfc75a1..7970f3081 100644
--- a/lass/2configs/sync/weechat.nix
+++ b/lass/2configs/sync/weechat.nix
@@ -1,5 +1,5 @@
 {
-  services.syncthing.declarative.folders."/home/lass/.weechat".devices = [ "blue" "green" "mors" ];
+  services.syncthing.declarative.folders."/home/lass/.weechat".devices = [ "green" "mors" ];
   krebs.permown."/home/lass/.weechat" = {
     owner = "lass";
     group = "syncthing";
diff --git a/lass/2configs/syncthing.nix b/lass/2configs/syncthing.nix
index 7758b860d..e288df68a 100644
--- a/lass/2configs/syncthing.nix
+++ b/lass/2configs/syncthing.nix
@@ -1,20 +1,11 @@
-{ config, pkgs, ... }: with import <stockholm/lib>; let
-  all_peers = filterAttrs (n: v: v.syncthing.id != null) config.krebs.hosts;
-  own_peers = filterAttrs (n: v: v.owner.name == "lass") all_peers;
-  mk_peers = mapAttrs (n: v: { id = v.syncthing.id; });
-in {
+{ config, pkgs, ... }: with import <stockholm/lib>;
+{
+  imports = [ <stockholm/krebs/2configs/syncthing.nix> ];
   services.syncthing = {
-    enable = true;
     group = "syncthing";
-    configDir = "/var/lib/syncthing";
     declarative = {
       key = toString <secrets/syncthing.key>;
       cert = toString <secrets/syncthing.cert>;
-      devices = mk_peers all_peers;
-      folders."/home/lass/sync" = {
-        devices = attrNames (filterAttrs (n: v: n != "phone") own_peers);
-        # ignorePerms = false;
-      };
     };
   };
   krebs.iptables.tables.filter.INPUT.rules = [
@@ -26,11 +17,5 @@ in {
     ${pkgs.coreutils}/bin/chmod a+x /home/lass
   '';
 
-  krebs.permown."/home/lass/sync" = {
-    file-mode = "u+rw,g+rw";
-    owner = "lass";
-    group = "syncthing";
-    umask = "0002";
-    keepGoing = true;
-  };
+  boot.kernel.sysctl."fs.inotify.max_user_watches" = 524288;
 }
diff --git a/lass/2configs/tv.nix b/lass/2configs/tv.nix
index 0ca1b340f..d49ed6125 100644
--- a/lass/2configs/tv.nix
+++ b/lass/2configs/tv.nix
@@ -8,6 +8,7 @@ nginxCfg = pkgs.writeText "nginx.conf" ''
     worker_connections  128;
   }
   error_log stderr info;
+
   http {
     client_body_temp_path /var/lib/rtmp/nginx_cache_client_body;
     proxy_temp_path /var/lib/rtmp/nginx_cache_proxy;
@@ -25,92 +26,6 @@ nginxCfg = pkgs.writeText "nginx.conf" ''
       location /stat {
         rtmp_stat all;
       }
-
-      location /hls {
-        # Serve HLS fragments
-        types {
-          application/vnd.apple.mpegurl m3u8;
-          video/mp2t ts;
-        }
-        root /var/lib/rtmp/tmp;
-        add_header Cache-Control no-cache;
-
-        # CORS setup
-        add_header 'Access-Control-Allow-Origin' '*' always;
-        add_header 'Access-Control-Expose-Headers' 'Content-Length';
-
-        # Allow CORS preflight requests
-        if ($request_method = 'OPTIONS') {
-          add_header 'Access-Control-Allow-Origin' '*';
-          add_header 'Access-Control-Max-Age' 1728000;
-          add_header 'Content-Type' 'text/plain charset=UTF-8';
-          add_header 'Content-Length' 0;
-          return 204;
-        }
-      }
-
-      location /dash {
-        # Serve DASH fragments
-        types {
-          application/dash+xml mpd;
-          video/mp4 mp4;
-        }
-        root /tmp;
-        add_header Cache-Control no-cache;
-
-        # CORS setup
-        add_header 'Access-Control-Allow-Origin' '*' always;
-        add_header 'Access-Control-Expose-Headers' 'Content-Length';
-
-        # Allow CORS preflight requests
-        if ($request_method = 'OPTIONS') {
-          add_header 'Access-Control-Allow-Origin' '*';
-          add_header 'Access-Control-Max-Age' 1728000;
-          add_header 'Content-Type' 'text/plain charset=UTF-8';
-          add_header 'Content-Length' 0;
-          return 204;
-        }
-      }
-
-      location "/dash.all.min.js" {
-        default_type "text/javascript";
-        alias ${pkgs.fetchurl {
-          url = "http://cdn.dashjs.org/v3.2.0/dash.all.min.js";
-          sha256 = "16f0b40gdqsnwqi01s5sz9f1q86dwzscgc3m701jd1sczygi481c";
-        }};
-      }
-
-      location /player {
-        default_type "text/html";
-        alias ${pkgs.writeText "player.html" ''
-          <!DOCTYPE html>
-          <html lang="en">
-            <head>
-              <meta charset="utf-8">
-              <title>lassulus livestream</title>
-            </head>
-            <body>
-              <div>
-                <video id="player" controls></video>
-                </video>
-              </div>
-              <script src="/dash.all.min.js"></script>
-              <script>
-                (function(){
-                  var url = "http://lassul.us:8080/dash/nixos.mpd";
-                  var player = dashjs.MediaPlayer().create();
-                  player.initialize(document.querySelector("#player"), url, true);
-                })();
-              </script>
-            </body>
-          </html>
-        ''};
-      }
-
-      location /records {
-        autoindex on;
-        root /var/lib/rtmp;
-      }
     }
   }
 
@@ -275,6 +190,5 @@ in {
 
   krebs.iptables.tables.filter.INPUT.rules = [
     { predicate = "-p tcp --dport 1935"; target = "ACCEPT"; }
-    { predicate = "-p tcp --dport 8080"; target = "ACCEPT"; }
   ];
 }
diff --git a/lass/2configs/websites/domsen.nix b/lass/2configs/websites/domsen.nix
index f3beb9eb9..c43c8c902 100644
--- a/lass/2configs/websites/domsen.nix
+++ b/lass/2configs/websites/domsen.nix
@@ -285,7 +285,6 @@ in {
     ];
   };
 
-  boot.kernel.sysctl."fs.inotify.max_user_watches" = "1048576";
   services.syncthing.declarative.folders = {
     domsen-backups = {
       path = "/backups/domsen";
diff --git a/lass/3modules/default.nix b/lass/3modules/default.nix
index 8bee08caa..1ce88b238 100644
--- a/lass/3modules/default.nix
+++ b/lass/3modules/default.nix
@@ -1,9 +1,7 @@
 _:
 {
   imports = [
-    ./bindfs.nix
     ./dnsmasq.nix
-    ./ejabberd
     ./folderPerms.nix
     ./hosts.nix
     ./klem.nix
@@ -13,7 +11,6 @@ _:
     ./pyload.nix
     ./restic.nix
     ./screenlock.nix
-    ./sync-containers.nix
     ./usershadow.nix
     ./xjail.nix
     ./autowifi.nix
diff --git a/lass/3modules/ejabberd/config.nix b/lass/3modules/ejabberd/config.nix
deleted file mode 100644
index 4630f25c1..000000000
--- a/lass/3modules/ejabberd/config.nix
+++ /dev/null
@@ -1,128 +0,0 @@
-with import <stockholm/lib>;
-{ config, ... }: let
-
-  # See https://github.com/processone/ejabberd/blob/master/ejabberd.yml.example
-
-  ciphers = concatStringsSep ":" [
-    "ECDHE-ECDSA-AES256-GCM-SHA384"
-    "ECDHE-RSA-AES256-GCM-SHA384"
-    "ECDHE-ECDSA-CHACHA20-POLY1305"
-    "ECDHE-RSA-CHACHA20-POLY1305"
-    "ECDHE-ECDSA-AES128-GCM-SHA256"
-    "ECDHE-RSA-AES128-GCM-SHA256"
-    "ECDHE-ECDSA-AES256-SHA384"
-    "ECDHE-RSA-AES256-SHA384"
-    "ECDHE-ECDSA-AES128-SHA256"
-    "ECDHE-RSA-AES128-SHA256"
-  ];
-
-  protocol_options = [
-    "no_sslv2"
-    "no_sslv3"
-    "no_tlsv1"
-    "no_tlsv1_10"
-  ];
-
-in /* yaml */ ''
-
-  access_rules:
-    announce:
-      - allow: admin
-    local:
-      - allow: local
-    configure:
-      - allow: admin
-    register:
-      - allow
-    s2s:
-      - allow
-    trusted_network:
-      - allow: loopback
-
-  acl:
-    local:
-      user_regexp: ""
-    loopback:
-      ip:
-        - "127.0.0.0/8"
-        - "::1/128"
-        - "::FFFF:127.0.0.1/128"
-
-  hosts: ${toJSON config.hosts}
-
-  language: "en"
-
-  listen:
-    -
-      port: 5222
-      ip: "::"
-      module: ejabberd_c2s
-      shaper: c2s_shaper
-      certfile: ${toJSON config.certfile.path}
-      ciphers: ${toJSON ciphers}
-      dhfile: ${toJSON config.dhfile.path}
-      protocol_options: ${toJSON protocol_options}
-      starttls: true
-      starttls_required: true
-      tls: false
-      tls_compression: false
-      max_stanza_size: 65536
-    -
-      port: 5269
-      ip: "::"
-      module: ejabberd_s2s_in
-      shaper: s2s_shaper
-      max_stanza_size: 131072
-
-  loglevel: 4
-
-  modules:
-    mod_adhoc: {}
-    mod_admin_extra: {}
-    mod_announce:
-      access: announce
-    mod_caps: {}
-    mod_carboncopy: {}
-    mod_client_state: {}
-    mod_configure: {}
-    mod_disco: {}
-    mod_echo: {}
-    mod_bosh: {}
-    mod_last: {}
-    mod_offline:
-      access_max_user_messages: max_user_offline_messages
-    mod_ping: {}
-    mod_privacy: {}
-    mod_private: {}
-    mod_register:
-      access_from: allow
-      access: register
-      # ip_access: trusted_network
-      registration_watchers: ${toJSON config.registration_watchers}
-    mod_roster: {}
-    mod_shared_roster: {}
-    mod_stats: {}
-    mod_time: {}
-    mod_vcard:
-      search: false
-    mod_version: {}
-    mod_http_api: {}
-
-  s2s_access: s2s
-  s2s_certfile: ${toJSON config.s2s_certfile.path}
-  s2s_ciphers: ${toJSON ciphers}
-  s2s_dhfile: ${toJSON config.dhfile.path}
-  s2s_protocol_options: ${toJSON protocol_options}
-  s2s_tls_compression: false
-  s2s_use_starttls: required
-
-  shaper_rules:
-    max_user_offline_messages:
-      - 5000: admin
-      - 100
-    max_user_sessions: 10
-    c2s_shaper:
-      - none: admin
-      - normal
-    s2s_shaper: fast
-''
diff --git a/lass/3modules/ejabberd/default.nix b/lass/3modules/ejabberd/default.nix
deleted file mode 100644
index 20a38d572..000000000
--- a/lass/3modules/ejabberd/default.nix
+++ /dev/null
@@ -1,103 +0,0 @@
-{ config, lib, pkgs, ... }@args: with import <stockholm/lib>; let
-  cfg = config.lass.ejabberd;
-
-  gen-dhparam = pkgs.writeDash "gen-dhparam" ''
-    set -efu
-    path=$1
-    bits=2048
-    # TODO regenerate dhfile after some time?
-    if ! test -e "$path"; then
-      ${pkgs.openssl}/bin/openssl dhparam "$bits" > "$path"
-    fi
-  '';
-
-in {
-  options.lass.ejabberd = {
-    enable = mkEnableOption "lass.ejabberd";
-    certfile = mkOption {
-      type = types.secret-file;
-      default = {
-        name = "ejabberd-certfile";
-        path = "${cfg.user.home}/ejabberd.pem";
-        owner = cfg.user;
-        source-path = "/var/lib/acme/lassul.us/full.pem";
-      };
-    };
-    dhfile = mkOption {
-      type = types.secret-file;
-      default = {
-        name = "ejabberd-dhfile";
-        path = "${cfg.user.home}/dhparams.pem";
-        owner = cfg.user;
-        source-path = "/dev/null";
-      };
-    };
-    hosts = mkOption {
-      type = with types; listOf str;
-    };
-    pkgs.ejabberdctl = mkOption {
-      type = types.package;
-      default = pkgs.writeDashBin "ejabberdctl" ''
-        exec ${pkgs.ejabberd}/bin/ejabberdctl \
-            --config ${toFile "ejabberd.yaml" (import ./config.nix {
-              inherit pkgs;
-              config = cfg;
-            })} \
-            --logs ${shell.escape cfg.user.home} \
-            --spool ${shell.escape cfg.user.home} \
-            "$@"
-      '';
-    };
-    registration_watchers = mkOption {
-      type = types.listOf types.str;
-      default = [
-        config.krebs.users.tv.mail
-      ];
-    };
-    s2s_certfile = mkOption {
-      type = types.secret-file;
-      default = cfg.certfile;
-    };
-    user = mkOption {
-      type = types.user;
-      default = {
-        name = "ejabberd";
-        home = "/var/ejabberd";
-      };
-    };
-  };
-  config = lib.mkIf cfg.enable {
-    environment.systemPackages = [ cfg.pkgs.ejabberdctl ];
-
-    krebs.secret.files = {
-      ejabberd-certfile = cfg.certfile;
-      ejabberd-s2s_certfile = cfg.s2s_certfile;
-    };
-
-    systemd.services.ejabberd = {
-      wantedBy = [ "multi-user.target" ];
-      after = [
-        config.krebs.secret.files.ejabberd-certfile.service
-        config.krebs.secret.files.ejabberd-s2s_certfile.service
-        "network.target"
-      ];
-      partOf = [
-        config.krebs.secret.files.ejabberd-certfile.service
-        config.krebs.secret.files.ejabberd-s2s_certfile.service
-      ];
-      serviceConfig = {
-        ExecStartPre = "${gen-dhparam} ${cfg.dhfile.path}";
-        ExecStart = "${cfg.pkgs.ejabberdctl}/bin/ejabberdctl foreground";
-        PermissionsStartOnly = true;
-        SyslogIdentifier = "ejabberd";
-        User = cfg.user.name;
-        TimeoutStartSec = 60;
-      };
-    };
-
-    users.users.${cfg.user.name} = {
-      inherit (cfg.user) home name uid;
-      createHome = true;
-    };
-  };
-}
diff --git a/lass/5pkgs/l-gen-secrets/default.nix b/lass/5pkgs/l-gen-secrets/default.nix
index 85b050644..6cf28c3c2 100644
--- a/lass/5pkgs/l-gen-secrets/default.nix
+++ b/lass/5pkgs/l-gen-secrets/default.nix
@@ -29,7 +29,7 @@ pkgs.writeDashBin "l-gen-secrets" ''
       nets = {
         retiolum = {
           ip4.addr = "10.243.0.changeme";
-          ip6.addr = "42:0:0:0:0:0:0:changeme";
+          ip6.addr = r6 "changeme";
           aliases = [
             "$HOSTNAME.r"
           ];
@@ -38,7 +38,7 @@ pkgs.writeDashBin "l-gen-secrets" ''
           ${"''"};
         };
         wiregrill = {
-          ip6.addr = (wip6 "changeme").address;
+          ip6.addr = w6 "changeme";
           aliases = [
             "$HOSTNAME.w"
           ];
diff --git a/lass/5pkgs/tdlib-purple/default.nix b/lass/5pkgs/tdlib-purple/default.nix
new file mode 100644
index 000000000..445839a4b
--- /dev/null
+++ b/lass/5pkgs/tdlib-purple/default.nix
@@ -0,0 +1,33 @@
+{ stdenv, fetchFromGitHub, cmake, tdlib, pidgin, libwebp, libtgvoip } :
+
+stdenv.mkDerivation rec {
+  pname = "tdlib-purple";
+  version = "0.7.6";
+
+  src = fetchFromGitHub {
+    owner = "ars3niy";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "1inamfzbrz0sy4y431jgwjfg6lz14a7c71khrg02481raxchhzzf";
+  };
+
+  cmakeFlags = [
+    "-Dtgvoip_INCLUDE_DIRS=${libtgvoip.dev}/include/tgvoip"
+  ];
+
+  nativeBuildInputs = [ cmake ];
+  buildInputs = [ pidgin tdlib libwebp libtgvoip ];
+
+  installPhase = ''
+    mkdir -p $out/lib/purple-2/
+    cp *.so $out/lib/purple-2/
+  '';
+
+  meta = with stdenv.lib; {
+    homepage = "https://github.com/ars3niy/tdlib-purple";
+    description = "New libpurple plugin for Telegram";
+    license = licenses.gpl2;
+    maintainers = [ maintainers.lassulus ];
+    platforms = platforms.linux;
+  };
+}