diff --git a/krebs/3modules/fetchWallpaper.nix b/krebs/3modules/fetchWallpaper.nix
index bd3d6d3b2..0adcec3d8 100644
--- a/krebs/3modules/fetchWallpaper.nix
+++ b/krebs/3modules/fetchWallpaper.nix
@@ -40,8 +40,7 @@ let
     };
   };
 
-  fetchWallpaperScript = pkgs.writeScript "fetchWallpaper" ''
-    #! ${pkgs.bash}/bin/bash
+  fetchWallpaperScript = pkgs.writeDash "fetchWallpaper" ''
     set -euf
 
     mkdir -p ${shell.escape cfg.stateDir}
diff --git a/krebs/3modules/iptables.nix b/krebs/3modules/iptables.nix
index 9596229de..4b99873a1 100644
--- a/krebs/3modules/iptables.nix
+++ b/krebs/3modules/iptables.nix
@@ -20,6 +20,7 @@ let
     flatten
     length
     hasAttr
+    hasPrefix
     mkEnableOption
     mkOption
     mkIf
@@ -123,7 +124,7 @@ let
 
       buildRule = tn: cn: rule:
         #target validation test:
-        assert (elem rule.target ([ "ACCEPT" "REJECT" "DROP" "QUEUE" "LOG" "RETURN" ] ++ (attrNames ts."${tn}")));
+        assert (elem rule.target ([ "ACCEPT" "REJECT" "DROP" "QUEUE" "LOG" "RETURN" ] ++ (attrNames ts."${tn}"))) || hasPrefix "REDIRECT" rule.target;
 
         #predicate validation test:
         #maybe use iptables-test
diff --git a/krebs/3modules/lass/default.nix b/krebs/3modules/lass/default.nix
index b4686894e..03e067f35 100644
--- a/krebs/3modules/lass/default.nix
+++ b/krebs/3modules/lass/default.nix
@@ -12,6 +12,7 @@ with config.krebs.lib;
           aliases = [
             "dishfire.internet"
           ];
+          ssh.port = 45621;
         };
         retiolum = {
           via = internet;
@@ -40,10 +41,11 @@ with config.krebs.lib;
       cores = 2;
       nets = rec {
         internet = {
-          ip4.addr = "162.252.241.33";
+          ip4.addr = "104.233.79.118";
           aliases = [
             "echelon.internet"
           ];
+          ssh.port = 45621;
         };
         retiolum = {
           via = internet;
@@ -79,6 +81,7 @@ with config.krebs.lib;
           aliases = [
             "prism.internet"
           ];
+          ssh.port = 45621;
         };
         retiolum = {
           via = internet;
@@ -143,6 +146,7 @@ with config.krebs.lib;
           aliases = [
             "cloudkrebs.internet"
           ];
+          ssh.port = 45621;
         };
         retiolum = {
           via = internet;
@@ -174,6 +178,7 @@ with config.krebs.lib;
         gg23 = {
           ip4.addr = "10.23.1.12";
           aliases = ["uriel.gg23"];
+          ssh.port = 45621;
         };
         retiolum = {
           ip4.addr = "10.243.81.176";
@@ -205,6 +210,7 @@ with config.krebs.lib;
         gg23 = {
           ip4.addr = "10.23.1.11";
           aliases = ["mors.gg23"];
+          ssh.port = 45621;
         };
         retiolum = {
           ip4.addr = "10.243.0.2";
@@ -257,21 +263,53 @@ with config.krebs.lib;
       ssh.privkey.path = <secrets/ssh.id_ed25519>;
       ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDWlIxkX41V55Yker8n4gErx2xcKpXFNKthhbP3+bTJ7";
     };
+    shodan = {
+      cores = 2;
+      nets = {
+        retiolum = {
+          ip4.addr = "10.243.0.4";
+          ip6.addr = "42:0:0:0:0:0:0:50d4";
+          aliases = [
+            "shodan.retiolum"
+            "shodan.r"
+            "cgit.shodan.retiolum"
+          ];
+          tinc.pubkey = ''
+            -----BEGIN RSA PUBLIC KEY-----
+            MIIBCgKCAQEA9bUSItw8rEu2Cm2+3IGHyRxopre9lqpFjZNG2QTnjXkZ97QlDesT
+            YYZgM2lBkYcDN3/LdGaFFKrQQSGiF90oXA2wFqPuIfycx+1+TENGCzF8pExwbTd7
+            ROSVnISbghXYDgr3TqkjpPmnM+piFKymMDBGhxWuy1bw1AUfvRzhQwPAvtjB4VvF
+            7AVN/Z9dAZ/LLmYfYq7fL8V7PzQNvR+f5DP6+Eubx0xCuyuo63bWuGgp3pqKupx4
+            xsixtMQPuqMBvOUo0SBCCPa9a+6I8dSwqAmKWM5BhmNlNCRDi37mH/m96av7SIiZ
+            V29hwypVnmLoJEFiDzPMCdiH9wJNpHuHuQIDAQAB
+            -----END RSA PUBLIC KEY-----
+          '';
+        };
+      };
+      secure = true;
+      ssh.privkey.path = <secrets/ssh.id_ed25519>;
+      ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC9vup68R0I+62FK+8LNtwM90V9P4ukBmU7G7d54wf4C";
+    };
 
   };
   users = {
     lass = {
-      pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAp83zynhIueJJsWlSEykVSBrrgBFKq38+vT8bRfa+csqyjZBl2SQFuCPo+Qbh49mwchpZRshBa9jQEIGqmXxv/PYdfBFQuOFgyUq9ZcTZUXqeynicg/SyOYFW86iiqYralIAkuGPfQ4howLPVyjTZtWeEeeEttom6p6LMY5Aumjz2em0FG0n9rRFY2fBzrdYAgk9C0N6ojCs/Gzknk9SGntA96MDqHJ1HXWFMfmwOLCnxtE5TY30MqSmkrJb7Fsejwjoqoe9Y/mCaR0LpG2cStC1+37GbHJNH0caCMaQCX8qdfgMVbWTVeFWtV6aWOaRgwLrPDYn4cHWQJqTfhtPrNQ== lass@mors";
       mail = "lass@mors.retiolum";
-      pgp.pubkeys.default = builtins.readFile ./default.pgp;
+      pubkey = builtins.readFile ./ssh/mors.rsa;
+      pgp.pubkeys.default = builtins.readFile ./pgp/mors.pgp;
     };
     lass-uriel = {
-      pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDExWuRcltGM2FqXO695nm6/QY3wU3r1bDTyCpMrLfUSym7TxcXDSmZSWcueexPXV6GENuUfjJPZswOdWqIo5u2AXw9t0aGvwEDmI6uJ7K5nzQOsXIneGMdYuoOaAzWI8pxZ4N+lIP1HsOYttIPDp8RwU6kyG+Ud8mnVHWSTO13C7xC9vePnDP6b+44nHS691Zj3X/Cq35Ls0ISC3EM17jreucdP62L3TKk2R4NCm3Sjqj+OYEv0LAqIpgqSw5FypTYQgNByxRcIcNDlri63Q1yVftUP1338UiUfxtraUu6cqa2CdsHQmtX5mTNWEluVWO3uUKTz9zla3rShC+d3qvr lass@uriel";
       mail = "lass@uriel.retiolum";
+      pubkey = builtins.readFile ./ssh/uriel.rsa;
     };
     lass-helios = {
-      pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDBOnMtgy5GH6R6tHp2ugy5QTe3gAGxh2CKsstSNSNAJwvWGiaWJkbNmgM8KlCWeq1GJBGa95kU4I2BDO5fJd7J9vqyrTGF1+sx0Nwj/ELKSNVxDoKVYiU09pTqSB3pi46i+E8N49y4/8aRhu4/7O2dSTH7OS3YoZpt2Soas+cYJYhQdZtYQAgPX5LOkTfQvPhGR8AzrrTvOUrHyTWaSBEELVZ088LrFT6ibXHcPhwXX7A5+YMS8LLr3KRstySWzJEmfVOJxuMhQJSH1Xiq4bLilVn9V4AK5pCOnlALSYf48SexsCqzBUKgISuncurIBbXtW9EkNTMX3jSKlSQ7WniGRlmzrBAJCh4VXJUZgXDf8hAaPckIRbLosbTnEAauWcfnIXLfvI+bYkURhfYKsWelM+MS6ihk+P2yr8rNT9w5iUVJGVypOXUp45PrFuPn6ayCpNRJzqPwCCPE7fFagzLs7wibIXlrhCnRALT5HHyExFFcQoGvIq/8o+Oia8mrTimb55IDLwkiYrG6I5DPXFPKsTC0hium9T3I8dC+M7n9GbwnLTUK2kWnoklD3HTab21xJTtbF98nQ94df7doqPFxL/jongeZCGMB+PJ+BdQTtHr7tCY0kN2GXpoHxz/2w8YEWTKHhWIUsD+Utf8pDkKQfCqlm7iR7byxL51gHL9Z3Q== lass@helios";
       mail = "lass@helios.retiolum";
+      pubkey = builtins.readFile ./ssh/helios.rsa;
+    };
+    lass-shodan = {
+      mail = "lass@shodan.retiolum";
+      pubkey = builtins.readFile ./ssh/shodan.rsa;
+      pgp.pubkeys.default = builtins.readFile ./pgp/shodan.pgp;
     };
   };
 }
diff --git a/krebs/3modules/lass/default.pgp b/krebs/3modules/lass/default.pgp
deleted file mode 100644
index 38e2fa8df..000000000
--- a/krebs/3modules/lass/default.pgp
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v2
-
-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
-It6jrzDh3+COSQ==
-=0gFT
------END PGP PUBLIC KEY BLOCK-----
diff --git a/krebs/3modules/lass/pgp/mors.pgp b/krebs/3modules/lass/pgp/mors.pgp
new file mode 100644
index 000000000..6d985f0e2
--- /dev/null
+++ b/krebs/3modules/lass/pgp/mors.pgp
@@ -0,0 +1,51 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2
+
+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
+=fgFG
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/krebs/3modules/lass/pgp/shodan.pgp b/krebs/3modules/lass/pgp/shodan.pgp
new file mode 100644
index 000000000..543b05b71
--- /dev/null
+++ b/krebs/3modules/lass/pgp/shodan.pgp
@@ -0,0 +1,30 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2
+
+mQENBFc/U8EBCADaPobNwlm8oI3cVtDhsdHpW7gyNTloqM1JdUPoJ30kS8xIbKfF
+U+UWEj+/G0hXg3jGpqsYKzCegLcZuvKrLuyWas3nFync/KeWjPpmQWh8h/AQ63gi
+6FjikRS9iDHEnUBqXXymG6JOo9NrGX7viWcPx+rQzvXOFxVYt1JJY+Ki30tSL+0l
+igJBJ+x2qndnlPZE9uyKjYC9+9NlZ04h5WOponTtgIddBlBPhIOAW+f5mBVeWuaK
+8wPBY2z98ZIclwdTohCpBRjs/EAEhN+2djSjyJti2TARceMKV2ZLRoUh6bNqj3xV
+Y4IkDe47dS8rRmH/xj+9odJjtlbFHDmtElcfABEBAAG0HWxhc3NAc2hvZGFuLnIg
+PGxhc3NAc2hvZGFuLnI+iQE3BBMBCAAhBQJXP1PBAhsDBQsJCAcCBhUICQoLAgQW
+AgMBAh4BAheAAAoJECOf1I8qjNLnWCsH/Rr70NVjCpqou5JRJqc9NMYJflH8qUSR
+xxYsVXaLjf1sa5X0qbq1u5EaYQGsdP7qKuLggoom7CGBhG3WZnfhuLi9y2IXAFo8
+RprBmrTmXgpXqm8IrcWMDJUEwhjUn+x1iCnGUfmbUpIdBIj8HsCfDUmg+WT0GflT
+9tfYR0v1vRzK6WWYEobP9abhZdjOHIS8cXDgFVREllKjjOcLzsB23I9g1nlvX3+W
+J7iliC4s1OGvcpw0MHl/1KRpSBXK3we0WTNZLIJXr8W+BvURYxhVfbvgjHuv6K0h
+J0a/me8nkh05pdRLLGL+C8eFjAXALnTIxgiVNGjtXBAR+/HN2//iG665AQ0EVz9T
+wQEIAMsxDQ3Y5SL2gI1EjEuCc6RyTSBmsna9g/wKjzUbcB9zpEN9i85NDRvvfGn6
+ihxI9Z1rvn8zr8MKu9OcZB2XEQDriHUcS4IxnZzdbUIKOtR+1BjZvMKupbw+KHag
+WoeUh+tfb50bEMy/Z6Mp5mLOyXMyyiGS3CHJ6sHUXTub6kuHQnAOqiMsqnegZMcS
+sF+NpSNoSngC060jgh7fl4T8M3Vuv9NKGu9+0J48QR+LFsKe/7LwRQ9HFSH4sPeD
+vQI1BEo4piXthwd6mUHCbish38H77PGO0kKHaJ0HkBu+3tKXP1JJdm9SiN+ypUIB
+FyfLpaWf6pcc/0QX6qE4gL00MI0AEQEAAYkBHwQYAQgACQUCVz9TwQIbDAAKCRAj
+n9SPKozS5w85B/4o2Zf7oLqjNmOu+YE0fNJmbGCETNotNnE/GToiejNAM9B/rYJe
+qjM9/kq0GJKVfKKrBGA0YQy9O847TVW26gPeiEgS7DO1Dl9YiLJJVzUGlOPijTIJ
+A3LmMCLU/M3+a/33HGjm7gYk+aRwqOwHeC+f1pder8InoC3ebWupfcQsWkwTVqZk
+lrLzoywjqQcdjAYFJp1c0ZxXyrgOS4dIGMU+o+DDCyK/ry9UGd3ZacMqDsyWO51A
+iXDMtvVsuxbIP5o3muF9kEX7hx4EF7+MzRI3FjYwlHLNw+v3OVhfOxuPSt71VOiC
+G2aT2z4sz8+qbOIIG3JX99osG6v683lvDUCW
+=s4OM
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/krebs/3modules/lass/ssh/helios.rsa b/krebs/3modules/lass/ssh/helios.rsa
new file mode 100644
index 000000000..c2a54b621
--- /dev/null
+++ b/krebs/3modules/lass/ssh/helios.rsa
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDBOnMtgy5GH6R6tHp2ugy5QTe3gAGxh2CKsstSNSNAJwvWGiaWJkbNmgM8KlCWeq1GJBGa95kU4I2BDO5fJd7J9vqyrTGF1+sx0Nwj/ELKSNVxDoKVYiU09pTqSB3pi46i+E8N49y4/8aRhu4/7O2dSTH7OS3YoZpt2Soas+cYJYhQdZtYQAgPX5LOkTfQvPhGR8AzrrTvOUrHyTWaSBEELVZ088LrFT6ibXHcPhwXX7A5+YMS8LLr3KRstySWzJEmfVOJxuMhQJSH1Xiq4bLilVn9V4AK5pCOnlALSYf48SexsCqzBUKgISuncurIBbXtW9EkNTMX3jSKlSQ7WniGRlmzrBAJCh4VXJUZgXDf8hAaPckIRbLosbTnEAauWcfnIXLfvI+bYkURhfYKsWelM+MS6ihk+P2yr8rNT9w5iUVJGVypOXUp45PrFuPn6ayCpNRJzqPwCCPE7fFagzLs7wibIXlrhCnRALT5HHyExFFcQoGvIq/8o+Oia8mrTimb55IDLwkiYrG6I5DPXFPKsTC0hium9T3I8dC+M7n9GbwnLTUK2kWnoklD3HTab21xJTtbF98nQ94df7doqPFxL/jongeZCGMB+PJ+BdQTtHr7tCY0kN2GXpoHxz/2w8YEWTKHhWIUsD+Utf8pDkKQfCqlm7iR7byxL51gHL9Z3Q== lass@helios
diff --git a/krebs/3modules/lass/ssh/mors.rsa b/krebs/3modules/lass/ssh/mors.rsa
new file mode 100644
index 000000000..172fd2dda
--- /dev/null
+++ b/krebs/3modules/lass/ssh/mors.rsa
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAp83zynhIueJJsWlSEykVSBrrgBFKq38+vT8bRfa+csqyjZBl2SQFuCPo+Qbh49mwchpZRshBa9jQEIGqmXxv/PYdfBFQuOFgyUq9ZcTZUXqeynicg/SyOYFW86iiqYralIAkuGPfQ4howLPVyjTZtWeEeeEttom6p6LMY5Aumjz2em0FG0n9rRFY2fBzrdYAgk9C0N6ojCs/Gzknk9SGntA96MDqHJ1HXWFMfmwOLCnxtE5TY30MqSmkrJb7Fsejwjoqoe9Y/mCaR0LpG2cStC1+37GbHJNH0caCMaQCX8qdfgMVbWTVeFWtV6aWOaRgwLrPDYn4cHWQJqTfhtPrNQ== lass@mors
diff --git a/krebs/3modules/lass/ssh/shodan.rsa b/krebs/3modules/lass/ssh/shodan.rsa
new file mode 100644
index 000000000..3ee08ad41
--- /dev/null
+++ b/krebs/3modules/lass/ssh/shodan.rsa
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDV+EscrUKgsu6iO94lJQ45o0t9QV88H7RrbLCsysgesQqiCbq0XNJKSrKI4T/o5dBNfoHMi4FSuPsF3YzffvMOWmdluHRBIhDJSDiFaraHr1zu7fHDO8gsUf/a3H3LPHtRRoXQFNsIK5NRLR35WpKt+zG6GK/WLBzb2N4MR3Ym5Qo2OepW3pgMWjjbmiUbGGiao9OWgx5tjjT8PLHIWdoEmJsaE5UnOWebqY+xfkWXMLdzMBPyEdCVwUO7X3Ip0Zk/BJFSqtIHBqQtp+njgeRwfkL2xabge3VGALAnQg5iYXzT8kfzIu/wfaoSdGkdPWxMo80KDiJJlpLj1oC3ABmDj01Hgu9p+g5Em0SFevcenspTii3IvYqdq+eg5+pPny4ki9748t6FlWRsrjrmjdQVVMWbhx42+lsyxIYsdXhwWMqNwTNzvY7Fxy3/8XE14pYWCV5eEll2/hSNfI6AcOoJ0vfHvOXsY6GVMYklXDIFzmiJOpyox+DnTahyUqQ6IcLH73vp9boVK31kf8EC7VDp8ms2ZiXz9nfPYltiUOtKKG0gqg9Jgs7xthpX82WYEp2+PXzPCHWs4WXs3OsUzQ8ykXXD2A7JMVBBv0FaMD4aBsOe7hU20/sO+/J/uuPe5xnpI//uFK4KkYCmDHZcZ3Qzh9CQTISwFvOBbYtRWbDo5w== lass@shodan
diff --git a/krebs/3modules/lass/ssh/uriel.rsa b/krebs/3modules/lass/ssh/uriel.rsa
new file mode 100644
index 000000000..015b57837
--- /dev/null
+++ b/krebs/3modules/lass/ssh/uriel.rsa
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDExWuRcltGM2FqXO695nm6/QY3wU3r1bDTyCpMrLfUSym7TxcXDSmZSWcueexPXV6GENuUfjJPZswOdWqIo5u2AXw9t0aGvwEDmI6uJ7K5nzQOsXIneGMdYuoOaAzWI8pxZ4N+lIP1HsOYttIPDp8RwU6kyG+Ud8mnVHWSTO13C7xC9vePnDP6b+44nHS691Zj3X/Cq35Ls0ISC3EM17jreucdP62L3TKk2R4NCm3Sjqj+OYEv0LAqIpgqSw5FypTYQgNByxRcIcNDlri63Q1yVftUP1338UiUfxtraUu6cqa2CdsHQmtX5mTNWEluVWO3uUKTz9zla3rShC+d3qvr lass@uriel
diff --git a/krebs/3modules/per-user.nix b/krebs/3modules/per-user.nix
index 13da5c4c3..93a7d2293 100644
--- a/krebs/3modules/per-user.nix
+++ b/krebs/3modules/per-user.nix
@@ -26,7 +26,10 @@ let
     environment = {
       etc = flip mapAttrs' cfg (name: { packages, ... }: {
         name = "per-user/${name}";
-        value.source = pkgs.symlinkJoin "per-user.${name}" packages;
+        value.source = pkgs.symlinkJoin {
+          name = "per-user.${name}";
+          paths = packages;
+        };
       });
       profiles = ["/etc/per-user/$LOGNAME"];
     };
