diff --git a/krebs/3modules/apt-cacher-ng.nix b/krebs/3modules/apt-cacher-ng.nix
new file mode 100644
index 000000000..75296bafb
--- /dev/null
+++ b/krebs/3modules/apt-cacher-ng.nix
@@ -0,0 +1,157 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+let
+  acng-config = pkgs.writeTextFile {
+    name = "acng-configuration";
+    destination = "/acng.conf";
+    text = ''
+      ForeGround: 1
+      CacheDir: ${cfg.cacheDir}
+      LogDir: ${cfg.logDir}
+      PidFile: /var/run/apt-cacher-ng.pid
+      ExTreshold: ${toString cfg.cacheExpiration}
+      CAfile: ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt
+
+      Port: ${toString cfg.port}
+      BindAddress: ${cfg.bindAddress}
+
+      # defaults:
+      Remap-debrep: file:deb_mirror*.gz /debian ; file:backends_debian
+      Remap-uburep: file:ubuntu_mirrors /ubuntu ; file:backends_ubuntu
+      Remap-debvol: file:debvol_mirror*.gz /debian-volatile ; file:backends_debvol
+      Remap-cygwin: file:cygwin_mirrors /cygwin
+      Remap-sfnet:  file:sfnet_mirrors
+      Remap-alxrep: file:archlx_mirrors /archlinux
+      Remap-fedora: file:fedora_mirrors
+      Remap-epel:   file:epel_mirrors
+      Remap-slrep:  file:sl_mirrors # Scientific Linux
+      Remap-gentoo: file:gentoo_mirrors.gz /gentoo ; file:backends_gentoo
+
+      ReportPage: acng-report.html
+      SupportDir: ${pkgs.apt-cacher-ng}/lib/apt-cacher-ng
+      LocalDirs: acng-doc ${pkgs.apt-cacher-ng}/share/doc/apt-cacher-ng
+
+      # Nix cache
+      ${optionalString cfg.enableNixCache ''
+        Remap-nix: http://cache.nixos.org /nixos ; https://cache.nixos.org
+        PfilePatternEx: (^|.*?/).*\.nar(info)?(|\.gz|\.xz|\.bz2)$
+        VfilePatternEx: (^|.*?/)nix-cache-info$
+      ''}
+
+      ${cfg.extraConfig}
+    '';
+  };
+
+  acng-home = "/var/cache/acng";
+  cfg = config.krebs.apt-cacher-ng;
+
+  api = {
+    enable = mkEnableOption "apt-cacher-ng";
+
+    cacheDir = mkOption {
+      default = acng-home + "/cache";
+      type = types.str;
+      description = ''
+        Path to apt-cacher-ng cache directory.
+        Will be created and chowned to acng-user
+      '';
+    };
+
+    logDir = mkOption {
+      default = acng-home + "/log";
+      type = types.str;
+      description = ''
+        Path to apt-cacher-ng log directory.
+        Will be created and chowned to acng-user
+      '';
+    };
+
+    port = mkOption {
+      default = 3142;
+      type = types.int;
+      description = ''
+        port of apt-cacher-ng
+      '';
+    };
+
+    bindAddress = mkOption {
+      default = "";
+      type = types.str;
+      example = "localhost 192.168.7.254 publicNameOnMainInterface";
+      description = ''
+        listen address of apt-cacher-ng. Defaults to every interface.
+      '';
+    };
+
+    cacheExpiration = mkOption {
+      default = 4;
+      type = types.int;
+      description = ''
+        number of days before packages expire in the cache without being
+        requested.
+      '';
+    };
+
+    enableNixCache = mkOption {
+      default = true;
+      type = types.bool;
+      description = ''
+        enable cache.nixos.org caching via PfilePatternEx and VfilePatternEx.
+
+        to use the apt-cacher-ng in your nixos configuration:
+          nix.binary-cache = [ http://acng-host:port/nixos ];
+
+        These options cannot be used in extraConfig, use SVfilePattern and
+        SPfilePattern or disable this option.
+      '';
+    };
+
+    extraConfig = mkOption {
+      default = "";
+      type = types.lines;
+      description = ''
+        extra config appended to the generated acng.conf
+      '';
+    };
+  };
+
+  imp = {
+
+    users.extraUsers.acng = {
+    # uid = config.ids.uids.acng;
+      uid = 897955083; #genid Reaktor
+      description = "apt-cacher-ng";
+      home = acng-home;
+      createHome = false;
+    };
+
+    users.extraGroups.acng = {
+      gid = 897955083; #genid Reaktor
+    # gid = config.ids.gids.Reaktor;
+    };
+
+    systemd.services.apt-cacher-ng = {
+      description = "apt-cacher-ng";
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        PermissionsStartOnly = true;
+        ExecStartPre = pkgs.writeScript "acng-init" ''
+          #!/bin/sh
+          mkdir -p ${shell.escape cfg.cacheDir} ${shell.escape cfg.logDir}
+          chown acng:acng  ${shell.escape cfg.cacheDir} ${shell.escape cfg.logDir}
+        '';
+        ExecStart = "${pkgs.apt-cacher-ng}/bin/apt-cacher-ng -c ${acng-config}";
+        PrivateTmp = "true";
+        User = "acng";
+        Restart = "always";
+        RestartSec = "10";
+      };
+    };
+  };
+in
+{
+  options.krebs.apt-cacher-ng = api;
+  config = mkIf cfg.enable imp;
+}
diff --git a/krebs/3modules/default.nix b/krebs/3modules/default.nix
index a908d437b..740ba67b8 100644
--- a/krebs/3modules/default.nix
+++ b/krebs/3modules/default.nix
@@ -6,13 +6,16 @@ let
 
   out = {
     imports = [
+      ./apt-cacher-ng.nix
       ./bepasty-server.nix
       ./build.nix
       ./current.nix
       ./exim-retiolum.nix
       ./exim-smarthost.nix
+      ./fetchWallpaper.nix
       ./github-hosts-sync.nix
       ./git.nix
+      ./go.nix
       ./iptables.nix
       ./nginx.nix
       ./per-user.nix
@@ -85,6 +88,7 @@ let
       krebs.dns.providers = {
         de.krebsco = "zones";
         gg23 = "hosts";
+        shack = "hosts";
         internet = "hosts";
         retiolum = "hosts";
       };
diff --git a/krebs/3modules/fetchWallpaper.nix b/krebs/3modules/fetchWallpaper.nix
new file mode 100644
index 000000000..83ecf4177
--- /dev/null
+++ b/krebs/3modules/fetchWallpaper.nix
@@ -0,0 +1,89 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.krebs.fetchWallpaper;
+
+  out = {
+    options.krebs.fetchWallpaper = api;
+    config = mkIf cfg.enable imp;
+  };
+
+  api = {
+    enable = mkEnableOption "fetch wallpaper";
+    predicate = mkOption {
+      type = with types; nullOr path;
+      default = null;
+    };
+    url = mkOption {
+      type = types.str;
+    };
+    timerConfig = mkOption {
+      type = types.unspecified;
+      default = {
+        OnCalendar = "*:00,10,20,30,40,50";
+      };
+    };
+    stateDir = mkOption {
+      type = types.str;
+      default = "/var/lib/wallpaper";
+    };
+    display = mkOption {
+      type = types.str;
+      default = ":11";
+    };
+  };
+
+  fetchWallpaperScript = pkgs.writeScript "fetchWallpaper" ''
+    #! ${pkgs.bash}/bin/bash
+    ${optionalString (cfg.predicate != null) ''
+      if ! ${cfg.predicate}; then
+        echo "predicate failed - will not fetch from remote"
+        exit 0
+      fi
+    ''}
+    mkdir -p ${shell.escape cfg.stateDir}
+    curl -s -o ${shell.escape cfg.stateDir}/wallpaper -z ${shell.escape cfg.stateDir}/wallpaper ${shell.escape cfg.url}
+    feh --no-fehbg --bg-scale ${shell.escape cfg.stateDir}/wallpaper
+  '';
+
+  imp = {
+    users.users.fetchWallpaper = {
+      name = "fetchWallpaper";
+      uid = 3332383611; #genid fetchWallpaper
+      description = "fetchWallpaper user";
+      home = cfg.stateDir;
+      createHome = true;
+    };
+
+    systemd.timers.fetchWallpaper = {
+      description = "fetch wallpaper timer";
+      wantedBy = [ "timers.target" ];
+
+      timerConfig = cfg.timerConfig;
+    };
+    systemd.services.fetchWallpaper = {
+      description = "fetch wallpaper";
+      after = [ "network.target" ];
+
+      path = with pkgs; [
+        curl
+        feh
+      ];
+
+      environment = {
+        URL = cfg.url;
+        DISPLAY = cfg.display;
+      };
+
+      restartIfChanged = true;
+
+      serviceConfig = {
+        Type = "simple";
+        ExecStart = fetchWallpaperScript;
+        User = "fetchWallpaper";
+      };
+    };
+  };
+in out
diff --git a/lass/3modules/go.nix b/krebs/3modules/go.nix
similarity index 88%
rename from lass/3modules/go.nix
rename to krebs/3modules/go.nix
index aa900f118..793d1f60d 100644
--- a/lass/3modules/go.nix
+++ b/krebs/3modules/go.nix
@@ -4,10 +4,10 @@ with builtins;
 with lib;
 
 let
-  cfg = config.lass.go;
+  cfg = config.krebs.go;
 
   out = {
-    options.lass.go = api;
+    options.krebs.go = api;
     config = mkIf cfg.enable imp;
   };
 
@@ -26,6 +26,11 @@ let
   };
 
   imp = {
+    services.redis = {
+      enable = mkDefault true;
+      bind = mkDefault "127.0.0.1";
+    };
+
     users.extraUsers.go = {
       name = "go";
       uid = 42774411; #genid go
diff --git a/krebs/3modules/lass/default.nix b/krebs/3modules/lass/default.nix
index 2ad4353bd..26b0947bb 100644
--- a/krebs/3modules/lass/default.nix
+++ b/krebs/3modules/lass/default.nix
@@ -2,42 +2,14 @@
 
 with lib;
 
-let
-  testHosts = lib.genAttrs [
-    "test-arch"
-    "test-centos6"
-    "test-centos7"
-  ] (name: {
-    inherit name;
-    cores = 1;
-    nets = {
-      retiolum = {
-        addrs4 = ["10.243.111.111"];
-        addrs6 = ["42:0:0:0:0:0:0:7357"];
-        aliases = [
-          "test.retiolum"
-        ];
-        tinc.pubkey = ''
-          -----BEGIN RSA PUBLIC KEY-----
-          MIIBCgKCAQEAy41YKF/wpHLnN370MSdnAo63QUW30aw+6O79cnaJyxoL6ZQkk4Nd
-          mrX2tBIfb2hhhgm4Jecy33WVymoEL7EiRZ6gshJaYwte51Jnrac6IFQyiRGMqHY5
-          TG/6IzzTOkeQrT1fw3Yfh0NRfqLBZLr0nAFoqgzIVRxvy+QO1gCU2UDKkQ/y5df1
-          K+YsMipxU08dsOkPkmLdC/+vDaZiEdYljIS3Omd+ED5JmLM3MSs/ZPQ8xjkjEAy8
-          QqD9/67bDoeXyg1ZxED2n0+aRKtU/CK/66Li//yev6yv38OQSEM4t/V0dr9sjLcY
-          VIdkxKf96F9r3vcDf/9xw2HrqVoy+D5XYQIDAQAB
-          -----END RSA PUBLIC KEY-----
-        '';
-      };
-    };
-  });
-in {
+{
   hosts = addNames {
     echelon = {
       cores = 2;
       dc = "lass"; #dc = "cac";
       nets = rec {
         internet = {
-          addrs4 = ["167.88.34.158"];
+          addrs4 = ["162.252.241.33"];
           aliases = [
             "echelon.internet"
           ];
@@ -241,7 +213,7 @@ in {
       };
     };
 
-  } // testHosts;
+  };
   users = addNames {
     lass = {
       pubkey = readFile ../../Zpubkeys/lass.ssh.pub;
diff --git a/krebs/3modules/makefu/default.nix b/krebs/3modules/makefu/default.nix
index 652527da2..1970a0777 100644
--- a/krebs/3modules/makefu/default.nix
+++ b/krebs/3modules/makefu/default.nix
@@ -84,6 +84,31 @@ with lib;
         };
       };
     };
+
+    vbob = {
+      cores = 2;
+      dc = "makefu"; #vm local
+      nets = {
+        retiolum = {
+          addrs4 = ["10.243.1.91"];
+          addrs6 = ["42:0b2c:d90e:e717:03dd:9ac1:0000:a400"];
+          aliases = [
+            "vbob.retiolum"
+          ];
+          tinc.pubkey = ''
+          -----BEGIN RSA PUBLIC KEY-----
+          MIIBCgKCAQEA+0TIo0dS9LtSdrmH0ClPHLO7dHtV9Dj7gaBAsbyuwxAI5cQgYKwr
+          4G6t7IcJW+Gu2bh+LKtPP91+zYXq4Qr1nAaKw4ajsify6kpxsCBzknmwi6ibIJMI
+          AK114dr/XSk/Pc6hOSA8kqDP4c0MZXwitRBiNjrWbTrQh6GJ3CXhmpZ2lJkoAyNP
+          hjdPerbTUrhQlNW8FanyQQzOgN5I7/PXsZShmb3iNKz1Ban5yWKFCVpn8fjWQs5o
+          Un2AKowH4Y+/g8faGemL8uy/k5xrHSrn05L92TPDUpAXrcZXzo6ao1OBiwJJVl7s
+          AVduOY18FU82GUw7edR0e/b2UC6hUONflwIDAQAB
+          -----END RSA PUBLIC KEY-----
+
+            '';
+        };
+      };
+    };
     flap = rec {
       cores = 1;
       dc = "cac"; #vps
@@ -238,6 +263,31 @@ with lib;
         };
       };
     };
+
+    omo = rec {
+      cores = 2;
+      dc = "makefu"; #AMD E350
+
+      nets = {
+        retiolum = {
+          addrs4 = ["10.243.0.89"];
+          addrs6 = ["42:f9f0::10"];
+          aliases = [
+            "omo.retiolum"
+          ];
+          tinc.pubkey = ''
+              -----BEGIN RSA PUBLIC KEY-----
+              MIIBCgKCAQEAuHQEeowvxRkoHJUw6cUp431pnoIy4MVv7kTLgWEK46nzgZtld9LM
+              ZdNMJB9CuOVVMHEaiY6Q5YchUmapGxwEObc0y+8zQxTPw3I4q0GkSJqKLPrsTpkn
+              sgEkHPfs2GVdtIBXDn9I8i5JsY2+U8QF8fbIQSOO08/Vpa3nknDAMege9yEa3NFm
+              s/+x+2pS+xV6uzf/H21XNv0oufInXwZH1NCNXAy5I2V6pz7BmAHilVOGCT7g2zn6
+              GasmofiYEnro4V5s8gDlQkb7bCZEIA9EgX/HP6fZJQezSUHcDCQFI0vg26xywbr6
+              5+9tTn8fN2mWS5+Pdmx3haX1qFcBP5HglwIDAQAB
+              -----END RSA PUBLIC KEY-----
+            '';
+        };
+      };
+    };
     gum = rec {
       cores = 1;
       dc = "online.net"; #root-server
@@ -245,7 +295,10 @@ with lib;
       extraZones = {
         "krebsco.de" = ''
           share.euer        IN A      ${head nets.internet.addrs4}
+          mattermost.euer   IN A      ${head nets.internet.addrs4}
+          git.euer          IN A      ${head nets.internet.addrs4}
           gum               IN A      ${head nets.internet.addrs4}
+          cgit.euer         IN A      ${head nets.internet.addrs4}
         '';
       };
       nets = {
@@ -260,6 +313,7 @@ with lib;
           addrs6 = ["42:f9f0:0000:0000:0000:0000:0000:70d2"];
           aliases = [
             "gum.retiolum"
+            "cgit.gum.retiolum"
           ];
           tinc.pubkey = ''
             -----BEGIN RSA PUBLIC KEY-----
@@ -275,10 +329,26 @@ with lib;
       };
     };
   };
-  users = addNames {
+  users = addNames rec {
     makefu = {
       mail = "makefu@pornocauster.retiolum";
-      pubkey = readFile ../../Zpubkeys/makefu_arch.ssh.pub;
+      pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCl3RTOHd5DLiVeUbUr/GSiKoRWknXQnbkIf+uNiFO+XxiqZVojPlumQUVhasY8UzDzj9tSDruUKXpjut50FhIO5UFAgsBeMJyoZbgY/+R+QKU00Q19+IiUtxeFol/9dCO+F4o937MC0OpAC10LbOXN/9SYIXueYk3pJxIycXwUqhYmyEqtDdVh9Rx32LBVqlBoXRHpNGPLiswV2qNe0b5p919IGcslzf1XoUzfE3a3yjk/XbWh/59xnl4V7Oe7+iQheFxOT6rFA30WYwEygs5As//ZYtxvnn0gA02gOnXJsNjOW9irlxOUeP7IOU6Ye3WRKFRR0+7PS+w8IJLag2xb makefu@pornocauster";
+    };
+    makefu-omo = {
+      inherit (makefu) mail;
+      pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAtDhAxjiCH0SmTGNDqmlKPug9qTf+IFOVjdXfk01lAV2KMVW00CgNo2d5kl5+6pM99K7zZO7Uo7pmSFLSCAg8J6cMRI3v5OxFsnQfcJ9TeGLZt/ua7F8YsyIIr5wtqKtFbujqve31q9xJMypEpiX4np3nLiHfYwcWu7AFAUY8UHcCNl4JXm6hsmPe+9f6Mg2jICOdkfMMn0LtW+iq1KZpw1Nka2YUSiE2YuUtV+V+YaVMzdcjknkVkZNqcVk6tbJ1ZyZKM+bFEnE4VkHJYDABZfELpcgBAszfWrVG0QpEFjVCUq5atpIVHJcWWDx072r0zgdTPcBuzsHHC5PRfVBLEw== makefu@servarch";
+    };
+    makefu-tsp = {
+      inherit (makefu) mail;
+      pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1srWa67fcsw3r64eqgIuHbMbrj6Ywd9AwzCM+2dfXqYQZblchzH4Q4oydjdFOnV9LaA1LfNcWEjV/gVQKA2/xLSyXSDwzTxQDyOAZaqseKVg1F0a7wAF20+LiegQj6KXE29wcTW1RjcPncmagTBv5/vYbo1eDLKZjwGpEnG0+s+TRftrAhrgtbsuwR1GWWYACxk1CbxbcV+nIZ1RF9E1Fngbl4C4WjXDvsASi8s24utCd/XxgKwKcSFv7EWNfXlNzlETdTqyNVdhA7anc3N7d/TGrQuzCdtrvBFq4WbD3IRhSk79PXaB3L6xJ7LS8DyOSzfPyiJPK65Zw5s4BC07Z makefu@tsp";
+    };
+    makefu-vbob = {
+      inherit (makefu) mail;
+      pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCiKvLKaRQPL/Y/4EWx3rNhrY5YGKK4AeqDOFTLgJ7djwJnMo7FP+OIH/4pFxS6Ri2TZwS9QsR3hsycA4n8Z15jXAOXuK52kP65Ei3lLyz9mF+/s1mJsV0Ui/UKF3jE7PEAVky7zXuyYirJpMK8LhXydpFvH95aGrL1Dk30R9/vNkE9rc1XylBfNpT0X0GXmldI+r5OPOtiKLA5BHJdlV8qDYhQsU2fH8S0tmAHF/ir2bh7+PtLE2hmRT+b8I7y1ZagkJsC0sn9GT1AS8ys5s65V2xTTIfQO1zQ4sUH0LczuRuY8MLaO33GAzhyoSQdbdRAmwZQpY/JRJ3C/UROgHYt makefu@vbob";
+    };
+    exco = {
+      mail = "dickbutt@excogitation.de";
+      pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC7HCK+TzelJp7atCbvCbvZZnXFr3cE35ioactgpIJL7BOyQM6lJ/7y24WbbrstClTuV7n0rWolDgfjx/8kVQExP3HXEAgCwV6tIcX/Ep84EXSok7QguN0ozZMCwX9CYXOEyLmqpe2KAx3ggXDyyDUr2mWs04J95CFjiR/YgOhIfM4+gVBxGtLSTyegyR3Fk7O0KFwYDjBRLi7a5TIub3UYuOvw3Dxo7bUkdhtf38Kff8LEK8PKtIku/AyDlwZ0mZT4Z7gnihSG2ezR5mLD6QXVuGhG6gW/gsqfPVRF4aZbrtJWZCp2G21wBRafpEZJ8KFHtR18JNcvsuWA1HJmFOj2K0mAY5hBvzCbXGhSzBtcGxKOmTBDTRlZ7FIFgukP/ckSgDduydFUpsv07ZRj+qY07zKp3Nhh3RuN7ZcveCo2WpaAzTuWCMPB0BMhEQvsO8I/p5YtTaw2T1poOPorBbURQwEgNrZ92kB1lL5t1t1ZB4oNeDJX5fddKLkgnLqQZWOZBTKtoq0EAVXojTDLZaA+5z20h8DU7sicDQ/VG4LWtqm9fh8iDpvt/3IHUn/HJEEnlfE1Gd+F2Q+R80yu4e1PClmuzfWjCtkPc4aY7oDxfcJqyeuRW6husAufPqNs31W6X9qXwoaBh9vRQ1erZUo46iicxbzujXIy/Hwg67X8dw== dickbutt@excogitation.de";
     };
   };
 }
diff --git a/krebs/3modules/retiolum.nix b/krebs/3modules/retiolum.nix
index 633642537..28ac67306 100644
--- a/krebs/3modules/retiolum.nix
+++ b/krebs/3modules/retiolum.nix
@@ -50,6 +50,14 @@ let
       '';
     };
 
+    extraConfig = mkOption {
+      type = types.str;
+      default = "";
+      description = ''
+        Extra Configuration to be appended to tinc.conf
+      '';
+    };
+
     tincPackage = mkOption {
       type = types.package;
       default = pkgs.tinc;
@@ -203,6 +211,7 @@ let
     Interface = ${cfg.network}
     ${concatStrings (map (c : "ConnectTo = " + c + "\n") cfg.connectTo)}
     PrivateKeyFile = /tmp/retiolum-rsa_key.priv
+    ${cfg.extraConfig}
     EOF
 
     # source: krebscode/painload/retiolum/scripts/tinc_setup/tinc-up
diff --git a/krebs/3modules/shared/default.nix b/krebs/3modules/shared/default.nix
index 24dd7b782..b332676c6 100644
--- a/krebs/3modules/shared/default.nix
+++ b/krebs/3modules/shared/default.nix
@@ -2,15 +2,48 @@
 
 with lib;
 
-{
+let
+  testHosts = lib.genAttrs [
+    "test-arch"
+    "test-centos6"
+    "test-centos7"
+  ] (name: {
+    inherit name;
+    cores = 1;
+    nets = {
+      retiolum = {
+        addrs4 = ["10.243.111.111"];
+        addrs6 = ["42:0:0:0:0:0:0:7357"];
+        aliases = [
+          "test.retiolum"
+        ];
+        tinc.pubkey = ''
+          -----BEGIN RSA PUBLIC KEY-----
+          MIIBCgKCAQEAy41YKF/wpHLnN370MSdnAo63QUW30aw+6O79cnaJyxoL6ZQkk4Nd
+          mrX2tBIfb2hhhgm4Jecy33WVymoEL7EiRZ6gshJaYwte51Jnrac6IFQyiRGMqHY5
+          TG/6IzzTOkeQrT1fw3Yfh0NRfqLBZLr0nAFoqgzIVRxvy+QO1gCU2UDKkQ/y5df1
+          K+YsMipxU08dsOkPkmLdC/+vDaZiEdYljIS3Omd+ED5JmLM3MSs/ZPQ8xjkjEAy8
+          QqD9/67bDoeXyg1ZxED2n0+aRKtU/CK/66Li//yev6yv38OQSEM4t/V0dr9sjLcY
+          VIdkxKf96F9r3vcDf/9xw2HrqVoy+D5XYQIDAQAB
+          -----END RSA PUBLIC KEY-----
+        '';
+      };
+    };
+  });
+in {
   hosts = addNames {
     wolf = {
-      #dc = "shack";
+      dc = "shack";
       nets = {
-        #shack = {
-        #  addrs4 = [ TODO ];
-        #  aliases = ["wolf.shack"];
-        #};
+        shack = {
+          addrs4 = [ "10.42.2.150" ];
+          aliases = [
+            "wolf.shack"
+            "graphite.shack"
+            "acng.shack"
+            "drivedroid.shack"
+          ];
+        };
         retiolum = {
           addrs4 = ["10.243.77.1"];
           addrs6 = ["42:0:0:0:0:0:77:1"];
@@ -32,7 +65,7 @@ with lib;
       ssh.privkey.path = <secrets/ssh.id_ed25519>;
       ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKYMXMWZIK0jjnZDM9INiYAKcwjXs2241vew54K8veCR";
     };
-  };
+  } // testHosts;
   users = addNames {
     shared = {
       mail = "spam@krebsco.de";
diff --git a/krebs/3modules/tinc_graphs.nix b/krebs/3modules/tinc_graphs.nix
index e415d20ab..ba81dd416 100644
--- a/krebs/3modules/tinc_graphs.nix
+++ b/krebs/3modules/tinc_graphs.nix
@@ -89,9 +89,10 @@ let
       };
 
       restartIfChanged = true;
-
       serviceConfig = {
         Type = "simple";
+        TimeoutSec = 300; # we will wait 5 minutes, kill otherwise
+        restart = "always";
 
         ExecStartPre = pkgs.writeScript "tinc_graphs-init" ''
           #!/bin/sh
@@ -103,7 +104,6 @@ let
             cp -fr "$(${pkgs.tinc_graphs}/bin/tincstats-static-dir)/external/." "${external_dir}"
           fi
         '';
-
         ExecStart = "${pkgs.tinc_graphs}/bin/all-the-graphs";
 
         ExecStartPost = pkgs.writeScript "tinc_graphs-post" ''
diff --git a/krebs/4lib/infest/prepare.sh b/krebs/4lib/infest/prepare.sh
index 182a068ef..0bfc49380 100644
--- a/krebs/4lib/infest/prepare.sh
+++ b/krebs/4lib/infest/prepare.sh
@@ -66,6 +66,7 @@ prepare_debian() {
   type bzip2 2>/dev/null || apt-get install bzip2
   type git   2>/dev/null || apt-get install git
   type rsync 2>/dev/null || apt-get install rsync
+  type curl 2>/dev/null || apt-get install curl
   prepare_common
 }
 
diff --git a/krebs/5pkgs/Reaktor/default.nix b/krebs/5pkgs/Reaktor/default.nix
index c38aa6423..c4a362757 100644
--- a/krebs/5pkgs/Reaktor/default.nix
+++ b/krebs/5pkgs/Reaktor/default.nix
@@ -2,14 +2,14 @@
 
 python3Packages.buildPythonPackage rec {
   name = "Reaktor-${version}";
-  version = "0.5.0";
+  version = "0.5.1";
   propagatedBuildInputs = with pkgs;[
     python3Packages.docopt
     python3Packages.requests2
   ];
   src = fetchurl {
     url = "https://pypi.python.org/packages/source/R/Reaktor/Reaktor-${version}.tar.gz";
-    sha256 = "1npag52xmnyqv56z0anyf6xf00q0smfzsippal0xdbxrfj7s8qim";
+    sha256 = "0dn9r0cyxi1sji2pnybsrc4hhaaq7hmf235nlgkrxqlsdb7y6n6n";
   };
   meta = {
     homepage = http://krebsco.de/;
diff --git a/krebs/5pkgs/apt-cacher-ng/default.nix b/krebs/5pkgs/apt-cacher-ng/default.nix
new file mode 100644
index 000000000..f253cdba0
--- /dev/null
+++ b/krebs/5pkgs/apt-cacher-ng/default.nix
@@ -0,0 +1,21 @@
+{ stdenv, fetchurl, cmake, doxygen, zlib, openssl, bzip2, pkgconfig, libpthreadstubs }:
+
+stdenv.mkDerivation rec {
+  name = "apt-cacher-ng-${version}";
+  version = "0.8.6";
+
+  src = fetchurl {
+    url = "http://ftp.debian.org/debian/pool/main/a/apt-cacher-ng/apt-cacher-ng_${version}.orig.tar.xz";
+    sha256 = "0044dfks8djl11fs28jj8894i4rq424xix3d3fkvzz2i6lnp8nr5";
+  };
+
+  NIX_LDFLAGS = "-lpthread";
+  buildInputs = [ doxygen cmake zlib openssl bzip2 pkgconfig libpthreadstubs ];
+
+  meta = {
+    description = "A caching proxy specialized for linux distribution files";
+    homepage = http://www.unix-ag.uni-kl.de/~bloch/acng/;
+    license = stdenv.lib.licenses.gpl2;
+    maintainers = [ stdenv.lib.maintainers.makefu ];
+  };
+}
diff --git a/krebs/5pkgs/cac/default.nix b/krebs/5pkgs/cac/default.nix
index e29f091e4..40dd56412 100644
--- a/krebs/5pkgs/cac/default.nix
+++ b/krebs/5pkgs/cac/default.nix
@@ -4,9 +4,9 @@ stdenv.mkDerivation {
   name = "cac-1.0.0";
 
   src = fetchgit {
-    url = http://cgit.cd.retiolum/cac;
-    rev = "14de1d3c78385e3f8b6d694f5d799eb1b613159e";
-    sha256 = "9b2a3d47345d6f8f27d9764c4f2f2acff17d3dde145dd0e674e4183e9312fec3";
+    url = http://cgit.gum/cac;
+    rev = "fe3b2ecb0aaf7d863842b896e18cd2b829f2297b";
+    sha256 = "05bnd7wyjhqy8srmpnc8d234rv3jxdjgb4z0hlfb9kg7mb12w1ya";
   };
 
   phases = [
diff --git a/krebs/5pkgs/cacpanel/default.nix b/krebs/5pkgs/cacpanel/default.nix
new file mode 100644
index 000000000..3e3e2e1fc
--- /dev/null
+++ b/krebs/5pkgs/cacpanel/default.nix
@@ -0,0 +1,18 @@
+{pkgs, python3Packages, ...}:
+
+python3Packages.buildPythonPackage rec {
+  name = "cacpanel-${version}";
+  version = "0.2.1";
+
+  src = pkgs.fetchurl {
+    url = "https://pypi.python.org/packages/source/c/cacpanel/cacpanel-${version}.tar.gz";
+    sha256 = "1zaazg5r10kgva32zh4fhpw6l6h51ijkwpa322na0kh4x6f6aqj3";
+  };
+
+  propagatedBuildInputs = with python3Packages; [
+    docopt
+    requests2
+    beautifulsoup4
+  ];
+}
+
diff --git a/krebs/5pkgs/drivedroid-gen-repo/default.nix b/krebs/5pkgs/drivedroid-gen-repo/default.nix
new file mode 100644
index 000000000..de8046c4a
--- /dev/null
+++ b/krebs/5pkgs/drivedroid-gen-repo/default.nix
@@ -0,0 +1,22 @@
+{stdenv,fetchurl,pkgs,python3Packages, ... }:
+
+python3Packages.buildPythonPackage rec {
+  name = "drivedroid-gen-repo-${version}";
+  version = "0.4.4";
+
+  propagatedBuildInputs = with pkgs;[
+    python3Packages.docopt
+  ];
+
+  src = fetchurl {
+    url = "https://pypi.python.org/packages/source/d/drivedroid-gen-repo/drivedroid-gen-repo-${version}.tar.gz";
+    sha256 = "09p58hzp61r5fp025lak9z52y0aakmaqpi59p9w5xq42dvy2hnvl";
+  };
+
+  meta = {
+    homepage = http://krebsco.de/;
+    description = "Generate Drivedroid repos";
+    license = stdenv.lib.licenses.wtfpl;
+  };
+}
+
diff --git a/krebs/5pkgs/fortclientsslvpn/default.nix b/krebs/5pkgs/fortclientsslvpn/default.nix
new file mode 100644
index 000000000..720d4004f
--- /dev/null
+++ b/krebs/5pkgs/fortclientsslvpn/default.nix
@@ -0,0 +1,87 @@
+{ stdenv, lib, fetchurl, gtk, glib, libSM, gdk_pixbuf, libX11, libXinerama, iproute,
+  makeWrapper, libredirect, ppp, coreutils, gawk, pango }:
+stdenv.mkDerivation rec {
+  name = "forticlientsslvpn";
+  # forticlient will be copied into /tmp before execution. this is necessary as
+  # the software demands $base to be writeable
+
+  src = fetchurl {
+    # archive.org mirror:
+    # https://archive.org/download/ForticlientsslvpnLinux4.4.23171.tar/forticlientsslvpn_linux_4.4.2317.tar.gz
+    url = http://www.zen.co.uk/userfiles/knowledgebase/FortigateSSLVPNClient/forticlientsslvpn_linux_4.4.2317.tar.gz;
+    sha256 = "19clnf9rgrnwazlpah8zz5kvz6kc8lxawrgmksx25k5ywflmbcrr";
+  };
+  phases = [ "unpackPhase" "buildPhase" "installPhase" "fixupPhase" ];
+
+  buildInputs = [ makeWrapper ];
+
+  binPath = lib.makeSearchPath "bin" [
+    coreutils
+    gawk
+  ];
+
+
+  libPath = lib.makeLibraryPath [
+    stdenv.cc.cc
+  ];
+
+  guiLibPath = lib.makeLibraryPath [
+    gtk
+    glib
+    libSM
+    gdk_pixbuf
+    libX11
+    libXinerama
+    pango
+  ];
+
+  buildPhase = ''
+    # TODO: 32bit, use the 32bit folder
+    patchelf --set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \
+      --set-rpath "$libPath" \
+      64bit/forticlientsslvpn_cli
+
+    patchelf --set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \
+      --set-rpath "$libPath:$guiLibPath" \
+      64bit/forticlientsslvpn
+
+    patchelf --set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \
+      --set-rpath "$libPath" \
+      64bit/helper/subproc
+
+    sed -i 's#\(export PATH=\).*#\1"${binPath}"#' 64bit/helper/waitppp.sh
+  '';
+
+  installPhase = ''
+    mkdir -p "$out/opt/fortinet"
+
+    cp -r 64bit/. "$out/opt/fortinet"
+    wrapProgram $out/opt/fortinet/forticlientsslvpn \
+      --set LD_PRELOAD "${libredirect}/lib/libredirect.so" \
+      --set NIX_REDIRECTS /usr/sbin/ip=${iproute}/bin/ip:/usr/sbin/ppp=${ppp}/bin/ppp
+
+    mkdir -p "$out/bin/"
+
+    cat > $out/bin/forticlientsslvpn <<EOF
+    #!/bin/sh
+    # prepare suid bit in tmp
+    # TODO maybe tmp does not support suid
+    set -euf
+    tmpforti=\$(${coreutils}/bin/mktemp -d)
+    trap "rm -rf \$tmpforti;" INT TERM EXIT
+    cp -r $out/opt/fortinet/. \$tmpforti
+    chmod +s \$tmpforti/helper/subproc
+    cd \$tmpforti
+    "./forticlientsslvpn" "\$@"
+    EOF
+
+    chmod +x $out/bin/forticlientsslvpn
+    chmod -x $out/opt/fortinet/helper/showlicense
+  '';
+  meta = {
+    homepage = http://www.fortinet.com;
+    description = "Forticlient SSL-VPN client";
+    license = lib.licenses.nonfree;
+    maintainers = [ lib.maintainers.makefu ];
+  };
+}
diff --git a/lass/5pkgs/go/default.nix b/krebs/5pkgs/go/default.nix
similarity index 100%
rename from lass/5pkgs/go/default.nix
rename to krebs/5pkgs/go/default.nix
diff --git a/lass/5pkgs/go/packages.nix b/krebs/5pkgs/go/packages.nix
similarity index 100%
rename from lass/5pkgs/go/packages.nix
rename to krebs/5pkgs/go/packages.nix
diff --git a/krebs/5pkgs/snapraid/default.nix b/krebs/5pkgs/snapraid/default.nix
new file mode 100644
index 000000000..41db0f284
--- /dev/null
+++ b/krebs/5pkgs/snapraid/default.nix
@@ -0,0 +1,33 @@
+{stdenv, fetchurl}:
+let
+  s = # Generated upstream information
+  rec {
+    baseName="jq";
+    version="1.5";
+    name="${baseName}-${version}";
+    url=https://github.com/stedolan/jq/releases/download/jq-1.5/jq-1.5.tar.gz;
+    sha256="0g29kyz4ykasdcrb0zmbrp2jqs9kv1wz9swx849i2d1ncknbzln4";
+  };
+  buildInputs = [
+  ];
+in
+stdenv.mkDerivation {
+  inherit (s) name version;
+  inherit buildInputs;
+  src = fetchurl {
+    inherit (s) url sha256;
+  };
+
+  # jq is linked to libjq:
+  configureFlags = [
+    "LDFLAGS=-Wl,-rpath,\\\${libdir}"
+  ];
+  meta = {
+    inherit (s) version;
+    description = ''A lightweight and flexible command-line JSON processor'';
+    license = stdenv.lib.licenses.mit ;
+    maintainers = [stdenv.lib.maintainers.raskin];
+    platforms = stdenv.lib.platforms.linux ++ stdenv.lib.platforms.darwin;
+  };
+}
+
diff --git a/krebs/Zhosts/gum b/krebs/Zhosts/gum
index d43bb0d08..7a1a305d6 100644
--- a/krebs/Zhosts/gum
+++ b/krebs/Zhosts/gum
@@ -1,5 +1,7 @@
 Address= 195.154.108.70
 Address= 195.154.108.70 53
+Address= 195.154.108.70 21031
+
 Subnet = 10.243.0.211
 Subnet = 42:f9f0:0000:0000:0000:0000:0000:70d2
 
diff --git a/krebs/Zhosts/vbob b/krebs/Zhosts/vbob
new file mode 100644
index 000000000..b233a46b0
--- /dev/null
+++ b/krebs/Zhosts/vbob
@@ -0,0 +1,9 @@
+-----BEGIN RSA PUBLIC KEY-----
+MIIBCgKCAQEA+0TIo0dS9LtSdrmH0ClPHLO7dHtV9Dj7gaBAsbyuwxAI5cQgYKwr
+4G6t7IcJW+Gu2bh+LKtPP91+zYXq4Qr1nAaKw4ajsify6kpxsCBzknmwi6ibIJMI
+AK114dr/XSk/Pc6hOSA8kqDP4c0MZXwitRBiNjrWbTrQh6GJ3CXhmpZ2lJkoAyNP
+hjdPerbTUrhQlNW8FanyQQzOgN5I7/PXsZShmb3iNKz1Ban5yWKFCVpn8fjWQs5o
+Un2AKowH4Y+/g8faGemL8uy/k5xrHSrn05L92TPDUpAXrcZXzo6ao1OBiwJJVl7s
+AVduOY18FU82GUw7edR0e/b2UC6hUONflwIDAQAB
+-----END RSA PUBLIC KEY-----
+Subnet = 10.243.1.91/32
diff --git a/krebs/Zpubkeys/makefu_arch.ssh.pub b/krebs/Zpubkeys/makefu_arch.ssh.pub
deleted file mode 100644
index 6092ec469..000000000
--- a/krebs/Zpubkeys/makefu_arch.ssh.pub
+++ /dev/null
@@ -1 +0,0 @@
-ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCl3RTOHd5DLiVeUbUr/GSiKoRWknXQnbkIf+uNiFO+XxiqZVojPlumQUVhasY8UzDzj9tSDruUKXpjut50FhIO5UFAgsBeMJyoZbgY/+R+QKU00Q19+IiUtxeFol/9dCO+F4o937MC0OpAC10LbOXN/9SYIXueYk3pJxIycXwUqhYmyEqtDdVh9Rx32LBVqlBoXRHpNGPLiswV2qNe0b5p919IGcslzf1XoUzfE3a3yjk/XbWh/59xnl4V7Oe7+iQheFxOT6rFA30WYwEygs5As//ZYtxvnn0gA02gOnXJsNjOW9irlxOUeP7IOU6Ye3WRKFRR0+7PS+w8IJLag2xb makefu@pornocauster
diff --git a/krebs/Zpubkeys/makefu_omo.ssh.pub b/krebs/Zpubkeys/makefu_omo.ssh.pub
deleted file mode 100644
index 5567040fb..000000000
--- a/krebs/Zpubkeys/makefu_omo.ssh.pub
+++ /dev/null
@@ -1 +0,0 @@
-ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAtDhAxjiCH0SmTGNDqmlKPug9qTf+IFOVjdXfk01lAV2KMVW00CgNo2d5kl5+6pM99K7zZO7Uo7pmSFLSCAg8J6cMRI3v5OxFsnQfcJ9TeGLZt/ua7F8YsyIIr5wtqKtFbujqve31q9xJMypEpiX4np3nLiHfYwcWu7AFAUY8UHcCNl4JXm6hsmPe+9f6Mg2jICOdkfMMn0LtW+iq1KZpw1Nka2YUSiE2YuUtV+V+YaVMzdcjknkVkZNqcVk6tbJ1ZyZKM+bFEnE4VkHJYDABZfELpcgBAszfWrVG0QpEFjVCUq5atpIVHJcWWDx072r0zgdTPcBuzsHHC5PRfVBLEw== makefu@servarch
diff --git a/krebs/Zpubkeys/makefu_tsp.ssh.pub b/krebs/Zpubkeys/makefu_tsp.ssh.pub
deleted file mode 100644
index 9a9c9b6f8..000000000
--- a/krebs/Zpubkeys/makefu_tsp.ssh.pub
+++ /dev/null
@@ -1 +0,0 @@
-ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1srWa67fcsw3r64eqgIuHbMbrj6Ywd9AwzCM+2dfXqYQZblchzH4Q4oydjdFOnV9LaA1LfNcWEjV/gVQKA2/xLSyXSDwzTxQDyOAZaqseKVg1F0a7wAF20+LiegQj6KXE29wcTW1RjcPncmagTBv5/vYbo1eDLKZjwGpEnG0+s+TRftrAhrgtbsuwR1GWWYACxk1CbxbcV+nIZ1RF9E1Fngbl4C4WjXDvsASi8s24utCd/XxgKwKcSFv7EWNfXlNzlETdTqyNVdhA7anc3N7d/TGrQuzCdtrvBFq4WbD3IRhSk79PXaB3L6xJ7LS8DyOSzfPyiJPK65Zw5s4BC07Z makefu@tsp
diff --git a/krebs/default.nix b/krebs/default.nix
index bfd6175d9..ad0205426 100644
--- a/krebs/default.nix
+++ b/krebs/default.nix
@@ -11,6 +11,7 @@ let out = {
     inherit infest;
     inherit init;
     inherit nixos-install;
+    inherit populate;
   };
 
   deploy =
diff --git a/lass/1systems/echelon.nix b/lass/1systems/echelon.nix
index dc0ca0274..39af4a96f 100644
--- a/lass/1systems/echelon.nix
+++ b/lass/1systems/echelon.nix
@@ -13,7 +13,7 @@ in {
     ../2configs/realwallpaper-server.nix
     ../2configs/privoxy-retiolum.nix
     ../2configs/git.nix
-    ../2configs/redis.nix
+    #../2configs/redis.nix
     ../2configs/go.nix
     ../2configs/ircd.nix
     ../2configs/newsbot-js.nix
diff --git a/lass/1systems/mors.nix b/lass/1systems/mors.nix
index 7db3f8333..4ba9df6f9 100644
--- a/lass/1systems/mors.nix
+++ b/lass/1systems/mors.nix
@@ -18,10 +18,40 @@
     ../2configs/chromium-patched.nix
     ../2configs/git.nix
     ../2configs/retiolum.nix
-    ../2configs/wordpress.nix
+    #../2configs/wordpress.nix
     ../2configs/bitlbee.nix
     ../2configs/firefoxPatched.nix
     ../2configs/skype.nix
+    ../2configs/teamviewer.nix
+    ../2configs/libvirt.nix
+    ../2configs/fetchWallpaper.nix
+    {
+      #risk of rain port
+      krebs.iptables.tables.filter.INPUT.rules = [
+        { predicate = "-p tcp --dport 11100"; target = "ACCEPT"; }
+      ];
+    }
+    {
+      #wordpress-test
+      #imports = singleton (sitesGenerators.createWordpress "testserver.de");
+      imports = [
+        ../3modules/wordpress_nginx.nix
+      ];
+      lass.wordpress."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; }
+      ];
+    }
   ];
 
   krebs.build.host = config.krebs.hosts.mors;
diff --git a/lass/1systems/prism.nix b/lass/1systems/prism.nix
index 87334c3c2..95c55533c 100644
--- a/lass/1systems/prism.nix
+++ b/lass/1systems/prism.nix
@@ -10,6 +10,8 @@ in {
     ../2configs/downloading.nix
     ../2configs/git.nix
     ../2configs/ts3.nix
+    ../2configs/bitlbee.nix
+    ../2configs/weechat.nix
     {
       users.extraGroups = {
         # ● systemd-tmpfiles-setup.service - Create Volatile Files and Directories
@@ -87,6 +89,50 @@ in {
     {
       nixpkgs.config.allowUnfree = true;
     }
+    {
+      #stuff for juhulian
+      users.extraUsers.juhulian = {
+        name = "juhulian";
+        uid = 1339;
+        home = "/home/juhulian";
+        group = "users";
+        createHome = true;
+        useDefaultShell = true;
+        extraGroups = [
+        ];
+        openssh.authorizedKeys.keys = [
+          "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBQhLGvfv4hyQ/nqJGy1YgHXPSVl6igeWTroJSvAhUFgoh+rG+zvqY0EahKXNb3sq0/OYDCTJVuucc0hgCg7T2KqTqMtTb9EEkRmCFbD7F7DWZojCrh/an6sHneqT5eFvzAPZ8E5hup7oVQnj5P5M3I9keRHBWt1rq6q0IcOEhsFvne4qJc73aLASTJkxzlo5U8ju3JQOl6474ECuSn0lb1fTrQ/SR1NgF7jV11eBldkS8SHEB+2GXjn4Yrn+QUKOnDp+B85vZmVlJSI+7XR1/U/xIbtAjGTEmNwB6cTbBv9NCG9jloDDOZG4ZvzzHYrlBXjaigtQh2/4mrHoKa5eV juhulian@juhulian"
+        ];
+      };
+      krebs.iptables.tables.filter.INPUT.rules = [
+        { predicate = "-p udp --dport 60000:61000"; target = "ACCEPT";}
+      ];
+    }
+    {
+      environment.systemPackages = [
+        pkgs.perlPackages.Plack
+      ];
+      krebs.iptables.tables.filter.INPUT.rules = [
+        { predicate = "-p tcp --dport 8080"; target = "ACCEPT";}
+      ];
+    }
+    {
+      users.users.chat.openssh.authorizedKeys.keys = [
+        "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDJJKlOeAHyi7lToCqRF/hdA2TrtVbrTUd2ayuWsXe9JWiyeyKH/LNY3SrgxCWPZSItE9VK68ghMuVYK/A8IAcgzNhzFYLDxmtsidjiOJBj2ZGsjqevoQ5HuKB/pob8CLW3dr1Rx38Any/XXxpfeO6vemCJMGLTe5gSlrCI+Tk1qNt0Rz+rke73Hwt9wW39g8X3prF2q9ryL9OFCcsoYUE7PIOV9xM1GaDFfTR4bKux7HyFKmG+rBvmJHB5OPW8UAtVZGY/FIChwlmF6QNO5Zym497bG1RCOGplaLpRXVJrmoUkZUO7EazePPxIjz2duWYqFtwl5R9YGy1+a+F58G19DS7wJHM29td117/ZANjRTxE5q/aJm2okJYOVSqhYzdhji+BWVZ5ai7cktpAdtPo++yiZN90LvogXNB64kFxVGuX52xZcA3KLKmvrd47o9k0pzO+oCoArxPFIx0YkHfy/yw7OG8Z+KLK8l9WXWBZO5TpjcydnEcRZ8OEqVhtmDh+9h1zhPphuFBtT1JPbt8m132RUy23qsNRtZ/lnnfQbrxgHPRzVuvA8o4ahOEUdvV9SYnzKb6qMFXGp25EhlcWnR4/toyG6I3paBtByeHkaxjgCuvm9Hob6f/xFr3kEJ4WXTVguyrcFgNg2EcEfdkrTMhNn9OIHEFFQ8whIBv5jlw== JuiceSSH"
+      ];
+    }
+    {
+      time.timeZone = "Europe/Berlin";
+    }
+    {
+      imports = [
+        ../2configs/websites/wohnprojekt-rhh.de.nix
+        ../2configs/websites/domsen.nix
+      ];
+      krebs.iptables.tables.filter.INPUT.rules = [
+         { predicate = "-p tcp --dport 80"; target = "ACCEPT"; }
+      ];
+    }
   ];
 
   krebs.build.host = config.krebs.hosts.prism;
diff --git a/lass/1systems/test-centos7.nix b/lass/1systems/test-centos7.nix
deleted file mode 100644
index 91bd3e0fe..000000000
--- a/lass/1systems/test-centos7.nix
+++ /dev/null
@@ -1,31 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-let
-  inherit (import ../4lib { inherit pkgs lib; }) getDefaultGateway;
-  inherit (lib) head;
-
-  ip = "168.235.145.85";
-in {
-  imports = [
-    ../2configs/base.nix
-    ../2configs/os-templates/CAC-CentOS-7-64bit.nix
-    {
-      networking.interfaces.enp2s1.ip4 = [
-        {
-          address = ip;
-          prefixLength = 24;
-        }
-      ];
-      networking.defaultGateway = getDefaultGateway ip;
-      networking.nameservers = [
-        "8.8.8.8"
-      ];
-
-    }
-    {
-      sound.enable = false;
-    }
-  ];
-
-  krebs.build.host = config.krebs.hosts.test-centos7;
-}
diff --git a/lass/2configs/base.nix b/lass/2configs/base.nix
index 11bc4f089..40f4e12c7 100644
--- a/lass/2configs/base.nix
+++ b/lass/2configs/base.nix
@@ -17,6 +17,7 @@ with lib;
         root = {
           openssh.authorizedKeys.keys = [
             config.krebs.users.lass.pubkey
+            config.krebs.users.uriel.pubkey
           ];
         };
         mainUser = {
@@ -30,6 +31,7 @@ with lib;
           ];
           openssh.authorizedKeys.keys = [
             config.krebs.users.lass.pubkey
+            config.krebs.users.uriel.pubkey
           ];
         };
       };
@@ -48,7 +50,7 @@ with lib;
       source = {
         git.nixpkgs = {
           url = https://github.com/Lassulus/nixpkgs;
-          rev = "6d31e9b81dcd4ab927bb3dc91b612dd5abfa2f80";
+          rev = "363c8430f1efad8b03d5feae6b3a4f2fe7b29251";
         };
         dir.secrets = {
           host = config.krebs.hosts.mors;
@@ -92,6 +94,10 @@ with lib;
     most
     rxvt_unicode.terminfo
 
+  #monitoring tools
+    htop
+    iotop
+
   #network
     iptables
 
diff --git a/lass/2configs/baseX.nix b/lass/2configs/baseX.nix
index 3be3676aa..4e46c18d2 100644
--- a/lass/2configs/baseX.nix
+++ b/lass/2configs/baseX.nix
@@ -5,7 +5,8 @@ let
 in {
   imports = [
     ./base.nix
-    ./urxvt.nix
+    #./urxvt.nix
+    ./xserver
   ];
 
   users.extraUsers.mainUser.extraGroups = [ "audio" ];
@@ -34,38 +35,39 @@ in {
     sxiv
     much
     push
+    zathura
 
   #window manager stuff
-    haskellPackages.xmobar
-    haskellPackages.yeganesh
-    dmenu2
-    xlibs.fontschumachermisc
+    #haskellPackages.xmobar
+    #haskellPackages.yeganesh
+    #dmenu2
+    #xlibs.fontschumachermisc
   ];
 
-  fonts.fonts = [
-    pkgs.xlibs.fontschumachermisc
-  ];
+  #fonts.fonts = [
+  #  pkgs.xlibs.fontschumachermisc
+  #];
 
-  services.xserver = {
-    enable = true;
+  #services.xserver = {
+  #  enable = true;
 
-    windowManager.xmonad.extraPackages = hspkgs: with hspkgs; [
-      X11-xshape
-    ];
-    windowManager.xmonad.enable = true;
-    windowManager.xmonad.enableContribAndExtras = true;
-    windowManager.default = "xmonad";
-    desktopManager.default = "none";
-    desktopManager.xterm.enable = false;
-    displayManager.slim.enable = true;
-    displayManager.auto.enable = true;
-    displayManager.auto.user = mainUser.name;
+  #  windowManager.xmonad.extraPackages = hspkgs: with hspkgs; [
+  #    X11-xshape
+  #  ];
+  #  windowManager.xmonad.enable = true;
+  #  windowManager.xmonad.enableContribAndExtras = true;
+  #  windowManager.default = "xmonad";
+  #  desktopManager.default = "none";
+  #  desktopManager.xterm.enable = false;
+  #  displayManager.slim.enable = true;
+  #  displayManager.auto.enable = true;
+  #  displayManager.auto.user = mainUser.name;
 
-    layout = "us";
-    xkbModel = "evdev";
-    xkbVariant = "altgr-intl";
-    xkbOptions = "caps:backspace";
-  };
+  #  layout = "us";
+  #  xkbModel = "evdev";
+  #  xkbVariant = "altgr-intl";
+  #  xkbOptions = "caps:backspace";
+  #};
 
   services.logind.extraConfig = ''
     HandleLidSwitch=ignore
diff --git a/lass/2configs/bitlbee.nix b/lass/2configs/bitlbee.nix
index fa14c7fea..b23628dc5 100644
--- a/lass/2configs/bitlbee.nix
+++ b/lass/2configs/bitlbee.nix
@@ -1,16 +1,12 @@
 { config, pkgs, ... }:
 
-let
-  lpkgs = import ../5pkgs { inherit pkgs; };
-in {
-
-  imports = [
-    ../3modules/bitlbee.nix
-  ];
-
-  lass.bitlbee = {
+{
+  services.bitlbee = {
     enable = true;
-    bitlbeePkg = lpkgs.bitlbee;
     portNumber = 6666;
+    plugins = [
+      pkgs.bitlbee-facebook
+      pkgs.bitlbee-steam
+    ];
   };
 }
diff --git a/lass/2configs/browsers.nix b/lass/2configs/browsers.nix
index 5a1857973..d36801863 100644
--- a/lass/2configs/browsers.nix
+++ b/lass/2configs/browsers.nix
@@ -1,8 +1,6 @@
 { config, lib, pkgs, ... }:
 
 let
-  inherit (import ../4lib { inherit pkgs lib; }) simpleScript;
-
   mainUser = config.users.extraUsers.mainUser;
   createChromiumUser = name: extraGroups: packages:
     {
@@ -18,8 +16,8 @@ let
         ${mainUser.name} ALL=(${name}) NOPASSWD: ALL
       '';
       environment.systemPackages = [
-        (simpleScript name ''
-          sudo -u ${name} -i chromium $@
+        (pkgs.writeScriptBin name ''
+          /var/setuid-wrappers/sudo -u ${name} -i chromium $@
         '')
       ];
     };
@@ -38,8 +36,8 @@ let
         ${mainUser.name} ALL=(${name}) NOPASSWD: ALL
       '';
       environment.systemPackages = [
-        (simpleScript name ''
-          sudo -u ${name} -i firefox $@
+        (pkgs.writeScriptBin name ''
+          /var/setuid-wrappers/sudo -u ${name} -i firefox $@
         '')
       ];
     };
@@ -49,7 +47,7 @@ let
 in {
 
   environment.systemPackages = [
-    (simpleScript "browser-select" ''
+    (pkgs.writeScriptBin "browser-select" ''
       BROWSER=$(echo -e "ff\ncr\nfb\ngm\nflash" | dmenu)
       $BROWSER $@
     '')
@@ -62,7 +60,7 @@ in {
     ( createChromiumUser "cr" [ "audio" ] [ pkgs.chromium ] )
     ( createChromiumUser "fb" [ ] [ pkgs.chromium ] )
     ( createChromiumUser "gm" [ ] [ pkgs.chromium ] )
-   # ( createChromiumUser "flash" [ ] [ pkgs.flash ] )
+    ( createChromiumUser "flash" [ ] [ pkgs.flash ] )
   ];
 
   nixpkgs.config.packageOverrides = pkgs : {
diff --git a/lass/2configs/elster.nix b/lass/2configs/elster.nix
index 1edd01896..e3a88c789 100644
--- a/lass/2configs/elster.nix
+++ b/lass/2configs/elster.nix
@@ -14,6 +14,9 @@ in {
       createHome = true;
     };
   };
+  krebs.per-user.elster.packages = [
+    pkgs.chromium
+  ];
   security.sudo.extraConfig = ''
     ${mainUser.name} ALL=(elster) NOPASSWD: ALL
   '';
diff --git a/lass/2configs/fetchWallpaper.nix b/lass/2configs/fetchWallpaper.nix
new file mode 100644
index 000000000..9c27706cb
--- /dev/null
+++ b/lass/2configs/fetchWallpaper.nix
@@ -0,0 +1,11 @@
+{ config, pkgs, ... }:
+
+let
+
+in {
+  krebs.fetchWallpaper = {
+    enable = true;
+    url = "echelon/wallpaper.png";
+  };
+}
+
diff --git a/lass/2configs/git.nix b/lass/2configs/git.nix
index 7e8fc03c7..16ecaefec 100644
--- a/lass/2configs/git.nix
+++ b/lass/2configs/git.nix
@@ -1,6 +1,6 @@
 { config, lib, pkgs, ... }:
 
-with import ../../tv/4lib { inherit lib pkgs; };
+with lib;
 
 let
 
@@ -43,19 +43,19 @@ let
         collaborators = with config.krebs.users; [ tv makefu ];
       };
     } //
-    import /root/src/secrets/repos.nix { inherit config lib pkgs; }
+    import <secrets/repos.nix> { inherit config lib pkgs; }
   );
 
   make-public-repo = name: { desc ? null, ... }: {
     inherit name desc;
     public = true;
     hooks = {
-      post-receive = git.irc-announce {
+      post-receive = pkgs.git-hooks.irc-announce {
         # TODO make nick = config.krebs.build.host.name the default
         nick = config.krebs.build.host.name;
         channel = "#retiolum";
         server = "cd.retiolum";
-        verbose = config.krebs.build.host.name == "echelon";
+        verbose = config.krebs.build.host.name == "prism";
       };
     };
   };
diff --git a/lass/2configs/go.nix b/lass/2configs/go.nix
index 81a02ec7c..f4c2ac289 100644
--- a/lass/2configs/go.nix
+++ b/lass/2configs/go.nix
@@ -2,13 +2,10 @@
 
 with lib;
 {
-  imports = [
-    ../3modules/go.nix
-  ];
   environment.systemPackages = [
     pkgs.go
   ];
-  lass.go = {
+  krebs.go = {
     enable = true;
   };
   krebs.nginx = {
diff --git a/lass/2configs/libvirt.nix b/lass/2configs/libvirt.nix
new file mode 100644
index 000000000..368722e77
--- /dev/null
+++ b/lass/2configs/libvirt.nix
@@ -0,0 +1,22 @@
+{ config, pkgs, ... }:
+
+let
+  mainUser = config.users.extraUsers.mainUser;
+
+in {
+  virtualisation.libvirtd.enable = true;
+
+  users.extraUsers = {
+    libvirt = {
+      uid = 358821352; # genid libvirt
+      description = "user for running libvirt stuff";
+      home = "/home/libvirt";
+      useDefaultShell = true;
+      extraGroups = [ "libvirtd" "audio" ];
+      createHome = true;
+    };
+  };
+  security.sudo.extraConfig = ''
+    ${mainUser.name} ALL=(libvirt) NOPASSWD: ALL
+  '';
+}
diff --git a/lass/2configs/mc.nix b/lass/2configs/mc.nix
index 87880ed00..b7d5a4ceb 100644
--- a/lass/2configs/mc.nix
+++ b/lass/2configs/mc.nix
@@ -159,37 +159,25 @@ let
 
     ### Images ###
 
-    type/^GIF
+    shell/i/.gif
       Include=image
 
-    type/^JPEG
+    regex/i/\.jpe?g$
       Include=image
 
-    type/^PC\ bitmap
+    shell/i/.bmp
       Include=image
 
-    type/^PNG
+    shell/i/.png
       Include=image
 
-    type/^JNG
+    shell/i/.jng
       Include=image
 
-    type/^MNG
+    shell/i/.mng
       Include=image
 
-    type/^TIFF
-      Include=image
-
-    type/^PBM
-      Include=image
-
-    type/^PGM
-      Include=image
-
-    type/^PPM
-      Include=image
-
-    type/^Netpbm
+    shell/i/.tiff
       Include=image
 
     shell/.ico
@@ -283,7 +271,7 @@ let
     ### Documents ###
 
     # PDF
-    type/^PDF
+    shell/i/.pdf
       Open=zathura %f
       View=zathura %f
 
diff --git a/lass/2configs/skype.nix b/lass/2configs/skype.nix
index 7e4618a7b..6a226441b 100644
--- a/lass/2configs/skype.nix
+++ b/lass/2configs/skype.nix
@@ -4,10 +4,6 @@ let
   mainUser = config.users.extraUsers.mainUser;
 
 in {
-  imports = [
-    ../3modules/per-user.nix
-  ];
-
   users.extraUsers = {
     skype = {
       name = "skype";
@@ -20,7 +16,7 @@ in {
     };
   };
 
-  lass.per-user.skype.packages = [
+  krebs.per-user.skype.packages = [
     pkgs.skype
   ];
 
diff --git a/lass/2configs/teamviewer.nix b/lass/2configs/teamviewer.nix
new file mode 100644
index 000000000..48053d7db
--- /dev/null
+++ b/lass/2configs/teamviewer.nix
@@ -0,0 +1,6 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+{
+  services.teamviewer.enable = true;
+}
diff --git a/lass/2configs/websites/domsen.nix b/lass/2configs/websites/domsen.nix
new file mode 100644
index 000000000..109c216c0
--- /dev/null
+++ b/lass/2configs/websites/domsen.nix
@@ -0,0 +1,35 @@
+{ config, pkgs, ... }:
+
+{
+  imports = [
+    ../../3modules/static_nginx.nix
+    ../../3modules/owncloud_nginx.nix
+    ../../3modules/wordpress_nginx.nix
+  ];
+
+  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" = {
+  #  };
+  #};
+
+}
+
diff --git a/lass/2configs/websites/wohnprojekt-rhh.de.nix b/lass/2configs/websites/wohnprojekt-rhh.de.nix
new file mode 100644
index 000000000..cd31450c5
--- /dev/null
+++ b/lass/2configs/websites/wohnprojekt-rhh.de.nix
@@ -0,0 +1,12 @@
+{ config, ... }:
+
+{
+  imports = [
+    ../../3modules/static_nginx.nix
+  ];
+
+  lass.staticPage = {
+    "wohnprojekt-rhh.de" = {};
+  };
+}
+
diff --git a/lass/2configs/weechat.nix b/lass/2configs/weechat.nix
index cfcc1a2f6..18007ed61 100644
--- a/lass/2configs/weechat.nix
+++ b/lass/2configs/weechat.nix
@@ -1,22 +1,37 @@
 { config, lib, pkgs, ... }:
 
-with lib;
 {
-  imports = [
-    ../3modules/per-user.nix
-  ];
-
-  lass.per-user.chat.packages = [
+  krebs.per-user.chat.packages = [
     pkgs.weechat
     pkgs.tmux
   ];
 
   users.extraUsers.chat = {
     home = "/home/chat";
+    uid = 986764891; # genid chat
     useDefaultShell = true;
     createHome = true;
-    openssh.authorizedKeys.keys = map readFile [
-      ../../krebs/Zpubkeys/lass.ssh.pub
+    openssh.authorizedKeys.keys = [
+      config.krebs.users.lass.pubkey
     ];
   };
+
+  #systemd.services.chat = {
+  #  description = "chat environment setup";
+  #  after = [ "network.target" ];
+  #  wantedBy = [ "multi-user.target" ];
+
+  #  path = with pkgs; [
+  #    weechat
+  #    tmux
+  #  ];
+
+  #  restartIfChanged = true;
+
+  #  serviceConfig = {
+  #    User = "chat";
+  #    Restart = "always";
+  #    ExecStart = "${pkgs.tmux}/bin/tmux new -s IM weechat";
+  #  };
+  #};
 }
diff --git a/lass/2configs/xserver/Xresources.nix b/lass/2configs/xserver/Xresources.nix
new file mode 100644
index 000000000..d52418897
--- /dev/null
+++ b/lass/2configs/xserver/Xresources.nix
@@ -0,0 +1,27 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+pkgs.writeText "Xresources" ''
+  URxvt*scrollBar:                      false
+  URxvt*urgentOnBell:                   true
+  URxvt*font:                           -*-clean-*-*-*-*-*-*-*-*-*-*-iso10646-*
+  URxvt*boldFont:                       -*-clean-*-*-*-*-*-*-*-*-*-*-iso10646-*
+
+  ! ref https://github.com/muennich/urxvt-perls
+  URxvt.perl-lib: ${pkgs.urxvt_perls}/lib/urxvt/perl
+  URxvt.perl-ext-common:      default,clipboard,url-select,keyboard-select
+  URxvt.url-select.launcher:  browser-select
+  URxvt.url-select.underline: true
+  URxvt.keysym.M-u:           perl:url-select:select_next
+  URxvt.keysym.M-Escape:      perl:keyboard-select:activate
+  URxvt.keysym.M-s:           perl:keyboard-select:search
+
+  URxvt.intensityStyles: false
+
+  URxvt*background:                     #000000
+  URxvt*foreground:                     #ffffff
+
+  !change unreadable blue
+  URxvt*color4:                         #268bd2
+''
diff --git a/lass/2configs/xserver/default.nix b/lass/2configs/xserver/default.nix
new file mode 100644
index 000000000..da337f6a7
--- /dev/null
+++ b/lass/2configs/xserver/default.nix
@@ -0,0 +1,160 @@
+{ config, lib, pkgs, ... }@args:
+
+with lib;
+
+let
+  # TODO krebs.build.user
+  user = config.users.users.mainUser;
+
+  out = {
+
+    services.xserver = {
+      display = 11;
+      tty = 11;
+
+      synaptics = {
+        enable = true;
+        twoFingerScroll = true;
+        accelFactor = "0.035";
+      };
+
+      #keyboard stuff
+      layout = "us";
+      xkbVariant = "altgr-intl";
+      xkbOptions = "caps:backspace";
+    };
+
+    fonts.fonts = [
+      pkgs.xlibs.fontschumachermisc
+    ];
+
+    systemd.services.urxvtd = {
+      wantedBy = [ "multi-user.target" ];
+      reloadIfChanged = true;
+      serviceConfig = {
+        ExecReload = need-reload "urxvtd.service";
+        ExecStart = "${pkgs.rxvt_unicode}/bin/urxvtd";
+        Restart = "always";
+        RestartSec = "2s";
+        StartLimitBurst = 0;
+        User = user.name;
+      };
+    };
+
+    environment.systemPackages = [
+      pkgs.gitAndTools.qgit
+      pkgs.mpv
+      pkgs.pavucontrol
+      pkgs.slock
+      pkgs.sxiv
+      pkgs.xsel
+      pkgs.zathura
+    ];
+
+    security.setuidPrograms = [
+      "slock"
+    ];
+
+    systemd.services.display-manager = mkForce {};
+
+    services.xserver.enable = true;
+
+    systemd.services.xmonad = {
+      wantedBy = [ "multi-user.target" ];
+      requires = [ "xserver.service" ];
+      environment = xmonad-environment;
+      serviceConfig = {
+        ExecStart = "${xmonad-start}/bin/xmonad";
+        ExecStop = "${xmonad-stop}/bin/xmonad-stop";
+        User = user.name;
+        WorkingDirectory = user.home;
+      };
+    };
+
+    systemd.services.xserver = {
+      after = [
+        "systemd-udev-settle.service"
+        "local-fs.target"
+        "acpid.service"
+      ];
+      reloadIfChanged = true;
+      environment = xserver-environment;
+      serviceConfig = {
+        ExecReload = need-reload "xserver.service";
+        ExecStart = "${xserver}/bin/xserver";
+      };
+    };
+  };
+
+  xmonad-environment = {
+    DISPLAY = ":${toString config.services.xserver.display}";
+    XMONAD_STATE = "/tmp/xmonad.state";
+
+    # XXX JSON is close enough :)
+    XMONAD_WORKSPACES0_FILE = pkgs.writeText "xmonad.workspaces0" (toJSON [
+      "cr"
+      "gm"
+      "ff"
+      "IM"
+      "mail"
+      "stockholm"
+    ]);
+  };
+
+  xmonad-start = pkgs.writeScriptBin "xmonad" ''
+    #! ${pkgs.bash}/bin/bash
+    set -efu
+    export PATH; PATH=${makeSearchPath "bin" ([
+      pkgs.rxvt_unicode
+      pkgs.i3lock
+      pkgs.haskellPackages.yeganesh
+      pkgs.dmenu
+    ] ++ config.environment.systemPackages)}:/var/setuid-wrappers
+    settle() {(
+      # Use PATH for a clean journal
+      command=''${1##*/}
+      PATH=''${1%/*}; export PATH
+      shift
+      until "$command" "$@"; do
+        ${pkgs.coreutils}/bin/sleep 1
+      done
+    )&}
+    settle ${pkgs.xorg.xhost}/bin/xhost +LOCAL:
+    settle ${pkgs.xorg.xrdb}/bin/xrdb -merge ${import ./Xresources.nix args}
+    settle ${pkgs.xorg.xsetroot}/bin/xsetroot -solid '#1c1c1c'
+    exec ${pkgs.xmonad-lass}/bin/xmonad
+  '';
+
+  xmonad-stop = pkgs.writeScriptBin "xmonad-stop" ''
+    #! /bin/sh
+    exec ${pkgs.xmonad-lass}/bin/xmonad --shutdown
+  '';
+
+  xserver-environment = {
+    XKB_BINDIR = "${pkgs.xorg.xkbcomp}/bin"; # Needed for the Xkb extension.
+    XORG_DRI_DRIVER_PATH = "/run/opengl-driver/lib/dri"; # !!! Depends on the driver selected at runtime.
+    LD_LIBRARY_PATH = concatStringsSep ":" (
+      [ "${pkgs.xorg.libX11}/lib" "${pkgs.xorg.libXext}/lib" ]
+      ++ concatLists (catAttrs "libPath" config.services.xserver.drivers));
+  };
+
+  xserver = pkgs.writeScriptBin "xserver" ''
+    #! /bin/sh
+    set -efu
+    exec ${pkgs.xorg.xorgserver}/bin/X \
+        :${toString config.services.xserver.display} \
+        vt${toString config.services.xserver.tty} \
+        -config ${import ./xserver.conf.nix args} \
+        -logfile /var/log/X.${toString config.services.xserver.display}.log \
+        -nolisten tcp \
+        -xkbdir ${pkgs.xkeyboard_config}/etc/X11/xkb \
+  '';
+
+  need-reload = s: let
+    pkg = pkgs.writeScriptBin "need-reload" ''
+      #! /bin/sh
+      echo "$*"
+    '';
+  in "${pkg}/bin/need-reload ${s}";
+
+in out
diff --git a/lass/2configs/xserver/xserver.conf.nix b/lass/2configs/xserver/xserver.conf.nix
new file mode 100644
index 000000000..e8a997a99
--- /dev/null
+++ b/lass/2configs/xserver/xserver.conf.nix
@@ -0,0 +1,40 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver;
+in
+
+pkgs.stdenv.mkDerivation {
+  name = "xserver.conf";
+
+  xfs = optionalString (cfg.useXFS != false)
+    ''FontPath "${toString cfg.useXFS}"'';
+
+  inherit (cfg) config;
+
+  buildCommand =
+    ''
+      echo 'Section "Files"' >> $out
+      echo $xfs >> $out
+
+      for i in ${toString config.fonts.fonts}; do
+        if test "''${i:0:''${#NIX_STORE}}" == "$NIX_STORE"; then
+          for j in $(find $i -name fonts.dir); do
+            echo "  FontPath \"$(dirname $j)\"" >> $out
+          done
+        fi
+      done
+
+      for i in $(find ${toString cfg.modules} -type d); do
+        if test $(echo $i/*.so* | wc -w) -ne 0; then
+          echo "  ModulePath \"$i\"" >> $out
+        fi
+      done
+
+      echo 'EndSection' >> $out
+
+      echo "$config" >> $out
+    '';
+}
diff --git a/lass/3modules/bitlbee.nix b/lass/3modules/bitlbee.nix
deleted file mode 100644
index 8ce560146..000000000
--- a/lass/3modules/bitlbee.nix
+++ /dev/null
@@ -1,153 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-
-let
-
-  inherit (lib)
-    mkIf
-    mkOption
-    types
-    singleton
-  ;
-
-  authModeCheck = v:
-    v == "Open" ||
-    v == "Closed" ||
-    v == "Registered"
-  ;
-
-  bitlbeeConfig = pkgs.writeText "bitlbee.conf" ''
-    [settings]
-    RunMode = Daemon
-    User = bitlbee
-    ConfigDir = ${cfg.configDir}
-    DaemonInterface = ${cfg.interface}
-    DaemonPort = ${toString cfg.portNumber}
-    AuthMode = ${cfg.authMode}
-    ${lib.optionalString (cfg.hostName != "") "HostName = ${cfg.hostName}"}
-    ${lib.optionalString (cfg.protocols != "") "Protocols = ${cfg.protocols}"}
-    ${cfg.extraSettings}
-
-    [defaults]
-    ${cfg.extraDefaults}
-  '';
-
-  cfg = config.lass.bitlbee;
-
-  out = {
-    options.lass.bitlbee = api;
-    config = mkIf cfg.enable imp;
-  };
-
-  api = {
-    enable = mkOption {
-      default = false;
-      description = ''
-        Whether to run the BitlBee IRC to other chat network gateway.
-        Running it allows you to access the MSN, Jabber, Yahoo! and ICQ chat
-        networks via an IRC client.
-      '';
-    };
-
-    interface = mkOption {
-      default = "127.0.0.1";
-      description = ''
-        The interface the BitlBee deamon will be listening to.  If `127.0.0.1',
-        only clients on the local host can connect to it; if `0.0.0.0', clients
-        can access it from any network interface.
-      '';
-    };
-
-    portNumber = mkOption {
-      default = 6667;
-      description = ''
-        Number of the port BitlBee will be listening to.
-      '';
-    };
-
-    authMode = mkOption {
-      default = "Open";
-      type = types.addCheck types.str authModeCheck;
-      description = ''
-        The following authentication modes are available:
-          Open -- Accept connections from anyone, use NickServ for user authentication.
-          Closed -- Require authorization (using the PASS command during login) before allowing the user to connect at all.
-          Registered -- Only allow registered users to use this server; this disables the register- and the account command until the user identifies himself.
-      '';
-    };
-
-    hostName = mkOption {
-      default = "";
-      type = types.str;
-      description = ''
-        Normally, BitlBee gets a hostname using getsockname(). If you have a nicer
-        alias for your BitlBee daemon, you can set it here and BitlBee will identify
-        itself with that name instead.
-      '';
-    };
-
-    configDir = mkOption {
-      default = "/var/lib/bitlbee";
-      type = types.path;
-      description = ''
-        Specify an alternative directory to store all the per-user configuration
-        files.
-      '';
-    };
-
-    protocols = mkOption {
-      default = "";
-      type = types.str;
-      description = ''
-        This option allows to remove the support of protocol, even if compiled
-        in. If nothing is given, there are no restrictions.
-      '';
-    };
-
-    extraSettings = mkOption {
-      default = "";
-      description = ''
-        Will be inserted in the Settings section of the config file.
-      '';
-    };
-
-    extraDefaults = mkOption {
-      default = "";
-      description = ''
-        Will be inserted in the Default section of the config file.
-      '';
-    };
-
-    bitlbeePkg = mkOption {
-      default = pkgs.bitlbee;
-      description = ''
-        the bitlbee pkg to use.
-      '';
-    };
-  };
-
-  imp = {
-    users.extraUsers = singleton {
-      name = "bitlbee";
-      uid = config.ids.uids.bitlbee;
-      description = "BitlBee user";
-      home = "/var/lib/bitlbee";
-      createHome = true;
-    };
-
-    users.extraGroups = singleton {
-      name = "bitlbee";
-      gid = config.ids.gids.bitlbee;
-    };
-
-    systemd.services.bitlbee = {
-      description = "BitlBee IRC to other chat networks gateway";
-      after = [ "network.target" ];
-      wantedBy = [ "multi-user.target" ];
-      serviceConfig.User = "bitlbee";
-      serviceConfig.ExecStart = "${cfg.bitlbeePkg}/sbin/bitlbee -F -n -c ${bitlbeeConfig}";
-    };
-  };
-
-in
-out
diff --git a/lass/3modules/default.nix b/lass/3modules/default.nix
index b081dc3cc..0dcad971c 100644
--- a/lass/3modules/default.nix
+++ b/lass/3modules/default.nix
@@ -2,12 +2,11 @@ _:
 {
   imports = [
     ./xresources.nix
-    ./bitlbee.nix
     ./folderPerms.nix
-    ./go.nix
     ./newsbot-js.nix
     ./per-user.nix
     ./urxvtd.nix
     ./xresources.nix
+    ./wordpress_nginx.nix
   ];
 }
diff --git a/lass/3modules/dnsmasq.nix b/lass/3modules/dnsmasq.nix
index 99c165479..83a9cb180 100644
--- a/lass/3modules/dnsmasq.nix
+++ b/lass/3modules/dnsmasq.nix
@@ -25,13 +25,6 @@ let
   configFile = pkgs.writeText "dnsmasq.conf" cfg.config;
 
   imp = {
-    #users.extraUsers.go = {
-    #  name = "go";
-    #  uid = 42774411; #genid go
-    #  description = "go url shortener user";
-    #  home = "/var/lib/go";
-    #  createHome = true;
-    #};
 
     systemd.services.dnsmasq = {
       description = "dnsmasq";
diff --git a/lass/3modules/owncloud_nginx.nix b/lass/3modules/owncloud_nginx.nix
new file mode 100644
index 000000000..a0db87b0b
--- /dev/null
+++ b/lass/3modules/owncloud_nginx.nix
@@ -0,0 +1,215 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.lass.owncloud;
+
+  out = {
+    options.lass.owncloud = api;
+    config = imp;
+  };
+
+  api = mkOption {
+    type = with types; attrsOf (submodule ({ config, ... }: {
+      options = {
+        domain = mkOption {
+          type = str;
+          default = config._module.args.name;
+        };
+        dataDir = mkOption {
+          type = str;
+          default = "${config.folder}/data";
+        };
+        dbUser = mkOption {
+          type = str;
+          default = replaceStrings ["."] ["_"] config.domain;
+        };
+        dbName = mkOption {
+          type = str;
+          default = replaceStrings ["."] ["_"] config.domain;
+        };
+        dbType = mkOption {
+        # TODO: check for valid dbType
+          type = str;
+          default = "mysql";
+        };
+        folder = mkOption {
+          type = str;
+          default = "/srv/http/${config.domain}";
+        };
+        auto = mkOption {
+          type = bool;
+          default = false;
+        };
+        instanceid = mkOption {
+          type = str;
+        };
+        ssl = mkOption {
+          type = bool;
+          default = false;
+        };
+      };
+    }));
+    default = {};
+  };
+
+  user = config.services.nginx.user;
+  group = config.services.nginx.group;
+
+  imp = {
+    krebs.nginx.servers = flip mapAttrs cfg ( name: { domain, folder, ... }: {
+      server-names = [
+        "${domain}"
+        "www.${domain}"
+      ];
+      locations = [
+        (nameValuePair "/" ''
+          # The following 2 rules are only needed with webfinger
+          rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
+          rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
+
+          rewrite ^/.well-known/carddav /remote.php/carddav/ redirect;
+          rewrite ^/.well-known/caldav /remote.php/caldav/ redirect;
+
+          rewrite ^(/core/doc/[^\/]+/)$ $1/index.html;
+
+          try_files $uri $uri/ /index.php;
+        '')
+        (nameValuePair "~ \.php$" ''
+          fastcgi_split_path_info ^(.+\.php)(/.+)$;
+          include ${pkgs.nginx}/conf/fastcgi.conf;
+          fastcgi_param PATH_INFO $fastcgi_path_info;
+          fastcgi_pass unix:${folder}/phpfpm.pool;
+        '')
+        (nameValuePair "~ /\\." ''
+          deny all;
+        '')
+      ];
+      extraConfig = ''
+        root ${folder}/;
+        #index index.php;
+        access_log /tmp/nginx_acc.log;
+        error_log /tmp/nginx_err.log;
+
+        # set max upload size
+        client_max_body_size 10G;
+        fastcgi_buffers 64 4K;
+
+        rewrite ^/caldav(.*)$ /remote.php/caldav$1 redirect;
+        rewrite ^/carddav(.*)$ /remote.php/carddav$1 redirect;
+        rewrite ^/webdav(.*)$ /remote.php/webdav$1 redirect;
+
+        error_page 403 /core/templates/403.php;
+        error_page 404 /core/templates/404.php;
+      '';
+    });
+    services.phpfpm.poolConfigs = flip mapAttrs cfg (name: { domain, folder, ... }: ''
+      listen = ${folder}/phpfpm.pool
+      user = ${user}
+      group = ${group}
+      pm = dynamic
+      pm.max_children = 5
+      pm.start_servers = 2
+      pm.min_spare_servers = 1
+      pm.max_spare_servers = 3
+      listen.owner = ${user}
+      listen.group = ${group}
+      # errors to journal
+      php_admin_value[error_log] = 'stderr'
+      php_admin_flag[log_errors] = on
+      catch_workers_output = yes
+    '');
+    #systemd.services = flip mapAttrs' cfg (name: { domain, folder, dbName, dbUser, dbType, dataDir, instanceid, ... }: {
+    #  name = "owncloudInit-${name}";
+    #  value = {
+    #    path = [
+    #      pkgs.mysql
+    #      pkgs.su
+    #      pkgs.gawk
+    #      pkgs.jq
+    #    ];
+    #    requiredBy = [ "nginx.service" ];
+    #    serviceConfig = let
+    #      php.define = name: value:
+    #        "define(${php.newdoc name}, ${php.newdoc value});";
+    #      php.toString = x:
+    #        "'${x}'";
+    #      php.newdoc = s:
+    #        let b = "EOF${builtins.hashString "sha256" s}"; in
+    #        ''<<<'${b}'
+    #        ${s}
+    #        ${b}
+    #        '';
+    #    in {
+    #      Type = "oneshot";
+    #      ExecStart = pkgs.writeScript "wordpressInit" ''
+    #        #!/bin/sh
+    #        set -euf
+    #        oc_secrets=${shell.escape "${toString <secrets>}/${domain}/oc-secrets"}
+    #        db_password=$(cat ${shell.escape "${toString <secrets>}/${domain}/sql-db-pw"})
+    #        get_secret() {
+    #          echo "'$1' => $(jq -r ."$1" "$oc_secrets" | to_php_string),"
+    #        }
+    #        to_php_string() {
+    #          echo "base64_decode('$(base64)')"
+    #        }
+    #        {
+    #          cat ${toString <secrets/mysql_rootPassword>}
+    #          password=$(cat ${shell.escape (toString (<secrets/mysql_rootPassword>))})
+    #          # TODO passwordhash=$(su nobody_oc -c mysql <<< "SELECT PASSWORD($(toSqlString <<< "$password"));")
+    #          # TODO as package pkgs.sqlHashPassword
+    #          # TODO not using mysql
+    #          # SET SESSION sql_mode = 'NO_BACKSLASH_ESCAPES';
+    #          passwordhash=$(su nobody_oc -c 'mysql -u nobody --silent' <<< "SELECT PASSWORD('$db_password');")
+    #          user=${shell.escape dbUser}@localhost
+    #          database=${shell.escape dbName}
+    #          cat << EOF
+    #            CREATE DATABASE IF NOT EXISTS $database;
+    #            GRANT USAGE ON *.* TO $user IDENTIFIED BY PASSWORD '$passwordhash';
+    #            GRANT ALL PRIVILEGES ON $database.* TO $user;
+    #            FLUSH PRIVILEGES;
+    #        EOF
+    #        } | mysql -u root -p
+    #        # TODO nix2php for wp-config.php
+    #        mkdir -p ${folder}/config
+    #        cat > ${folder}/config/config.php << EOF
+    #        <?php
+    #        \$CONFIG = array (
+    #          'dbhost' => 'localhost',
+    #          'dbtableprefix' => 'oc_',
+    #          'dbpassword' => '$db_password',
+    #          'installed' => 'true',
+    #          'trusted_domains' =>
+    #          array (
+    #            0 => '${domain}',
+    #          ),
+    #          'overwrite.cli.url' => 'http://${domain}',
+
+    #        ${concatStringsSep "\n" (mapAttrsToList (name: value:
+    #          "'${name}' => $(printf '%s' ${shell.escape value} | to_php_string),"
+    #        ) {
+    #          instanceid = instanceid;
+    #          datadirectory = dataDir;
+    #          dbtype = dbType;
+    #          dbname = dbName;
+    #          dbuser = dbUser;
+    #        })}
+
+    #        ${concatMapStringsSep "\n" (key: "$(get_secret ${shell.escape key})") [
+    #          "secret"
+    #          "passwordsalt"
+    #        ]}
+    #        );
+    #        EOF
+    #      '';
+    #    };
+    #  };
+    #});
+    users.users.nobody_oc = {
+      uid = 1651469147; # genid nobody_oc
+      useDefaultShell = true;
+    };
+  };
+
+in out
diff --git a/lass/3modules/static_nginx.nix b/lass/3modules/static_nginx.nix
new file mode 100644
index 000000000..cc2641af2
--- /dev/null
+++ b/lass/3modules/static_nginx.nix
@@ -0,0 +1,49 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.lass.staticPage;
+
+  out = {
+    options.lass.staticPage = api;
+    config = imp;
+  };
+
+  api = mkOption {
+    type = with types; attrsOf (submodule ({ config, ... }: {
+      options = {
+        domain = mkOption {
+          type = str;
+          default = config._module.args.name;
+        };
+        folder = mkOption {
+          type = str;
+          default = "/srv/http/${config.domain}";
+        };
+      };
+    }));
+    default = {};
+  };
+
+  user = config.services.nginx.user;
+  group = config.services.nginx.group;
+
+  imp = {
+    krebs.nginx.servers = flip mapAttrs cfg ( name: { domain, folder, ... }: {
+      server-names = [
+        "${domain}"
+        "www.${domain}"
+      ];
+      locations = [
+        (nameValuePair "/" ''
+          root ${folder};
+        '')
+        (nameValuePair "~ /\\." ''
+          deny all;
+        '')
+      ];
+    });
+  };
+
+in out
diff --git a/lass/3modules/wordpress_nginx.nix b/lass/3modules/wordpress_nginx.nix
new file mode 100644
index 000000000..2f31f6e02
--- /dev/null
+++ b/lass/3modules/wordpress_nginx.nix
@@ -0,0 +1,239 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.lass.wordpress;
+
+  out = {
+    options.lass.wordpress = api;
+    config = imp;
+  };
+
+  api = mkOption {
+    type = with types; attrsOf (submodule ({ config, ... }: {
+      options = {
+        domain = mkOption {
+          type = str;
+          default = config._module.args.name;
+        };
+        dbUser = mkOption {
+          type = str;
+          default = replaceStrings ["."] ["_"] config.domain;
+        };
+        dbName = mkOption {
+          type = str;
+          default = replaceStrings ["."] ["_"] config.domain;
+        };
+        folder = mkOption {
+          type = str;
+          default = "/srv/http/${config.domain}";
+        };
+        auto = mkOption {
+          type = bool;
+          default = false;
+        };
+        charset = mkOption {
+          type = str;
+          default = "utf8mb4";
+        };
+        collate = mkOption {
+          type = str;
+          default = "";
+        };
+        debug = mkOption {
+          type = bool;
+          default = false;
+        };
+        multiSite = mkOption {
+          type = attrsOf str;
+          default = {};
+          example = {
+            "0" = "bla.testsite.de";
+            "1" = "test.testsite.de";
+          };
+        };
+      };
+    }));
+    default = {};
+  };
+
+  user = config.services.nginx.user;
+  group = config.services.nginx.group;
+
+  imp = {
+    #services.nginx.appendConfig = mkIf (cfg.multiSite != {}) ''
+    #  map $http_host $blogid {
+    #  ${concatStringsSep "\n" (mapAttrsToList (n: v: indent "v n;") multiSite)}
+    #  }
+    #'';
+
+    krebs.nginx.servers = flip mapAttrs cfg ( name: { domain, folder, multiSite, ... }: {
+      server-names = [
+        "${domain}"
+        "www.${domain}"
+      ];
+        #(mkIf (multiSite != {})
+        #)
+      locations = (if (multiSite != {}) then
+        [
+          (nameValuePair "~ ^/files/(.*)$" ''
+            try_files /wp-content/blogs.dir/$blogid/$uri /wp-includes/ms-files.php?file=$1 ;
+          '')
+          (nameValuePair "^~ /blogs.dir" ''
+            internal;
+            alias ${folder}/wp-content/blogs.dir ;
+            access_log off; log_not_found off; expires max;
+          '')
+        ]
+      else
+        []
+      ) ++
+      [
+        (nameValuePair "/" ''
+          try_files $uri $uri/ /index.php?$args;
+        '')
+        (nameValuePair "~ \.php$" ''
+          fastcgi_pass unix:${folder}/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;
+        '')
+      ];
+      extraConfig = ''
+        root ${folder}/;
+        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;
+      '';
+    });
+    services.phpfpm.poolConfigs = flip mapAttrs cfg (name: { domain, folder, ... }: ''
+      listen = ${folder}/phpfpm.pool
+      user = ${user}
+      group = ${group}
+      pm = dynamic
+      pm.max_children = 5
+      pm.start_servers = 2
+      pm.min_spare_servers = 1
+      pm.max_spare_servers = 3
+      listen.owner = ${user}
+      listen.group = ${group}
+      # errors to journal
+      php_admin_value[error_log] = 'stderr'
+      php_admin_flag[log_errors] = on
+      catch_workers_output = yes
+    '');
+    systemd.services = flip mapAttrs' cfg (name: { domain, folder, charset, collate, dbName, dbUser, debug, multiSite, ... }: {
+      name = "wordpressInit-${name}";
+      value = {
+        path = [
+          pkgs.mysql
+          pkgs.su
+          pkgs.gawk
+          pkgs.jq
+        ];
+        requiredBy = [ "nginx.service" ];
+        serviceConfig = let
+          php.define = name: value:
+            "define(${php.newdoc name}, ${php.newdoc value});";
+          php.toString = x:
+            "'${x}'";
+          php.newdoc = s:
+            let b = "EOF${builtins.hashString "sha256" s}"; in
+            ''<<<'${b}'
+            ${s}
+            ${b}
+            '';
+        in {
+          Type = "oneshot";
+          ExecStart = pkgs.writeScript "wordpressInit" ''
+            #!/bin/sh
+            set -euf
+            wp_secrets=${shell.escape "${toString <secrets>}/${domain}/wp-secrets"}
+            db_password=$(cat ${shell.escape "${toString <secrets>}/${domain}/sql-db-pw"})
+            get_secret() {
+              echo "define('$1', $(jq -r ."$1" "$wp_secrets" | to_php_string));"
+            }
+            to_php_string() {
+              echo "base64_decode('$(base64)')"
+            }
+            {
+              cat ${toString <secrets/mysql_rootPassword>}
+              password=$(cat ${shell.escape (toString (<secrets/mysql_rootPassword>))})
+              # TODO passwordhash=$(su nobody2 -c mysql <<< "SELECT PASSWORD($(toSqlString <<< "$password"));")
+              # TODO as package pkgs.sqlHashPassword
+              # TODO not using mysql
+              # SET SESSION sql_mode = 'NO_BACKSLASH_ESCAPES';
+              passwordhash=$(su nobody2 -c 'mysql -u nobody --silent' <<< "SELECT PASSWORD('$db_password');")
+              user=${shell.escape dbUser}@localhost
+              database=${shell.escape dbName}
+              cat << EOF
+                CREATE DATABASE IF NOT EXISTS $database;
+                GRANT USAGE ON *.* TO $user IDENTIFIED BY PASSWORD '$passwordhash';
+                GRANT ALL PRIVILEGES ON $database.* TO $user;
+                FLUSH PRIVILEGES;
+            EOF
+            } | mysql -u root -p
+            # TODO nix2php for wp-config.php
+            cat > ${folder}/wp-config.php << EOF
+            <?php
+            define('DB_PASSWORD', '$db_password');
+            define('DB_HOST', 'localhost');
+
+            ${concatStringsSep "\n" (mapAttrsToList (name: value:
+              "define('${name}', $(printf '%s' ${shell.escape value} | to_php_string));"
+            ) {
+              DB_NAME = dbName;
+              DB_USER = dbUser;
+              DB_CHARSET = charset;
+              DB_COLLATE = collate;
+            })}
+
+            ${concatMapStringsSep "\n" (key: "$(get_secret ${shell.escape key})") [
+              "AUTH_KEY"
+              "SECURE_AUTH_KEY"
+              "LOGGED_IN_KEY"
+              "NONCE_KEY"
+              "AUTH_SALT"
+              "SECURE_AUTH_SALT"
+              "LOGGED_IN_SALT"
+              "NONCE_SALT"
+            ]}
+
+            \$table_prefix = 'wp_';
+
+            ${if (multiSite != {}) then
+              "define('WP_ALLOW_MULTISITE', true);"
+            else
+              ""
+            }
+
+            define('WP_DEBUG', ${toJSON debug});
+            if ( !defined('ABSPATH') )
+              define('ABSPATH', dirname(__FILE__) . '/');
+
+            /** Sets up WordPress vars and included files. */
+            require_once(ABSPATH . 'wp-settings.php');
+            EOF
+          '';
+        };
+      };
+    });
+    users.users.nobody2 = mkDefault {
+      uid = mkDefault 125816384; # genid nobody2
+      useDefaultShell = mkDefault true;
+    };
+  };
+
+  indent = replaceChars ["\n"] ["\n  "];
+
+in out
diff --git a/lass/4lib/default.nix b/lass/4lib/default.nix
index 6a8a28972..a751a2995 100644
--- a/lass/4lib/default.nix
+++ b/lass/4lib/default.nix
@@ -1,19 +1,9 @@
-{ lib, pkgs, ... }:
+{ lib, ... }:
 
 with lib;
 
 {
 
-  simpleScript = name: content:
-    pkgs.stdenv.mkDerivation {
-      inherit name;
-      phases = [ "installPhase" ];
-      installPhase = ''
-        mkdir -p $out/bin
-        ln -s ${pkgs.writeScript name content} $out/bin/${name}
-      '';
-    };
-
   getDefaultGateway = ip:
     concatStringsSep "." (take 3 (splitString "." ip) ++ ["1"]);
 
diff --git a/lass/5pkgs/bitlbee-dev.nix b/lass/5pkgs/bitlbee-dev.nix
deleted file mode 100644
index dd129591e..000000000
--- a/lass/5pkgs/bitlbee-dev.nix
+++ /dev/null
@@ -1,20 +0,0 @@
-{ fetchurl, stdenv, gnutls, glib, pkgconfig, check, libotr, python }:
-
-stdenv.mkDerivation rec {
-  name = "bitlbee-3.4.1";
-
-  src = fetchurl {
-    url = "mirror://bitlbee/src/${name}.tar.gz";
-    sha256 = "1qf0ypa9ba5jvsnpg9slmaran16hcc5fnfzbb1sdch1hjhchn2jh";
-  };
-
-  buildInputs = [ gnutls glib pkgconfig libotr python ];
-
-  buildPhase = "";
-
-  installPhase = ''
-    make install-dev
-  '';
-
-}
-
diff --git a/lass/5pkgs/bitlbee-steam.nix b/lass/5pkgs/bitlbee-steam.nix
deleted file mode 100644
index d869eaac5..000000000
--- a/lass/5pkgs/bitlbee-steam.nix
+++ /dev/null
@@ -1,31 +0,0 @@
-{ stdenv, fetchgit, autoconf, automake, bitlbee-dev, glib, libgcrypt, libtool, pkgconfig }:
-
-stdenv.mkDerivation rec {
-  name = "bitlbee-steam-1.3.1";
-
-  src = fetchgit {
-    url = "https://github.com/jgeboski/bitlbee-steam";
-    rev = "439d777c7e8d06712ffc15c3e51d61799f4c0d0c";
-    sha256 = "493924da1083a3b23073c595a9e1989a7ae09a196524ad66ca99c4d8ccc20d2a";
-  };
-
-  buildInputs = [
-    autoconf
-    automake
-    bitlbee-dev
-    glib
-    libgcrypt
-    libtool
-    pkgconfig
-  ];
-
-  configurePhase = ''
-    ./autogen.sh
-  '';
-
-  installPhase = ''
-    mkdir -p $out
-    cp steam/.libs/steam.la $out/
-    cp steam/.libs/steam.so $out/
-  '';
-}
diff --git a/lass/5pkgs/bitlbee.nix b/lass/5pkgs/bitlbee.nix
deleted file mode 100644
index 2a5a8d86d..000000000
--- a/lass/5pkgs/bitlbee.nix
+++ /dev/null
@@ -1,71 +0,0 @@
-{ fetchurl, stdenv, gnutls, glib, pkgconfig, check, libotr, python
-  , bitlbee-facebook ? null
-  , bitlbee-steam ? null
-}:
-
-with stdenv.lib;
-stdenv.mkDerivation rec {
-  name = "bitlbee-3.4.1";
-
-  src = fetchurl {
-    url = "mirror://bitlbee/src/${name}.tar.gz";
-    sha256 = "1qf0ypa9ba5jvsnpg9slmaran16hcc5fnfzbb1sdch1hjhchn2jh";
-  };
-
-
-  buildInputs = [ gnutls glib pkgconfig libotr python ]
-    ++ optional doCheck check;
-
-  configureFlags = [
-    "--gcov=1"
-    "--otr=1"
-    "--ssl=gnutls"
-  ];
-
-  postBuild = ''
-    ${if (bitlbee-steam != null) then
-      ''
-        mkdir -p $out/lib/bitlbee/
-        find ${bitlbee-steam}
-        cp ${bitlbee-steam}/* $out/lib/bitlbee/
-      ''
-    else
-      ""
-    }
-  '';
-    #${concatMapStringsSep "\n" ([] ++
-    #  (if (bitlbee-facebook != null) then
-    #    "cp ${bitlbee-faceook}/* $out/"
-    #  else
-    #    ""
-    #  ) ++
-    #  (if (bitlbee-steam != null) then
-    #    "cp ${bitlbee-steam}/* $out/"
-    #  else
-    #    ""
-    #  )
-    #)}
-
-  doCheck = true;
-
-  meta = {
-    description = "IRC instant messaging gateway";
-
-    longDescription = ''
-      BitlBee brings IM (instant messaging) to IRC clients.  It's a
-      great solution for people who have an IRC client running all the
-      time and don't want to run an additional MSN/AIM/whatever
-      client.
-
-      BitlBee currently supports the following IM networks/protocols:
-      XMPP/Jabber (including Google Talk), MSN Messenger, Yahoo!
-      Messenger, AIM and ICQ.
-    '';
-
-    homepage = http://www.bitlbee.org/;
-    license = licenses.gpl2Plus;
-
-    maintainers = with maintainers; [ wkennington pSub ];
-    platforms = platforms.gnu;  # arbitrary choice
-  };
-}
diff --git a/lass/5pkgs/default.nix b/lass/5pkgs/default.nix
index 869f808ce..2b9582912 100644
--- a/lass/5pkgs/default.nix
+++ b/lass/5pkgs/default.nix
@@ -5,14 +5,13 @@ let
 in
 
 rec {
-  bitlbee-dev = callPackage ./bitlbee-dev.nix {};
-  bitlbee-steam = callPackage ./bitlbee-steam.nix { inherit bitlbee-dev; };
-  bitlbee = callPackage ./bitlbee.nix { inherit bitlbee-steam; };
   firefoxPlugins = {
     noscript = callPackage ./firefoxPlugins/noscript.nix {};
     ublock = callPackage ./firefoxPlugins/ublock.nix {};
     vimperator = callPackage ./firefoxPlugins/vimperator.nix {};
   };
-  go = callPackage ./go/default.nix {};
   newsbot-js = callPackage ./newsbot-js/default.nix {};
+  xmonad-lass =
+    let src = pkgs.writeNixFromCabal "xmonad-lass.nix" ./xmonad-lass; in
+    pkgs.haskellPackages.callPackage src {};
 }
diff --git a/lass/5pkgs/xmonad-lass/.gitignore b/lass/5pkgs/xmonad-lass/.gitignore
new file mode 100644
index 000000000..616204547
--- /dev/null
+++ b/lass/5pkgs/xmonad-lass/.gitignore
@@ -0,0 +1 @@
+/shell.nix
diff --git a/lass/5pkgs/xmonad-lass/Main.hs b/lass/5pkgs/xmonad-lass/Main.hs
new file mode 100644
index 000000000..ce5afe33a
--- /dev/null
+++ b/lass/5pkgs/xmonad-lass/Main.hs
@@ -0,0 +1,203 @@
+{-# LANGUAGE DeriveDataTypeable #-} -- for XS
+{-# LANGUAGE FlexibleContexts #-} -- for xmonad'
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+
+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.Prompt (defaultXPConfig)
+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 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
+
+
+myTerm :: String
+myTerm = "urxvtc"
+
+myRootTerm :: String
+myRootTerm = "urxvtc -name root-urxvt -e su -"
+
+myFont :: String
+myFont = "-schumacher-*-*-*-*-*-*-*-*-*-*-*-iso10646-*"
+
+main :: IO ()
+main = getArgs >>= \case
+    ["--shutdown"] -> sendShutdownEvent
+    _ -> mainNoArgs
+
+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 ")
+        $ defaultConfig
+            { 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"
+            , focusedBorderColor = "#f000b0"
+            , handleEventHook = handleShutdownEvent
+            } `additionalKeysP` myKeyMap
+
+myLayoutHook = defLayout
+  where
+    defLayout = (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 ()
+xmonad' conf = do
+    path <- getEnv "XMONAD_STATE"
+    try (readFile path) >>= \case
+        Right content -> do
+            hPutStrLn stderr ("resuming from " ++ path)
+            withArgs ("--resume" : lines content) (xmonad conf)
+        Left e -> do
+            hPutStrLn stderr (displaySomeException e)
+            xmonad conf
+
+getWorkspaces0 :: IO [String]
+getWorkspaces0 =
+    try (getEnv "XMONAD_WORKSPACES0_FILE") >>= \case
+      Left e -> warn (displaySomeException e)
+      Right p -> try (readFile p) >>= \case
+        Left e -> warn (displaySomeException e)
+        Right x -> case readEither x of
+          Left e -> warn e
+          Right y -> return y
+  where
+    warn msg = hPutStrLn stderr ("getWorkspaces0: " ++ msg) >> return []
+
+displaySomeException :: SomeException -> String
+displaySomeException = displayException
+
+
+myKeyMap =
+    [ ("M4-<F11>", spawn "/var/setuid-wrappers/slock")
+    , ("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%")
+    , ("<XF86Launch1>", gridselectWorkspace myWSConfig W.view)
+
+    , ("M4-a", focusUrgent)
+    , ("M4-S-r", renameWorkspace    defaultXPConfig)
+    , ("M4-S-a", addWorkspacePrompt defaultXPConfig)
+    , ("M4-S-<Backspace>", removeEmptyWorkspace)
+    , ("M4-S-c", kill1)
+    , ("M4-<Esc>", toggleWS)
+    , ("M4-S-<Enter>", spawn myTerm)
+    , ("M4-x", floatNext True >> spawn myTerm)
+    , ("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))
+
+    -- , (_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-<F1>", perWorkspaceAction workspaceConfigs)
+    , ("M4-S-q", return ())
+    ]
+
+myGSConfig = defaultGSConfig
+    { gs_cellheight = 50
+    , gs_cellpadding = 2
+    , gs_navigate = navNSearch
+    , gs_font = myFont
+    }
+
+myXPConfig :: XPConfig
+myXPConfig = defaultXPConfig
+    { autoComplete = Just 5000
+    }
+
+myWSConfig = myGSConfig
+    { gs_cellwidth = 50
+    }
+
+pagerConfig :: PagerConfig
+pagerConfig = defaultPagerConfig
+    { 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 def = defaultWindowColors wsf m c u wf
+        if m == False && wf == True
+            then ("#402020", snd def)
+            else def
+
+wGSConfig :: GSConfig Window
+wGSConfig = defaultGSConfig
+    { 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/Makefile b/lass/5pkgs/xmonad-lass/Makefile
new file mode 100644
index 000000000..cbb0776e6
--- /dev/null
+++ b/lass/5pkgs/xmonad-lass/Makefile
@@ -0,0 +1,6 @@
+.PHONY: ghci
+ghci: shell.nix
+	nix-shell --command 'exec ghci -Wall'
+
+shell.nix: xmonad.cabal
+	cabal2nix --shell . > $@
diff --git a/lass/5pkgs/xmonad-lass/Util/PerWorkspaceConfig.hs b/lass/5pkgs/xmonad-lass/Util/PerWorkspaceConfig.hs
new file mode 100644
index 000000000..bba7c8c60
--- /dev/null
+++ b/lass/5pkgs/xmonad-lass/Util/PerWorkspaceConfig.hs
@@ -0,0 +1,52 @@
+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
diff --git a/lass/5pkgs/xmonad-lass/xmonad.cabal b/lass/5pkgs/xmonad-lass/xmonad.cabal
new file mode 100644
index 000000000..37809b599
--- /dev/null
+++ b/lass/5pkgs/xmonad-lass/xmonad.cabal
@@ -0,0 +1,17 @@
+Author: lass
+Build-Type: Simple
+Cabal-Version: >= 1.2
+License: MIT
+Name: xmonad-lass
+Version: 0
+
+Executable xmonad
+  Build-Depends:
+    base,
+    containers,
+    unix,
+    xmonad,
+    xmonad-contrib,
+    xmonad-stockholm
+  GHC-Options: -Wall -O3 -threaded -rtsopts
+  Main-Is: Main.hs
diff --git a/makefu/1systems/filepimp.nix b/makefu/1systems/filepimp.nix
index fb1a57552..66ea2ce90 100644
--- a/makefu/1systems/filepimp.nix
+++ b/makefu/1systems/filepimp.nix
@@ -7,8 +7,6 @@
 {
   imports =
     [ # Include the results of the hardware scan.
-      ../2configs/default.nix
-      ../2configs/fs/vm-single-partition.nix
       ../2configs/fs/single-partition-ext4.nix
       ../2configs/tinc-basic-retiolum.nix
     ];
diff --git a/makefu/1systems/gum.nix b/makefu/1systems/gum.nix
index 85cf4c533..417a020fa 100644
--- a/makefu/1systems/gum.nix
+++ b/makefu/1systems/gum.nix
@@ -9,24 +9,71 @@ in {
       # TODO: copy this config or move to krebs
       ../2configs/tinc-basic-retiolum.nix
       ../2configs/headless.nix
+      ../2configs/fs/simple-swap.nix
+      ../2configs/fs/single-partition-ext4.nix
       # ../2configs/iodined.nix
-
-      # Reaktor
-      ../2configs/Reaktor/simpleExtend.nix
+      ../2configs/git/cgit-retiolum.nix
+      ../2configs/mattermost-docker.nix
+      ../2configs/nginx/euer.test.nix
   ];
 
+
+  nixpkgs.config.packageOverrides = pkgs: { tinc = pkgs.tinc_pre; };
+
+  ###### stable
+  krebs.build.target = "root@gum.krebsco.de";
   krebs.build.host = config.krebs.hosts.gum;
+  krebs.retiolum.extraConfig = ''
+    ListenAddress = ${external-ip} 53
+    ListenAddress = ${external-ip} 655
+    ListenAddress = ${external-ip} 21031
+  '';
 
-  krebs.Reaktor.enable = true;
+  # Chat
+  environment.systemPackages = with pkgs;[
+    weechat
+    bepasty-client-cli
+    get
+  ];
+  services.bitlbee.enable = true;
 
-  # prepare graphs
-  krebs.nginx.enable = true;
+  # Hardware
+  boot.loader.grub.device = "/dev/sda";
+  boot.initrd.availableKernelModules = [ "pata_via" "uhci_hcd" ];
+  boot.kernelModules = [ "kvm-intel" ];
 
+  # Network
+  services.udev.extraRules = ''
+    SUBSYSTEM=="net", ATTR{address}=="c8:0a:a9:c8:ee:dd", NAME="et0"
+  '';
+  boot.kernelParams = [ "ipv6.disable=1" ];
   networking = {
-    firewall.allowPing = true;
-    firewall.allowedTCPPorts = [ 80 443 655 ];
-    firewall.allowedUDPPorts = [ 655 ];
-    interfaces.enp2s1.ip4 = [{
+    enableIPv6 = false;
+    firewall = {
+        allowPing = true;
+        logRefusedConnections = false;
+        allowedTCPPorts = [
+          # smtp
+          25
+          # http
+          80 443
+          # tinc
+          655
+          # tinc-shack
+          21032
+          # tinc-retiolum
+          21031
+        ];
+        allowedUDPPorts = [
+          # tinc
+          655 53
+          # tinc-retiolum
+          21031
+          # tinc-shack
+          21032
+        ];
+    };
+    interfaces.et0.ip4 = [{
       address = external-ip;
       prefixLength = 24;
     }];
@@ -34,5 +81,4 @@ in {
     nameservers = [ "8.8.8.8" ];
   };
 
-  # based on ../../tv/2configs/CAC-Developer-2.nix
 }
diff --git a/makefu/1systems/omo.nix b/makefu/1systems/omo.nix
new file mode 100644
index 000000000..6ae79398a
--- /dev/null
+++ b/makefu/1systems/omo.nix
@@ -0,0 +1,37 @@
+# Edit this configuration file to define what should be installed on
+# your system.  Help is available in the configuration.nix(5) man page
+# and in the NixOS manual (accessible by running ‘nixos-help’).
+
+{ config, pkgs, ... }:
+
+{
+  imports =
+    [ # Include the results of the hardware scan.
+      ../2configs/fs/single-partition-ext4.nix
+      ../2configs/tinc-basic-retiolum.nix
+      ../2configs/exim-retiolum.nix
+    ];
+  krebs.build.host = config.krebs.hosts.omo;
+
+  # AMD E350
+  boot = {
+    loader.grub.device = "/dev/sda";
+
+    initrd.availableKernelModules = [
+      "usb_storage"
+      "ahci"
+      "xhci_hcd"
+      "ata_piix"
+      "uhci_hcd"
+      "ehci_pci"
+    ];
+
+    kernelModules = [ ];
+    extraModulePackages = [ ];
+  };
+
+  hardware.enableAllFirmware = true;
+  hardware.cpu.amd.updateMicrocode = true;
+
+  networking.firewall.allowPing = true;
+}
diff --git a/makefu/1systems/pornocauster.nix b/makefu/1systems/pornocauster.nix
index 8624cb2d1..28b77d330 100644
--- a/makefu/1systems/pornocauster.nix
+++ b/makefu/1systems/pornocauster.nix
@@ -6,21 +6,21 @@
 {
   imports =
     [ # Include the results of the hardware scan.
-      ../2configs/main-laptop.nix #< base-gui
+      ../2configs/main-laptop.nix #< base-gui + zsh
 
       # Krebs
       ../2configs/tinc-basic-retiolum.nix
       #../2configs/disable_v6.nix
 
-      # environment
-      ../2configs/zsh-user.nix
 
       # applications
+
       ../2configs/exim-retiolum.nix
       ../2configs/mail-client.nix
+      ../2configs/printer.nix
       #../2configs/virtualization.nix
       ../2configs/virtualization.nix
-      #../2configs/virtualization-virtualbox.nix
+      ../2configs/virtualization-virtualbox.nix
       ../2configs/wwan.nix
 
       # services
@@ -34,15 +34,23 @@
       # ../2configs/mediawiki.nix
       #../2configs/wordpress.nix
     ];
+  nixpkgs.config.packageOverrides = pkgs: {
+    tinc = pkgs.tinc_pre;
+    buildbot = let
+      pkgs1509 = import (fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/nixos-unstable.tar.gz) {};
+      in pkgs1509.buildbot;
+  };
+  makefu.buildbot.master.enable = true;
+
   #krebs.Reaktor.enable = true;
   #krebs.Reaktor.nickname = "makefu|r";
-
-  krebs.build.host = config.krebs.hosts.pornocauster;
+  # nix.binaryCaches = [ "http://acng.shack/nixos" "https://cache.nixos.org" ];
 
   environment.systemPackages = with pkgs;[
     get
     virtmanager
     gnome3.dconf
+    krebspaste
     ];
 
   services.logind.extraConfig = "HandleLidSwitch=ignore";
@@ -54,4 +62,5 @@
     25
   ];
 
+  krebs.build.host = config.krebs.hosts.pornocauster;
 }
diff --git a/makefu/1systems/vbob.nix b/makefu/1systems/vbob.nix
new file mode 100644
index 000000000..a24cefd0d
--- /dev/null
+++ b/makefu/1systems/vbob.nix
@@ -0,0 +1,88 @@
+#
+#
+#
+{ lib, config, pkgs, ... }:
+let
+    pkgs-unst = import (fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/nixos-unstable.tar.gz) {};
+in {
+  krebs.build.host = config.krebs.hosts.vbob;
+  krebs.build.target = "root@10.10.10.220";
+  imports =
+    [ # Include the results of the hardware scan.
+      <nixpkgs/nixos/modules/virtualisation/virtualbox-image.nix>
+      ../2configs/main-laptop.nix #< base-gui
+
+      # environment
+
+    ];
+  nixpkgs.config.packageOverrides = pkgs: {
+    tinc = pkgs.tinc_pre;
+    buildbot = pkgs-unst.buildbot;
+    buildbot-slave = pkgs-unst.buildbot-slave;
+  };
+
+  makefu.buildbot.master = {
+    enable = true;
+    irc = {
+      enable = true;
+      server = "cd.retiolum";
+      channel = "retiolum";
+      allowForce = true;
+    };
+  };
+  makefu.buildbot.slave = {
+    enable = true;
+    masterhost = "localhost";
+    username = "testslave";
+    password = "krebspass";
+    packages = with pkgs;[ git nix ];
+    extraEnviron = { NIX_PATH="nixpkgs=${toString <nixpkgs>}"; };
+  };
+
+  krebs.build.source.git.nixpkgs = {
+    #url = https://github.com/nixos/nixpkgs;
+    # HTTP Everywhere
+    rev = "a3974e";
+  };
+  fileSystems."/nix" = {
+    device ="/dev/disk/by-label/nixstore";
+    fsType = "ext4";
+  };
+  #makefu.buildbot.master.enable = true;
+  # allow vbob to deploy self
+  users.extraUsers = {
+    root = {
+        openssh.authorizedKeys.keys = [ config.krebs.users.makefu-vbob.pubkey  ];
+    };
+  };
+  environment.systemPackages = with pkgs;[
+    buildbot
+    buildbot-slave
+    get
+    genid
+  ];
+
+  networking.firewall.allowedTCPPorts = [
+    25
+    80
+    8010
+  ];
+
+  krebs.retiolum = {
+    enable = true;
+    extraConfig = "Proxy = http global.proxy.alcatel-lucent.com 8000";
+    hosts = ../../krebs/Zhosts;
+    connectTo = [
+      "gum"
+    ];
+  };
+
+  networking.proxy.default = "http://global.proxy.alcatel-lucent.com:8000";
+  fileSystems."/media/share" = {
+    fsType = "vboxsf";
+    device = "share";
+    options = "rw,uid=9001,gid=9001";
+  };
+
+}
+
diff --git a/makefu/1systems/wry.nix b/makefu/1systems/wry.nix
index ba94972fb..cd2b3f657 100644
--- a/makefu/1systems/wry.nix
+++ b/makefu/1systems/wry.nix
@@ -24,11 +24,11 @@ in {
       # other nginx
       ../2configs/nginx/euer.wiki.nix
       ../2configs/nginx/euer.blog.nix
+      ../2configs/nginx/euer.test.nix
 
       # collectd
       ../2configs/collectd/collectd-base.nix
   ];
-
   krebs.build.host = config.krebs.hosts.wry;
 
   krebs.Reaktor.enable = true;
@@ -59,9 +59,12 @@ in {
   };
 
   networking = {
-    firewall.allowPing = true;
-    firewall.allowedTCPPorts = [ 53 80 443 ];
-    firewall.allowedUDPPorts = [ 655 ];
+  firewall = {
+      allowPing = true;
+      logRefusedConnections = false;
+      allowedTCPPorts = [ 53 80 443 ];
+      allowedUDPPorts = [ 655 ];
+    };
     interfaces.enp2s1.ip4 = [{
       address = external-ip;
       prefixLength = 24;
@@ -70,5 +73,9 @@ in {
     nameservers = [ "8.8.8.8" ];
   };
 
-  environment.systemPackages = [ pkgs.translate-shell ];
+  # small machine - do not forget to gc every day
+  nix.gc.automatic = true;
+  nix.gc.dates = "03:10";
+
+  environment.systemPackages = [ ];
 }
diff --git a/makefu/2configs/Reaktor/full.nix b/makefu/2configs/Reaktor/full.nix
new file mode 100644
index 000000000..50620890f
--- /dev/null
+++ b/makefu/2configs/Reaktor/full.nix
@@ -0,0 +1,18 @@
+_:
+{
+  # implementation of the complete Reaktor bot
+  imports = [
+      #./stockholmLentil.nix
+      ./simpleExtend.nix
+      ./random-emoji.nix
+      ./titlebot.nix
+      ./shack-correct.nix
+      ./sed-plugin.nix
+  ];
+  krebs.Reaktor.nickname = "Reaktor|bot";
+  krebs.Reaktor.enable = true;
+
+  krebs.Reaktor.extraEnviron = {
+    REAKTOR_CHANNELS = "#krebs,#binaergewitter,#shackspace";
+  };
+}
diff --git a/makefu/2configs/Reaktor/sed-plugin.nix b/makefu/2configs/Reaktor/sed-plugin.nix
new file mode 100644
index 000000000..a451e0d3e
--- /dev/null
+++ b/makefu/2configs/Reaktor/sed-plugin.nix
@@ -0,0 +1,18 @@
+{ config, lib, pkgs, ... }:
+
+with pkgs;
+let
+  script =  ./sed-plugin.py;
+in {
+  #TODO: this will eat up the last regex, fix Reaktor
+  krebs.Reaktor.extraConfig = ''
+  public_commands.append({
+    'capname' : "sed-plugin",
+    # only support s///gi
+    'pattern' : '^(?P<args>.*)$$',
+    'argv'    : ["${pkgs.python3}/bin/python3","${script}"],
+    'env'     : { 'state_dir' : workdir,
+                  'PATH':'${lib.makeSearchPath "bin" [pkgs.gnused]}' }})
+  '';
+}
+
diff --git a/makefu/2configs/Reaktor/sed-plugin.py b/makefu/2configs/Reaktor/sed-plugin.py
new file mode 100644
index 000000000..8103c9585
--- /dev/null
+++ b/makefu/2configs/Reaktor/sed-plugin.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python3
+
+# Usage:
+# _from=krebs state_dir=. python sed-plugin.py 'dick butt'
+# _from=krebs state_dir=. python sed-plugin.py 's/t/l/g'
+## dick bull
+import shelve
+from os import environ
+from os.path import join
+from sys import argv
+d = shelve.open(join(environ['state_dir'],'sed-plugin.shelve'),writeback=True)
+usr = environ['_from']
+import re
+
+def is_regex(line):
+    myre = re.compile(r'^s/((?:\\/|[^/])+)/((?:\\/|[^/])*)/([ig]*)$')
+    return myre.match(line)
+
+line = argv[1]
+m = is_regex(line)
+
+if m:
+    f,t,flagstr = m.groups()
+    fn = f.replace('\/','/')
+    tn = t.replace('\/','/')
+    flags =  0
+    count = 1
+    if flagstr:
+        if 'i' in flagstr:
+            flags = re.IGNORECASE
+        if 'g' in flagstr:
+            count = 0
+    else:
+        flagstr = ''
+    last = d.get(usr,None)
+    if last:
+        #print(re.sub(fn,tn,last,count=count,flags=flags))
+        from subprocess import Popen,PIPE
+        p = Popen(['sed','s/{}/{}/{}'.format(f,t,flagstr)],stdin=PIPE,stdout=PIPE )
+        so,se = p.communicate(bytes("{}\n".format(last),"UTF-8"))
+        if p.returncode:
+            print("something went wrong when trying to process your regex: {}".format(se.decode()))
+        ret = so.decode()
+        print("\x1b[1m{}\x1b[0m meinte: {}".format(usr,ret.strip()))
+        if ret:
+            d[usr] = ret
+
+    else:
+        print("no last message")
+else:
+    d[usr] = line
+
+d.close()
diff --git a/makefu/2configs/base-gui.nix b/makefu/2configs/base-gui.nix
index 7b7f85f13..1d6750284 100644
--- a/makefu/2configs/base-gui.nix
+++ b/makefu/2configs/base-gui.nix
@@ -10,6 +10,17 @@
 #
 # if this is not enough, check out main-laptop.nix
 
+## TODO: .Xdefaults:
+# URxvt*termName:         rxvt
+# URxvt.scrollBar : false
+# URxvt*scrollBar_right:  false
+# URxvt*borderLess:       false
+# URxvt.foreground: white
+# URxvt.background: black
+# URxvt.urgentOnBell: true
+# URxvt.visualBell: false
+# URxvt.font : xft:Terminus
+
 with lib;
 let
   mainUser = config.krebs.build.user.name;
@@ -62,4 +73,33 @@ in
      enable = true;
    #  systemWide = true;
   };
+  services.xserver.displayManager.sessionCommands = let
+    xdefaultsfile = pkgs.writeText "Xdefaults"  ''
+      cat |derp <<EOF
+      XTerm*background: black
+      XTerm*foreground: white
+      XTerm*FaceName  : Terminus:pixelsize=14
+
+      URxvt*termName:         rxvt
+      URxvt.scrollBar : False
+      URxvt*scrollBar_right:  false
+      URxvt*borderLess:       false
+      URxvt.foreground: white
+      URxvt.background: black
+      URxvt.urgentOnBell: true
+      URxvt.visualBell: false
+      URxvt.font : xft:Terminus
+
+      ! blue
+      URxvt*color4:                         #268bd2
+
+
+      URxvt.perl-ext:      default,url-select
+      URxvt.keysym.M-u:    perl:url-select:select_next
+      #URxvt.url-select.launcher:   firefox -new-tab
+      URxvt.url-select.launcher:   chromium
+      URxvt.url-select.underline: true
+      URxvt.searchable-scrollback: CM-s
+    '';
+    in "cat ${xdefaultsfile} | xrdb -merge";
 }
diff --git a/makefu/2configs/default.nix b/makefu/2configs/default.nix
index 3d9174788..c0d7685e3 100644
--- a/makefu/2configs/default.nix
+++ b/makefu/2configs/default.nix
@@ -65,6 +65,7 @@ with lib;
   time.timeZone = "Europe/Berlin";
   #nix.maxJobs = 1;
 
+  programs.ssh.startAgent = false;
   services.openssh.enable = true;
   nix.useChroot = true;
 
@@ -79,7 +80,14 @@ with lib;
     "d /tmp 1777 root root - -"
   ];
 
-  environment.variables.EDITOR = mkForce "vim";
+  environment.variables = {
+    NIX_PATH = with config.krebs.build.source; with dir; with git;
+      mkForce (concatStringsSep ":" [
+        "nixpkgs=${nixpkgs.target-path}"
+        "${nixpkgs.target-path}"
+      ]);
+    EDITOR = mkForce "vim";
+  };
 
   environment.systemPackages = with pkgs; [
       jq
@@ -96,6 +104,8 @@ with lib;
       HISTSIZE=900001
       HISTFILESIZE=$HISTSIZE
 
+      PYTHONSTARTUP="~/.pythonrc";
+
       shopt -s checkhash
       shopt -s histappend histreedit histverify
       shopt -s no_empty_cmd_completion
@@ -115,6 +125,9 @@ with lib;
 
   environment.shellAliases = {
     lsl = "ls -lAtr";
+    psg = "ps -ef | grep";
+    nmap = "nmap -oN $HOME/loot/scan-`date +\%s`.nmap -oX $HOME/loot/scan-`date +%s`.xml";
+    grep = "grep --color=auto";
   };
 
   nixpkgs.config.packageOverrides = pkgs: {
@@ -123,6 +136,14 @@ with lib;
 
   services.cron.enable = false;
   services.nscd.enable = false;
+  services.ntp.enable = false;
+  services.timesyncd.enable = true;
+  services.ntp.servers = [
+    "pool.ntp.org"
+    "time.windows.com"
+    "time.apple.com"
+    "time.nist.gov"
+  ];
 
   security.setuidPrograms = [ "sendmail" ];
   services.journald.extraConfig = ''
diff --git a/makefu/2configs/fetchWallpaper.nix b/makefu/2configs/fetchWallpaper.nix
new file mode 100644
index 000000000..b071a128d
--- /dev/null
+++ b/makefu/2configs/fetchWallpaper.nix
@@ -0,0 +1,24 @@
+{ config, pkgs, ... }:
+
+let
+  # check if laptop runs on umts
+  weaksauce-internet = with pkgs;writeScript "weaksauce-internet" ''
+    #! /bin/sh
+    if  ${iproute}/bin/ip addr show dev ppp0 2>/dev/null \
+      | ${gnugrep}/bin/grep -q inet;then
+      exit 1
+    fi
+  '';
+
+in {
+  krebs.fetchWallpaper = {
+    enable = true;
+    display = ":0";
+    predicate = weaksauce-internet;
+    timerConfig = {
+      OnCalendar = "*:0/30";
+    };
+    url = "http://echelon/wallpaper.png";
+  };
+}
+
diff --git a/makefu/2configs/fs/simple-swap.nix b/makefu/2configs/fs/simple-swap.nix
new file mode 100644
index 000000000..8c161b287
--- /dev/null
+++ b/makefu/2configs/fs/simple-swap.nix
@@ -0,0 +1,11 @@
+_:
+{
+  # do not swap that often
+  boot.kernel.sysctl = {
+    "vm.swappiness" = 25;
+  };
+
+  swapDevices = [
+    { device = "/dev/disk/by-label/swap"; }
+  ];
+}
diff --git a/makefu/2configs/git/brain-retiolum.nix b/makefu/2configs/git/brain-retiolum.nix
index 793373859..25ef584bf 100644
--- a/makefu/2configs/git/brain-retiolum.nix
+++ b/makefu/2configs/git/brain-retiolum.nix
@@ -1,6 +1,6 @@
 { config, lib, pkgs, ... }:
 # TODO: remove tv lib :)
-with import ../../../tv/4lib { inherit lib pkgs; };
+with lib;
 let
 
   repos = priv-repos // krebs-repos ;
@@ -26,7 +26,7 @@ let
     inherit name desc;
     public = false;
     hooks = {
-      post-receive = git.irc-announce {
+      post-receive = pkgs.git-hooks.irc-announce {
         nick = config.networking.hostName;
         channel = "#retiolum";
         # TODO remove the hardcoded hostname
@@ -59,16 +59,7 @@ let
     set-owners repo all-makefu ++ set-ro-access repo krebsminister;
 
 in {
-  imports = [{
-    krebs.users.makefu-omo = {
-        name = "makefu-omo" ;
-        pubkey= with builtins; readFile ../../../krebs/Zpubkeys/makefu_omo.ssh.pub;
-    };
-    krebs.users.makefu-tsp = {
-        name = "makefu-tsp" ;
-        pubkey= with builtins; readFile ../../../krebs/Zpubkeys/makefu_tsp.ssh.pub;
-    };
-  }];
+  imports = [ ];
   krebs.git = {
     enable = true;
     cgit = false;
diff --git a/makefu/2configs/git/cgit-retiolum.nix b/makefu/2configs/git/cgit-retiolum.nix
index 189dd66c8..35bb169cf 100644
--- a/makefu/2configs/git/cgit-retiolum.nix
+++ b/makefu/2configs/git/cgit-retiolum.nix
@@ -1,10 +1,12 @@
 { config, lib, pkgs, ... }:
 # TODO: remove tv lib :)
-with import ../../../tv/4lib { inherit lib pkgs; };
+with lib;
 let
 
-  repos = priv-repos // krebs-repos ;
-  rules = concatMap krebs-rules (attrValues krebs-repos) ++ concatMap priv-rules (attrValues priv-repos);
+  repos = priv-repos // krebs-repos // connector-repos ;
+  rules = concatMap krebs-rules (attrValues krebs-repos)
+    ++ concatMap priv-rules (attrValues priv-repos)
+    ++ concatMap connector-rules (attrValues connector-repos);
 
   krebs-repos = mapAttrs make-krebs-repo {
     stockholm = {
@@ -13,12 +15,21 @@ let
     tinc_graphs = {
       desc = "Tinc Advanced Graph Generation";
     };
+    cac = { };
   };
 
   priv-repos = mapAttrs make-priv-repo {
     autosync = { };
   };
 
+  connector-repos = mapAttrs make-priv-repo {
+    connector = { };
+    minikrebs = { };
+    mattermost = {
+      desc = "Mattermost Docker files";
+    };
+  };
+
 
   # TODO move users to separate module
   make-priv-repo = name: { desc ? null, ... }: {
@@ -30,9 +41,9 @@ let
     inherit name desc;
     public = true;
     hooks = {
-      post-receive = git.irc-announce {
+      post-receive = pkgs.git-hooks.irc-announce {
         nick = config.networking.hostName;
-        verbose = config.krebs.build.host.name == "pnp";
+        verbose = config.krebs.build.host.name == "gum";
         channel = "#retiolum";
         # TODO remove the hardcoded hostname
         server = "cd.retiolum";
@@ -40,12 +51,19 @@ let
     };
   };
 
-  set-owners = with git;repo: user:
-      singleton {
-        inherit user;
-        repo = [ repo ];
-        perm = push "refs/*" [ non-fast-forward create delete merge ];
-      };
+
+
+  # TODO: get the list of all krebsministers
+  krebsminister = with config.krebs.users; [ lass tv uriel ];
+  all-makefu = with config.krebs.users; [ makefu makefu-omo makefu-tsp makefu-vbob ];
+  all-exco = with config.krebs.users; [ exco ];
+
+  priv-rules = repo: set-owners repo all-makefu;
+
+  connector-rules = repo: set-owners repo all-makefu ++ set-owners repo all-exco;
+
+  krebs-rules = repo:
+    set-owners repo all-makefu ++ set-ro-access repo krebsminister;
 
   set-ro-access = with git; repo: user:
       optional repo.public {
@@ -54,26 +72,14 @@ let
         perm = fetch;
       };
 
-  # TODO: get the list of all krebsministers
-  krebsminister = with config.krebs.users; [ lass tv uriel ];
-  all-makefu = with config.krebs.users; [ makefu makefu-omo makefu-tsp ];
-
-  priv-rules = repo: set-owners repo all-makefu;
-
-  krebs-rules = repo:
-    set-owners repo all-makefu ++ set-ro-access repo krebsminister;
+  set-owners = with git;repo: user:
+      singleton {
+        inherit user;
+        repo = [ repo ];
+        perm = push "refs/*" [ non-fast-forward create delete merge ];
+      };
 
 in {
-  imports = [{
-    krebs.users.makefu-omo = {
-        name = "makefu-omo" ;
-        pubkey= with builtins; readFile ../../../krebs/Zpubkeys/makefu_omo.ssh.pub;
-    };
-    krebs.users.makefu-tsp = {
-        name = "makefu-tsp" ;
-        pubkey= with builtins; readFile ../../../krebs/Zpubkeys/makefu_tsp.ssh.pub;
-    };
-  }];
   krebs.git = {
     enable = true;
     root-title = "public repositories";
diff --git a/makefu/2configs/main-laptop.nix b/makefu/2configs/main-laptop.nix
index 294ee7510..b725f661d 100644
--- a/makefu/2configs/main-laptop.nix
+++ b/makefu/2configs/main-laptop.nix
@@ -6,13 +6,17 @@
 
 with lib;
 {
-  imports = [ ./base-gui.nix ];
+  imports = [
+    ./base-gui.nix
+    ./fetchWallpaper.nix
+    ./zsh-user.nix
+  ];
   environment.systemPackages = with pkgs;[
     vlc
     firefox
     chromium
     keepassx
-
+    ntfs3g
     virtmanager
     at_spi2_core # dep for virtmanager?
   ];
diff --git a/makefu/2configs/mattermost-docker.nix b/makefu/2configs/mattermost-docker.nix
new file mode 100644
index 000000000..20a93dff1
--- /dev/null
+++ b/makefu/2configs/mattermost-docker.nix
@@ -0,0 +1,47 @@
+{config, lib, ...}:
+
+with lib;
+let
+  sec = toString <secrets>;
+  ssl_cert = "${sec}/wildcard.krebsco.de.crt";
+  ssl_key  = "${sec}/wildcard.krebsco.de.key";
+in {
+  # mattermost docker config and deployment guide: git.euer.krebsco.de
+  virtualisation.docker.enable = true;
+  users.extraUsers.${config.krebs.build.user.name}.extraGroups = [ "docker" ];
+  krebs.nginx = {
+    enable = true;
+    servers.mattermost = {
+      listen = [ "80" "443 ssl" ];
+      server-names = [ "mattermost.euer.krebsco.de" ];
+      extraConfig = ''
+        gzip on;
+        gzip_buffers 4 32k;
+        gzip_types  text/plain application/x-javascript text/css;
+        ssl_certificate ${ssl_cert};
+        ssl_certificate_key ${ssl_key};
+        default_type text/plain;
+
+        if ($scheme = http){
+          return 301 https://$server_name$request_uri;
+        }
+
+        client_max_body_size 4G;
+        keepalive_timeout 10;
+
+      '';
+      locations = [
+        (nameValuePair "/" ''
+          proxy_http_version 1.1;
+          proxy_set_header Upgrade $http_upgrade;
+          proxy_set_header Connection "upgrade";
+          proxy_set_header   Host $host;
+          proxy_set_header   X-Real-IP          $remote_addr;
+          proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
+          proxy_redirect      off;
+          proxy_pass http://localhost:8065/;
+        '')
+      ];
+    };
+  };
+}
diff --git a/makefu/2configs/nginx/euer.test.nix b/makefu/2configs/nginx/euer.test.nix
new file mode 100644
index 000000000..ffdc0bc60
--- /dev/null
+++ b/makefu/2configs/nginx/euer.test.nix
@@ -0,0 +1,26 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  hostname = config.krebs.build.host.name;
+  user = config.services.nginx.user;
+  group = config.services.nginx.group;
+  external-ip = head config.krebs.build.host.nets.internet.addrs4;
+  internal-ip = head config.krebs.build.host.nets.retiolum.addrs4;
+in {
+  krebs.nginx = {
+    enable = mkDefault true;
+    servers = {
+      euer-share = {
+        listen = [ ];
+        server-names = [ "share.euer.krebsco.de" ];
+        locations = singleton (nameValuePair "/" ''
+          proxy_set_header   Host $host;
+          proxy_set_header   X-Real-IP          $remote_addr;
+          proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
+          proxy_pass http://localhost:8000/;
+        '');
+      };
+    };
+  };
+}
diff --git a/makefu/2configs/printer.nix b/makefu/2configs/printer.nix
new file mode 100644
index 000000000..35ad54bd9
--- /dev/null
+++ b/makefu/2configs/printer.nix
@@ -0,0 +1,10 @@
+{ pkgs, ... }:
+
+{
+  services.printing = {
+    enable = true;
+    drivers = [
+      pkgs.samsungUnifiedLinuxDriver
+    ];
+  };
+}
diff --git a/makefu/2configs/tinc-basic-retiolum.nix b/makefu/2configs/tinc-basic-retiolum.nix
index fd6d1683d..2abf4f188 100644
--- a/makefu/2configs/tinc-basic-retiolum.nix
+++ b/makefu/2configs/tinc-basic-retiolum.nix
@@ -9,6 +9,7 @@ with lib;
       "gum"
       "pigstarter"
       "fastpoke"
+      "ire"
     ];
   };
 }
diff --git a/makefu/2configs/virtualization-virtualbox.nix b/makefu/2configs/virtualization-virtualbox.nix
index 610b63732..aaabcd50e 100644
--- a/makefu/2configs/virtualization-virtualbox.nix
+++ b/makefu/2configs/virtualization-virtualbox.nix
@@ -2,11 +2,11 @@
 
 let
   mainUser = config.krebs.build.user;
-  version = "5.0.4";
-  rev = "102546";
+  version = "5.0.6";
+  rev = "103037";
   vboxguestpkg = pkgs.fetchurl {
         url = "http://download.virtualbox.org/virtualbox/${version}/Oracle_VM_VirtualBox_Extension_Pack-${version}-${rev}.vbox-extpack";
-        sha256 = "1ykwpjvfgj11iwhx70bh2hbxhyy3hg6rnqzl4qac7xzg8xw8wqg4";
+        sha256 = "1dc70x2m7x266zzw5vw36mxqj7xykkbk357fc77f9zrv4lylzvaf";
       };
 in {
   #inherit vboxguestpkg;
diff --git a/makefu/2configs/wwan.nix b/makefu/2configs/wwan.nix
index dd1c63090..29a610ac6 100644
--- a/makefu/2configs/wwan.nix
+++ b/makefu/2configs/wwan.nix
@@ -9,6 +9,10 @@ in {
     wvdial
   ];
 
+  environment.shellAliases = {
+    umts = "sudo wvdial netzclub";
+  };
+
   # configure for NETZCLUB
   environment.wvdial.dialerDefaults = ''
     Phone = *99***1#
diff --git a/makefu/2configs/zsh-user.nix b/makefu/2configs/zsh-user.nix
index 3089b706a..1b1762418 100644
--- a/makefu/2configs/zsh-user.nix
+++ b/makefu/2configs/zsh-user.nix
@@ -5,6 +5,46 @@ let
   mainUser = config.krebs.build.user.name;
 in
 {
-  programs.zsh.enable = true;
   users.extraUsers.${mainUser}.shell = "/run/current-system/sw/bin/zsh";
+  programs.zsh= {
+    enable = true;
+    interactiveShellInit = ''
+      HISTSIZE=900001
+      HISTFILESIZE=$HISTSIZE
+      SAVEHIST=$HISTSIZE
+
+      setopt HIST_IGNORE_ALL_DUPS
+      setopt HIST_IGNORE_SPACE
+      setopt HIST_FIND_NO_DUPS
+      bindkey -e
+      # shift-tab
+      bindkey '^[[Z' reverse-menu-complete
+
+      autoload -U compinit && compinit
+      zstyle ':completion:*' menu select
+
+      # load gpg-agent
+      envfile="$HOME/.gnupg/gpg-agent.env"
+      if [ -e "$envfile" ] && kill -0 $(grep GPG_AGENT_INFO "$envfile" | cut -d: -f 2) 2>/dev/null; then
+        eval "$(cat "$envfile")"
+      else
+        eval "$(${pkgs.gnupg}/bin/gpg-agent --daemon --enable-ssh-support --write-env-file "$envfile")"
+      fi
+      export GPG_AGENT_INFO
+      export SSH_AUTH_SOCK
+      '';
+
+    promptInit = ''
+      RPROMPT=""
+      autoload colors && colors
+      case $UID in
+         0) PROMPT="%{$fg[red]%}%~%{$reset_color%} " ;;
+      9001) PROMPT="%{$fg[green]%}%~%{$reset_color%} " ;;
+         *) PROMPT="%{$fg[yellow]%}%n %{$fg[green]%}%~%{$reset_color%} " ;;
+      esac
+      if test -n "$SSH_CLIENT"; then
+        PROMPT="%{$fg[magenta]%}%m $PROMPT"
+      fi
+      '';
+  };
 }
diff --git a/makefu/3modules/buildbot/master.nix b/makefu/3modules/buildbot/master.nix
new file mode 100644
index 000000000..58e2f8175
--- /dev/null
+++ b/makefu/3modules/buildbot/master.nix
@@ -0,0 +1,263 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+let
+  buildbot = pkgs.buildbot;
+  buildbot-master-config = pkgs.writeText "buildbot-master.cfg" ''
+    # -*- python -*-
+    from buildbot.plugins import *
+    import re
+
+    c = BuildmasterConfig = {}
+
+    c['slaves'] = []
+    # TODO: template potential buildslaves
+    # TODO: set password?
+    slavenames= [ 'testslave' ]
+    for i in slavenames:
+      c['slaves'].append(buildslave.BuildSlave(i, "krebspass"))
+
+    c['protocols'] = {'pb': {'port': 9989}}
+
+    ####### Build Inputs
+    stockholm_repo = 'http://cgit.gum/stockholm'
+    c['change_source'] = []
+    c['change_source'].append(changes.GitPoller(
+            stockholm_repo,
+            workdir='stockholm-poller', branch='master',
+            project='stockholm',
+            pollinterval=120))
+
+    ####### Build Scheduler
+    # TODO: configure scheduler
+    c['schedulers'] = []
+
+    # test the master real quick
+    fast = schedulers.SingleBranchScheduler(
+                                change_filter=util.ChangeFilter(branch="master"),
+                                name="fast-master-test",
+                                builderNames=["fast-tests"])
+
+    force = schedulers.ForceScheduler(
+                                name="force",
+                                builderNames=["full-tests"])
+
+    # files everyone depends on or are part of the share branch
+    def shared_files(change):
+      r =re.compile("^((krebs|share)/.*|Makefile|default.nix)")
+      for file in change.files:
+        if r.match(file):
+          return True
+      return False
+
+    full = schedulers.SingleBranchScheduler(
+                                change_filter=util.ChangeFilter(branch="master"),
+                                fileIsImportant=shared_files,
+                                name="full-master-test",
+                                builderNames=["full-tests"])
+    c['schedulers'] = [ fast, force, full ]
+    ###### The actual build
+    # couple of fast steps:
+    f = util.BuildFactory()
+    ## fetch repo
+    grab_repo = steps.Git(repourl=stockholm_repo, mode='incremental')
+    f.addStep(grab_repo)
+
+    # the dependencies which are used by the test script
+    deps = [ "gnumake", "jq" ]
+    nixshell = ["nix-shell", "-p" ] + deps + [ "--run" ]
+    def addShell(f,**kwargs):
+      f.addStep(steps.ShellCommand(**kwargs))
+
+    addShell(f,name="centos7-eval",env={"LOGNAME": "shared",
+                  "get" : "krebs.deploy",
+                  "filter" : "json"
+                 },
+             command=nixshell + ["make -s eval system=test-centos7"])
+
+    addShell(f,name="wolf-eval",env={"LOGNAME": "shared",
+                  "get" : "krebs.deploy",
+                  "filter" : "json"
+                 },
+             command=nixshell + ["make -s eval system=wolf"])
+
+    c['builders'] = []
+    c['builders'].append(
+        util.BuilderConfig(name="fast-tests",
+          slavenames=slavenames,
+          factory=f))
+
+    # TODO slow build
+    c['builders'].append(
+        util.BuilderConfig(name="full-tests",
+          slavenames=slavenames,
+          factory=f))
+
+    ####### Status of Builds
+    c['status'] = []
+
+    from buildbot.status import html
+    from buildbot.status.web import authz, auth
+    # TODO: configure if http is wanted
+    authz_cfg=authz.Authz(
+        # TODO: configure user/pw
+        auth=auth.BasicAuth([("krebs","bob")]),
+        gracefulShutdown = False,
+        forceBuild = 'auth',
+        forceAllBuilds = 'auth',
+        pingBuilder = False,
+        stopBuild = False,
+        stopAllBuilds = False,
+        cancelPendingBuild = False,
+    )
+    # TODO: configure nginx
+    c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
+
+    from buildbot.status import words
+    ${optionalString (cfg.irc.enable) ''
+      irc = words.IRC("${cfg.irc.server}", "krebsbuild",
+                      # TODO: multiple channels
+                      channels=["${cfg.irc.channel}"],
+                      notify_events={
+                        #'success': 1,
+                        #'failure': 1,
+                        'exception': 1,
+                        'successToFailure': 1,
+                        'failureToSuccess': 1,
+                      }${optionalString cfg.irc.allowForce ",allowForce=True"})
+      c['status'].append(irc)
+      ''}
+
+    ####### PROJECT IDENTITY
+    c['title'] = "Stockholm"
+    c['titleURL'] = "http://krebsco.de"
+
+    #c['buildbotURL'] = "http://buildbot.krebsco.de/"
+    # TODO: configure url
+    c['buildbotURL'] = "http://vbob:8010/"
+
+    ####### DB URL
+    c['db'] = {
+        'db_url' : "sqlite:///state.sqlite",
+    }
+    ${cfg.extraConfig}
+    '';
+
+  cfg = config.makefu.buildbot.master;
+
+  api = {
+    enable = mkEnableOption "Buildbot Master";
+    workDir = mkOption {
+      default = "/var/lib/buildbot/master";
+      type = types.str;
+      description = ''
+        Path to build bot master directory.
+        Will be created on startup.
+      '';
+    };
+    irc = mkOption {
+      default = {};
+      type = types.submodule ({ config, ... }: {
+        options = {
+          enable = mkEnableOption "Buildbot Master IRC Status";
+          channel = mkOption {
+            default = "nix-buildbot-meetup";
+            type = types.str;
+            description = ''
+              irc channel the bot should connect to
+            '';
+          };
+          allowForce = mkOption {
+            default = false;
+            type = types.bool;
+            description = ''
+              Determines if builds can be forced via IRC
+            '';
+          };
+          nick = mkOption {
+            default = "nix-buildbot";
+            type = types.str;
+            description = ''
+              nickname for IRC
+            '';
+          };
+          server = mkOption {
+            default = "irc.freenode.net";
+            type = types.str;
+            description = ''
+              Buildbot Status IRC Server to connect to
+            '';
+          };
+        };
+      });
+    };
+
+    extraConfig = mkOption {
+      default = "";
+      type = types.lines;
+      description = ''
+        extra config appended to the generated master.cfg
+      '';
+    };
+  };
+
+  imp = {
+
+    users.extraUsers.buildbotMaster = {
+      uid = 672626386; #genid buildbotMaster
+      description = "Buildbot Master";
+      home = cfg.workDir;
+      createHome = false;
+    };
+
+    users.extraGroups.buildbotMaster = {
+      gid = 672626386;
+    };
+
+    systemd.services.buildbotMaster = {
+      description = "Buildbot Master";
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      path = [ pkgs.git ];
+      serviceConfig = let
+        workdir="${lib.shell.escape cfg.workDir}";
+        # TODO: check if git is the only dep
+      in {
+        PermissionsStartOnly = true;
+        Type = "forking";
+        PIDFile = "${workdir}/twistd.pid";
+        # TODO: maybe also prepare buildbot.tac?
+        ExecStartPre = pkgs.writeScript "buildbot-master-init" ''
+          #!/bin/sh
+          set -efux
+          if [ ! -e ${workdir} ];then
+            mkdir -p ${workdir}
+            ${buildbot}/bin/buildbot create-master -r -l 10 -f ${workdir}
+          fi
+          # always override the master.cfg
+          cp ${buildbot-master-config} ${workdir}/master.cfg
+          # sanity
+          ${buildbot}/bin/buildbot checkconfig ${workdir}
+
+          # TODO: maybe upgrade? not sure about this
+          #       normally we should write buildbot.tac by our own
+          # ${buildbot}/bin/buildbot upgrade-master ${workdir}
+
+          chmod 700 -R ${workdir}
+          chown buildbotMaster:buildbotMaster -R ${workdir}
+        '';
+        ExecStart = "${buildbot}/bin/buildbot start ${workdir}";
+        ExecStop = "${buildbot}/bin/buildbot stop ${workdir}";
+        ExecReload = "${buildbot}/bin/buildbot reconfig ${workdir}";
+        PrivateTmp = "true";
+        User = "buildbotMaster";
+        Restart = "always";
+        RestartSec = "10";
+      };
+    };
+  };
+in
+{
+  options.makefu.buildbot.master = api;
+  config = mkIf cfg.enable imp;
+}
diff --git a/makefu/3modules/buildbot/slave.nix b/makefu/3modules/buildbot/slave.nix
new file mode 100644
index 000000000..69d0361bf
--- /dev/null
+++ b/makefu/3modules/buildbot/slave.nix
@@ -0,0 +1,185 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+let
+  buildbot-slave-init = pkgs.writeText "buildbot-slave.tac" ''
+    import os
+
+    from buildslave.bot import BuildSlave
+    from twisted.application import service
+
+    basedir = '${cfg.workDir}'
+    rotateLength = 10000000
+    maxRotatedFiles = 10
+
+    application = service.Application('buildslave')
+
+    from twisted.python.logfile import LogFile
+    from twisted.python.log import ILogObserver, FileLogObserver
+    logfile = LogFile.fromFullPath(os.path.join(basedir, "twistd.log"), rotateLength=rotateLength,
+                                  maxRotatedFiles=maxRotatedFiles)
+    application.setComponent(ILogObserver, FileLogObserver(logfile).emit)
+
+    buildmaster_host = '${cfg.masterhost}'
+    # TODO: masterport?
+    port = 9989
+    slavename = '${cfg.username}'
+    passwd = '${cfg.password}'
+    keepalive = 600
+    usepty = 0
+    umask = None
+    maxdelay = 300
+    allow_shutdown = None
+
+    ${cfg.extraConfig}
+
+    s = BuildSlave(buildmaster_host, port, slavename, passwd, basedir,
+                  keepalive, usepty, umask=umask, maxdelay=maxdelay,
+                  allow_shutdown=allow_shutdown)
+    s.setServiceParent(application)
+    '';
+  default-packages = [ pkgs.git pkgs.bash ];
+  cfg = config.makefu.buildbot.slave;
+
+  api = {
+    enable = mkEnableOption "Buildbot Slave";
+
+    workDir = mkOption {
+      default = "/var/lib/buildbot/slave";
+      type = types.str;
+      description = ''
+        Path to build bot slave directory.
+        Will be created on startup.
+      '';
+    };
+
+    masterhost = mkOption {
+      default = "localhost";
+      type = types.str;
+      description = ''
+        Hostname/IP of the buildbot master
+      '';
+    };
+
+    username = mkOption {
+      type = types.str;
+      description = ''
+        slavename used to authenticate with master
+      '';
+    };
+
+    password = mkOption {
+      type = types.str;
+      description = ''
+        slave password used to authenticate with master
+      '';
+    };
+
+    contact = mkOption {
+      default = "nix slave <buildslave@${config.networking.hostName}>";
+      type = types.str;
+      description = ''
+        contact to be announced by buildslave
+      '';
+    };
+
+    description = mkOption {
+      default = "Nix Generated BuildSlave";
+      type = types.str;
+      description = ''
+        description for hostto be announced by buildslave
+      '';
+    };
+
+    packages = mkOption {
+      default = [ pkgs.git ];
+      type = with types; listOf package;
+      description = ''
+        packages which should be in path for buildslave
+      '';
+    };
+
+    extraEnviron = mkOption {
+      default = {};
+      example = {
+        NIX_PATH = "nixpkgs=/path/to/my/nixpkgs";
+      };
+      type = types.attrsOf types.str;
+      description = ''
+        extra environment variables to be provided to the buildslave service
+        if you need nixpkgs, e.g. for running nix-shell you can set NIX_PATH here.
+      '';
+    };
+
+    extraConfig = mkOption {
+      default = "";
+      type = types.lines;
+      example = ''
+        port = 443
+        keepalive = 600
+      '';
+      description = ''
+        extra config evaluated before calling BuildSlave init in .tac file
+      '';
+    };
+  };
+
+  imp = {
+
+    users.extraUsers.buildbotSlave = {
+      uid = 1408105834; #genid buildbotMaster
+      description = "Buildbot Slave";
+      home = cfg.workDir;
+      createHome = false;
+    };
+
+    users.extraGroups.buildbotSlave = {
+      gid = 1408105834;
+    };
+
+    systemd.services."buildbotSlave-${cfg.username}-${cfg.masterhost}" = {
+      description = "Buildbot Slave for ${cfg.username}@${cfg.masterhost}";
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      path = default-packages ++ cfg.packages;
+
+      environment = {
+          NIX_REMOTE="daemon";
+      } // cfg.extraEnviron;
+
+      serviceConfig = let
+        workdir = "${lib.shell.escape cfg.workDir}";
+        contact = "${lib.shell.escape cfg.contact}";
+        description = "${lib.shell.escape cfg.description}";
+        buildbot = pkgs.buildbot-slave;
+        # TODO:make this
+      in {
+        PermissionsStartOnly = true;
+        Type = "forking";
+        PIDFile = "${workdir}/twistd.pid";
+        # TODO: maybe also prepare buildbot.tac?
+        ExecStartPre = pkgs.writeScript "buildbot-master-init" ''
+          #!/bin/sh
+          set -efux
+          mkdir -p ${workdir}/info
+          cp ${buildbot-slave-init} ${workdir}/buildbot.tac
+          echo ${contact} > ${workdir}/info/admin
+          echo ${description} > ${workdir}/info/host
+
+          chown buildbotSlave:buildbotSlave -R ${workdir}
+          chmod 700 -R ${workdir}
+        '';
+        ExecStart = "${buildbot}/bin/buildslave start ${workdir}";
+        ExecStop = "${buildbot}/bin/buildslave stop ${workdir}";
+        PrivateTmp = "true";
+        User = "buildbotSlave";
+        Restart = "always";
+        RestartSec = "10";
+      };
+    };
+  };
+in
+{
+  options.makefu.buildbot.slave = api;
+  config = mkIf cfg.enable imp;
+}
diff --git a/makefu/3modules/default.nix b/makefu/3modules/default.nix
index a8a1f69d0..ffbf54cc0 100644
--- a/makefu/3modules/default.nix
+++ b/makefu/3modules/default.nix
@@ -2,6 +2,8 @@ _:
 
 {
   imports = [
+    ./buildbot/master.nix
+    ./buildbot/slave.nix
   ];
 }
 
diff --git a/makefu/5pkgs/awesomecfg/full.cfg b/makefu/5pkgs/awesomecfg/full.cfg
index b3f94e655..15711a5d5 100644
--- a/makefu/5pkgs/awesomecfg/full.cfg
+++ b/makefu/5pkgs/awesomecfg/full.cfg
@@ -12,6 +12,8 @@ local beautiful = require("beautiful")
 local naughty = require("naughty")
 local menubar = require("menubar")
 
+
+
 -- {{{ Error handling
 -- Check if awesome encountered an error during startup and fell back to
 -- another config (This code will only ever execute for the fallback config)
@@ -90,6 +92,20 @@ vicious.register(batwidget, vicious.widgets.bat, "$2%", 61, "BAT0")
 --
 -- beautiful.init("/nix/store/qbx8r72yzaxpz41zq00902zwajl31b5h-awesome-3.5.6/share/awesome/themes/default/theme.lua")
 
+function find_default_theme()
+  -- find the default lua theme in the package path
+  for path in package.path:gmatch('([^;]+);') do
+    if path:match('awesome.*share') then
+      theme_path = path:match('^([^?]*)') .. '../themes/default/theme.lua'
+      if awful.util.file_readable(theme_path) then return theme_path end
+    end
+  end
+end
+
+beautiful.init(find_default_theme())
+client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
+client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
+
 -- This is used later as the default terminal and editor to run.
 terminal = "urxvt"
 editor = os.getenv("EDITOR") or "vim"
@@ -494,21 +510,9 @@ local os = {
     date = os.date,
     time = os.time
 }
+
 -- }}}
 
 
 
-function find_default_theme()
-  -- find the default lua theme in the package path
-  for path in package.path:gmatch('([^;]+);') do
-    if path:match('awesome.*share') then
-      theme_path = path:match('^([^?]*)') .. '../themes/default/theme.lua'
-      if awful.util.file_readable(theme_path) then return theme_path end
-    end
-  end
-end
-
-beautiful.init(find_default_theme())
-client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
-client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
 -- }}}
diff --git a/lass/1systems/test-arch.nix b/shared/1systems/test-arch.nix
similarity index 79%
rename from lass/1systems/test-arch.nix
rename to shared/1systems/test-arch.nix
index 0ab9da2f3..ece209490 100644
--- a/lass/1systems/test-arch.nix
+++ b/shared/1systems/test-arch.nix
@@ -1,10 +1,6 @@
-{ config, lib, pkgs, ... }:
+{ config, pkgs, ... }:
 
-let
-  inherit (import ../4lib { inherit pkgs lib; }) getDefaultGateway;
-  inherit (lib) head;
-
-in {
+{
   imports = [
     ../2configs/base.nix
     {
diff --git a/lass/1systems/test-centos6.nix b/shared/1systems/test-centos6.nix
similarity index 79%
rename from lass/1systems/test-centos6.nix
rename to shared/1systems/test-centos6.nix
index 7270c2262..a8b5f9b9c 100644
--- a/lass/1systems/test-centos6.nix
+++ b/shared/1systems/test-centos6.nix
@@ -1,10 +1,10 @@
 { config, lib, pkgs, ... }:
 
 let
-  inherit (import ../4lib { inherit pkgs lib; }) getDefaultGateway;
   inherit (lib) head;
 
   ip = "168.235.148.52";
+  gw = "168.235.148.1";
 in {
   imports = [
     ../2configs/base.nix
@@ -16,7 +16,7 @@ in {
           prefixLength = 24;
         }
       ];
-      networking.defaultGateway = getDefaultGateway ip;
+      networking.defaultGateway = gw;
       networking.nameservers = [
         "8.8.8.8"
       ];
diff --git a/shared/1systems/test-centos7.nix b/shared/1systems/test-centos7.nix
new file mode 100644
index 000000000..077a5d61b
--- /dev/null
+++ b/shared/1systems/test-centos7.nix
@@ -0,0 +1,15 @@
+{ config, lib, pkgs, ... }:
+
+let
+  inherit (lib) head;
+
+in {
+  imports = [
+    ../2configs/base.nix
+    ../2configs/os-templates/CAC-CentOS-7-64bit.nix
+    ../2configs/os-templates/temp-networking.nix
+  ];
+
+  sound.enable = false;
+  krebs.build.host = config.krebs.hosts.test-centos7;
+}
diff --git a/shared/1systems/wolf.nix b/shared/1systems/wolf.nix
index 60d1e8ce8..2c51ac8fe 100644
--- a/shared/1systems/wolf.nix
+++ b/shared/1systems/wolf.nix
@@ -1,46 +1,42 @@
 { config, lib, pkgs, ... }:
 
-with lib;
-
+let
+  shack-ip = lib.head config.krebs.build.host.nets.shack.addrs4;
+  internal-ip = lib.head config.krebs.build.host.nets.retiolum.addrs4;
+in
 {
   imports = [
+    ../2configs/base.nix
     <nixpkgs/nixos/modules/profiles/qemu-guest.nix>
     ../2configs/collectd-base.nix
+    ../2configs/shack-nix-cacher.nix
+    ../2configs/shack-drivedroid.nix
+    ../2configs/cac-ci.nix
+    ../2configs/graphite.nix
   ];
+  # use your own binary cache, fallback use cache.nixos.org (which is used by
+  # apt-cacher-ng in first place)
+  nix.binaryCaches = [ "http://localhost:3142/nixos" "https://cache.nixos.org" ];
 
+  networking = {
+    firewall.enable = false;
+    interfaces.eth0.ip4 = [{
+      address = shack-ip;
+      prefixLength = 20;
+    }];
+
+    defaultGateway = "10.42.0.1";
+    nameservers = [ "10.42.0.100" "10.42.0.200" ];
+  };
+
+  #####################
+  # uninteresting stuff
+  #####################
   krebs.build.host = config.krebs.hosts.wolf;
   # TODO rename shared user to "krebs"
   krebs.build.user = config.krebs.users.shared;
   krebs.build.target = "wolf";
 
-  krebs.enable = true;
-  krebs.retiolum = {
-    enable = true;
-    connectTo = [
-      # TODO remove connectTo cd, this was only used for bootstrapping
-      "cd"
-      "gum"
-      "pigstarter"
-    ];
-  };
-
-  krebs.build.source = {
-    git.nixpkgs = {
-      url = https://github.com/NixOS/nixpkgs;
-      rev = "6d31e9b81dcd4ab927bb3dc91b612dd5abfa2f80";
-    };
-    dir.secrets = {
-      host = config.krebs.current.host;
-      path = "${getEnv "HOME"}/secrets/krebs/wolf";
-    };
-    dir.stockholm = {
-      host = config.krebs.current.host;
-      path = "${getEnv "HOME"}/stockholm";
-    };
-  };
-
-  networking.hostName = config.krebs.build.host.name;
-
   boot.kernel.sysctl = {
     # Enable IPv6 Privacy Extensions
     "net.ipv6.conf.all.use_tempaddr" = 2;
@@ -60,48 +56,8 @@ with lib;
   fileSystems."/" = { device = "/dev/disk/by-label/nixos"; fsType = "ext4"; };
 
   swapDevices = [
-    { device = "/dev/disk/by-label/swap"; }
-  ];
-
-  nix.maxJobs = 1;
-  nix.trustedBinaryCaches = [
-    "https://cache.nixos.org"
-    "http://cache.nixos.org"
-    "http://hydra.nixos.org"
-  ];
-  nix.useChroot = true;
-
-  nixpkgs.config.packageOverrides = pkgs: {
-    nano = pkgs.vim;
-  };
-
-  environment.systemPackages = with pkgs; [
-    git
-    rxvt_unicode.terminfo
+    { device = "/dev/disk/by-label/swap";  }
   ];
 
   time.timeZone = "Europe/Berlin";
-
-  programs.ssh.startAgent = false;
-
-  services.openssh = {
-    enable = true;
-    hostKeys = [
-      { type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; }
-    ];
-  };
-  services.cron.enable = false;
-  services.nscd.enable = false;
-  services.ntp.enable = false;
-
-  users.mutableUsers = false;
-  users.extraUsers.root.openssh.authorizedKeys.keys = [
-    # TODO
-    config.krebs.users.lass.pubkey
-    config.krebs.users.makefu.pubkey
-    config.krebs.users.tv.pubkey
-  ];
-
-  # The NixOS release to be compatible with for stateful data such as databases.
-  system.stateVersion = "15.09";
 }
diff --git a/shared/2configs/base.nix b/shared/2configs/base.nix
new file mode 100644
index 000000000..df41eae1a
--- /dev/null
+++ b/shared/2configs/base.nix
@@ -0,0 +1,76 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+{
+  krebs.enable = true;
+  krebs.retiolum = {
+    enable = true;
+    connectTo = [
+      # TODO remove connectTo cd, this was only used for bootstrapping
+      "cd"
+      "gum"
+      "pigstarter"
+    ];
+  };
+
+  krebs.build.source = {
+    git.nixpkgs = {
+      url = https://github.com/NixOS/nixpkgs;
+      rev = "6d31e9b81dcd4ab927bb3dc91b612dd5abfa2f80";
+    };
+    dir.secrets = {
+      host = config.krebs.current.host;
+      path = "${getEnv "HOME"}/secrets/krebs/wolf";
+    };
+    dir.stockholm = {
+      host = config.krebs.current.host;
+      path = "${getEnv "HOME"}/stockholm";
+    };
+  };
+
+  networking.hostName = config.krebs.build.host.name;
+
+  nix.maxJobs = 1;
+  nix.trustedBinaryCaches = [
+    "https://cache.nixos.org"
+    "http://cache.nixos.org"
+    "http://hydra.nixos.org"
+  ];
+  nix.useChroot = true;
+
+  nixpkgs.config.packageOverrides = pkgs: {
+    nano = pkgs.vim;
+  };
+
+  environment.systemPackages = with pkgs; [
+    git
+    rxvt_unicode.terminfo
+  ];
+
+  programs.ssh.startAgent = false;
+
+  services.openssh = {
+    enable = true;
+    hostKeys = [
+      { type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; }
+    ];
+  };
+  services.cron.enable = false;
+  services.nscd.enable = false;
+  services.ntp.enable = false;
+
+  users.mutableUsers = false;
+  users.extraUsers.root.openssh.authorizedKeys.keys = [
+    # TODO
+    config.krebs.users.lass.pubkey
+    config.krebs.users.makefu.pubkey
+    # TODO HARDER:
+    (readFile ../../krebs/Zpubkeys/makefu_omo.ssh.pub)
+    config.krebs.users.tv.pubkey
+  ];
+
+
+  # The NixOS release to be compatible with for stateful data such as databases.
+  system.stateVersion = "15.09";
+
+}
diff --git a/shared/2configs/cac-ci.nix b/shared/2configs/cac-ci.nix
new file mode 100644
index 000000000..06cce2746
--- /dev/null
+++ b/shared/2configs/cac-ci.nix
@@ -0,0 +1,11 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+{
+  environment.systemPackages = with pkgs;[
+    get
+    cac
+    cacpanel
+    jq
+  ];
+}
diff --git a/shared/2configs/graphite.nix b/shared/2configs/graphite.nix
new file mode 100644
index 000000000..707ec6e9a
--- /dev/null
+++ b/shared/2configs/graphite.nix
@@ -0,0 +1,37 @@
+{ config, lib, pkgs, ... }:
+
+# graphite-web on port 8080
+# carbon cache on port 2003 (tcp/udp)
+
+# TODO: krebs.graphite.minimal.enable
+# TODO: configure firewall
+with lib;
+{
+  imports = [ ];
+
+  services.graphite = {
+    web = {
+      enable = true;
+      host = "0.0.0.0";
+    };
+    carbon = {
+      enableCache = true;
+      # save disk usage by restricting to 1 bulk update per second
+      config = ''
+        [cache]
+        MAX_CACHE_SIZE = inf
+        MAX_UPDATES_PER_SECOND = 1
+        MAX_CREATES_PER_MINUTE = 50
+        '';
+      storageSchemas = ''
+        [carbon]
+        pattern = ^carbon\.
+        retentions = 60:90d
+
+        [default]
+        pattern = .*
+        retentions = 60s:30d,300s:1y
+        '';
+    };
+  };
+}
diff --git a/shared/2configs/os-templates/CAC-CentOS-6.5-64bit.nix b/shared/2configs/os-templates/CAC-CentOS-6.5-64bit.nix
new file mode 100644
index 000000000..b5ec722a0
--- /dev/null
+++ b/shared/2configs/os-templates/CAC-CentOS-6.5-64bit.nix
@@ -0,0 +1,47 @@
+_:
+
+{
+  boot.loader.grub = {
+    device = "/dev/sda";
+    splashImage = null;
+  };
+
+  boot.initrd.availableKernelModules = [
+    "ata_piix"
+    "vmw_pvscsi"
+  ];
+
+  fileSystems."/" = {
+    device = "/dev/VolGroup/lv_root";
+    fsType = "ext4";
+  };
+
+  fileSystems."/boot" = {
+    device = "/dev/sda1";
+    fsType = "ext4";
+  };
+
+  swapDevices = [
+    { device = "/dev/VolGroup/lv_swap"; }
+  ];
+
+  users.extraGroups = {
+    # ● systemd-tmpfiles-setup.service - Create Volatile Files and Directories
+    #    Loaded: loaded (/nix/store/2l33gg7nmncqkpysq9f5fxyhlw6ncm2j-systemd-217/example/systemd/system/systemd-tmpfiles-setup.service)
+    #    Active: failed (Result: exit-code) since Mon 2015-03-16 10:29:18 UTC; 4s ago
+    #      Docs: man:tmpfiles.d(5)
+    #            man:systemd-tmpfiles(8)
+    #   Process: 19272 ExecStart=/nix/store/2l33gg7nmncqkpysq9f5fxyhlw6ncm2j-systemd-217/bin/systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev (code=exited, status=1/FAILURE)
+    #  Main PID: 19272 (code=exited, status=1/FAILURE)
+    #
+    # Mar 16 10:29:17 cd systemd-tmpfiles[19272]: [/usr/lib/tmpfiles.d/legacy.conf:26] Unknown group 'lock'.
+    # Mar 16 10:29:18 cd systemd-tmpfiles[19272]: Two or more conflicting lines for /var/log/journal configured, ignoring.
+    # Mar 16 10:29:18 cd systemd-tmpfiles[19272]: Two or more conflicting lines for /var/log/journal/7b35116927d74ea58785e00b47ac0f0d configured, ignoring.
+    # Mar 16 10:29:18 cd systemd[1]: systemd-tmpfiles-setup.service: main process exited, code=exited, status=1/FAILURE
+    # Mar 16 10:29:18 cd systemd[1]: Failed to start Create Volatile Files and Directories.
+    # Mar 16 10:29:18 cd systemd[1]: Unit systemd-tmpfiles-setup.service entered failed state.
+    # Mar 16 10:29:18 cd systemd[1]: systemd-tmpfiles-setup.service failed.
+    # warning: error(s) occured while switching to the new configuration
+    lock.gid = 10001;
+  };
+}
diff --git a/shared/2configs/os-templates/CAC-CentOS-7-64bit.nix b/shared/2configs/os-templates/CAC-CentOS-7-64bit.nix
new file mode 100644
index 000000000..168d1d97b
--- /dev/null
+++ b/shared/2configs/os-templates/CAC-CentOS-7-64bit.nix
@@ -0,0 +1,47 @@
+_:
+
+{
+  boot.loader.grub = {
+    device = "/dev/sda";
+    splashImage = null;
+  };
+
+  boot.initrd.availableKernelModules = [
+    "ata_piix"
+    "vmw_pvscsi"
+  ];
+
+  fileSystems."/" = {
+    device = "/dev/centos/root";
+    fsType = "xfs";
+  };
+
+  fileSystems."/boot" = {
+    device = "/dev/sda1";
+    fsType = "xfs";
+  };
+
+  swapDevices = [
+    { device = "/dev/centos/swap"; }
+  ];
+
+  users.extraGroups = {
+    # ● systemd-tmpfiles-setup.service - Create Volatile Files and Directories
+    #    Loaded: loaded (/nix/store/2l33gg7nmncqkpysq9f5fxyhlw6ncm2j-systemd-217/example/systemd/system/systemd-tmpfiles-setup.service)
+    #    Active: failed (Result: exit-code) since Mon 2015-03-16 10:29:18 UTC; 4s ago
+    #      Docs: man:tmpfiles.d(5)
+    #            man:systemd-tmpfiles(8)
+    #   Process: 19272 ExecStart=/nix/store/2l33gg7nmncqkpysq9f5fxyhlw6ncm2j-systemd-217/bin/systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev (code=exited, status=1/FAILURE)
+    #  Main PID: 19272 (code=exited, status=1/FAILURE)
+    #
+    # Mar 16 10:29:17 cd systemd-tmpfiles[19272]: [/usr/lib/tmpfiles.d/legacy.conf:26] Unknown group 'lock'.
+    # Mar 16 10:29:18 cd systemd-tmpfiles[19272]: Two or more conflicting lines for /var/log/journal configured, ignoring.
+    # Mar 16 10:29:18 cd systemd-tmpfiles[19272]: Two or more conflicting lines for /var/log/journal/7b35116927d74ea58785e00b47ac0f0d configured, ignoring.
+    # Mar 16 10:29:18 cd systemd[1]: systemd-tmpfiles-setup.service: main process exited, code=exited, status=1/FAILURE
+    # Mar 16 10:29:18 cd systemd[1]: Failed to start Create Volatile Files and Directories.
+    # Mar 16 10:29:18 cd systemd[1]: Unit systemd-tmpfiles-setup.service entered failed state.
+    # Mar 16 10:29:18 cd systemd[1]: systemd-tmpfiles-setup.service failed.
+    # warning: error(s) occured while switching to the new configuration
+    lock.gid = 10001;
+  };
+}
diff --git a/shared/2configs/shack-drivedroid.nix b/shared/2configs/shack-drivedroid.nix
new file mode 100644
index 000000000..08a6b0697
--- /dev/null
+++ b/shared/2configs/shack-drivedroid.nix
@@ -0,0 +1,44 @@
+{ pkgs, lib, config, ... }:
+let
+  repodir = "/var/srv/drivedroid";
+  srepodir = lib.shell.escape repodir;
+in
+{
+  environment.systemPackages = [ pkgs.drivedroid-gen-repo ];
+
+  systemd.services.drivedroid = {
+    description = "generates drivedroid repo file";
+    restartIfChanged = true;
+    wantedBy = [ "multi-user.target" ];
+
+    serviceConfig = {
+      Type = "simple";
+      Restart = "always";
+      ExecStartPre = pkgs.writeScript "prepare-drivedroid-gen-repo" ''
+        #!/bin/sh
+        mkdir -p ${srepodir}/repos
+      '';
+      ExecStart = pkgs.writeScript "start-drivedroid-gen-repo" ''
+        #!/bin/sh
+        while sleep 60; do
+          ${pkgs.inotify-tools}/bin/inotifywait -r ${srepodir} && ${pkgs.drivedroid-gen-repo}/bin/drivedroid-gen-repo --chdir "${srepodir}" repos/ > "${srepodir}/main.json"
+        done
+      '';
+    };
+  };
+
+  krebs.nginx = {
+    enable = lib.mkDefault true;
+    servers = {
+      drivedroid-repo = {
+        server-names = [ "drivedroid.shack" ];
+        # TODO: prepare this somehow
+        locations = lib.singleton (lib.nameValuePair "/" ''
+          root ${repodir};
+          index main.json;
+        '');
+      };
+    };
+  };
+
+}
diff --git a/shared/2configs/shack-nix-cacher.nix b/shared/2configs/shack-nix-cacher.nix
new file mode 100644
index 000000000..7519bb3ac
--- /dev/null
+++ b/shared/2configs/shack-nix-cacher.nix
@@ -0,0 +1,25 @@
+{ pkgs, lib, ... }:
+
+{
+  krebs.nginx = {
+    enable = lib.mkDefault true;
+    servers = {
+      apt-cacher-ng = {
+        server-names = [ "acng.shack" ];
+        locations = lib.singleton (lib.nameValuePair "/" ''
+          proxy_set_header   Host $host;
+          proxy_set_header   X-Real-IP          $remote_addr;
+          proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
+          proxy_pass http://localhost:3142/;
+        '');
+      };
+    };
+  };
+
+  krebs.apt-cacher-ng = {
+    enable = true;
+    port = 3142;
+    bindAddress = "localhost";
+    cacheExpiration = 30;
+  };
+}