diff --git a/krebs/5pkgs/default.nix b/krebs/5pkgs/default.nix
index bcc894b2c..c96e71538 100644
--- a/krebs/5pkgs/default.nix
+++ b/krebs/5pkgs/default.nix
@@ -36,6 +36,19 @@ with config.krebs.lib;
 
     ReaktorPlugins = callPackage ./Reaktor/plugins.nix {};
 
+    buildbot = callPackage <nixpkgs/pkgs/development/tools/build-managers/buildbot> {
+      inherit (pkgs.pythonPackages) twisted jinja2;
+      dateutil = pkgs.pythonPackages.dateutil_1_5;
+      sqlalchemy_migrate_0_7 = pkgs.pythonPackages.sqlalchemy_migrate_func (pkgs.pythonPackages.sqlalchemy7.override {
+        doCheck = false;
+      });
+    };
+
+    # XXX symlinkJoin changed arguments somewhere around nixpkgs d541e0d
+    symlinkJoin = { name, paths, ... }@args: let
+      x = pkgs.symlinkJoin args;
+    in if typeOf x != "lambda" then x else pkgs.symlinkJoin name paths;
+
     test = {
       infest-cac-centos7 = callPackage ./test/infest-cac-centos7 {};
     };
diff --git a/lass/1systems/cloudkrebs.nix b/lass/1systems/cloudkrebs.nix
index 6cfba567a..a3cc9d7b3 100644
--- a/lass/1systems/cloudkrebs.nix
+++ b/lass/1systems/cloudkrebs.nix
@@ -8,11 +8,13 @@ in {
   imports = [
     ../.
     ../2configs/os-templates/CAC-CentOS-7-64bit.nix
-    ../2configs/base.nix
+    ../2configs/default.nix
+    ../2configs/exim-retiolum.nix
     ../2configs/retiolum.nix
-    ../2configs/fastpoke-pages.nix
     ../2configs/git.nix
     ../2configs/realwallpaper.nix
+    ../2configs/realwallpaper-server.nix
+    ../2configs/privoxy-retiolum.nix
     {
       networking.interfaces.enp2s1.ip4 = [
         {
diff --git a/lass/1systems/dishfire.nix b/lass/1systems/dishfire.nix
index c7d016cd3..b5e551952 100644
--- a/lass/1systems/dishfire.nix
+++ b/lass/1systems/dishfire.nix
@@ -4,9 +4,9 @@
   imports = [
     ../.
     <nixpkgs/nixos/modules/profiles/qemu-guest.nix>
-    ../2configs/base.nix
+    ../2configs/default.nix
+    ../2configs/exim-retiolum.nix
     ../2configs/git.nix
-    ../2configs/websites/fritz.nix
     {
       boot.loader.grub = {
         device = "/dev/vda";
@@ -26,10 +26,19 @@
         fsType = "ext4";
       };
 
+      fileSystems."/srv/http" = {
+        device = "/dev/pool/srv_http";
+        fsType = "ext4";
+      };
+
       fileSystems."/boot" = {
         device = "/dev/vda1";
         fsType = "ext4";
       };
+      fileSystems."/bku" = {
+        device = "/dev/pool/bku";
+        fsType = "ext4";
+      };
     }
     {
       networking.dhcpcd.allowInterfaces = [
@@ -40,6 +49,20 @@
     {
       sound.enable = false;
     }
+    {
+      environment.systemPackages = with pkgs; [
+        mk_sql_pair
+      ];
+    }
+    {
+      imports = [
+        ../2configs/websites/fritz.nix
+      ];
+      krebs.iptables.tables.filter.INPUT.rules = [
+         { predicate = "-p tcp --dport http"; target = "ACCEPT"; }
+         { predicate = "-p tcp --dport https"; target = "ACCEPT"; }
+      ];
+    }
   ];
 
   krebs.build.host = config.krebs.hosts.dishfire;
diff --git a/lass/1systems/echelon.nix b/lass/1systems/echelon.nix
index 80611ee80..97734a7bd 100644
--- a/lass/1systems/echelon.nix
+++ b/lass/1systems/echelon.nix
@@ -8,7 +8,8 @@ in {
   imports = [
     ../.
     ../2configs/os-templates/CAC-CentOS-7-64bit.nix
-    ../2configs/base.nix
+    ../2configs/default.nix
+    ../2configs/exim-retiolum.nix
     ../2configs/retiolum.nix
     ../2configs/realwallpaper-server.nix
     ../2configs/privoxy-retiolum.nix
diff --git a/lass/1systems/helios.nix b/lass/1systems/helios.nix
index cc98c2c5b..10b00de47 100644
--- a/lass/1systems/helios.nix
+++ b/lass/1systems/helios.nix
@@ -5,10 +5,13 @@ with builtins;
   imports = [
     ../.
     ../2configs/baseX.nix
+    ../2configs/exim-retiolum.nix
     ../2configs/browsers.nix
     ../2configs/programs.nix
     ../2configs/git.nix
     ../2configs/pass.nix
+    ../2configs/fetchWallpaper.nix
+    ../2configs/backups.nix
     #{
     #  users.extraUsers = {
     #    root = {
@@ -52,6 +55,16 @@ with builtins;
     "/boot" = {
       device = "/dev/sda1";
     };
+
+    "/home" = {
+      device = "/dev/pool/home";
+      fsType = "ext4";
+    };
+
+    "/bku" = {
+      device = "/dev/pool/bku";
+      fsType = "ext4";
+    };
   };
 
   #services.udev.extraRules = ''
diff --git a/lass/1systems/mors.nix b/lass/1systems/mors.nix
index 1f7a13c56..e2ab562fa 100644
--- a/lass/1systems/mors.nix
+++ b/lass/1systems/mors.nix
@@ -4,6 +4,7 @@
   imports = [
     ../.
     ../2configs/baseX.nix
+    ../2configs/exim-retiolum.nix
     ../2configs/programs.nix
     ../2configs/bitcoin.nix
     ../2configs/browsers.nix
@@ -26,6 +27,8 @@
     ../2configs/libvirt.nix
     ../2configs/fetchWallpaper.nix
     ../2configs/cbase.nix
+    ../2configs/mail.nix
+    ../2configs/krebs-pass.nix
     #../2configs/buildbot-standalone.nix
     {
       #risk of rain port
@@ -33,124 +36,28 @@
         { predicate = "-p tcp --dport 11100"; target = "ACCEPT"; }
       ];
     }
-    {
-      #static-nginx-test
-      imports = [
-        ../3modules/static_nginx.nix
-      ];
-      lass.staticPage."testserver.de" = {
-        #sslEnable = true;
-        #certificate = "${toString <secrets>}/testserver.de/server.cert";
-        #certificate_key = "${toString <secrets>}/testserver.de/server.pem";
-        ssl = {
-          enable = true;
-          certificate = "${toString <secrets>}/testserver.de/server.cert";
-          certificate_key = "${toString <secrets>}/testserver.de/server.pem";
-        };
-      };
-      networking.extraHosts = ''
-        10.243.0.2 testserver.de
-      '';
-    }
     #{
-    #  #wordpress-test
-    #  #imports = singleton (sitesGenerators.createWordpress "testserver.de");
-    #  imports = [
-    #    ../3modules/wordpress_nginx.nix
-    #  ];
-    #  lass.wordpress."testserver.de" = {
-    #    multiSite = {
-    #      "1" = "testserver.de";
-    #      "2" = "bla.testserver.de";
-    #    };
-    #  };
-
     #  services.mysql = {
     #    enable = true;
     #    package = pkgs.mariadb;
     #    rootPassword = "<secrets>/mysql_rootPassword";
     #  };
-    #  networking.extraHosts = ''
-    #    10.243.0.2 testserver.de
-    #  '';
-    #  krebs.iptables.tables.filter.INPUT.rules = [
-    #    { predicate = "-i retiolum -p tcp --dport 80"; target = "ACCEPT"; precedence = 9998; }
-    #  ];
     #}
     #{
-    #  #owncloud-test
-    #  #imports = singleton (sitesGenerators.createWordpress "testserver.de");
-    #  imports = [
-    #    ../3modules/owncloud_nginx.nix
-    #  ];
-    #  lass.owncloud."owncloud-test.de" = {
+    #  services.elasticsearch = {
+    #    enable = true;
+    #    plugins = [
+    #    #  pkgs.elasticsearchPlugins.elasticsearch_kopf
+    #    ];
+    #  };
+    #}
+    #{
+    #  services.postgresql = {
+    #    enable = true;
+    #    package = pkgs.postgresql;
     #  };
-
-    #  #services.mysql = {
-    #  #  enable = true;
-    #  #  package = pkgs.mariadb;
-    #  #  rootPassword = "<secrets>/mysql_rootPassword";
-    #  #};
-    #  networking.extraHosts = ''
-    #    10.243.0.2 owncloud-test.de
-    #  '';
-    #  krebs.iptables.tables.filter.INPUT.rules = [
-    #    { predicate = "-i retiolum -p tcp --dport 80"; target = "ACCEPT"; precedence = 9998; }
-    #  ];
     #}
     {
-      containers.pythonenv = {
-        config = {
-          services.openssh.enable = true;
-          users.users.root.openssh.authorizedKeys.keys = [
-            config.krebs.users.lass.pubkey
-          ];
-
-          environment = {
-            systemPackages = with pkgs; [
-              git
-              libxml2
-              libxslt
-              libzip
-              python27Full
-              python27Packages.buildout
-              stdenv
-              zlib
-            ];
-
-            pathsToLink = [ "/include" ];
-
-            shellInit = ''
-              # help pip to find libz.so when building lxml
-              export LIBRARY_PATH=/var/run/current-system/sw/lib
-              # ditto for header files, e.g. sqlite
-              export C_INCLUDE_PATH=/var/run/current-system/sw/include
-            '';
-          };
-
-        };
-      };
-    }
-    {
-      services.mysql = {
-        enable = true;
-        package = pkgs.mariadb;
-        rootPassword = "<secrets>/mysql_rootPassword";
-      };
-    }
-    {
-      services.elasticsearch = {
-        enable = true;
-        plugins = [
-        #  pkgs.elasticsearchPlugins.elasticsearch_kopf
-        ];
-      };
-    }
-    {
-      services.postgresql = {
-        enable = true;
-        package = pkgs.postgresql;
-      };
     }
   ];
 
@@ -158,15 +65,6 @@
 
   networking.wireless.enable = true;
 
-  networking.extraHosts = ''
-    213.239.205.240 wohnprojekt-rhh.de
-    213.239.205.240 karlaskop.de
-    213.239.205.240 makeup.apanowicz.de
-    213.239.205.240 pixelpocket.de
-    213.239.205.240 reich-gebaeudereinigung.de
-    213.239.205.240 o.ubikmedia.de
-  '';
-
   hardware.enableAllFirmware = true;
   nixpkgs.config.allowUnfree = true;
 
@@ -206,7 +104,7 @@
       fsType = "ext4";
     };
 
-    "/mnt/backups" = {
+    "/bku" = {
       device = "/dev/big/backups";
       fsType = "ext4";
     };
@@ -293,6 +191,8 @@
     get
     teamspeak_client
     hashPassword
+    urban
+    mk_sql_pair
   ];
 
   #TODO: fix this shit
@@ -324,16 +224,4 @@
       ];
     };
   };
-
-  #touchpad config
-  services.xserver.synaptics = {
-    enable = true;
-    accelFactor = "0.035";
-    additionalOptions = ''
-      Option "FingerHigh" "60"
-      Option "FingerLow"  "60"
-    '';
-    tapButtons = false;
-    twoFingerScroll = true;
-  };
 }
diff --git a/lass/1systems/prism.nix b/lass/1systems/prism.nix
index 20c919b9b..aa524720d 100644
--- a/lass/1systems/prism.nix
+++ b/lass/1systems/prism.nix
@@ -2,15 +2,28 @@
 
 let
   ip = config.krebs.build.host.nets.internet.ip4.addr;
+
+  inherit (import ../../4lib { inherit lib pkgs; })
+    manageCerts;
+
 in {
   imports = [
     ../.
-    ../2configs/base.nix
+    ../2configs/default.nix
+    ../2configs/exim-smarthost.nix
     ../2configs/downloading.nix
     ../2configs/git.nix
     ../2configs/ts3.nix
     ../2configs/bitlbee.nix
     ../2configs/weechat.nix
+    ../2configs/privoxy-retiolum.nix
+    ../2configs/radio.nix
+    {
+      #we need to use old sqlite for buildbot
+      imports = [
+        ../2configs/buildbot-standalone.nix
+      ];
+    }
     {
       users.extraGroups = {
         # ● systemd-tmpfiles-setup.service - Create Volatile Files and Directories
@@ -77,6 +90,18 @@ in {
         device = "/dev/pool/download";
       };
 
+      fileSystems."/srv/http" = {
+        device = "/dev/pool/http";
+      };
+
+      fileSystems."/srv/o.ubikmedia.de-data" = {
+        device = "/dev/pool/owncloud-ubik-data";
+      };
+
+      fileSystems."/bku" = {
+        device = "/dev/pool/bku";
+      };
+
     }
     {
       sound.enable = false;
@@ -117,7 +142,7 @@ in {
     }
     {
       users.users.chat.openssh.authorizedKeys.keys = [
-        "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFhFJUMTfPbv3SzqlT9S67Av/m/ctLfTd3mMhD4O9hZc+t+dZmaHWj3v1KujzMBiDp3Yfo2YdVVZLTwTluHD8yNoQH418Vm01nrYHwOsc5J0br3mb0URZSstPiz6/6Fc+PNCDfQ2skUAWUidWiH+JolROFQ4y2lfpLOw+wsK2jj+Gqx6w== JuiceSSH"
+        "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBBQjn/3n283RZkBs2CFqbpukyQ3zkLIjewRpKttPa5d4PUiT7/vOlutWH5EP4BxXQSoeZStx8D2alGjxfK+nfDvRJGGofpm23cN4j4i24Fcam1y1H7wqRXO1qbz5AB3qPg== JuiceSSH"
         config.krebs.users.lass-uriel.pubkey
       ];
     }
@@ -130,15 +155,47 @@ in {
         ../2configs/websites/domsen.nix
       ];
       krebs.iptables.tables.filter.INPUT.rules = [
-         { predicate = "-p tcp --dport 80"; target = "ACCEPT"; }
+         { predicate = "-p tcp --dport http"; target = "ACCEPT"; }
+         { predicate = "-p tcp --dport https"; target = "ACCEPT"; }
       ];
     }
     {
       services.tor = {
         enable = true;
-        client.enable = true;
       };
     }
+    {
+      security.acme = {
+        certs."lassul.us" = {
+          email = "lass@lassul.us";
+          webroot = "/var/lib/acme/challenges/lassul.us";
+          plugins = [
+            "account_key.json"
+            "key.pem"
+            "fullchain.pem"
+            "full.pem"
+          ];
+          user = "ejabberd";
+        };
+      };
+      krebs.nginx.servers."lassul.us" = {
+        server-names = [ "lassul.us" ];
+        locations = [
+          (lib.nameValuePair "/.well-known/acme-challenge" ''
+            root /var/lib/acme/challenges/lassul.us/;
+          '')
+        ];
+      };
+      lass.ejabberd = {
+        enable = true;
+        hosts = [ "lassul.us" ];
+        certfile = "/var/lib/acme/lassul.us/full.pem";
+      };
+      krebs.iptables.tables.filter.INPUT.rules = [
+        { predicate = "-p tcp --dport xmpp-client"; target = "ACCEPT"; }
+        { predicate = "-p tcp --dport xmpp-server"; target = "ACCEPT"; }
+      ];
+    }
   ];
 
   krebs.build.host = config.krebs.hosts.prism;
diff --git a/lass/1systems/shodan.nix b/lass/1systems/shodan.nix
new file mode 100644
index 000000000..6829428ff
--- /dev/null
+++ b/lass/1systems/shodan.nix
@@ -0,0 +1,76 @@
+{ config, pkgs, ... }:
+
+with builtins;
+{
+  imports = [
+    ../.
+    ../2configs/baseX.nix
+    ../2configs/exim-retiolum.nix
+    ../2configs/browsers.nix
+    ../2configs/programs.nix
+    ../2configs/fetchWallpaper.nix
+    ../2configs/backups.nix
+    #{
+    #  users.extraUsers = {
+    #    root = {
+    #      openssh.authorizedKeys.keys = map readFile [
+    #        ../../krebs/Zpubkeys/uriel.ssh.pub
+    #      ];
+    #    };
+    #  };
+    #}
+    {
+      #x220 config from mors
+      #TODO: make x220 config file (or look in other user dir)
+      hardware.trackpoint = {
+        enable = true;
+        sensitivity = 220;
+        speed = 0;
+        emulateWheel = true;
+      };
+
+      services.xserver = {
+        videoDriver = "intel";
+        vaapiDrivers = [ pkgs.vaapiIntel ];
+        deviceSection = ''
+          Option "AccelMethod" "sna"
+          BusID "PCI:0:2:0"
+        '';
+      };
+    }
+  ];
+
+  krebs.build.host = config.krebs.hosts.shodan;
+
+  networking.wireless.enable = true;
+
+  hardware.enableAllFirmware = true;
+  nixpkgs.config.allowUnfree = true;
+
+  boot = {
+    loader.grub.enable = true;
+    loader.grub.version = 2;
+    loader.grub.device = "/dev/sda";
+
+    initrd.luks.devices = [ { name = "luksroot"; device = "/dev/sda2"; } ];
+    initrd.luks.cryptoModules = [ "aes" "sha512" "sha1" "xts" ];
+    initrd.availableKernelModules = [ "xhci_hcd" "ehci_pci" "ahci" "usb_storage" ];
+    #kernelModules = [ "kvm-intel" "msr" ];
+    kernelModules = [ "msr" ];
+  };
+  fileSystems = {
+    "/" = {
+      device = "/dev/pool/nix";
+      fsType = "ext4";
+    };
+
+    "/boot" = {
+      device = "/dev/sda1";
+    };
+  };
+
+  #services.udev.extraRules = ''
+  #  SUBSYSTEM=="net", ATTR{address}=="64:27:37:7d:d8:ae", NAME="wl0"
+  #  SUBSYSTEM=="net", ATTR{address}=="f0:de:f1:b8:c8:2e", NAME="et0"
+  #'';
+}
diff --git a/lass/1systems/uriel.nix b/lass/1systems/uriel.nix
index 4e4eca21f..92996c181 100644
--- a/lass/1systems/uriel.nix
+++ b/lass/1systems/uriel.nix
@@ -5,6 +5,7 @@ with builtins;
   imports = [
     ../.
     ../2configs/baseX.nix
+    ../2configs/exim-retiolum.nix
     ../2configs/browsers.nix
     ../2configs/games.nix
     ../2configs/pass.nix
@@ -47,6 +48,11 @@ with builtins;
       fsType = "ext4";
     };
 
+    "/bku" = {
+      device = "/dev/pool/bku";
+      fsType = "ext4";
+    };
+
     "/boot" = {
       device = "/dev/sda1";
     };
diff --git a/lass/2configs/backups.nix b/lass/2configs/backups.nix
new file mode 100644
index 000000000..7d3046d43
--- /dev/null
+++ b/lass/2configs/backups.nix
@@ -0,0 +1,135 @@
+{ config, lib, ... }:
+with config.krebs.lib;
+{
+
+  krebs.backup.plans = {
+  } // mapAttrs (_: recursiveUpdate {
+    snapshots = {
+      daily    = { format = "%Y-%m-%d"; retain =  7; };
+      weekly   = { format = "%YW%W";    retain =  4; };
+      monthly  = { format = "%Y-%m";    retain = 12; };
+      yearly   = { format = "%Y";                    };
+    };
+  }) {
+    dishfire-http-prism = {
+      method = "pull";
+      src = { host = config.krebs.hosts.dishfire; path = "/srv/http"; };
+      dst = { host = config.krebs.hosts.prism;    path = "/bku/dishfire-http"; };
+      startAt = "03:00";
+    };
+    dishfire-http-mors = {
+      method = "pull";
+      src = { host = config.krebs.hosts.dishfire; path = "/srv/http"; };
+      dst = { host = config.krebs.hosts.mors;     path = "/bku/dishfire-http"; };
+      startAt = "03:05";
+    };
+    dishfire-http-uriel = {
+      method = "pull";
+      src = { host = config.krebs.hosts.dishfire; path = "/srv/http"; };
+      dst = { host = config.krebs.hosts.uriel;    path = "/bku/dishfire-http"; };
+      startAt = "03:10";
+    };
+    dishfire-sql-prism = {
+      method = "pull";
+      src = { host = config.krebs.hosts.dishfire; path = "/bku/sql_dumps"; };
+      dst = { host = config.krebs.hosts.prism;    path = "/bku/dishfire-sql"; };
+      startAt = "03:15";
+    };
+    dishfire-sql-mors = {
+      method = "pull";
+      src = { host = config.krebs.hosts.dishfire; path = "/bku/sql_dumps"; };
+      dst = { host = config.krebs.hosts.mors;     path = "/bku/dishfire-sql"; };
+      startAt = "03:20";
+    };
+    dishfire-sql-uriel = {
+      method = "pull";
+      src = { host = config.krebs.hosts.dishfire; path = "/bku/sql_dumps"; };
+      dst = { host = config.krebs.hosts.uriel;    path = "/bku/dishfire-sql"; };
+      startAt = "03:25";
+    };
+    prism-bitlbee-mors = {
+      method = "pull";
+      src = { host = config.krebs.hosts.prism; path = "/var/lib/bitlbee"; };
+      dst = { host = config.krebs.hosts.mors; path = "/bku/prism-bitlbee"; };
+      startAt = "03:25";
+    };
+    prism-bitlbee-uriel = {
+      method = "pull";
+      src = { host = config.krebs.hosts.prism; path = "/var/lib/bitlbee"; };
+      dst = { host = config.krebs.hosts.uriel; path = "/bku/prism-bitlbee"; };
+      startAt = "03:25";
+    };
+    prism-chat-mors = {
+      method = "pull";
+      src = { host = config.krebs.hosts.prism; path = "/home/chat"; };
+      dst = { host = config.krebs.hosts.mors;  path = "/bku/prism-chat"; };
+      startAt = "03:30";
+    };
+    prism-chat-uriel = {
+      method = "pull";
+      src = { host = config.krebs.hosts.prism; path = "/home/chat"; };
+      dst = { host = config.krebs.hosts.uriel; path = "/bku/prism-chat"; };
+      startAt = "03:35";
+    };
+    prism-sql-mors = {
+      method = "pull";
+      src = { host = config.krebs.hosts.prism; path = "/bku/sql_dumps"; };
+      dst = { host = config.krebs.hosts.mors;  path = "/bku/prism-sql_dumps"; };
+      startAt = "03:40";
+    };
+    prism-sql-uriel = {
+      method = "pull";
+      src = { host = config.krebs.hosts.prism; path = "/bku/sql_dumps"; };
+      dst = { host = config.krebs.hosts.uriel; path = "/bku/prism-sql_dumps"; };
+      startAt = "03:45";
+    };
+    prism-http-mors = {
+      method = "pull";
+      src = { host = config.krebs.hosts.prism; path = "/srv/http"; };
+      dst = { host = config.krebs.hosts.mors;  path = "/bku/prism-http"; };
+      startAt = "03:50";
+    };
+    prism-http-uriel = {
+      method = "pull";
+      src = { host = config.krebs.hosts.prism; path = "/srv/http"; };
+      dst = { host = config.krebs.hosts.uriel; path = "/bku/prism-http"; };
+      startAt = "03:55";
+    };
+    uriel-home-mors = {
+      method = "pull";
+      src = { host = config.krebs.hosts.uriel; path = "/home"; };
+      dst = { host = config.krebs.hosts.mors;  path = "/bku/uriel-home"; };
+      startAt = "04:00";
+    };
+    mors-home-uriel = {
+      method = "push";
+      src = { host = config.krebs.hosts.mors;  path = "/home"; };
+      dst = { host = config.krebs.hosts.uriel; path = "/bku/mors-home"; };
+      startAt = "05:00";
+    };
+    dishfire-http-helios = {
+      method = "pull";
+      src = { host = config.krebs.hosts.dishfire; path = "/srv/http"; };
+      dst = { host = config.krebs.hosts.helios;   path = "/bku/dishfire-http"; };
+      startAt = "12:00";
+    };
+    dishfire-sql-helios = {
+      method = "pull";
+      src = { host = config.krebs.hosts.dishfire; path = "/bku/sql_dumps"; };
+      dst = { host = config.krebs.hosts.helios;   path = "/bku/dishfire-sql"; };
+      startAt = "12:15";
+    };
+    prism-sql-helios = {
+      method = "pull";
+      src = { host = config.krebs.hosts.prism;  path = "/bku/sql_dumps"; };
+      dst = { host = config.krebs.hosts.helios; path = "/bku/prism-sql_dumps"; };
+      startAt = "12:30";
+    };
+    prism-http-helios = {
+      method = "pull";
+      src = { host = config.krebs.hosts.prism;  path = "/srv/http"; };
+      dst = { host = config.krebs.hosts.helios; path = "/bku/prism-http"; };
+      startAt = "12:45";
+    };
+  };
+}
diff --git a/lass/2configs/baseX.nix b/lass/2configs/baseX.nix
index 6c52240af..f918db156 100644
--- a/lass/2configs/baseX.nix
+++ b/lass/2configs/baseX.nix
@@ -4,9 +4,10 @@ let
   mainUser = config.users.extraUsers.mainUser;
 in {
   imports = [
-    ./base.nix
+    ./default.nix
     #./urxvt.nix
     ./xserver
+    ./mpv.nix
   ];
 
   users.extraUsers.mainUser.extraGroups = [ "audio" ];
@@ -33,17 +34,18 @@ in {
 
     dmenu
     gitAndTools.qgit
+    nmap
     much
     pavucontrol
     powertop
     push
     slock
     sxiv
+    xclip
     xorg.xbacklight
     xsel
     zathura
 
-    mpv
     mpv-poll
     yt-next
   #window manager stuff
diff --git a/lass/2configs/browsers.nix b/lass/2configs/browsers.nix
index 47a16d4cb..e230fff43 100644
--- a/lass/2configs/browsers.nix
+++ b/lass/2configs/browsers.nix
@@ -14,7 +14,7 @@ let
         useDefaultShell = true;
         createHome = true;
       };
-      lass.per-user.${name}.packages = packages;
+      krebs.per-user.${name}.packages = packages;
       security.sudo.extraConfig = ''
         ${mainUser.name} ALL=(${name}) NOPASSWD: ALL
       '';
@@ -35,7 +35,7 @@ let
         useDefaultShell = true;
         createHome = true;
       };
-      lass.per-user.${name}.packages = packages;
+      krebs.per-user.${name}.packages = packages;
       security.sudo.extraConfig = ''
         ${mainUser.name} ALL=(${name}) NOPASSWD: ALL
       '';
@@ -59,20 +59,9 @@ in {
 
   imports = [
     ( createFirefoxUser "ff" [ "audio" ] [ pkgs.firefox ] )
-    ( createChromiumUser "cr" [ "audio" ] [ pkgs.chromium ] )
-    ( createChromiumUser "wk" [ "audio" ] [ pkgs.chromium ] )
-    ( createChromiumUser "fb" [ "audio" ] [ pkgs.chromium ] )
-    ( createChromiumUser "gm" [ "audio" ] [ pkgs.chromium ] )
-    ( createChromiumUser "flash" [ "audio" ] [ pkgs.flash ] )
+    ( createChromiumUser "cr" [ "video" "audio" ] [ pkgs.chromium ] )
+    ( createChromiumUser "wk" [ "video" "audio" ] [ pkgs.chromium ] )
+    ( createChromiumUser "fb" [ "video" "audio" ] [ pkgs.chromium ] )
+    ( createChromiumUser "gm" [ "video" "audio" ] [ pkgs.chromium ] )
   ];
-
-  nixpkgs.config.packageOverrides = pkgs : {
-    flash = pkgs.chromium.override {
-    #  pulseSupport = true;
-      enablePepperFlash = true;
-    };
-    #chromium = pkgs.chromium.override {
-    #  pulseSupport = true;
-    #};
-  };
 }
diff --git a/lass/2configs/buildbot-standalone.nix b/lass/2configs/buildbot-standalone.nix
index 8c71553fe..604d0728d 100644
--- a/lass/2configs/buildbot-standalone.nix
+++ b/lass/2configs/buildbot-standalone.nix
@@ -1,15 +1,16 @@
 { lib, config, pkgs, ... }:
 {
-  #networking.firewall.allowedTCPPorts = [ 8010 9989 ];
-  krebs.buildbot.master = {
+  krebs.buildbot.master = let
+    stockholm-mirror-url = http://cgit.prism/stockholm ;
+  in {
     slaves = {
       testslave = "lasspass";
     };
     change_source.stockholm = ''
-      stockholm_repo = 'http://cgit.mors/stockholm'
+      stockholm_repo = '${stockholm-mirror-url}'
       cs.append(changes.GitPoller(
               stockholm_repo,
-              workdir='stockholm-poller', branch='master',
+              workdir='stockholm-poller', branches=True,
               project='stockholm',
               pollinterval=120))
     '';
@@ -20,10 +21,12 @@
                                     builderNames=["fast-tests"]))
       '';
       fast-tests-scheduler = ''
-        # test the master real quick
+        # test everything real quick
         sched.append(schedulers.SingleBranchScheduler(
-                                    change_filter=util.ChangeFilter(branch="master"),
-                                    name="fast-master-test",
+                                    ## all branches
+                                    change_filter=util.ChangeFilter(branch_re=".*"),
+                                    # treeStableTimer=10,
+                                    name="fast-all-branches",
                                     builderNames=["fast-tests"]))
       '';
     };
@@ -38,7 +41,10 @@
       deps = [ "gnumake", "jq","nix","rsync" ]
       # TODO: --pure , prepare ENV in nix-shell command:
       #                   SSL_CERT_FILE,LOGNAME,NIX_REMOTE
-      nixshell = ["nix-shell", "-I", "stockholm=.", "-p" ] + deps + [ "--run" ]
+      nixshell = ["nix-shell",
+                    "-I", "stockholm=.",
+                    "-I", "nixpkgs=/var/src/nixpkgs",
+                    "-p" ] + deps + [ "--run" ]
 
       # prepare addShell function
       def addShell(factory,**kwargs):
@@ -48,13 +54,26 @@
       fast-tests = ''
         f = util.BuildFactory()
         f.addStep(grab_repo)
-        addShell(f,name="mors-eval",env=env,
-                  command=nixshell + ["make -s eval get=krebs.deploy filter=json system=mors"])
+        for i in [ "prism", "mors", "echelon" ]:
+          addShell(f,name="populate-{}".format(i),env=env,
+                  command=nixshell + \
+                            ["{}( make system={} eval.config.krebs.build.populate \
+                               | jq -er .)".format("!" if "failing" in i else "",i)])
+
+        addShell(f,name="build-test-minimal",env=env,
+                  command=nixshell + \
+                            ["nix-instantiate \
+                                  --show-trace --eval --strict --json \
+                                  -I nixos-config=./shared/1systems/test-minimal-deploy.nix  \
+                                  -I secrets=. \
+                                  -A config.system.build.toplevel"]
+                )
 
         bu.append(util.BuilderConfig(name="fast-tests",
               slavenames=slavenames,
               factory=f))
-      '';
+
+            '';
     };
     enable = true;
     web.enable = true;
@@ -72,7 +91,17 @@
     masterhost = "localhost";
     username = "testslave";
     password = "lasspass";
-    packages = with pkgs;[ git nix ];
-    extraEnviron = { NIX_PATH="nixpkgs=${toString <nixpkgs>}"; };
+    packages = with pkgs;[ git nix gnumake jq rsync ];
+    extraEnviron = {
+      NIX_PATH="nixpkgs=/var/src/nixpkgs:nixos-config=./shared/1systems/wolf.nix";
+    };
+  };
+  krebs.iptables = {
+    tables = {
+      filter.INPUT.rules = [
+        { predicate = "-p tcp --dport 8010"; target = "ACCEPT"; }
+        { predicate = "-p tcp --dport 9989"; target = "ACCEPT"; }
+      ];
+    };
   };
 }
diff --git a/lass/2configs/base.nix b/lass/2configs/default.nix
similarity index 84%
rename from lass/2configs/base.nix
rename to lass/2configs/default.nix
index 8017d4270..ee320b9c9 100644
--- a/lass/2configs/base.nix
+++ b/lass/2configs/default.nix
@@ -7,10 +7,11 @@ with config.krebs.lib;
     ../2configs/zsh.nix
     ../2configs/mc.nix
     ../2configs/retiolum.nix
+    ./backups.nix
     {
       users.extraUsers =
         mapAttrs (_: h: { hashedPassword = h; })
-                 (import /root/secrets/hashedPasswords.nix);
+                 (import <secrets/hashedPasswords.nix>);
     }
     {
       users.extraUsers = {
@@ -18,7 +19,7 @@ with config.krebs.lib;
           openssh.authorizedKeys.keys = [
             config.krebs.users.lass.pubkey
             config.krebs.users.lass-uriel.pubkey
-            config.krebs.users.lass-helios.pubkey
+            config.krebs.users.lass-shodan.pubkey
           ];
         };
         mainUser = {
@@ -33,6 +34,7 @@ with config.krebs.lib;
           openssh.authorizedKeys.keys = [
             config.krebs.users.lass.pubkey
             config.krebs.users.lass-uriel.pubkey
+            config.krebs.users.lass-shodan.pubkey
           ];
         };
       };
@@ -45,7 +47,6 @@ with config.krebs.lib;
   krebs = {
     enable = true;
     search-domain = "retiolum";
-    exim-retiolum.enable = true;
     build = {
       user = config.krebs.users.lass;
       source = mapAttrs (_: mkDefault) ({
@@ -55,7 +56,7 @@ with config.krebs.lib;
         stockholm = "/home/lass/stockholm";
         nixpkgs = {
           url = https://github.com/NixOS/nixpkgs;
-          rev = "40c586b7ce2c559374df435f46d673baf711c543";
+          rev = "d541e0dc1c05f5514bf30f8039e687adddb45616";
           dev = "/home/lass/src/nixpkgs";
         };
       } // optionalAttrs config.krebs.build.host.secure {
@@ -85,9 +86,12 @@ with config.krebs.lib;
     MANPAGER=most
   '';
 
+  nixpkgs.config.allowUnfree = true;
+
   environment.systemPackages = with pkgs; [
   #stockholm
     git
+    gnumake
     jq
     parallel
     proot
@@ -102,12 +106,20 @@ with config.krebs.lib;
 
   #network
     iptables
+    iftop
 
   #stuff for dl
     aria2
 
   #neat utils
     krebspaste
+    psmisc
+    untilport
+
+  #unpack stuff
+    p7zip
+    unzip
+    unrar
   ];
 
   programs.bash = {
@@ -145,10 +157,6 @@ with config.krebs.lib;
     '';
   };
 
-  security.setuidPrograms = [
-    "sendmail"
-  ];
-
   services.openssh = {
     enable = true;
     hostKeys = [
@@ -165,6 +173,13 @@ with config.krebs.lib;
   krebs.iptables = {
     enable = true;
     tables = {
+      nat.PREROUTING.rules = [
+        { predicate = "! -i retiolum -p tcp -m tcp --dport 22"; target = "REDIRECT --to-ports 0"; precedence = 100; }
+        { predicate = "-p tcp -m tcp --dport 45621"; target = "REDIRECT --to-ports 22"; precedence = 99; }
+      ];
+      nat.OUTPUT.rules = [
+        { predicate = "-o lo -p tcp -m tcp --dport 45621"; target = "REDIRECT --to-ports 22"; precedence = 100; }
+      ];
       filter.INPUT.policy = "DROP";
       filter.FORWARD.policy = "DROP";
       filter.INPUT.rules = [
diff --git a/lass/2configs/downloading.nix b/lass/2configs/downloading.nix
index 115cb8b61..3639a743a 100644
--- a/lass/2configs/downloading.nix
+++ b/lass/2configs/downloading.nix
@@ -3,7 +3,7 @@
 with config.krebs.lib;
 
 let
-  rpc-password = import <secrets/transmission-pw.nix>;
+  rpc-password = import <secrets/transmission-pw>;
 in {
   imports = [
     ../3modules/folderPerms.nix
@@ -20,6 +20,7 @@ in {
       ];
       openssh.authorizedKeys.keys = [
         config.krebs.users.lass.pubkey
+        config.krebs.users.lass-uriel.pubkey
       ];
     };
 
diff --git a/lass/2configs/exim-retiolum.nix b/lass/2configs/exim-retiolum.nix
new file mode 100644
index 000000000..c07b6c15a
--- /dev/null
+++ b/lass/2configs/exim-retiolum.nix
@@ -0,0 +1,10 @@
+{ config, lib, pkgs, ... }:
+
+with config.krebs.lib;
+
+{
+  krebs.exim-retiolum.enable = true;
+  krebs.iptables.tables.filter.INPUT.rules = [
+    { predicate = "-i retiolum -p tcp --dport smtp"; target = "ACCEPT"; }
+  ];
+}
diff --git a/lass/2configs/exim-smarthost.nix b/lass/2configs/exim-smarthost.nix
new file mode 100644
index 000000000..84a57205b
--- /dev/null
+++ b/lass/2configs/exim-smarthost.nix
@@ -0,0 +1,49 @@
+{ config, lib, pkgs, ... }:
+
+with config.krebs.lib;
+
+{
+  krebs.exim-smarthost = {
+    enable = true;
+    dkim = [
+      { domain = "lassul.us"; }
+    ];
+    sender_domains = [
+      "lassul.us"
+      "aidsballs.de"
+    ];
+    relay_from_hosts = map (host: host.nets.retiolum.ip4.addr) [
+      config.krebs.hosts.mors
+      config.krebs.hosts.uriel
+      config.krebs.hosts.helios
+    ];
+    internet-aliases = with config.krebs.users; [
+      { from = "postmaster@lassul.us"; to = lass.mail; } # RFC 822
+      { from = "lass@lassul.us"; to = lass.mail; }
+      { from = "lassulus@lassul.us"; to = lass.mail; }
+      { from = "test@lassul.us"; to = lass.mail; }
+      { from = "outlook@lassul.us"; to = lass.mail; }
+      { from = "steuer@aidsballs.de"; to = lass.mail; }
+      { from = "lass@aidsballs.de"; to = lass.mail; }
+      { from = "wordpress@ubikmedia.de"; to = lass.mail; }
+    ];
+    system-aliases = [
+      { from = "mailer-daemon"; to = "postmaster"; }
+      { from = "postmaster"; to = "root"; }
+      { from = "nobody"; to = "root"; }
+      { from = "hostmaster"; to = "root"; }
+      { from = "usenet"; to = "root"; }
+      { from = "news"; to = "root"; }
+      { from = "webmaster"; to = "root"; }
+      { from = "www"; to = "root"; }
+      { from = "ftp"; to = "root"; }
+      { from = "abuse"; to = "root"; }
+      { from = "noc"; to = "root"; }
+      { from = "security"; to = "root"; }
+      { from = "root"; to = "lass"; }
+    ];
+  };
+  krebs.iptables.tables.filter.INPUT.rules = [
+    { predicate = "-p tcp --dport smtp"; target = "ACCEPT"; }
+  ];
+}
diff --git a/lass/2configs/fastpoke-pages.nix b/lass/2configs/fastpoke-pages.nix
deleted file mode 100644
index bf6ea8952..000000000
--- a/lass/2configs/fastpoke-pages.nix
+++ /dev/null
@@ -1,101 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with config.krebs.lib;
-
-let
-  createStaticPage = domain:
-    {
-      krebs.nginx.servers."${domain}" = {
-        server-names = [
-          "${domain}"
-          "www.${domain}"
-        ];
-        locations = [
-          (nameValuePair "/" ''
-            root /var/lib/http/${domain};
-          '')
-        ];
-      };
-      #networking.extraHosts = ''
-      #  10.243.206.102 ${domain}
-      #'';
-      users.extraUsers = {
-        ${domain} = {
-          name = domain;
-          home = "/var/lib/http/${domain}";
-          createHome = true;
-        };
-      };
-    };
-
-in {
-  imports = map createStaticPage [
-    "habsys.de"
-    "pixelpocket.de"
-    "karlaskop.de"
-    "ubikmedia.de"
-    "apanowicz.de"
-  ];
-
-  krebs.iptables = {
-    tables = {
-      filter.INPUT.rules = [
-        { predicate = "-p tcp --dport http"; target = "ACCEPT"; }
-      ];
-    };
-  };
-
-
-  krebs.nginx = {
-    enable = true;
-    servers = {
-      #"habsys.de" = {
-      #  server-names = [
-      #    "habsys.de"
-      #    "www.habsys.de"
-      #  ];
-      #  locations = [
-      #    (nameValuePair "/" ''
-      #      root /var/lib/http/habsys.de;
-      #    '')
-      #  ];
-      #};
-
-      #"karlaskop.de" = {
-      #  server-names = [
-      #    "karlaskop.de"
-      #    "www.karlaskop.de"
-      #  ];
-      #  locations = [
-      #    (nameValuePair "/" ''
-      #      root /var/lib/http/karlaskop.de;
-      #    '')
-      #  ];
-      #};
-
-      #"pixelpocket.de" = {
-      #  server-names = [
-      #    "pixelpocket.de"
-      #    "www.karlaskop.de"
-      #  ];
-      #  locations = [
-      #    (nameValuePair "/" ''
-      #      root /var/lib/http/karlaskop.de;
-      #    '')
-      #  ];
-      #};
-
-    };
-  };
-
-  #services.postgresql = {
-  #  enable = true;
-  #};
-
-  #config.services.vsftpd = {
-  #  enable = true;
-  #  userlistEnable = true;
-  #  userlistFile = pkgs.writeFile "vsftpd-userlist" ''
-  #  '';
-  #};
-}
diff --git a/lass/2configs/fetchWallpaper.nix b/lass/2configs/fetchWallpaper.nix
index 9c27706cb..f3b65e816 100644
--- a/lass/2configs/fetchWallpaper.nix
+++ b/lass/2configs/fetchWallpaper.nix
@@ -5,7 +5,7 @@ let
 in {
   krebs.fetchWallpaper = {
     enable = true;
-    url = "echelon/wallpaper.png";
+    url = "cloudkrebs/wallpaper.png";
   };
 }
 
diff --git a/lass/2configs/games.nix b/lass/2configs/games.nix
index 6043a8759..0eec97922 100644
--- a/lass/2configs/games.nix
+++ b/lass/2configs/games.nix
@@ -13,7 +13,7 @@ in {
       name = "games";
       description = "user playing games";
       home = "/home/games";
-      extraGroups = [ "audio" "video" "input" ];
+      extraGroups = [ "audio" "video" "input" "loot" ];
       createHome = true;
       useDefaultShell = true;
     };
diff --git a/lass/2configs/git.nix b/lass/2configs/git.nix
index 0aab298c7..5cbe46351 100644
--- a/lass/2configs/git.nix
+++ b/lass/2configs/git.nix
@@ -35,6 +35,8 @@ let
     newsbot-js = {};
     kimsufi-check = {};
     realwallpaper = {};
+    xmonad-stockholm = {};
+    the_playlist = {};
   };
 
   restricted-repos = mapAttrs make-restricted-repo (
diff --git a/lass/2configs/krebs-pass.nix b/lass/2configs/krebs-pass.nix
new file mode 100644
index 000000000..a605bc84b
--- /dev/null
+++ b/lass/2configs/krebs-pass.nix
@@ -0,0 +1,21 @@
+{ pkgs, ... }:
+
+let
+
+  #TODO: tab-completion
+  krebs-pass = pkgs.writeDashBin "krebs-pass" ''
+    PASSWORD_STORE_DIR=$HOME/.krebs-pass \
+    exec ${pkgs.pass}/bin/pass $@
+  '';
+
+  krebs-passmenu = pkgs.writeDashBin "krebs-passmenu" ''
+    PASSWORD_STORE_DIR=$HOME/.krebs-pass \
+    exec ${pkgs.pass}/bin/passmenu $@
+  '';
+
+in {
+  krebs.per-user.lass.packages = [
+    krebs-pass
+    krebs-passmenu
+  ];
+}
diff --git a/lass/2configs/mail.nix b/lass/2configs/mail.nix
new file mode 100644
index 000000000..72d6f987f
--- /dev/null
+++ b/lass/2configs/mail.nix
@@ -0,0 +1,110 @@
+{ pkgs, ... }:
+
+let
+
+  msmtprc = pkgs.writeText "msmtprc" ''
+    defaults
+      logfile ~/.msmtp.log
+    account prism
+      host prism.r
+    account default: prism
+  '';
+
+  msmtp = pkgs.writeDashBin "msmtp" ''
+    exec ${pkgs.msmtp}/bin/msmtp -C ${msmtprc} $@
+  '';
+
+  muttrc = pkgs.writeText "muttrc" ''
+    # gpg
+    source ${pkgs.mutt-kz}/share/doc/mutt-kz/samples/gpg.rc
+    set pgp_use_gpg_agent = yes
+    set pgp_sign_as = 0x976A7E4D
+    set crypt_autosign = yes
+    set crypt_replyencrypt = yes
+    set crypt_verify_sig = yes
+    set pgp_verify_command = "gpg --no-verbose --batch --output - --verify %s %f"
+
+    macro index \Cv \
+    "<enter-command> set my_crypt_verify_sig=\$crypt_verify_sig<enter> \
+    <enter-command> set crypt_verify_sig=yes<enter> \
+    <display-message><enter-command> set crypt_verify_sig=\$my_crypt_verify_sig<enter>" \
+     'Verify PGP signature and open the message'
+
+    macro pager \Cv \
+    "<exit><enter-command> set my_crypt_verify_sig=\$crypt_verify_sig<enter> \
+    <enter-command> set crypt_verify_sig=yes<enter> \
+    <display-message><enter-command> set crypt_verify_sig=\$my_crypt_verify_sig<enter>" \
+     'Verify PGP signature'
+
+
+    # notmuch
+    set nm_default_uri="notmuch://$HOME/Maildir" # path to the maildir
+    set nm_record = yes
+    set nm_record_tags = "-inbox me archive"
+    set virtual_spoolfile=yes                    # enable virtual folders
+    set sendmail="msmtp"                         # enables parsing of outgoing mail
+    set use_from=yes
+    set envelope_from=yes
+
+    set index_format="%4C %Z %?GI?%GI& ? %[%d/%b]  %-16.15F %?M?(%3M)&     ? %s %> %?g?%g?"
+
+    virtual-mailboxes \
+        "INBOX"     "notmuch://?query=tag:inbox and NOT tag:killed"\
+        "Unread"    "notmuch://?query=tag:unread"\
+        "TODO"      "notmuch://?query=tag:TODO"\
+        "Starred"   "notmuch://?query=tag:*"\
+        "Archive"   "notmuch://?query=tag:archive"\
+        "Sent"      "notmuch://?query=tag:sent"\
+        "Junk"      "notmuch://?query=tag:junk"
+
+    tag-transforms "junk"     "k" \
+                   "unread"   "u" \
+                   "replied"  "↻" \
+                   "TODO"     "T" \
+
+    # notmuch bindings
+    macro index \\\\ "<vfolder-from-query>"                   # looks up a hand made query
+    macro index A "<modify-labels>+archive -unread -inbox\n"  # tag as Archived
+    macro index + "<modify-labels>+*\n<sync-mailbox>"         # tag as starred
+    macro index - "<modify-labels>-*\n<sync-mailbox>"         # tag as unstarred
+
+
+    #killed
+    bind index d noop
+    bind pager d noop
+
+    bind pager S noop
+    macro index S "<modify-labels-then-hide>-inbox -unread +junk\n" # tag as Junk mail
+    macro pager S "<modify-labels-then-hide>-inbox -unread +junk\n" # tag as Junk mail
+
+    bind index t noop
+    bind pager t noop
+    macro index t "<modify-labels>+TODO\n"        # tag as Archived
+
+
+    # sidebar
+    set sidebar_width   = 20
+    set sidebar_visible = yes               # set to "no" to disable sidebar view at startup
+    color sidebar_new yellow default
+    # sidebar bindings
+    bind index <left> sidebar-prev          # got to previous folder in sidebar
+    bind index <right> sidebar-next         # got to next folder in sidebar
+    bind index <space> sidebar-open         # open selected folder from sidebar
+    # sidebar toggle
+    macro index ,@) "<enter-command> set sidebar_visible=no; macro index ~ ,@( 'Toggle sidebar'<Enter>"
+    macro index ,@( "<enter-command> set sidebar_visible=yes; macro index ~ ,@) 'Toggle sidebar'<Enter>"
+    macro index ~ ,@( 'Toggle sidebar'      # toggle the sidebar
+  '';
+
+  mutt = pkgs.writeDashBin "mutt" ''
+    exec ${pkgs.mutt-kz}/bin/mutt -F ${muttrc} $@
+  '';
+
+in {
+  environment.systemPackages = [
+    msmtp
+    mutt
+    pkgs.much
+    pkgs.notmuch
+  ];
+}
diff --git a/lass/2configs/mpv.nix b/lass/2configs/mpv.nix
new file mode 100644
index 000000000..ff5698e4e
--- /dev/null
+++ b/lass/2configs/mpv.nix
@@ -0,0 +1,49 @@
+{ pkgs, lib, ... }:
+
+let
+
+  mpv-config = pkgs.writeText "mpv-config" ''
+    script=${lib.concatStringsSep "," [
+      good
+      delete
+    ]}
+  '';
+  mpv = pkgs.writeDashBin "mpv" ''
+    exec ${pkgs.mpv}/bin/mpv --no-config --include=${mpv-config} "$@"
+  '';
+
+  moveToDir = key: dir: pkgs.writeText "move-with-${key}.lua" ''
+    tmp_dir = "${dir}"
+
+    function move_current_track_${key}()
+      track = mp.get_property("path")
+      os.execute("mkdir -p '" .. tmp_dir .. "'")
+      os.execute("mv '" .. track .. "' '" .. tmp_dir .. "'")
+      print("moved '" .. track .. "' to " .. tmp_dir)
+    end
+
+    mp.add_key_binding("${key}", "move_current_track_${key}", move_current_track_${key})
+  '';
+
+  good = moveToDir "G" "./.good";
+  delete = moveToDir "D" "./.graveyard";
+
+  deleteCurrentTrack = pkgs.writeText "delete.lua" ''
+    deleted_tmp = "./.graveyard"
+
+    -- Delete the current track by moving it to the `deleted_tmp` location.
+    function delete_current_track()
+      track = mp.get_property("path")
+      os.execute("mkdir -p '" .. deleted_tmp .. "'")
+      os.execute("mv '" .. track .. "' '" .. deleted_tmp .. "'")
+      print("'" .. track .. "' deleted.")
+    end
+
+    mp.add_key_binding("D", "delete_current_track", delete_current_track)
+  '';
+
+in {
+  krebs.per-user.lass.packages = [
+    mpv
+  ];
+}
diff --git a/lass/2configs/newsbot-js.nix b/lass/2configs/newsbot-js.nix
index d7c68bd7d..636b44395 100644
--- a/lass/2configs/newsbot-js.nix
+++ b/lass/2configs/newsbot-js.nix
@@ -154,7 +154,6 @@ let
     telepolis|http://www.heise.de/tp/rss/news-atom.xml|#news
     the_insider|http://www.theinsider.org/rss/news/headlines-xml.asp|#news
     tigsource|http://www.tigsource.com/feed/|#news
-    times|http://www.thetimes.co.uk/tto/news/rss|#news
     tinc|http://tinc-vpn.org/news/index.rss|#news
     topix_b|http://www.topix.com/rss/wire/de/berlin|#news
     torr_bits|http://feeds.feedburner.com/TorrentfreakBits|#news
diff --git a/lass/2configs/pass.nix b/lass/2configs/pass.nix
index 33eca0a17..5bd2f2f7f 100644
--- a/lass/2configs/pass.nix
+++ b/lass/2configs/pass.nix
@@ -1,10 +1,9 @@
 { config, pkgs, ... }:
 
 {
-  environment.systemPackages = with pkgs; [
+  krebs.per-user.lass.packages = with pkgs; [
     pass
     gnupg1
   ];
 
-  services.xserver.startGnuPGAgent = true;
 }
diff --git a/lass/2configs/programs.nix b/lass/2configs/programs.nix
index e4840383f..6cf23deaf 100644
--- a/lass/2configs/programs.nix
+++ b/lass/2configs/programs.nix
@@ -8,7 +8,6 @@
     htop
     i3lock
     mosh
-    mpv
     pass
     pavucontrol
     pv
diff --git a/lass/2configs/radio.nix b/lass/2configs/radio.nix
new file mode 100644
index 000000000..8cc2a2be7
--- /dev/null
+++ b/lass/2configs/radio.nix
@@ -0,0 +1,133 @@
+{ config, pkgs, ... }:
+let
+  name = "radio";
+  mainUser = config.users.extraUsers.mainUser;
+  inherit (config.krebs.lib) genid;
+
+  admin-password = import <secrets/icecast-admin-pw>;
+  source-password = import <secrets/icecast-source-pw>;
+
+in {
+  users.users = {
+    "${name}" = rec {
+      inherit name;
+      group = name;
+      uid = genid name;
+      description = "radio manager";
+      home = "/home/${name}";
+      useDefaultShell = true;
+      createHome = true;
+      openssh.authorizedKeys.keys = [
+        config.krebs.users.lass.pubkey
+      ];
+    };
+  };
+
+  users.groups = {
+    "radio" = {};
+  };
+
+  krebs.per-user.${name}.packages = with pkgs; [
+    ncmpcpp
+    mpc_cli
+    tmux
+  ];
+
+  security.sudo.extraConfig = ''
+    ${mainUser.name} ALL=(${name}) NOPASSWD: ALL
+  '';
+
+  services.mpd = {
+    enable = true;
+    group = "radio";
+    musicDirectory = "/home/radio/the_playlist/music";
+    extraConfig = ''
+      audio_output {
+          type        "shout"
+          encoding    "ogg"
+          name        "my cool stream"
+          host        "localhost"
+          port        "8000"
+          mount       "/radio.ogg"
+
+      # This is the source password in icecast.xml
+          password    "${source-password}"
+
+      # Set either quality or bit rate
+      #   quality     "5.0"
+          bitrate     "128"
+
+          format      "44100:16:1"
+
+      # Optional Parameters
+          user        "source"
+      #   description "here is my long description"
+      #   genre       "jazz"
+      } # end of audio_output
+
+    '';
+  };
+
+  services.icecast = {
+    enable = true;
+    hostname =  "config.krebs.build.host.name";
+    admin.password = admin-password;
+    extraConf = ''
+      <authentication>
+        <source-password>${source-password}</source-password>
+      </authentication>
+    '';
+  };
+
+  krebs.iptables = {
+    tables = {
+      filter.INPUT.rules = [
+        { predicate = "-p tcp --dport 8000"; target = "ACCEPT"; }
+      ];
+    };
+  };
+
+  systemd.timers.radio = {
+    description = "radio autoadder timer";
+    wantedBy = [ "timers.target" ];
+
+    timerConfig = {
+      OnCalendar = "*:*";
+    };
+  };
+
+  systemd.services.radio = let
+    autoAdd = pkgs.writeDash "autoAdd" ''
+      LIMIT=$1 #in secconds
+
+      addRandom () {
+        mpc add "$(mpc ls | shuf -n1)"
+      }
+
+      timeLeft () {
+        playlistDuration=$(mpc --format '%time%' playlist | awk -F ':' 'BEGIN{t=0} {t+=$1*60+$2} END{print t}')
+        currentTime=$(mpc status | awk '/^\[playing\]/ { sub(/\/.+/,"",$3); split($3,a,/:/); print a[1]*60+a[2] }')
+        expr ''${playlistDuration:-0} - ''${currentTime:-0}
+      }
+
+      if test $(timeLeft) -le $LIMIT; then
+        addRandom
+      fi
+    '';
+  in {
+    description = "radio playlist autoadder";
+    after = [ "network.target" ];
+
+    path = with pkgs; [
+      gawk
+      mpc_cli
+    ];
+
+    restartIfChanged = true;
+
+    serviceConfig = {
+      Restart = "always";
+      ExecStart = "${autoAdd} 100";
+    };
+  };
+}
diff --git a/lass/2configs/vim.nix b/lass/2configs/vim.nix
index b40227c61..8295d9d49 100644
--- a/lass/2configs/vim.nix
+++ b/lass/2configs/vim.nix
@@ -147,13 +147,8 @@ in {
       vimrcConfig.vam.pluginDictionaries = [
         { names = [
           "brogrammer"
-          "commentary"
-          "extradite"
           "file-line"
-          "fugitive"
           "Gundo"
-          "mustang2"
-          "unimpaired"
         ]; }
         { names = [ "vim-addon-nix" ]; ft_regex = "^nix\$"; }
       ];
diff --git a/lass/2configs/websites/domsen.nix b/lass/2configs/websites/domsen.nix
index 109c216c0..f31fccd51 100644
--- a/lass/2configs/websites/domsen.nix
+++ b/lass/2configs/websites/domsen.nix
@@ -1,35 +1,87 @@
-{ config, pkgs, ... }:
+{ config, pkgs, lib, ... }:
 
-{
+let
+  inherit (config.krebs.lib)
+    genid
+    readFile
+    ;
+  inherit (import ../../4lib { inherit lib pkgs; })
+    manageCert
+    manageCerts
+    activateACME
+    ssl
+    servePage
+    serveOwncloud
+    serveWordpress;
+
+  msmtprc = pkgs.writeText "msmtprc" ''
+    account prism
+      host localhost
+    account default: prism
+  '';
+
+  sendmail = pkgs.writeDash "msmtp" ''
+    exec ${pkgs.msmtp}/bin/msmtp --read-envelope-from -C ${msmtprc} "$@"
+  '';
+
+in {
   imports = [
-    ../../3modules/static_nginx.nix
-    ../../3modules/owncloud_nginx.nix
-    ../../3modules/wordpress_nginx.nix
+    ( ssl [ "reich-gebaeudereinigung.de" ])
+    ( servePage [ "reich-gebaeudereinigung.de" ])
+
+    ( manageCerts [ "karlaskop.de" ])
+    ( servePage [ "karlaskop.de" ])
+
+    ( ssl [ "makeup.apanowicz.de" ])
+    ( servePage [ "makeup.apanowicz.de" ])
+
+    ( manageCerts [ "pixelpocket.de" ])
+    ( servePage [ "pixelpocket.de" ])
+
+    ( ssl [ "o.ubikmedia.de" ])
+    ( serveOwncloud [ "o.ubikmedia.de" ])
+
+    ( ssl [ "ubikmedia.de" "aldona.ubikmedia.de" "apanowicz.de" "nirwanabluete.de" "aldonasiech.com" "360gradvideo.tv" "ubikmedia.eu" ] )
+    ( serveWordpress [ "ubikmedia.de" "*.ubikmedia.de" "apanowicz.de" "nirwanabluete.de" "aldonasiech.com" "360gradvideo.tv" "ubikmedia.eu" ] )
   ];
 
-  lass.staticPage = {
-    "karlaskop.de" = {};
-    "makeup.apanowicz.de" = {};
-    "pixelpocket.de" = {};
-    "reich-gebaeudereinigung.de" = {};
-  };
-
-  lass.owncloud = {
-    "o.ubikmedia.de" = {
-      instanceid = "oc8n8ddbftgh";
-    };
-  };
-
   services.mysql = {
     enable = true;
     package = pkgs.mariadb;
     rootPassword = toString (<secrets/mysql_rootPassword>);
   };
 
-  #lass.wordpress = {
-  #  "ubikmedia.de" = {
-  #  };
-  #};
+  lass.mysqlBackup = {
+    enable = true;
+    config.domsen = {
+      password = toString (<secrets/mysql_rootPassword>);
+      databases = [
+        "ubikmedia_de"
+        "o_ubikmedia_de"
+      ];
+    };
+  };
+  services.mysqlBackup = {
+    enable = true;
+    databases = [
+      "ubikmedia_de"
+      "o_ubikmedia_de"
+    ];
+    location = "/bku/sql_dumps";
+  };
 
+  users.users.domsen = {
+    uid = genid "domsen";
+    description = "maintenance acc for domsen";
+    home = "/home/domsen";
+    useDefaultShell = true;
+    extraGroups = [ "nginx" ];
+    createHome = true;
+  };
+
+  services.phpfpm.phpOptions = ''
+    extension=${pkgs.phpPackages.apcu}/lib/php/extensions/apcu.so
+    sendmail_path = ${sendmail} -t
+  '';
 }
 
diff --git a/lass/2configs/websites/fritz.nix b/lass/2configs/websites/fritz.nix
index 073f3de14..e35615040 100644
--- a/lass/2configs/websites/fritz.nix
+++ b/lass/2configs/websites/fritz.nix
@@ -1,33 +1,57 @@
-{ config, pkgs, ... }:
+{ config, pkgs, lib, ... }:
 
-{
+let
+  inherit (import ../../4lib { inherit lib pkgs; })
+    manageCerts
+    activateACME
+    ssl
+    servePage
+    serveWordpress;
 
+in {
   imports = [
-    ../../3modules/static_nginx.nix
-    ../../3modules/owncloud_nginx.nix
-    ../../3modules/wordpress_nginx.nix
+    ( manageCerts [ "biostase.de" "www.biostase.de" ])
+    #( serveWordpress [ "biostase.de" "www.biostase.de" ])
+
+    ( manageCerts [ "radical-dreamers.de" ])
+    ( serveWordpress [ "radical-dreamers.de" ])
+
+    ( manageCerts [ "gs-maubach.de" ])
+    ( serveWordpress [ "gs-maubach.de" ])
+
+    ( manageCerts [ "spielwaren-kern.de" ])
+    ( serveWordpress [ "spielwaren-kern.de" ])
+
+    ( manageCerts [ "familienpraxis-korntal.de" ])
+    ( servePage [ "familienpraxis-korntal.de" ])
+
+    ( manageCerts [ "ttf-kleinaspach.de" ])
+    ( serveWordpress [ "ttf-kleinaspach.de" ])
+
+    ( ssl [ "eastuttgart.de" ])
+    ( serveWordpress [ "eastuttgart.de" ])
+
+    ( ssl [ "habsys.de" "habsys.eu" ])
+    ( servePage [ "habsys.de" "habsys.eu" ])
   ];
 
-  lass.staticPage = {
-    "biostase.de" = {};
-    "gs-maubach.de" = {};
-    "spielwaren-kern.de" = {};
-    "societyofsimtech.de" = {};
-    "ttf-kleinaspach.de" = {};
-    "edsn.de" = {};
-    "eab.berkeley.edu" = {};
-    "habsys.de" = {};
+  services.mysql = {
+    enable = true;
+    package = pkgs.mariadb;
+    rootPassword = toString (<secrets/mysql_rootPassword>);
   };
 
-  #lass.owncloud = {
-  #  "o.ubikmedia.de" = {
-  #    instanceid = "oc8n8ddbftgh";
-  #  };
-  #};
-
-  #services.mysql = {
-  #  enable = true;
-  #  package = pkgs.mariadb;
-  #  rootPassword = toString (<secrets/mysql_rootPassword>);
-  #};
+  lass.mysqlBackup = {
+    enable = true;
+    config.fritz = {
+      password = toString (<secrets/mysql_rootPassword>);
+      databases = [
+        "biostase_de"
+        "eastuttgart_de"
+        "radical_dreamers_de"
+        "spielwaren_kern_de"
+        "ttf_kleinaspach_de"
+      ];
+    };
+  };
 }
diff --git a/lass/2configs/websites/wohnprojekt-rhh.de.nix b/lass/2configs/websites/wohnprojekt-rhh.de.nix
index ac784d4c7..858054531 100644
--- a/lass/2configs/websites/wohnprojekt-rhh.de.nix
+++ b/lass/2configs/websites/wohnprojekt-rhh.de.nix
@@ -1,14 +1,17 @@
-{ config, ... }:
+{ config, pkgs, lib, ... }:
 
-{
+let
+  inherit (config.krebs.lib) genid;
+  inherit (import ../../4lib { inherit lib pkgs; })
+    ssl
+    servePage;
+
+in {
   imports = [
-    ../../3modules/static_nginx.nix
+    ( ssl [ "wohnprojekt-rhh.de" ])
+    ( servePage [ "wohnprojekt-rhh.de" ])
   ];
 
-  lass.staticPage = {
-    "wohnprojekt-rhh.de" = {};
-  };
-
   users.users.laura = {
     home = "/srv/http/wohnprojekt-rhh.de";
     createHome = true;
diff --git a/lass/2configs/weechat.nix b/lass/2configs/weechat.nix
index 98f5df42a..5e14871ac 100644
--- a/lass/2configs/weechat.nix
+++ b/lass/2configs/weechat.nix
@@ -16,6 +16,7 @@ in {
     createHome = true;
     openssh.authorizedKeys.keys = [
       config.krebs.users.lass.pubkey
+      config.krebs.users.lass-shodan.pubkey
     ];
   };
 
diff --git a/lass/2configs/xserver/default.nix b/lass/2configs/xserver/default.nix
index 30afd787e..80c947a7b 100644
--- a/lass/2configs/xserver/default.nix
+++ b/lass/2configs/xserver/default.nix
@@ -40,8 +40,8 @@ let
       };
     };
 
-    security.setuidPrograms = [
-      "slock"
+    krebs.per-user.lass.packages = [
+      pkgs.rxvt_unicode_with-plugins
     ];
 
     systemd.services.display-manager.enable = false;
@@ -52,7 +52,7 @@ let
       wantedBy = [ "multi-user.target" ];
       requires = [ "xserver.service" ];
       environment = xmonad-environment;
-      restartIfChanged = false;
+      restartIfChanged = true;
       serviceConfig = {
         ExecStart = "${xmonad-start}/bin/xmonad";
         ExecStop = "${xmonad-stop}/bin/xmonad-stop";
@@ -82,12 +82,7 @@ let
 
     # XXX JSON is close enough :)
     XMONAD_WORKSPACES0_FILE = pkgs.writeText "xmonad.workspaces0" (toJSON [
-      "cr"
-      "gm"
-      "ff"
-      "IM"
-      "mail"
-      "stockholm"
+      "dashboard"
     ]);
   };
 
@@ -96,6 +91,9 @@ let
     set -efu
     export PATH; PATH=${makeSearchPath "bin" ([
       pkgs.rxvt_unicode
+      pkgs.i3lock
+      pkgs.pulseaudioLight
+      pkgs.xorg.xbacklight
     ] ++ config.environment.systemPackages)}:/var/setuid-wrappers
     settle() {(
       # Use PATH for a clean journal
@@ -114,7 +112,8 @@ let
 
   xmonad-stop = pkgs.writeScriptBin "xmonad-stop" ''
     #! /bin/sh
-    exec ${pkgs.xmonad-lass}/bin/xmonad --shutdown
+    ${pkgs.xmonad-lass}/bin/xmonad --shutdown
+    ${pkgs.coreutils}/bin/sleep 2s
   '';
 
   xserver-environment = {
@@ -128,7 +127,7 @@ let
   xserver = pkgs.writeScriptBin "xserver" ''
     #! /bin/sh
     set -efu
-    exec ${pkgs.xorg.xorgserver}/bin/X \
+    exec ${pkgs.xorg.xorgserver.out}/bin/X \
         :${toString config.services.xserver.display} \
         vt${toString config.services.xserver.tty} \
         -config ${import ./xserver.conf.nix args} \
diff --git a/lass/3modules/default.nix b/lass/3modules/default.nix
index f891498c2..380d83a91 100644
--- a/lass/3modules/default.nix
+++ b/lass/3modules/default.nix
@@ -1,11 +1,11 @@
 _:
 {
   imports = [
-    ./xresources.nix
+    ./ejabberd
     ./folderPerms.nix
-    ./per-user.nix
+    ./mysql-backup.nix
     ./urxvtd.nix
-    ./xresources.nix
     ./wordpress_nginx.nix
+    ./xresources.nix
   ];
 }
diff --git a/lass/3modules/ejabberd/config.nix b/lass/3modules/ejabberd/config.nix
new file mode 100644
index 000000000..9a4882644
--- /dev/null
+++ b/lass/3modules/ejabberd/config.nix
@@ -0,0 +1,93 @@
+{ config, ... }: with config.krebs.lib; let
+  cfg = config.lass.ejabberd;
+
+  # XXX this is a placeholder that happens to work the default strings.
+  toErlang = builtins.toJSON;
+in toFile "ejabberd.conf" ''
+  {loglevel, 3}.
+  {hosts, ${toErlang cfg.hosts}}.
+  {listen,
+   [
+    {5222, ejabberd_c2s, [
+        starttls,
+        {certfile, ${toErlang cfg.certfile}},
+        {access, c2s},
+        {shaper, c2s_shaper},
+        {max_stanza_size, 65536}
+             ]},
+    {5269, ejabberd_s2s_in, [
+           {shaper, s2s_shaper},
+           {max_stanza_size, 131072}
+          ]},
+    {5280, ejabberd_http, [
+         captcha,
+         http_bind,
+         http_poll,
+         web_admin
+        ]}
+   ]}.
+  {s2s_use_starttls, required}.
+  {s2s_certfile, ${toErlang cfg.s2s_certfile}}.
+  {auth_method, internal}.
+  {shaper, normal, {maxrate, 1000}}.
+  {shaper, fast, {maxrate, 50000}}.
+  {max_fsm_queue, 1000}.
+  {acl, local, {user_regexp, ""}}.
+  {access, max_user_sessions, [{10, all}]}.
+  {access, max_user_offline_messages, [{5000, admin}, {100, all}]}.
+  {access, local, [{allow, local}]}.
+  {access, c2s, [{deny, blocked},
+           {allow, all}]}.
+  {access, c2s_shaper, [{none, admin},
+            {normal, all}]}.
+  {access, s2s_shaper, [{fast, all}]}.
+  {access, announce, [{allow, admin}]}.
+  {access, configure, [{allow, admin}]}.
+  {access, muc_admin, [{allow, admin}]}.
+  {access, muc_create, [{allow, local}]}.
+  {access, muc, [{allow, all}]}.
+  {access, pubsub_createnode, [{allow, local}]}.
+  {access, register, [{allow, local}]}.
+  {language, "en"}.
+  {modules,
+   [
+    {mod_adhoc,    []},
+    {mod_announce, [{access, announce}]},
+    {mod_blocking,[]},
+    {mod_caps,     []},
+    {mod_configure,[]},
+    {mod_disco,    []},
+    {mod_irc,      []},
+    {mod_http_bind, []},
+    {mod_last,     []},
+    {mod_muc,      [
+        {access, muc},
+        {access_create, muc_create},
+        {access_persistent, muc_create},
+        {access_admin, muc_admin}
+       ]},
+    {mod_offline,  [{access_max_user_messages, max_user_offline_messages}]},
+    {mod_ping,     []},
+    {mod_privacy,  []},
+    {mod_private,  []},
+    {mod_pubsub,   [
+        {access_createnode, pubsub_createnode},
+        {ignore_pep_from_offline, true},
+        {last_item_cache, false},
+        {plugins, ["flat", "hometree", "pep"]}
+       ]},
+    {mod_register, [
+        {welcome_message, {"Welcome!",
+               "Hi.\nWelcome to this XMPP server."}},
+        {ip_access, [{allow, "127.0.0.0/8"},
+               {allow, "0.0.0.0/0"}]},
+        {access, register}
+       ]},
+    {mod_roster,   []},
+    {mod_shared_roster,[]},
+    {mod_stats,    []},
+    {mod_time,     []},
+    {mod_vcard,    []},
+    {mod_version,  []}
+   ]}.
+''
diff --git a/lass/3modules/ejabberd/default.nix b/lass/3modules/ejabberd/default.nix
new file mode 100644
index 000000000..c68f32ef0
--- /dev/null
+++ b/lass/3modules/ejabberd/default.nix
@@ -0,0 +1,57 @@
+{ config, lib, pkgs, ... }@args: with config.krebs.lib; let
+  cfg = config.lass.ejabberd;
+in {
+  options.lass.ejabberd = {
+    enable = mkEnableOption "lass.ejabberd";
+    certfile = mkOption {
+      type = types.str;
+    };
+    hosts = mkOption {
+      type = with types; listOf str;
+    };
+    pkgs.ejabberdctl = mkOption {
+      type = types.package;
+      default = pkgs.writeDashBin "ejabberdctl" ''
+        set -efu
+        export SPOOLDIR=${shell.escape cfg.user.home}
+        export EJABBERD_CONFIG_PATH=${shell.escape (import ./config.nix args)}
+        exec ${pkgs.ejabberd}/bin/ejabberdctl \
+            --logs ${shell.escape cfg.user.home} \
+            --spool ${shell.escape cfg.user.home} \
+            "$@"
+      '';
+    };
+    s2s_certfile = mkOption {
+      type = types.str;
+      default = cfg.certfile;
+    };
+    user = mkOption {
+      type = types.user;
+      default = {
+        name = "ejabberd";
+        home = "/var/ejabberd";
+      };
+    };
+  };
+  config = lib.mkIf cfg.enable {
+    environment.systemPackages = [ cfg.pkgs.ejabberdctl ];
+
+    systemd.services.ejabberd = {
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network.target" ];
+      serviceConfig = {
+        Type = "oneshot";
+        RemainAfterExit = "yes";
+        PermissionsStartOnly = "true";
+        SyslogIdentifier = "ejabberd";
+        User = cfg.user.name;
+        ExecStart = "${cfg.pkgs.ejabberdctl}/bin/ejabberdctl start";
+      };
+    };
+
+    users.users.${cfg.user.name} = {
+      inherit (cfg.user) home name uid;
+      createHome = true;
+    };
+  };
+}
diff --git a/lass/3modules/mysql-backup.nix b/lass/3modules/mysql-backup.nix
new file mode 100644
index 000000000..d2ae67171
--- /dev/null
+++ b/lass/3modules/mysql-backup.nix
@@ -0,0 +1,86 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.lass.mysqlBackup;
+
+  out = {
+    options.lass.mysqlBackup = api;
+    config = mkIf cfg.enable imp;
+  };
+
+  api = {
+    enable = mkEnableOption "mysqlBackup";
+    config = mkOption {
+      type = with types; attrsOf (submodule ({ config, ... }: {
+        options = {
+          name = mkOption {
+            type = types.str;
+            default = config._module.args.name;
+          };
+          startAt = mkOption {
+            type = with types; nullOr str; # TODO systemd.time(7)'s calendar event
+            default = "*-*-* 01:15:00";
+          };
+          user = mkOption {
+            type = str;
+            default = "root";
+          };
+          password = mkOption {
+            type = nullOr str;
+            default = null;
+            description = ''
+              path to a file containing the mysqlPassword for the specified user.
+            '';
+          };
+          databases = mkOption {
+            type = listOf str;
+            default = [];
+          };
+          location = mkOption {
+            type = str;
+            default = "/bku/sql_dumps";
+          };
+        };
+      }));
+      description = "configuration for mysqlBackup";
+    };
+  };
+
+  imp = {
+
+    #systemd.timers =
+    #  mapAttrs (_: plan: {
+    #  wantedBy = [ "timers.target" ];
+    #  timerConfig = plan.timerConfig;
+    #}) cfg.config;
+
+    systemd.services =
+      mapAttrs' (_: plan: nameValuePair "mysqlBackup-${plan.name}" {
+        path = with pkgs; [
+          mysql
+          gzip
+        ];
+        serviceConfig = rec {
+          ExecStart = start plan;
+          SyslogIdentifier = ExecStart.name;
+          Type = "oneshot";
+          User = plan.user;
+        };
+        startAt = plan.startAt;
+      }) cfg.config;
+  };
+
+
+  start = plan: let
+    backupScript = plan: db:
+      "mysqldump -u ${plan.user} ${optionalString (plan.password != null) "-p$(cat ${plan.password})"} ${db} | gzip -c > ${plan.location}/${db}.gz";
+
+  in pkgs.pkgs.writeDash "mysqlBackup.${plan.name}" ''
+    ${concatMapStringsSep "\n" (backupScript plan) plan.databases}
+  '';
+
+
+in out
diff --git a/lass/3modules/per-user.nix b/lass/3modules/per-user.nix
deleted file mode 100644
index f8d357ce2..000000000
--- a/lass/3modules/per-user.nix
+++ /dev/null
@@ -1,53 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with config.krebs.lib;
-let
-  cfg = config.lass.per-user;
-
-  out = {
-    options.lass.per-user = api;
-    config = imp;
-  };
-
-  api = mkOption {
-    type = with types; attrsOf (submodule {
-      options = {
-        packages = mkOption {
-          type = listOf path;
-          default = [];
-        };
-      };
-    });
-    default = {};
-  };
-
-  imp = {
-    #
-    # TODO only shellInit and use well-known paths
-    #
-    environment.shellInit = ''
-      if test -e ${user-profiles}/"$LOGNAME"; then
-        . ${user-profiles}/"$LOGNAME"
-      fi
-    '';
-    environment.interactiveShellInit = ''
-      if test -e ${user-profiles}/"$LOGNAME"; then
-        . ${user-profiles}/"$LOGNAME"
-      fi
-    '';
-    environment.profileRelativeEnvVars.PATH = mkForce [ "/bin" ];
-  };
-
-  user-profiles = pkgs.runCommand "user-profiles" {} ''
-    mkdir $out
-    ${concatStrings (mapAttrsToList (logname: { packages, ... }: ''
-      cat > $out/${logname} <<\EOF
-      ${optionalString (length packages > 0) (
-        let path = makeSearchPath "bin" packages; in
-        ''export PATH="$PATH":${escapeShellArg path}''
-      )}
-      EOF
-    '') cfg)}
-  '';
-
-in out
diff --git a/lass/4lib/default.nix b/lass/4lib/default.nix
index a751a2995..30cbced49 100644
--- a/lass/4lib/default.nix
+++ b/lass/4lib/default.nix
@@ -1,10 +1,231 @@
-{ lib, ... }:
+{ lib, pkgs, ... }:
 
 with lib;
 
-{
+rec {
 
   getDefaultGateway = ip:
     concatStringsSep "." (take 3 (splitString "." ip) ++ ["1"]);
 
+  manageCerts = domains:
+    let
+      domain = head domains;
+    in {
+      security.acme = {
+        certs."${domain}" = {
+          email = "lassulus@gmail.com";
+          webroot = "/var/lib/acme/challenges/${domain}";
+          plugins = [
+            "account_key.json"
+            "key.pem"
+            "fullchain.pem"
+          ];
+          group = "nginx";
+          allowKeysForGroup = true;
+          extraDomains = genAttrs domains (_: null);
+        };
+      };
+
+      krebs.nginx.servers."${domain}" = {
+        locations = [
+          (nameValuePair "/.well-known/acme-challenge" ''
+            root /var/lib/acme/challenges/${domain}/;
+          '')
+        ];
+      };
+    };
+
+  ssl = domains:
+    {
+      imports = [
+        ( manageCerts domains )
+        ( activateACME (head domains) )
+      ];
+    };
+
+  activateACME = domain:
+    {
+      krebs.nginx.servers."${domain}" = {
+        ssl = {
+          enable = true;
+          certificate = "/var/lib/acme/${domain}/fullchain.pem";
+          certificate_key = "/var/lib/acme/${domain}/key.pem";
+        };
+      };
+    };
+
+  servePage = domains:
+    let
+      domain = head domains;
+    in {
+      krebs.nginx.servers."${domain}" = {
+        server-names = domains;
+        locations = [
+          (nameValuePair "/" ''
+            root /srv/http/${domain};
+          '')
+        ];
+      };
+    };
+
+  serveOwncloud = domains:
+    let
+      domain = head domains;
+    in {
+      krebs.nginx.servers."${domain}" = {
+        server-names = domains;
+        extraConfig = ''
+          # Add headers to serve security related headers
+          add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
+          add_header X-Content-Type-Options nosniff;
+          add_header X-Frame-Options "SAMEORIGIN";
+          add_header X-XSS-Protection "1; mode=block";
+          add_header X-Robots-Tag none;
+
+          # Path to the root of your installation
+          root /srv/http/${domain}/;
+          # set max upload size
+          client_max_body_size 10G;
+          fastcgi_buffers 64 4K;
+
+          # Disable gzip to avoid the removal of the ETag header
+          gzip off;
+
+          # Uncomment if your server is build with the ngx_pagespeed module
+          # This module is currently not supported.
+          #pagespeed off;
+
+          index index.php;
+          error_page 403 /core/templates/403.php;
+          error_page 404 /core/templates/404.php;
+
+          rewrite ^/.well-known/carddav /remote.php/carddav/ permanent;
+          rewrite ^/.well-known/caldav /remote.php/caldav/ permanent;
+
+          # The following 2 rules are only needed for the user_webfinger app.
+          # Uncomment it if you're planning to use this app.
+          rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
+          rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
+        '';
+        locations = [
+          (nameValuePair "/robots.txt" ''
+            allow all;
+            log_not_found off;
+            access_log off;
+          '')
+          (nameValuePair "~ ^/(build|tests|config|lib|3rdparty|templates|data)/" ''
+            deny all;
+          '')
+
+          (nameValuePair "~ ^/(?:autotest|occ|issue|indie|db_|console)" ''
+            deny all;
+          '')
+
+          (nameValuePair "/" ''
+            rewrite ^/remote/(.*) /remote.php last;
+            rewrite ^(/core/doc/[^\/]+/)$ $1/index.html;
+            try_files $uri $uri/ =404;
+          '')
+
+          (nameValuePair "~ \.php(?:$|/)" ''
+            fastcgi_split_path_info ^(.+\.php)(/.+)$;
+            include ${pkgs.nginx}/conf/fastcgi_params;
+            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+            fastcgi_param PATH_INFO $fastcgi_path_info;
+            fastcgi_param HTTPS on;
+            fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
+            fastcgi_pass unix:/srv/http/${domain}/phpfpm.pool;
+            fastcgi_intercept_errors on;
+          '')
+
+          # Adding the cache control header for js and css files
+          # Make sure it is BELOW the location ~ \.php(?:$|/) { block
+          (nameValuePair "~* \.(?:css|js)$" ''
+            add_header Cache-Control "public, max-age=7200";
+            # Add headers to serve security related headers
+            add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
+            add_header X-Content-Type-Options nosniff;
+            add_header X-Frame-Options "SAMEORIGIN";
+            add_header X-XSS-Protection "1; mode=block";
+            add_header X-Robots-Tag none;
+            # Optional: Don't log access to assets
+            access_log off;
+          '')
+
+          # Optional: Don't log access to other assets
+          (nameValuePair "~* \.(?:jpg|jpeg|gif|bmp|ico|png|swf)$" ''
+            access_log off;
+          '')
+        ];
+      };
+      services.phpfpm.poolConfigs."${domain}" = ''
+        listen = /srv/http/${domain}/phpfpm.pool
+        user = nginx
+        group = nginx
+        pm = dynamic
+        pm.max_children = 5
+        pm.start_servers = 2
+        pm.min_spare_servers = 1
+        pm.max_spare_servers = 3
+        listen.owner = nginx
+        listen.group = nginx
+        # errors to journal
+        php_admin_value[error_log] = 'stderr'
+        php_admin_flag[log_errors] = on
+        catch_workers_output = yes
+      '';
+    };
+
+  serveWordpress = domains:
+    let
+      domain = head domains;
+
+    in {
+      krebs.nginx.servers."${domain}" = {
+        server-names = domains;
+        extraConfig = ''
+          root /srv/http/${domain}/;
+          index index.php;
+          access_log /tmp/nginx_acc.log;
+          error_log /tmp/nginx_err.log;
+          error_page 404 /404.html;
+          error_page 500 502 503 504 /50x.html;
+        '';
+        locations = [
+          (nameValuePair "/" ''
+            try_files $uri $uri/ /index.php?$args;
+          '')
+          (nameValuePair "~ \.php$" ''
+            fastcgi_pass unix:/srv/http/${domain}/phpfpm.pool;
+            include ${pkgs.nginx}/conf/fastcgi.conf;
+          '')
+          #(nameValuePair "~ /\\." ''
+          #  deny all;
+          #'')
+          #Directives to send expires headers and turn off 404 error logging.
+          (nameValuePair "~* ^.+\.(xml|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$" ''
+            access_log off;
+            log_not_found off;
+            expires max;
+          '')
+        ];
+      };
+      services.phpfpm.poolConfigs."${domain}" = ''
+        listen = /srv/http/${domain}/phpfpm.pool
+        user = nginx
+        group = nginx
+        pm = dynamic
+        pm.max_children = 5
+        pm.start_servers = 2
+        pm.min_spare_servers = 1
+        pm.max_spare_servers = 3
+        listen.owner = nginx
+        listen.group = nginx
+        # errors to journal
+        php_admin_value[error_log] = 'stderr'
+        php_admin_flag[log_errors] = on
+        catch_workers_output = yes
+      '';
+    };
+
 }
diff --git a/lass/5pkgs/acronym/default.nix b/lass/5pkgs/acronym/default.nix
index 53d5d015a..9f6f95587 100644
--- a/lass/5pkgs/acronym/default.nix
+++ b/lass/5pkgs/acronym/default.nix
@@ -1,13 +1,16 @@
 { pkgs, ... }:
 
 pkgs.writeScriptBin "acronym" ''
+
   #! ${pkgs.bash}/bin/bash
 
   acro=$1
 
   curl -s http://www.acronymfinder.com/$acro.html \
-  | grep 'class="result-list__body__rank"' \
-  | sed 's/.*title="\([^"]*\)".*/\1/' \
-  | sed 's/^.* - //' \
-  | sed "s/&#39;/'/g"
+    | grep 'class="result-list__body__rank"' \
+    | sed '
+      s/.*title="\([^"]*\)".*/\1/
+      s/^.* - //
+      s/&#39;/'\'''/g
+    '
 ''
diff --git a/lass/5pkgs/default.nix b/lass/5pkgs/default.nix
index 0c9dd94ca..467867f63 100644
--- a/lass/5pkgs/default.nix
+++ b/lass/5pkgs/default.nix
@@ -8,7 +8,10 @@
       ublock = pkgs.callPackage ./firefoxPlugins/ublock.nix {};
       vimperator = pkgs.callPackage ./firefoxPlugins/vimperator.nix {};
     };
+    mk_sql_pair = pkgs.callPackage ./mk_sql_pair/default.nix {};
     mpv-poll = pkgs.callPackage ./mpv-poll/default.nix {};
+    untilport = pkgs.callPackage ./untilport/default.nix {};
+    urban = pkgs.callPackage ./urban/default.nix {};
     xmonad-lass =
       let src = pkgs.writeNixFromCabal "xmonad-lass.nix" ./xmonad-lass; in
       pkgs.haskellPackages.callPackage src {};
diff --git a/lass/5pkgs/mk_sql_pair/default.nix b/lass/5pkgs/mk_sql_pair/default.nix
new file mode 100644
index 000000000..738a8daf6
--- /dev/null
+++ b/lass/5pkgs/mk_sql_pair/default.nix
@@ -0,0 +1,19 @@
+{ pkgs, ... }:
+
+pkgs.writeScriptBin "mk_sql_pair" ''
+  #!/bin/sh
+
+  name=$1
+  password=$2
+
+  if [ $# -ne 2 ]; then
+    echo '$1=name, $2=password'
+    exit 23;
+  fi
+
+  cat <<EOF
+  create database $name;
+  create user $name;
+  grant all on $name.* to $name@'localhost' identified by '$password';
+  EOF
+''
diff --git a/lass/5pkgs/untilport/default.nix b/lass/5pkgs/untilport/default.nix
new file mode 100644
index 000000000..61bcc2b89
--- /dev/null
+++ b/lass/5pkgs/untilport/default.nix
@@ -0,0 +1,18 @@
+{ pkgs, ... }:
+
+pkgs.writeDashBin "untilport" ''
+  set -euf
+
+  usage() {
+    echo 'untiport $target $port'
+    echo 'Sleeps until the destinated port is reachable.'
+    echo 'ex: untilport google.de 80 && echo "google is now reachable"'
+  }
+
+
+  if [ $# -ne 2 ]; then
+    usage
+  else
+    until ${pkgs.netcat-openbsd}/bin/nc -z "$@"; do sleep 1; done
+  fi
+''
diff --git a/lass/5pkgs/urban/default.nix b/lass/5pkgs/urban/default.nix
new file mode 100644
index 000000000..fb8adaed9
--- /dev/null
+++ b/lass/5pkgs/urban/default.nix
@@ -0,0 +1,21 @@
+{ pkgs, ... }:
+
+pkgs.writeScriptBin "urban" ''
+  #!/bin/sh
+  set -euf
+  term=$1
+  curl -LsS 'http://www.urbandictionary.com/define.php?term='"$term" \
+    | sed 's/<\/\?a\>[^>]*>//g' \
+    | sed 's/<\([^>]*\)>/\n<\1\n/g' \
+    | grep . \
+    | sed -n '/<div class=.meaning./,/<\/div/p' \
+    | sed 's/<div class=.meaning./-----/' \
+    | grep -v '^</div\>' \
+    | grep -v '^<br\>' \
+    | sed '
+      s/&quot;/"/g
+      s/&#39;/'\'''/g
+      s/&gt;/>/g
+      s/&lt;/>/g
+    '
+''
diff --git a/lass/5pkgs/xmonad-lass/Main.hs b/lass/5pkgs/xmonad-lass/Main.hs
index 503df3be7..d7c66bf4d 100644
--- a/lass/5pkgs/xmonad-lass/Main.hs
+++ b/lass/5pkgs/xmonad-lass/Main.hs
@@ -5,56 +5,37 @@
 
 
 module Main where
-
-import Control.Exception
-import Text.Read (readEither)
 import XMonad
-import System.IO (hPutStrLn, stderr)
-import System.Environment (getArgs, withArgs, getEnv, getEnvironment)
-import System.Posix.Process (executeFile)
-import XMonad.Actions.DynamicWorkspaces ( addWorkspacePrompt, renameWorkspace
-                                        , removeEmptyWorkspace)
-import XMonad.Actions.GridSelect
-import XMonad.Actions.CycleWS (toggleWS)
---import XMonad.Actions.CopyWindow ( copy )
-import XMonad.Layout.NoBorders ( smartBorders )
+
 import qualified XMonad.StackSet as W
-import Data.Map (Map)
-import qualified Data.Map as Map
--- TODO import XMonad.Layout.WorkspaceDir
-import XMonad.Hooks.UrgencyHook (SpawnUrgencyHook(..), withUrgencyHook)
--- import XMonad.Layout.Tabbed
---import XMonad.Layout.MouseResizableTile
-import XMonad.Layout.Reflect (reflectVert)
-import XMonad.Layout.FixedColumn (FixedColumn(..))
-import XMonad.Hooks.Place (placeHook, smart)
-import XMonad.Hooks.FloatNext (floatNextHook)
-import XMonad.Actions.PerWorkspaceKeys (chooseAction)
-import XMonad.Layout.PerWorkspace (onWorkspace)
---import XMonad.Layout.BinarySpacePartition
-import XMonad.Util.EZConfig (additionalKeysP)
-
-import XMonad.Prompt (autoComplete, defaultXPConfig, XPConfig, mkXPrompt)
-import XMonad.Hooks.UrgencyHook (focusUrgent, withUrgencyHook, urgencyBorderColor, BorderUrgencyHook(BorderUrgencyHook))
-import XMonad.Actions.DynamicWorkspaces (addWorkspacePrompt, removeEmptyWorkspace, renameWorkspace, withWorkspace)
-import XMonad.Hooks.FloatNext (floatNext, floatNextHook)
-import XMonad.Prompt.Workspace
+import Control.Exception
+import Data.List (isInfixOf)
+import System.Environment (getArgs, withArgs, getEnv)
+import System.IO (hPutStrLn, stderr)
+import Text.Read (readEither)
 import XMonad.Actions.CopyWindow (copy, kill1)
-import qualified Data.Map as M
-import XMonad.Hooks.ManageDocks (avoidStruts, manageDocks, ToggleStruts(ToggleStruts))
-
---import XMonad.Actions.Submap
-import XMonad.Stockholm.Pager
-import XMonad.Stockholm.Rhombus
-import XMonad.Stockholm.Shutdown
+import XMonad.Actions.CycleWS (toggleWS)
+import XMonad.Actions.DynamicWorkspaces ( addWorkspacePrompt, renameWorkspace, removeEmptyWorkspace)
+import XMonad.Actions.DynamicWorkspaces (withWorkspace)
+import XMonad.Actions.GridSelect (GSConfig(..), gridselectWorkspace, navNSearch)
+import XMonad.Hooks.FloatNext (floatNext)
+import XMonad.Hooks.FloatNext (floatNextHook)
+import XMonad.Hooks.ManageDocks (avoidStruts, ToggleStruts(ToggleStruts))
+import XMonad.Hooks.Place (placeHook, smart)
+import XMonad.Hooks.UrgencyHook (focusUrgent)
+import XMonad.Hooks.UrgencyHook (SpawnUrgencyHook(..), withUrgencyHook)
+import XMonad.Layout.FixedColumn (FixedColumn(..))
+import XMonad.Layout.Minimize (minimize, minimizeWindow, MinimizeMsg(RestoreNextMinimizedWin))
+import XMonad.Layout.NoBorders (smartBorders)
+import XMonad.Prompt (autoComplete, searchPredicate, XPConfig)
+import XMonad.Prompt.Window (windowPromptGoto, windowPromptBringCopy)
+import XMonad.Stockholm.Shutdown (sendShutdownEvent, handleShutdownEvent)
+import XMonad.Util.EZConfig (additionalKeysP)
 
 
 myTerm :: String
 myTerm = "urxvtc"
 
-myRootTerm :: String
-myRootTerm = "urxvtc -name root-urxvt -e su -"
-
 myFont :: String
 myFont = "-schumacher-*-*-*-*-*-*-*-*-*-*-*-iso10646-*"
 
@@ -67,18 +48,12 @@ mainNoArgs :: IO ()
 mainNoArgs = do
     workspaces0 <- getWorkspaces0
     xmonad'
-        -- $ withUrgencyHookC dzenUrgencyHook { args = ["-bg", "magenta", "-fg", "magenta", "-h", "2"], duration = 500000 }
-        --                   urgencyConfig { remindWhen = Every 1 }
-        -- $ withUrgencyHook borderUrgencyHook "magenta"
-        -- $ withUrgencyHookC BorderUrgencyHook { urgencyBorderColor = "magenta" } urgencyConfig { suppressWhen = Never }
         $ withUrgencyHook (SpawnUrgencyHook "echo emit Urgency ")
         $ def
             { terminal          = myTerm
             , modMask           = mod4Mask
             , workspaces        = workspaces0
             , layoutHook = smartBorders $ myLayoutHook
-            -- , handleEventHook   = myHandleEventHooks <+> handleTimerEvent
-            --, handleEventHook   = handleTimerEvent
             , manageHook        = placeHook (smart (1,0)) <+> floatNextHook
             , startupHook       = spawn "echo emit XMonadStartup"
             , normalBorderColor  = "#1c1c1c"
@@ -88,7 +63,7 @@ mainNoArgs = do
 
 myLayoutHook = defLayout
   where
-    defLayout = (avoidStruts $ Tall 1 (3/100) (1/2) ||| Full ||| Mirror (Tall 1 (3/100) (1/2))) ||| FixedColumn 2 80 80 1
+    defLayout = minimize $ ((avoidStruts $ Tall 1 (3/100) (1/2) ||| Full ||| Mirror (Tall 1 (3/100) (1/2))) ||| FixedColumn 2 80 80 1)
 
 
 xmonad' :: (LayoutClass l Window, Read (l Window)) => XConfig l -> IO ()
@@ -96,7 +71,7 @@ xmonad' conf = do
     path <- getEnv "XMONAD_STATE"
     try (readFile path) >>= \case
         Right content -> do
-            hPutStrLn stderr ("resuming from " ++ path)
+            hPutStrLn stderr ("resuming from " ++ path ++ "; state = " ++ show content)
             withArgs ("--resume" : lines content) (xmonad conf)
         Left e -> do
             hPutStrLn stderr (displaySomeException e)
@@ -118,19 +93,21 @@ displaySomeException :: SomeException -> String
 displaySomeException = displayException
 
 
+myKeyMap :: [([Char], X ())]
 myKeyMap =
-    [ ("M4-<F11>", spawn "/var/setuid-wrappers/slock")
+    [ ("M4-<F11>", spawn "i3lock -i /var/lib/wallpaper/wallpaper -f")
     , ("M4-p", spawn "passmenu --type")
-    --, ("M4-r", spawn "exe=$(yeganesh -x) && eval \"exec $exe\"")
     , ("<XF86AudioRaiseVolume>", spawn "pactl -- set-sink-volume 0 +4%")
     , ("<XF86AudioLowerVolume>", spawn "pactl -- set-sink-volume 0 -4%")
     , ("<XF86AudioMute>", spawn "pactl -- set-sink-mute 0 toggle")
     , ("<XF86AudioMicMute>", spawn "pactl -- set-source-mute 1 toggle")
-    , ("<XF86Launch1>", gridselectWorkspace myWSConfig W.view)
+    , ("<XF86Launch1>", gridselectWorkspace gridConfig W.view)
+    , ("<XF86MonBrightnessUp>", spawn "xbacklight -steps 1 -time 1 -inc 3")
+    , ("<XF86MonBrightnessDown>", spawn "xbacklight -steps 1 -time 1 -dec 3")
 
     , ("M4-a", focusUrgent)
-    , ("M4-S-r", renameWorkspace    defaultXPConfig)
-    , ("M4-S-a", addWorkspacePrompt defaultXPConfig)
+    , ("M4-S-r", renameWorkspace    def)
+    , ("M4-S-a", addWorkspacePrompt def)
     , ("M4-S-<Backspace>", removeEmptyWorkspace)
     , ("M4-S-c", kill1)
     , ("M4-<Esc>", toggleWS)
@@ -139,66 +116,34 @@ myKeyMap =
     , ("M4-f", floatNext True)
     , ("M4-b", sendMessage ToggleStruts)
 
-    , ("M4-v", withWorkspace myXPConfig (windows . W.view))
-    , ("M4-S-v", withWorkspace myXPConfig (windows . W.shift))
-    , ("M4-C-v", withWorkspace myXPConfig (windows . copy))
+    , ("M4-v", withWorkspace autoXPConfig (windows . W.view))
+    , ("M4-S-v", withWorkspace autoXPConfig (windows . W.shift))
+    , ("M4-C-v", withWorkspace autoXPConfig (windows . copy))
 
-    -- , (_4 , xK_q      ) & \k -> (k, goToSelected myCNConfig { gs_navigate = makeGSNav k }                   )
-    -- , (_4S, xK_q      ) & \k -> (k, bringSelected myCNConfig { gs_navigate = makeGSNav k }                  )
-    -- , (_4C, xK_q      ) & \k -> (k, withSelectedWindow ( \a -> get >>= \s -> put s { windowset = copyWindow a (W.tag $ W.workspace $ W.current $ windowset s) (windowset s) } ) myCNConfig { gs_navigate = makeGSNav k } )
+    , ("M4-m", withFocused minimizeWindow)
+    , ("M4-S-m", sendMessage RestoreNextMinimizedWin)
+
+    , ("M4-q", windowPromptGoto infixAutoXPConfig)
+    , ("M4-C-q", windowPromptBringCopy infixAutoXPConfig)
 
-    --, ("M4-<F1>", perWorkspaceAction workspaceConfigs)
     , ("M4-S-q", return ())
     ]
 
-myGSConfig = defaultGSConfig
-    { gs_cellheight = 50
+autoXPConfig :: XPConfig
+autoXPConfig = def
+    { autoComplete = Just 5000
+    }
+
+infixAutoXPConfig :: XPConfig
+infixAutoXPConfig = autoXPConfig
+    { searchPredicate = isInfixOf
+    }
+
+gridConfig :: GSConfig WorkspaceId
+gridConfig = def
+    { gs_cellwidth = 100
+    , gs_cellheight = 30
     , gs_cellpadding = 2
     , gs_navigate = navNSearch
     , gs_font = myFont
     }
-
-myXPConfig :: XPConfig
-myXPConfig = defaultXPConfig
-    { autoComplete = Just 5000
-    }
-
-myWSConfig = myGSConfig
-    { gs_cellwidth = 50
-    }
-
-pagerConfig :: PagerConfig
-pagerConfig = def
-    { pc_font           = myFont
-    , pc_cellwidth      = 64
-    --, pc_cellheight     = 36 -- TODO automatically keep screen aspect
-    --, pc_borderwidth    = 1
-    --, pc_matchcolor     = "#f0b000"
-    , pc_matchmethod    = MatchPrefix
-    --, pc_colors         = pagerWorkspaceColors
-    , pc_windowColors   = windowColors
-    }
-    where
-    windowColors _ _ _ True _ = ("#ef4242","#ff2323")
-    windowColors wsf m c u wf = do
-        let y = defaultWindowColors wsf m c u wf
-        if m == False && wf == True
-            then ("#402020", snd y)
-            else y
-
-wGSConfig :: GSConfig Window
-wGSConfig = def
-    { gs_cellheight = 20
-    , gs_cellwidth = 192
-    , gs_cellpadding = 5
-    , gs_font = myFont
-    , gs_navigate = navNSearch
-    }
-
-
-(&) :: a -> (a -> c) -> c
-(&) = flip ($)
-
-allWorkspaceNames :: W.StackSet i l a sid sd -> X [i]
-allWorkspaceNames ws =
-    return $ map W.tag (W.hidden ws) ++ [W.tag $ W.workspace $ W.current ws]
diff --git a/lass/5pkgs/xmonad-lass/Util/PerWorkspaceConfig.hs b/lass/5pkgs/xmonad-lass/Util/PerWorkspaceConfig.hs
deleted file mode 100644
index bba7c8c60..000000000
--- a/lass/5pkgs/xmonad-lass/Util/PerWorkspaceConfig.hs
+++ /dev/null
@@ -1,52 +0,0 @@
-module Util.PerWorkspaceConfig
-  ( WorkspaceConfig (..)
-  , WorkspaceConfigs
-  , switchToWorkspace
-  , defaultWorkspaceConfig
-  , perWorkspaceAction
-  , perWorkspaceTermAction
---  , myLayoutHack
-  )
-where
-
-import XMonad
-import XMonad.Core (LayoutClass)
-import Control.Monad (when)
-
-import qualified Data.Map as M
-import qualified XMonad.StackSet as W
-
-data WorkspaceConfig l =
-  WorkspaceConfig
-    { switchAction :: X ()
-    , startAction  :: X ()
-    , keyAction    :: X ()
-    , termAction   :: X ()
-    }
-
-type WorkspaceConfigs l = M.Map WorkspaceId (WorkspaceConfig l)
-
-defaultWorkspaceConfig = WorkspaceConfig
-                             { switchAction = return ()
-                             , startAction  = return ()
-                             , keyAction    = return ()
-                             , termAction   = spawn "urxvtc"
-                             }
-
-whenLookup wsId cfg a =
-    when (M.member wsId cfg) (a $ cfg M.! wsId)
-
-switchToWorkspace :: WorkspaceConfigs l -> WorkspaceId -> X ()
-switchToWorkspace cfg wsId = do
-  windows $ W.greedyView wsId
-  wins <- gets (W.integrate' . W.stack . W.workspace . W.current . windowset)
-  when (null wins) $ whenLookup wsId cfg startAction
-  whenLookup wsId cfg switchAction
-
-perWorkspaceAction :: WorkspaceConfigs l -> X ()
-perWorkspaceAction cfg = withWindowSet $ \s -> whenLookup (W.currentTag s) cfg keyAction
-
-perWorkspaceTermAction :: WorkspaceConfigs l -> X ()
-perWorkspaceTermAction cfg = withWindowSet $ \s -> case M.lookup (W.currentTag s) cfg of
-                                                       Just x -> termAction x
-                                                       _      -> termAction defaultWorkspaceConfig