diff --git a/Makefile b/Makefile
index 7252ca70e..a74e3a877 100644
--- a/Makefile
+++ b/Makefile
@@ -9,6 +9,7 @@ export STOCKHOLM_VERSION ?= $(shell \
 	printf '%s' "$$date.$$version"; \
 )
 
+system ?= $(HOSTNAME)
 $(if $(system),,$(error unbound variable: system))
 
 nixos-config ?= $(stockholm)/$(LOGNAME)/1systems/$(system).nix
@@ -54,15 +55,17 @@ evaluate = \
 		--show-trace \
 		-I nixos-config=$(nixos-config) \
 		-I stockholm=$(stockholm) \
-		-E '{ eval, f }: f eval' \
-		--arg eval 'import ./.' \
-		--arg f "eval@{ config, ... }: $(1)"
+		-E "let eval = import <stockholm>; in with eval; $(1)"
 
 execute = \
 	result=$$($(call evaluate,config.krebs.build.$(1))) && \
 	script=$$(echo "$$result" | jq -r .) && \
 	echo "$$script" | PS5=% sh
 
+ifeq ($(MAKECMDGOALS),)
+$(error No goals specified)
+endif
+
 # usage: make deploy system=foo [target_host=bar]
 deploy: ssh ?= ssh
 deploy:
@@ -73,7 +76,7 @@ deploy:
 
 # usage: make LOGNAME=shared system=wolf eval.config.krebs.build.host.name
 eval eval.:;@$(call evaluate,$${expr-eval})
-eval.%:;@$(call evaluate,$*)
+eval.%:;@$(call evaluate,$@)
 
 # usage: make install system=foo [target_host=bar]
 install: ssh ?= ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
diff --git a/krebs/3modules/backup.nix b/krebs/3modules/backup.nix
index d22dd3810..71b22d8cb 100644
--- a/krebs/3modules/backup.nix
+++ b/krebs/3modules/backup.nix
@@ -103,103 +103,91 @@ let
     plan.method == method &&
     config.krebs.build.host.name == plan.${side}.host.name;
 
-  start = plan: pkgs.writeDash "backup.${plan.name}" ''
+  start = plan: let
+    login-name = "root";
+    identity = local.host.ssh.privkey.path;
+    ssh = "ssh -i ${shell.escape identity}";
+    local = getAttr plan.method {
+      push = plan.src // { rsync = src-rsync; };
+      pull = plan.dst // { rsync = dst-rsync; };
+    };
+    remote = getAttr plan.method {
+      push = plan.dst // { rsync = dst-rsync; };
+      pull = plan.src // { rsync = src-rsync; };
+    };
+    src-rsync = "rsync";
+    dst-rsync = concatStringsSep " && " [
+      "stat ${shell.escape plan.dst.path} >/dev/null"
+      "mkdir -m 0700 -p ${shell.escape plan.dst.path}/current"
+      "flock -n ${shell.escape plan.dst.path} rsync"
+    ];
+  in pkgs.writeScript "backup.${plan.name}" ''
+    #! ${pkgs.bash}/bin/bash
     set -efu
+    start_date=$(date +%s)
+    ssh_target=${shell.escape login-name}@$(${fastest-address remote.host})
     ${getAttr plan.method {
       push = ''
-        identity=${shell.escape plan.src.host.ssh.privkey.path}
-        src_path=${shell.escape plan.src.path}
-        src=$src_path
-        dst_user=root
-        dst_host=$(${fastest-address plan.dst.host})
-        dst_port=$(${network-ssh-port plan.dst.host "$dst_host"})
-        dst_path=${shell.escape plan.dst.path}
-        dst=$dst_user@$dst_host:$dst_path
-        echo "update snapshot: current; $src -> $dst" >&2
-        dst_shell() {
-          exec ssh -F /dev/null \
-              -i "$identity" \
-              ''${dst_port:+-p $dst_port} \
-              "$dst_user@$dst_host" \
-              -T "$with_dst_path_lock_script"
-        }
-        rsh="ssh -F /dev/null -i $identity ''${dst_port:+-p $dst_port}"
-        local_rsync() {
-          rsync "$@"
-        }
-        remote_rsync=${shell.escape (concatStringsSep " && " [
-          "mkdir -m 0700 -p ${shell.escape plan.dst.path}/current"
-          "exec flock -n ${shell.escape plan.dst.path} rsync"
-        ])}
+        rsync_src=${shell.escape plan.src.path}
+        rsync_dst=$ssh_target:${shell.escape plan.dst.path}
+        echo >&2 "update snapshot current; $rsync_src -> $rsync_dst"
       '';
       pull = ''
-        identity=${shell.escape plan.dst.host.ssh.privkey.path}
-        src_user=root
-        src_host=$(${fastest-address plan.src.host})
-        src_port=$(${network-ssh-port plan.src.host "$src_host"})
-        src_path=${shell.escape plan.src.path}
-        src=$src_user@$src_host:$src_path
-        dst_path=${shell.escape plan.dst.path}
-        dst=$dst_path
-        echo "update snapshot: current; $dst <- $src" >&2
-        dst_shell() {
-          eval "$with_dst_path_lock_script"
-        }
-        rsh="ssh -F /dev/null -i $identity ''${src_port:+-p $src_port}"
-        local_rsync() {
-          mkdir -m 0700 -p ${shell.escape plan.dst.path}/current
-          flock -n ${shell.escape plan.dst.path} rsync "$@"
-        }
-        remote_rsync=rsync
+        rsync_src=$ssh_target:${shell.escape plan.src.path}
+        rsync_dst=${shell.escape plan.dst.path}
+        echo >&2 "update snapshot current; $rsync_dst <- $rsync_src"
       '';
     }}
-    # Note that this only works because we trust date +%s to produce output
-    # that doesn't need quoting when used to generate a command string.
-    # TODO relax this requirement by selectively allowing to inject variables
-    #   e.g.: ''${shell.quote "exec env NOW=''${shell.unquote "$NOW"} ..."}
-    with_dst_path_lock_script="exec env start_date=$(date +%s) "${shell.escape
-      "flock -n ${shell.escape plan.dst.path} /bin/sh"
-    }
-    local_rsync >&2 \
+    ${local.rsync} >&2 \
         -aAXF --delete \
-        --rsh="$rsh" \
-        --rsync-path="$remote_rsync" \
-        --link-dest="$dst_path/current" \
-        "$src/" \
-        "$dst/.partial"
-    dst_shell < ${toFile "backup.${plan.name}.take-snapshots" ''
+        --rsh=${shell.escape ssh} \
+        --rsync-path=${shell.escape remote.rsync} \
+        --link-dest=${shell.escape plan.dst.path}/current \
+        "$rsync_src/" \
+        "$rsync_dst/.partial"
+
+    dst_exec() {
+      ${getAttr plan.method {
+        push = ''exec ${ssh} "$ssh_target" -T "exec$(printf ' %q' "$@")"'';
+        pull = ''exec "$@"'';
+      }}
+    }
+    dst_exec env \
+        start_date="$start_date" \
+        flock -n ${shell.escape plan.dst.path} \
+        /bin/sh < ${toFile "backup.${plan.name}.take-snapshots" ''
       set -efu
       : $start_date
 
-      dst=${shell.escape plan.dst.path}
+      dst_path=${shell.escape plan.dst.path}
 
-      mv "$dst/current" "$dst/.previous"
-      mv "$dst/.partial" "$dst/current"
-      rm -fR "$dst/.previous"
+      mv "$dst_path/current" "$dst_path/.previous"
+      mv "$dst_path/.partial" "$dst_path/current"
+      rm -fR "$dst_path/.previous"
       echo >&2
 
       snapshot() {(
         : $ns $format $retain
         name=$(date --date="@$start_date" +"$format")
-        if ! test -e "$dst/$ns/$name"; then
+        if ! test -e "$dst_path/$ns/$name"; then
           echo >&2 "create snapshot: $ns/$name"
-          mkdir -m 0700 -p "$dst/$ns"
+          mkdir -m 0700 -p "$dst_path/$ns"
           rsync >&2 \
               -aAXF --delete \
-              --link-dest="$dst/current" \
-              "$dst/current/" \
-              "$dst/$ns/.partial.$name"
-          mv "$dst/$ns/.partial.$name" "$dst/$ns/$name"
+              --link-dest="$dst_path/current" \
+              "$dst_path/current/" \
+              "$dst_path/$ns/.partial.$name"
+          mv "$dst_path/$ns/.partial.$name" "$dst_path/$ns/$name"
           echo >&2
         fi
         case $retain in
           ([0-9]*)
             delete_from=$(($retain + 1))
-            ls -r "$dst/$ns" \
+            ls -r "$dst_path/$ns" \
               | sed -n "$delete_from,\$p" \
               | while read old_name; do
                   echo >&2 "delete snapshot: $ns/$old_name"
-                  rm -fR "$dst/$ns/$old_name"
+                  rm -fR "$dst_path/$ns/$old_name"
                 done
             ;;
           (ALL)
@@ -227,24 +215,12 @@ let
       | ${pkgs.coreutils}/bin/head -1; }
   '';
 
-  # Note that we don't escape word on purpose, so we can deref shell vars.
-  # TODO type word
-  network-ssh-port = host: word: ''
-    case ${word} in
-    ${concatStringsSep ";;\n" (mapAttrsToList
-      (_: net: "(${head net.aliases}) echo ${toString net.ssh.port}")
-      host.nets)};;
-    esac
-  '';
-
 in out
 # TODO ionice
-# TODO mail on failed push, pull
 # TODO mail on missing push
 # TODO don't cancel plans on activation
 #   also, don't hang while deploying at:
 #   starting the following units: backup.wu-home-xu.push.service, backup.wu-home-xu.push.timer
-# TODO make sure /bku is properly mounted
 # TODO make sure that secure hosts cannot backup to insecure ones
 # TODO optionally only backup when src and dst are near enough :)
 # TODO try using btrfs for snapshots (configurable)
diff --git a/krebs/3modules/build.nix b/krebs/3modules/build.nix
index d4c6b08df..9cd095622 100644
--- a/krebs/3modules/build.nix
+++ b/krebs/3modules/build.nix
@@ -88,6 +88,8 @@ let
           #! /bin/sh
           set -efu
 
+          export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
+
           verbose() {
             printf '%s%s\n' "$PS5$(printf ' %q' "$@")" >&2
             "$@"
diff --git a/krebs/3modules/default.nix b/krebs/3modules/default.nix
index be530d46f..c114b74df 100644
--- a/krebs/3modules/default.nix
+++ b/krebs/3modules/default.nix
@@ -13,6 +13,7 @@ let
       ./buildbot/slave.nix
       ./build.nix
       ./current.nix
+      ./exim.nix
       ./exim-retiolum.nix
       ./exim-smarthost.nix
       ./fetchWallpaper.nix
@@ -157,7 +158,11 @@ let
           makefu
           tv
         ];
+        ciko.mail = "wieczorek.stefan@gmail.com";
+        Mic92.mail = "joerg@higgsboson.tk";
       in {
+        "*@eloop.org" = [{ mail = "eloop2016@krebsco.de"; }];
+        "eloop2016@krebsco.de" = spam-ml ++ [ ciko Mic92 ];
         "postmaster@krebsco.de" = spam-ml; # RFC 822
         "lass@krebsco.de" = lass;
         "makefu@krebsco.de" = makefu;
@@ -218,7 +223,7 @@ let
                             (filter (hasSuffix ".${cfg.search-domain}")
                                     longs);
                       add-port = a:
-                        if net.ssh.port != null
+                        if net.ssh.port != 22
                           then "[${a}]:${toString net.ssh.port}"
                           else a;
                     in
@@ -228,8 +233,25 @@ let
             publicKey = host.ssh.pubkey;
           })
           (filterAttrs (_: host: host.ssh.pubkey != null) cfg.hosts);
+
+      programs.ssh.extraConfig = concatMapStrings
+        (net: ''
+          Host ${toString (net.aliases ++ net.addrs)}
+            Port ${toString net.ssh.port}
+        '')
+        (filter
+          (net: net.ssh.port != 22)
+          (concatMap (host: attrValues host.nets)
+            (mapAttrsToList
+              (_: host: recursiveUpdate host
+                (optionalAttrs (hasAttr config.krebs.search-domain host.nets) {
+                  nets."" = host.nets.${config.krebs.search-domain} // {
+                    aliases = [host.name];
+                    addrs = [];
+                  };
+                }))
+              config.krebs.hosts)));
     }
   ];
 
-in
-out
+in out
diff --git a/krebs/3modules/exim-retiolum.nix b/krebs/3modules/exim-retiolum.nix
index 696c48baf..d6b7ab753 100644
--- a/krebs/3modules/exim-retiolum.nix
+++ b/krebs/3modules/exim-retiolum.nix
@@ -32,7 +32,7 @@ let
   };
 
   imp = {
-    services.exim = {
+    krebs.exim = {
       enable = true;
       config =
         # This configuration makes only sense for retiolum-enabled hosts.
@@ -57,6 +57,8 @@ let
           syslog_timestamp = false
           syslog_duplication = false
 
+          tls_advertise_hosts =
+
           begin acl
 
           acl_check_rcpt:
diff --git a/krebs/3modules/exim-smarthost.nix b/krebs/3modules/exim-smarthost.nix
index cee10ce7d..aba6ee0b5 100644
--- a/krebs/3modules/exim-smarthost.nix
+++ b/krebs/3modules/exim-smarthost.nix
@@ -105,7 +105,7 @@ let
         requires = [ "secret.service" ];
       };
     };
-    services.exim = {
+    krebs.exim = {
       enable = true;
       config = ''
         keep_environment =
@@ -136,6 +136,8 @@ let
         syslog_timestamp = false
         syslog_duplication = false
 
+        tls_advertise_hosts =
+
         begin acl
 
         acl_check_rcpt:
@@ -162,7 +164,7 @@ let
                   control       = dkim_disable_verify
 
           accept message = relay not permitted 2
-                  recipients = lsearch;${lsearch.internet-aliases}
+                  recipients = lsearch*@;${lsearch.internet-aliases}
 
           require message = relay not permitted
                   domains = +local_domains : +relay_to_domains
@@ -196,7 +198,7 @@ let
         internet_aliases:
           debug_print = "R: internet_aliases for $local_part@$domain"
           driver = redirect
-          data = ''${lookup{$local_part@$domain}lsearch{${lsearch.internet-aliases}}}
+          data = ''${lookup{$local_part@$domain}lsearch*@{${lsearch.internet-aliases}}}
 
         dnslookup:
           debug_print = "R: dnslookup for $local_part@$domain"
diff --git a/krebs/3modules/exim.nix b/krebs/3modules/exim.nix
new file mode 100644
index 000000000..7b18c72c1
--- /dev/null
+++ b/krebs/3modules/exim.nix
@@ -0,0 +1,80 @@
+{ config, lib, pkgs, ... }: with config.krebs.lib; let
+  cfg = config.krebs.exim;
+in {
+  options.krebs.exim = {
+    enable = mkEnableOption "krebs.exim";
+    config = mkOption {
+      type = types.str;
+      default = "";
+      description = ''
+        Verbatim Exim configuration.  This should not contain exim_user,
+        exim_group, exim_path, or spool_directory.
+      '';
+    };
+    user = mkOption {
+      type = types.user;
+      default = {
+        name = "exim";
+        home = "/var/spool/exim";
+      };
+      description = ''
+        User to use when no root privileges are required.
+        In particular, this applies when receiving messages and when doing
+        remote deliveries.  (Local deliveries run as various non-root users,
+        typically as the owner of a local mailbox.) Specifying this value
+        as root is not supported.
+      '';
+    };
+    group = mkOption {
+      type = types.group;
+      default = {
+        name = "exim";
+      };
+      description = ''
+        Group to use when no root privileges are required.
+      '';
+    };
+  };
+  config = lib.mkIf cfg.enable {
+    environment = {
+      etc."exim.conf".source = pkgs.writeEximConfig "exim.conf" ''
+        exim_user = ${cfg.user.name}
+        exim_group = ${cfg.group.name}
+        exim_path = /var/setuid-wrappers/exim
+        spool_directory = ${cfg.user.home}
+        ${cfg.config}
+      '';
+      systemPackages = [ pkgs.exim ];
+    };
+    krebs.setuid = {
+      exim = {
+        filename = "${pkgs.exim}/bin/exim";
+        mode = "4111";
+      };
+      sendmail = {
+        filename = "${pkgs.exim}/bin/exim";
+        mode = "4111";
+      };
+    };
+    systemd.services.exim = {
+      restartTriggers = [
+        config.environment.etc."exim.conf".source
+      ];
+      serviceConfig = {
+        ExecStart = "${pkgs.exim}/bin/exim -bdf -q30m";
+        ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+      };
+      wantedBy = [ "multi-user.target" ];
+    };
+    users = {
+      groups.${cfg.group.name} = {
+        inherit (cfg.group) name gid;
+      };
+      users.${cfg.user.name} = {
+        inherit (cfg.user) home name uid;
+        createHome = true;
+        group = cfg.group.name;
+      };
+    };
+  };
+}
diff --git a/krebs/3modules/lass/default.nix b/krebs/3modules/lass/default.nix
index 3d54900e4..b4686894e 100644
--- a/krebs/3modules/lass/default.nix
+++ b/krebs/3modules/lass/default.nix
@@ -8,15 +8,15 @@ with config.krebs.lib;
       cores = 4;
       nets = rec {
         internet = {
-          addrs4 = ["144.76.172.188"];
+          ip4.addr = "144.76.172.188";
           aliases = [
             "dishfire.internet"
           ];
         };
         retiolum = {
           via = internet;
-          addrs4 = ["10.243.133.99"];
-          addrs6 = ["42:0000:0000:0000:0000:0000:d15f:1233"];
+          ip4.addr = "10.243.133.99";
+          ip6.addr = "42:0000:0000:0000:0000:0000:d15f:1233";
           aliases = [
             "dishfire.retiolum"
             "dishfire.r"
@@ -40,15 +40,15 @@ with config.krebs.lib;
       cores = 2;
       nets = rec {
         internet = {
-          addrs4 = ["162.252.241.33"];
+          ip4.addr = "162.252.241.33";
           aliases = [
             "echelon.internet"
           ];
         };
         retiolum = {
           via = internet;
-          addrs4 = ["10.243.206.103"];
-          addrs6 = ["42:941e:2816:35f4:5c5e:206b:3f0b:f763"];
+          ip4.addr = "10.243.206.103";
+          ip6.addr = "42:941e:2816:35f4:5c5e:206b:3f0b:f763";
           aliases = [
             "echelon.retiolum"
             "echelon.r"
@@ -75,15 +75,15 @@ with config.krebs.lib;
       cores = 4;
       nets = rec {
         internet = {
-          addrs4 = ["213.239.205.240"];
+          ip4.addr = "213.239.205.240";
           aliases = [
             "prism.internet"
           ];
         };
         retiolum = {
           via = internet;
-          addrs4 = ["10.243.0.103"];
-          addrs6 = ["42:0000:0000:0000:0000:0000:0000:15ab"];
+          ip4.addr = "10.243.0.103";
+          ip6.addr = "42:0000:0000:0000:0000:0000:0000:15ab";
           aliases = [
             "prism.retiolum"
             "prism.r"
@@ -107,15 +107,15 @@ with config.krebs.lib;
     fastpoke = {
       nets = rec {
         internet = {
-          addrs4 = ["193.22.164.36"];
+          ip4.addr = "193.22.164.36";
           aliases = [
             "fastpoke.internet"
           ];
         };
         retiolum = {
           via = internet;
-          addrs4 = ["10.243.253.152"];
-          addrs6 = ["42:422a:194f:ff3b:e196:2f82:5cf5:bc00"];
+          ip4.addr = "10.243.253.152";
+          ip6.addr = "42:422a:194f:ff3b:e196:2f82:5cf5:bc00";
           aliases = [
             "fastpoke.retiolum"
             "fastpoke.r"
@@ -139,15 +139,15 @@ with config.krebs.lib;
       cores = 1;
       nets = rec {
         internet = {
-          addrs4 = ["104.167.113.104"];
+          ip4.addr = "104.167.113.104";
           aliases = [
             "cloudkrebs.internet"
           ];
         };
         retiolum = {
           via = internet;
-          addrs4 = ["10.243.206.102"];
-          addrs6 = ["42:941e:2816:35f4:5c5e:206b:3f0b:f762"];
+          ip4.addr = "10.243.206.102";
+          ip6.addr = "42:941e:2816:35f4:5c5e:206b:3f0b:f762";
           aliases = [
             "cloudkrebs.retiolum"
             "cloudkrebs.r"
@@ -172,12 +172,12 @@ with config.krebs.lib;
       cores = 1;
       nets = {
         gg23 = {
-          addrs4 = ["10.23.1.12"];
+          ip4.addr = "10.23.1.12";
           aliases = ["uriel.gg23"];
         };
         retiolum = {
-          addrs4 = ["10.243.81.176"];
-          addrs6 = ["42:dc25:60cf:94ef:759b:d2b6:98a9:2e56"];
+          ip4.addr = "10.243.81.176";
+          ip6.addr = "42:dc25:60cf:94ef:759b:d2b6:98a9:2e56";
           aliases = [
             "uriel.retiolum"
             "uriel.r"
@@ -203,12 +203,12 @@ with config.krebs.lib;
       cores = 2;
       nets = {
         gg23 = {
-          addrs4 = ["10.23.1.11"];
+          ip4.addr = "10.23.1.11";
           aliases = ["mors.gg23"];
         };
         retiolum = {
-          addrs4 = ["10.243.0.2"];
-          addrs6 = ["42:0:0:0:0:0:0:dea7"];
+          ip4.addr = "10.243.0.2";
+          ip6.addr = "42:0:0:0:0:0:0:dea7";
           aliases = [
             "mors.retiolum"
             "mors.r"
@@ -234,8 +234,8 @@ with config.krebs.lib;
       cores = 2;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.0.3"];
-          addrs6 = ["42:0:0:0:0:0:0:7105"];
+          ip4.addr = "10.243.0.3";
+          ip6.addr = "42:0:0:0:0:0:0:7105";
           aliases = [
             "helios.retiolum"
             "helios.r"
diff --git a/krebs/3modules/makefu/default.nix b/krebs/3modules/makefu/default.nix
index 418224138..79d9a59b4 100644
--- a/krebs/3modules/makefu/default.nix
+++ b/krebs/3modules/makefu/default.nix
@@ -8,8 +8,8 @@ with config.krebs.lib;
       cores = 1;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.0.210"];
-          addrs6 = ["42:f9f1:0000:0000:0000:0000:0000:0001"];
+          ip4.addr = "10.243.0.210";
+          ip6.addr = "42:f9f1:0000:0000:0000:0000:0000:0001";
           aliases = [
             "pnp.retiolum"
             "cgit.pnp.retiolum"
@@ -31,8 +31,8 @@ with config.krebs.lib;
       cores = 4;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.0.84"];
-          addrs6 = ["42:ff6b:5f0b:460d:2cee:4d05:73f7:5566"];
+          ip4.addr = "10.243.0.84";
+          ip6.addr = "42:ff6b:5f0b:460d:2cee:4d05:73f7:5566";
           aliases = [
             "darth.retiolum"
             "darth.r"
@@ -54,8 +54,8 @@ with config.krebs.lib;
       cores = 1;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.0.212"];
-          addrs6 = ["42:f9f1:0000:0000:0000:0000:0000:0002"];
+          ip4.addr = "10.243.0.212";
+          ip6.addr = "42:f9f1:0000:0000:0000:0000:0000:0002";
           aliases = [
             "tsp.retiolum"
           ];
@@ -81,8 +81,8 @@ with config.krebs.lib;
       cores = 2;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.0.91"];
-          addrs6 = ["42:0b2c:d90e:e717:03dc:9ac1:7c30:a4db"];
+          ip4.addr = "10.243.0.91";
+          ip6.addr = "42:0b2c:d90e:e717:03dc:9ac1:7c30:a4db";
           aliases = [
             "pornocauster.retiolum"
             "pornocauster.r"
@@ -108,8 +108,8 @@ with config.krebs.lib;
       cores = 2;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.1.91"];
-          addrs6 = ["42:0b2c:d90e:e717:03dd:9ac1:0000:a400"];
+          ip4.addr = "10.243.1.91";
+          ip6.addr = "42:0b2c:d90e:e717:03dd:9ac1:0000:a400";
           aliases = [
             "vbob.retiolum"
           ];
@@ -135,22 +135,22 @@ with config.krebs.lib;
       extraZones = {
         "krebsco.de" = ''
           euer              IN MX 1   aspmx.l.google.com.
-          pigstarter        IN A      ${head nets.internet.addrs4}
-          gold              IN A      ${head nets.internet.addrs4}
-          boot              IN A      ${head nets.internet.addrs4}
+          pigstarter        IN A      ${nets.internet.ip4.addr}
+          gold              IN A      ${nets.internet.ip4.addr}
+          boot              IN A      ${nets.internet.ip4.addr}
         '';
       };
       nets = {
         internet = {
-          addrs4 = ["192.40.56.122"];
-          addrs6 = ["2604:2880::841f:72c"];
+          ip4.addr = "192.40.56.122";
+          ip6.addr = "2604:2880::841f:72c";
           aliases = [
             "pigstarter.internet"
           ];
         };
         retiolum = {
-          addrs4 = ["10.243.0.153"];
-          addrs6 = ["42:9143:b4c0:f981:6030:7aa2:8bc5:4110"];
+          ip4.addr = "10.243.0.153";
+          ip6.addr = "42:9143:b4c0:f981:6030:7aa2:8bc5:4110";
           aliases = [
             "pigstarter.retiolum"
           ];
@@ -171,18 +171,18 @@ with config.krebs.lib;
       cores = 1;
       extraZones = {
         "krebsco.de" = ''
-          euer           IN A  ${head nets.internet.addrs4}
-          wiki.euer      IN A  ${head nets.internet.addrs4}
-          wry            IN A  ${head nets.internet.addrs4}
+          euer           IN A  ${nets.internet.ip4.addr}
+          wiki.euer      IN A  ${nets.internet.ip4.addr}
+          wry            IN A  ${nets.internet.ip4.addr}
           io             IN NS wry.krebsco.de.
-          graphs         IN A  ${head nets.internet.addrs4}
-          paste       60 IN A  ${head nets.internet.addrs4}
-          tinc           IN A  ${head nets.internet.addrs4}
+          graphs         IN A  ${nets.internet.ip4.addr}
+          paste       60 IN A  ${nets.internet.ip4.addr}
+          tinc           IN A  ${nets.internet.ip4.addr}
         '';
       };
       nets = rec {
         internet = {
-          addrs4 = ["104.233.87.86"];
+          ip4.addr = "104.233.87.86";
           aliases = [
             "wry.internet"
             "paste.internet"
@@ -190,8 +190,8 @@ with config.krebs.lib;
         };
         retiolum = {
           via = internet;
-          addrs4 = ["10.243.29.169"];
-          addrs6 = ["42:6e1e:cc8a:7cef:827:f938:8c64:baad"];
+          ip4.addr = "10.243.29.169";
+          ip6.addr = "42:6e1e:cc8a:7cef:827:f938:8c64:baad";
           aliases = [
             "graphs.wry.retiolum"
             "graphs.retiolum"
@@ -228,8 +228,8 @@ with config.krebs.lib;
 
       nets = {
         retiolum = {
-          addrs4 = ["10.243.153.102"];
-          addrs6 = ["42:4b0b:d990:55ba:8da8:630f:dc0e:aae0"];
+          ip4.addr = "10.243.153.102";
+          ip6.addr = "42:4b0b:d990:55ba:8da8:630f:dc0e:aae0";
           aliases = [
             "filepimp.retiolum"
           ];
@@ -252,8 +252,8 @@ with config.krebs.lib;
 
       nets = {
         retiolum = {
-          addrs4 = ["10.243.0.89"];
-          addrs6 = ["42:f9f0::10"];
+          ip4.addr = "10.243.0.89";
+          ip6.addr = "42:f9f0::10";
           aliases = [
             "omo.retiolum"
             "omo.r"
@@ -277,8 +277,8 @@ with config.krebs.lib;
       cores = 1;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.214.15"];
-          addrs6 = ["42:5a02:2c30:c1b1:3f2e:7c19:2496:a732"];
+          ip4.addr = "10.243.214.15";
+          ip6.addr = "42:5a02:2c30:c1b1:3f2e:7c19:2496:a732";
           aliases = [
               "wbob.retiolum"
           ];
@@ -301,24 +301,24 @@ TNs2RYfwDy/r6H/hDeB/BSngPouedEVcPwIDAQAB
 
       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}
+          share.euer        IN A      ${nets.internet.ip4.addr}
+          mattermost.euer   IN A      ${nets.internet.ip4.addr}
+          git.euer          IN A      ${nets.internet.ip4.addr}
+          gum               IN A      ${nets.internet.ip4.addr}
+          cgit.euer         IN A      ${nets.internet.ip4.addr}
         '';
       };
       nets = rec {
         internet = {
-          addrs4 = ["195.154.108.70"];
+          ip4.addr = "195.154.108.70";
           aliases = [
             "gum.internet"
           ];
         };
         retiolum = {
           via = internet;
-          addrs4 = ["10.243.0.211"];
-          addrs6 = ["42:f9f0:0000:0000:0000:0000:0000:70d2"];
+          ip4.addr = "10.243.0.211";
+          ip6.addr = "42:f9f0:0000:0000:0000:0000:0000:70d2";
           aliases = [
             "gum.r"
             "gum.retiolum"
@@ -346,20 +346,20 @@ TNs2RYfwDy/r6H/hDeB/BSngPouedEVcPwIDAQAB
       cores = 1;
       extraZones = {
         "krebsco.de" = ''
-          mediengewitter    IN A      ${head nets.internet.addrs4}
-          flap              IN A      ${head nets.internet.addrs4}
+          mediengewitter    IN A      ${nets.internet.ip4.addr}
+          flap              IN A      ${nets.internet.ip4.addr}
         '';
       };
       nets = {
         internet = {
-          addrs4 = ["162.248.11.162"];
+          ip4.addr = "162.248.11.162";
           aliases = [
             "flap.internet"
           ];
         };
         retiolum = {
-          addrs4 = ["10.243.211.172"];
-          addrs6 = ["42:472a:3d01:bbe4:4425:567e:592b:065d"];
+          ip4.addr = "10.243.211.172";
+          ip6.addr = "42:472a:3d01:bbe4:4425:567e:592b:065d";
           aliases = [
             "flap.retiolum"
             "flap.r"
@@ -382,8 +382,8 @@ TNs2RYfwDy/r6H/hDeB/BSngPouedEVcPwIDAQAB
       cores = 1;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.231.219"];
-          addrs6 = ["42:f7bf:178d:4b68:1c1b:42e8:6b27:6a72"];
+          ip4.addr = "10.243.231.219";
+          ip6.addr = "42:f7bf:178d:4b68:1c1b:42e8:6b27:6a72";
           aliases = [
             "nukular.r"
           ];
@@ -405,9 +405,12 @@ TNs2RYfwDy/r6H/hDeB/BSngPouedEVcPwIDAQAB
       cores = 1;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.124.21"];
-          addrs6 = ["42:9898:a8be:ce56:0ee3:b99c:42c5:109e"];
-          aliases = [ "heidi.r" "heidi.retiolum" ];
+          ip4.addr = "10.243.124.21";
+          ip6.addr = "42:9898:a8be:ce56:0ee3:b99c:42c5:109e";
+          aliases = [
+            "heidi.r"
+            "heidi.retiolum"
+          ];
           tinc.pubkey = ''
             -----BEGIN RSA PUBLIC KEY-----
             MIIBCgKCAQEAqRLnAJNZ1OoO1bTS58DQgxi1VKgITHIuTW0fVGDvbXnsjPUB3cgx
@@ -427,7 +430,7 @@ TNs2RYfwDy/r6H/hDeB/BSngPouedEVcPwIDAQAB
       cores = 1;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.69.184"];
+          ip4.addr = "10.243.69.184";
           aliases = [
             "soundflower.r"
           ];
@@ -449,7 +452,7 @@ TNs2RYfwDy/r6H/hDeB/BSngPouedEVcPwIDAQAB
       cores = 1;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.120.19"];
+          ip4.addr = "10.243.120.19";
           aliases = [
             "falk.r"
           ];
@@ -471,8 +474,8 @@ TNs2RYfwDy/r6H/hDeB/BSngPouedEVcPwIDAQAB
       cores = 4;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.189.130"];
-          addrs6 = ["42:c64e:011f:9755:31e1:c3e6:73c0:af2d"];
+          ip4.addr = "10.243.189.130";
+          ip6.addr = "42:c64e:011f:9755:31e1:c3e6:73c0:af2d";
           aliases = [
             "filebitch.r"
           ];
@@ -494,8 +497,8 @@ TNs2RYfwDy/r6H/hDeB/BSngPouedEVcPwIDAQAB
       cores = 1;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.26.29"];
-          addrs6 = ["42:927a:3d59:1cb3:29d6:1a08:78d3:812e"];
+          ip4.addr = "10.243.26.29";
+          ip6.addr = "42:927a:3d59:1cb3:29d6:1a08:78d3:812e";
           aliases = [
             "excobridge.r"
           ];
@@ -517,14 +520,14 @@ TNs2RYfwDy/r6H/hDeB/BSngPouedEVcPwIDAQAB
       cores = 1;
       nets = {
         internet = {
-          addrs4 = ["148.251.47.69"];
+          ip4.addr = "148.251.47.69";
           aliases = [
             "wooki.internet"
           ];
         };
         retiolum = {
-          addrs4 = ["10.243.57.85"];
-          addrs6 = ["42:2f06:b899:a3b5:1dcf:51a4:a02b:8731"];
+          ip4.addr = "10.243.57.85";
+          ip6.addr = "42:2f06:b899:a3b5:1dcf:51a4:a02b:8731";
           aliases = [
             "wooki.r"
           ];
@@ -546,8 +549,8 @@ TNs2RYfwDy/r6H/hDeB/BSngPouedEVcPwIDAQAB
       cores = 2;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.0.163"];
-          addrs6 = ["42:b67b:5752:a730:5f28:d80d:6b37:5bda/128"];
+          ip4.addr = "10.243.0.163";
+          ip6.addr = "42:b67b:5752:a730:5f28:d80d:6b37:5bda";
           aliases = [
             "senderechner.r"
           ];
@@ -569,14 +572,14 @@ TNs2RYfwDy/r6H/hDeB/BSngPouedEVcPwIDAQAB
       cores = 1;
       nets = {
         internet = {
-          addrs4 = ["217.160.206.154"];
+          ip4.addr = "217.160.206.154";
           aliases = [
             "muhbaasu.internet"
           ];
         };
         retiolum = {
-          addrs4 = ["10.243.139.184"];
-          addrs6 = ["42:d568:6106:ba30:753b:0f2a:8225:b1fb"];
+          ip4.addr = "10.243.139.184";
+          ip6.addr = "42:d568:6106:ba30:753b:0f2a:8225:b1fb";
           aliases = [
             "muhbaasu.r"
           ];
diff --git a/krebs/3modules/miefda/default.nix b/krebs/3modules/miefda/default.nix
index 9a5866294..a03f7ff4d 100644
--- a/krebs/3modules/miefda/default.nix
+++ b/krebs/3modules/miefda/default.nix
@@ -8,8 +8,8 @@ with config.krebs.lib;
       cores = 4;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.111.112"];
-          addrs6 = ["42:0:0:0:0:0:111:112"];
+          ip4.addr = "10.243.111.112";
+          ip6.addr = "42:0:0:0:0:0:111:112";
           aliases = [
             "bobby.retiolum"
             "cgit.bobby.retiolum"
diff --git a/krebs/3modules/mv/default.nix b/krebs/3modules/mv/default.nix
index 3b4001e7a..20118c61f 100644
--- a/krebs/3modules/mv/default.nix
+++ b/krebs/3modules/mv/default.nix
@@ -8,8 +8,8 @@ with config.krebs.lib;
       cores = 4;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.111.111"];
-          addrs6 = ["42:0:0:0:0:0:111:111"];
+          ip4.addr = "10.243.111.111";
+          ip6.addr = "42:0:0:0:0:0:111:111";
           aliases = [
             "stro.retiolum"
             "cgit.stro.retiolum"
diff --git a/krebs/3modules/nginx.nix b/krebs/3modules/nginx.nix
index 816c2ff69..6af93a570 100644
--- a/krebs/3modules/nginx.nix
+++ b/krebs/3modules/nginx.nix
@@ -117,28 +117,24 @@ let
     }
   '';
 
-  to-server = { server-names, listen, locations, extraConfig, ssl, ... }:
-    let
-      _extraConfig = if ssl.enable then
-        extraConfig + ''
-          ssl_certificate ${ssl.certificate};
-          ssl_certificate_key ${ssl.certificate_key};
-          ${optionalString ssl.prefer_server_ciphers "ssl_prefer_server_ciphers On;"}
-          ssl_ciphers ${ssl.ciphers};
-          ssl_protocols ${toString ssl.protocols};
-        ''
-      else
-        extraConfig
-      ;
-
-    in ''
-      server {
-        ${concatMapStringsSep "\n" (x: "listen ${x};") (listen ++ optional ssl.enable "443 ssl")}
-        server_name ${toString server-names};
-        ${indent _extraConfig}
-        ${indent (concatMapStrings to-location locations)}
-      }
-    '';
+  to-server = { server-names, listen, locations, extraConfig, ssl, ... }: ''
+    server {
+      server_name ${toString server-names};
+      ${concatMapStringsSep "\n" (x: indent "listen ${x};") listen}
+      ${optionalString ssl.enable (indent ''
+        listen 443 ssl;
+        ssl_certificate ${ssl.certificate};
+        ssl_certificate_key ${ssl.certificate_key};
+        ${optionalString ssl.prefer_server_ciphers ''
+          ssl_prefer_server_ciphers On;
+        ''}
+        ssl_ciphers ${ssl.ciphers};
+        ssl_protocols ${toString ssl.protocols};
+      '')}
+      ${indent extraConfig}
+      ${indent (concatMapStrings to-location locations)}
+    }
+  '';
 
 in
 out
diff --git a/krebs/3modules/on-failure.nix b/krebs/3modules/on-failure.nix
index 13d561b8d..a471a4bc2 100644
--- a/krebs/3modules/on-failure.nix
+++ b/krebs/3modules/on-failure.nix
@@ -84,6 +84,14 @@
       ${pkgs.systemd}/bin/journalctl \
           --lines=${toString plan.journalctl.lines} \
           --output=${plan.journalctl.output} \
+          --since="$(
+            ${pkgs.coreutils}/bin/date +'%F %T UTC' -ud "$(
+              ${pkgs.systemd}/bin/systemctl show \
+                  -p ExecMainStartTimestamp \
+                  ${shell.escape plan.name} \
+                | ${pkgs.coreutils}/bin/cut -d= -f2-
+            )"
+          )" \
           --unit=${shell.escape plan.name}.service
     } | ${shell.escape cfg.sendmail} -t
   '';
diff --git a/krebs/3modules/retiolum.nix b/krebs/3modules/retiolum.nix
index 422935848..5a035fa50 100644
--- a/krebs/3modules/retiolum.nix
+++ b/krebs/3modules/retiolum.nix
@@ -11,26 +11,13 @@ let
   api = {
     enable = mkEnableOption "krebs.retiolum";
 
-    name = mkOption {
-      type = types.str;
-      default = config.networking.hostName;
-      # Description stolen from tinc.conf(5).
-      description = ''
-        This is the name which identifies this tinc daemon.  It must
-        be unique for the virtual private network this daemon will
-        connect to.  The Name may only consist of alphanumeric and
-        underscore characters.  If Name starts with a $, then the
-        contents of the environment variable that follows will be
-        used.  In that case, invalid characters will be converted to
-        underscores.  If Name is $HOST, but no such environment
-        variable exist, the hostname will be read using the
-        gethostnname() system call This is the name which identifies
-        the this tinc daemon.
-      '';
+    host = mkOption {
+      type = types.host;
+      default = config.krebs.build.host;
     };
 
     netname = mkOption {
-      type = types.str;
+      type = types.enum (attrNames cfg.host.nets);
       default = "retiolum";
       description = ''
         The tinc network name.
@@ -99,17 +86,13 @@ let
       description = "Iproute2 package to use.";
     };
 
-
-    privateKeyFile = mkOption {
-      # TODO if it's types.path then it gets copied to /nix/store with
-      #      bad unsafe permissions...
-      type = types.str;
-      default = toString <secrets/retiolum.rsa_key.priv>;
-      description = ''
-          Generate file with <literal>tincd -K</literal>.
-          This file must exist on the local system. The default points to 
-          <secrets/retiolum.rsa_key.priv>.
-        '';
+    privkey = mkOption {
+      type = types.secret-file;
+      default = {
+        path = "${cfg.user.home}/tinc.rsa_key.priv";
+        owner = cfg.user;
+        source-path = toString <secrets> + "/${cfg.netname}.rsa_key.priv";
+      };
     };
 
     connectTo = mkOption {
@@ -126,81 +109,67 @@ let
       '';
     };
 
+    user = mkOption {
+      type = types.user;
+      default = {
+        name = cfg.netname;
+        home = "/var/lib/${cfg.user.name}";
+      };
+    };
   };
 
   imp = {
+    krebs.secret.files."${cfg.netname}.rsa_key.priv" = cfg.privkey;
+
     environment.systemPackages = [ tinc iproute ];
 
-    systemd.services.retiolum = {
+    systemd.services.${cfg.netname} = {
       description = "Tinc daemon for Retiolum";
       after = [ "network.target" ];
       wantedBy = [ "multi-user.target" ];
+      requires = [ "secret.service" ];
       path = [ tinc iproute ];
       serviceConfig = rec {
-        PermissionsStartOnly = "true";
-        PrivateTmp = "true";
         Restart = "always";
-        # TODO we cannot chroot (-R) b/c we use symlinks to hosts
-        #      and the private key.
-        ExecStartPre = pkgs.writeScript "retiolum-init" ''
-          #! /bin/sh
-          install -o ${user.name} -m 0400 ${cfg.privateKeyFile} /tmp/retiolum-rsa_key.priv
-        '';
-        ExecStart = "${tinc}/sbin/tincd -c ${confDir} -d 0 -U ${user.name} -D --pidfile=/var/run/tinc.${SyslogIdentifier}.pid";
-        SyslogIdentifier = "retiolum";
+        ExecStart = "${tinc}/sbin/tincd -c ${confDir} -d 0 -U ${cfg.user.name} -D --pidfile=/var/run/tinc.${SyslogIdentifier}.pid";
+        SyslogIdentifier = cfg.netname;
       };
     };
 
-    users.extraUsers = singleton {
-      inherit (user) name uid;
+    users.users.${cfg.user.name} = {
+      inherit (cfg.user) home name uid;
+      createHome = true;
     };
   };
 
-  user = rec {
-    name = "retiolum";
-    uid = genid name;
-  };
+  net = cfg.host.nets.${cfg.netname};
 
   tinc = cfg.tincPackage;
 
   iproute = cfg.iproutePackage;
 
-  confDir = pkgs.runCommand "retiolum" {
-    # TODO text
-    executable = true;
-    preferLocalBuild = true;
-  } ''
-    set -euf
-
-    mkdir -p $out
-
-    ln -s ${cfg.hostsPackage} $out/hosts
-
-    cat > $out/tinc.conf <<EOF
-    Name = ${cfg.name}
-    Device = /dev/net/tun
-    Interface = ${cfg.netname}
-    ${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
-    cat > $out/tinc-up <<EOF
-    host=$out/hosts/${cfg.name}
-    ${iproute}/sbin/ip link set \$INTERFACE up
-
-    addr4=\$(sed -n 's|^ *Subnet *= *\(10[.][^ ]*\) *$|\1|p' \$host)
-    if [ -n "\$addr4" ];then
-        ${iproute}/sbin/ip -4 addr add \$addr4 dev \$INTERFACE
-        ${iproute}/sbin/ip -4 route add 10.243.0.0/16 dev \$INTERFACE
-    fi
-    addr6=\$(sed -n 's|^ *Subnet *= *\(42[:][^ ]*\) *$|\1|p' \$host)
-    ${iproute}/sbin/ip -6 addr add \$addr6 dev \$INTERFACE
-    ${iproute}/sbin/ip -6 route add 42::/16 dev \$INTERFACE
-    EOF
-
-    chmod +x $out/tinc-up
-  '';
+  confDir = let
+    namePathPair = name: path: { inherit name path; };
+  in pkgs.linkFarm "${cfg.netname}-etc-tinc" (mapAttrsToList namePathPair {
+    "hosts" = cfg.hostsPackage;
+    "tinc.conf" = pkgs.writeText "${cfg.netname}-tinc.conf" ''
+      Name = ${cfg.host.name}
+      Interface = ${cfg.netname}
+      ${concatStrings (map (c: "ConnectTo = ${c}\n") cfg.connectTo)}
+      PrivateKeyFile = ${cfg.privkey.path}
+      ${cfg.extraConfig}
+    '';
+    "tinc-up" = pkgs.writeScript "${cfg.netname}-tinc-up" ''
+      ${iproute}/sbin/ip link set ${cfg.netname} up
+      ${optionalString (net.ip4 != null) ''
+        ${iproute}/sbin/ip -4 addr add ${net.ip4.addr} dev ${cfg.netname}
+        ${iproute}/sbin/ip -4 route add ${net.ip4.prefix} dev ${cfg.netname}
+      ''}
+      ${optionalString (net.ip6 != null) ''
+        ${iproute}/sbin/ip -6 addr add ${net.ip6.addr} dev ${cfg.netname}
+        ${iproute}/sbin/ip -6 route add ${net.ip6.prefix} dev ${cfg.netname}
+      ''}
+    '';
+  });
 
 in out
diff --git a/krebs/3modules/shared/default.nix b/krebs/3modules/shared/default.nix
index ccd15b569..47767d370 100644
--- a/krebs/3modules/shared/default.nix
+++ b/krebs/3modules/shared/default.nix
@@ -12,8 +12,8 @@ let
     cores = 1;
     nets = {
       retiolum = {
-        addrs4 = ["10.243.111.111"];
-        addrs6 = ["42:0:0:0:0:0:0:7357"];
+        ip4.addr = "10.243.111.111";
+        ip6.addr = "42:0:0:0:0:0:0:7357";
         aliases = [
           "test.r"
           "test.retiolum"
@@ -36,7 +36,7 @@ in {
     wolf = {
       nets = {
         shack = {
-          addrs4 = [ "10.42.2.150" ];
+          ip4.addr =  "10.42.2.150" ;
           aliases = [
             "wolf.shack"
             "graphite.shack"
@@ -45,8 +45,8 @@ in {
           ];
         };
         retiolum = {
-          addrs4 = ["10.243.77.1"];
-          addrs6 = ["42:0:0:0:0:0:77:1"];
+          ip4.addr = "10.243.77.1";
+          ip6.addr = "42:0:0:0:0:0:77:1";
           aliases = [
             "wolf.retiolum"
             "cgit.wolf.retiolum"
diff --git a/krebs/3modules/tv/default.nix b/krebs/3modules/tv/default.nix
index 13d3163c0..12aa91ba8 100644
--- a/krebs/3modules/tv/default.nix
+++ b/krebs/3modules/tv/default.nix
@@ -13,15 +13,15 @@ with config.krebs.lib;
         # TODO generate krebsco.de zone from nets and don't use extraZones at all
         "krebsco.de" = ''
           krebsco.de. 60 IN MX 5 mx23
-          mx23        60 IN A ${elemAt nets.internet.addrs4 0}
-          cd          60 IN A ${elemAt nets.internet.addrs4 0}
-          cgit        60 IN A ${elemAt nets.internet.addrs4 0}
-          cgit.cd     60 IN A ${elemAt nets.internet.addrs4 0}
+          mx23        60 IN A ${nets.internet.ip4.addr}
+          cd          60 IN A ${nets.internet.ip4.addr}
+          cgit        60 IN A ${nets.internet.ip4.addr}
+          cgit.cd     60 IN A ${nets.internet.ip4.addr}
         '';
       };
       nets = rec {
         internet = {
-          addrs4 = ["162.219.7.216"];
+          ip4.addr = "45.62.237.203";
           aliases = [
             "cd.i"
             "cd.internet"
@@ -34,8 +34,8 @@ with config.krebs.lib;
         };
         retiolum = {
           via = internet;
-          addrs4 = ["10.243.113.222"];
-          addrs6 = ["42:4522:25f8:36bb:8ccb:0150:231a:2af3"];
+          ip4.addr = "10.243.113.222";
+          ip6.addr = "42:4522:25f8:36bb:8ccb:0150:231a:2af3";
           aliases = [
             "cd.r"
             "cd.retiolum"
@@ -66,7 +66,7 @@ with config.krebs.lib;
       cores = 1;
       nets = rec {
         internet = {
-          addrs4 = ["104.167.114.142"];
+          ip4.addr = "104.167.114.142";
           aliases = [
             "mkdir.i"
             "mkdir.internet"
@@ -74,8 +74,8 @@ with config.krebs.lib;
         };
         retiolum = {
           via = internet;
-          addrs4 = ["10.243.113.223"];
-          addrs6 = ["42:4522:25f8:36bb:8ccb:0150:231a:2af4"];
+          ip4.addr = "10.243.113.223";
+          ip6.addr = "42:4522:25f8:36bb:8ccb:0150:231a:2af4";
           aliases = [
             "mkdir.r"
             "mkdir.retiolum"
@@ -101,12 +101,12 @@ with config.krebs.lib;
       extraZones = {
         # TODO generate krebsco.de zone from nets and don't use extraZones at all
         "krebsco.de" = ''
-          ire 60 IN A ${elemAt nets.internet.addrs4 0}
+          ire 60 IN A ${nets.internet.ip4.addr}
         '';
       };
       nets = rec {
         internet = {
-          addrs4 = ["198.147.22.115"];
+          ip4.addr = "198.147.22.115";
           aliases = [
             "ire.i"
             "ire.internet"
@@ -116,8 +116,8 @@ with config.krebs.lib;
         };
         retiolum = {
           via = internet;
-          addrs4 = ["10.243.231.66"];
-          addrs6 = ["42:b912:0f42:a82d:0d27:8610:e89b:490c"];
+          ip4.addr = "10.243.231.66";
+          ip6.addr = "42:b912:0f42:a82d:0d27:8610:e89b:490c";
           aliases = [
             "ire.r"
             "ire.retiolum"
@@ -140,7 +140,7 @@ with config.krebs.lib;
     kaepsele = {
       nets = {
         internet = {
-          addrs4 = ["92.222.10.169"];
+          ip4.addr = "92.222.10.169";
           aliases = [
             "kaepsele.i"
             "kaepsele.internet"
@@ -148,8 +148,8 @@ with config.krebs.lib;
           ];
         };
         retiolum = {
-          addrs4 = ["10.243.166.2"];
-          addrs6 = ["42:0b9d:6660:d07c:2bb7:4e91:1a01:2e7d"];
+          ip4.addr = "10.243.166.2";
+          ip6.addr = "42:0b9d:6660:d07c:2bb7:4e91:1a01:2e7d";
           aliases = [
             "kaepsele.r"
             "kaepsele.retiolum"
@@ -172,8 +172,8 @@ with config.krebs.lib;
       cores = 2;
       nets = {
         retiolum = {
-          addrs4 = ["10.243.20.1"];
-          addrs6 = ["42:0:0:0:0:0:0:2001"];
+          ip4.addr = "10.243.20.1";
+          ip6.addr = "42:0:0:0:0:0:0:2001";
           aliases = [
             "mu.r"
             "mu.retiolum"
@@ -197,13 +197,13 @@ with config.krebs.lib;
       cores = 2;
       nets = rec {
         gg23 = {
-          addrs4 = ["10.23.1.110"];
+          ip4.addr = "10.23.1.110";
           aliases = ["nomic.gg23"];
           ssh.port = 11423;
         };
         retiolum = {
-          addrs4 = ["10.243.0.110"];
-          addrs6 = ["42:02d5:733f:d6da:c0f5:2bb7:2b18:09ec"];
+          ip4.addr = "10.243.0.110";
+          ip6.addr = "42:02d5:733f:d6da:c0f5:2bb7:2b18:09ec";
           aliases = [
             "nomic.r"
             "nomic.retiolum"
@@ -229,7 +229,7 @@ with config.krebs.lib;
     ok = {
       nets = {
         gg23 = {
-          addrs4 = ["10.23.1.1"];
+          ip4.addr = "10.23.1.1";
           aliases = ["ok.gg23"];
         };
       };
@@ -238,7 +238,7 @@ with config.krebs.lib;
       cores = 1;
       nets = rec {
         internet = {
-          addrs4 = ["167.88.34.182"];
+          ip4.addr = "167.88.34.182";
           aliases = [
             "rmdir.i"
             "rmdir.internet"
@@ -246,8 +246,8 @@ with config.krebs.lib;
         };
         retiolum = {
           via = internet;
-          addrs4 = ["10.243.113.224"];
-          addrs6 = ["42:4522:25f8:36bb:8ccb:0150:231a:2af5"];
+          ip4.addr = "10.243.113.224";
+          ip6.addr = "42:4522:25f8:36bb:8ccb:0150:231a:2af5";
           aliases = [
             "rmdir.r"
             "rmdir.retiolum"
@@ -272,7 +272,7 @@ with config.krebs.lib;
     schnabeldrucker = {
       nets = {
         gg23 = {
-          addrs4 = ["10.23.1.21"];
+          ip4.addr = "10.23.1.21";
           aliases = ["schnabeldrucker.gg23"];
         };
       };
@@ -280,7 +280,7 @@ with config.krebs.lib;
     schnabelscanner = {
       nets = {
         gg23 = {
-          addrs4 = ["10.23.1.22"];
+          ip4.addr = "10.23.1.22";
           aliases = ["schnabelscanner.gg23"];
         };
       };
@@ -289,7 +289,7 @@ with config.krebs.lib;
       cores = 4;
       nets = {
         gg23 = {
-          addrs4 = ["10.23.1.37"];
+          ip4.addr = "10.23.1.37";
           aliases = [
             "wu.gg23"
             "cache.wu.gg23"
@@ -297,8 +297,8 @@ with config.krebs.lib;
           ssh.port = 11423;
         };
         retiolum = {
-          addrs4 = ["10.243.13.37"];
-          addrs6 = ["42:0:0:0:0:0:0:1337"];
+          ip4.addr = "10.243.13.37";
+          ip6.addr = "42:0:0:0:0:0:0:1337";
           aliases = [
             "wu.r"
             "wu.retiolum"
@@ -325,13 +325,13 @@ with config.krebs.lib;
       cores = 4;
       nets = {
         gg23 = {
-          addrs4 = ["10.23.1.38"];
+          ip4.addr = "10.23.1.38";
           aliases = ["xu.gg23"];
           ssh.port = 11423;
         };
         retiolum = {
-          addrs4 = ["10.243.13.38"];
-          addrs6 = ["42:0:0:0:0:0:0:1338"];
+          ip4.addr = "10.243.13.38";
+          ip6.addr = "42:0:0:0:0:0:0:1338";
           aliases = [
             "xu.r"
             "xu.retiolum"
@@ -355,13 +355,14 @@ with config.krebs.lib;
   };
   users = rec {
     mv = {
-      mail = "mv@cd.retiolum";
+      mail = "mv@cd.r";
       pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGer9e2+Lew7vnisgBbsFNECEIkpNJgEaqQqgb9inWkQ mv@vod";
     };
     tv = {
-      mail = "tv@nomic.retiolum";
+      mail = "tv@nomic.r";
       pgp.pubkeys.default = ''
         -----BEGIN PGP PUBLIC KEY BLOCK-----
+
         mQINBFbJ/B0BEADZx8l5gRurzhEHcc3PbBepdZqDJQZ2cGHixi8VEk9iN25qJO5y
         HB0q5sQRsh7oNCbzKp6qRhaG9kXmEda+Uu+qbHWxE32QcT76+W8npH73qthaFwC/
         5RA8KcSE8/XFxVBnVb14PNVHyAVxPHawawbhsOeaiZcHrq5IF6sVzcsc2KN87sIE
diff --git a/krebs/4lib/types.nix b/krebs/4lib/types.nix
index 7255dc3e1..56d1d55c3 100644
--- a/krebs/4lib/types.nix
+++ b/krebs/4lib/types.nix
@@ -63,34 +63,62 @@ types // rec {
 
   net = submodule ({ config, ... }: {
     options = {
+      name = mkOption {
+        type = label;
+        default = config._module.args.name;
+      };
       via = mkOption {
         type = nullOr net;
         default = null;
       };
       addrs = mkOption {
         type = listOf addr;
-        default = config.addrs4 ++ config.addrs6;
-        # TODO only default addrs make sense
-      };
-      addrs4 = mkOption {
-        type = listOf addr4;
-        default = [];
-      };
-      addrs6 = mkOption {
-        type = listOf addr6;
-        default = [];
+        default =
+          optional (config.ip4 != null) config.ip4.addr ++
+          optional (config.ip6 != null) config.ip6.addr;
+        readOnly = true;
       };
       aliases = mkOption {
         # TODO nonEmptyListOf hostname
         type = listOf hostname;
         default = [];
       };
+      ip4 = mkOption {
+        type = nullOr (submodule {
+          options = {
+            addr = mkOption {
+              type = addr4;
+            };
+            prefix = mkOption ({
+              type = str; # TODO routing prefix (CIDR)
+            } // optionalAttrs (config.name == "retiolum") {
+              default = "10.243.0.0/16";
+            });
+          };
+        });
+        default = null;
+      };
+      ip6 = mkOption {
+        type = nullOr (submodule {
+          options = {
+            addr = mkOption {
+              type = addr6;
+            };
+            prefix = mkOption ({
+              type = str; # TODO routing prefix (CIDR)
+            } // optionalAttrs (config.name == "retiolum") {
+              default = "42::/16";
+            });
+          };
+        });
+        default = null;
+      };
       ssh = mkOption {
         type = submodule {
           options = {
             port = mkOption {
-              type = nullOr int;
-              default = null;
+              type = int;
+              default = 22;
             };
           };
         };
@@ -185,6 +213,18 @@ types // rec {
       };
     };
   });
+  group = submodule ({ config, ... }: {
+    options = {
+      name = mkOption {
+        type = username;
+        default = config._module.args.name;
+      };
+      gid = mkOption {
+        type = int;
+        default = genid config.name;
+      };
+    };
+  });
 
   addr = either addr4 addr6;
   addr4 = mkOptionType {
@@ -192,10 +232,17 @@ types // rec {
     check = let
       IPv4address = let d = "([1-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"; in
         concatMapStringsSep "." (const d) (range 1 4);
-    in x: match IPv4address != null;
+    in x: match IPv4address x != null;
+    merge = mergeOneOption;
+  };
+  addr6 = mkOptionType {
+    name = "IPv6 address";
+    check = let
+      # TODO check IPv6 address harder
+      IPv6address = "[0-9a-f.:]+";
+    in x: match IPv6address x != null;
     merge = mergeOneOption;
   };
-  addr6 = str; # TODO
 
   pgp-pubkey = str;
 
diff --git a/krebs/5pkgs/builders.nix b/krebs/5pkgs/builders.nix
index 146e6f9e1..70d65cfc3 100644
--- a/krebs/5pkgs/builders.nix
+++ b/krebs/5pkgs/builders.nix
@@ -56,6 +56,14 @@ rec {
     '';
   };
 
+  writeEximConfig = name: text: pkgs.runCommand name {
+    inherit text;
+    passAsFile = [ "text" ];
+  } ''
+    ${pkgs.exim}/bin/exim -C "$textPath" -bV >/dev/null
+    mv "$textPath" $out
+  '';
+
   writeNixFromCabal = name: path: pkgs.runCommand name {} ''
     ${pkgs.cabal2nix}/bin/cabal2nix ${path} > $out
   '';
diff --git a/krebs/5pkgs/default.nix b/krebs/5pkgs/default.nix
index 0c39324a7..bcc894b2c 100644
--- a/krebs/5pkgs/default.nix
+++ b/krebs/5pkgs/default.nix
@@ -14,7 +14,12 @@ with config.krebs.lib;
       then trace "Upstream `${upstream.name}' gets overridden by `${override.name}'." override
       else override;
 
-  in {
+  in {}
+  // import ./builders.nix args
+  // mapAttrs (_: flip callPackage {})
+              (filterAttrs (_: dir.has-default-nix)
+                           (subdirsOf ./.))
+  // {
     haskellPackages = pkgs.haskellPackages.override {
       overrides = self: super:
         mapAttrs (name: path: self.callPackage path {})
@@ -29,18 +34,10 @@ with config.krebs.lib;
             (builtins.readDir ./haskell-overrides));
     };
 
-    push = callPackage ./push {
-      inherit (subdirs) get;
-    };
-
     ReaktorPlugins = callPackage ./Reaktor/plugins.nix {};
 
     test = {
       infest-cac-centos7 = callPackage ./test/infest-cac-centos7 {};
     };
-  }
-  // import ./builders.nix args
-  // mapAttrs (_: flip callPackage {})
-              (filterAttrs (_: dir.has-default-nix)
-                           (subdirsOf ./.));
+  };
 }
diff --git a/lass/1systems/cloudkrebs.nix b/lass/1systems/cloudkrebs.nix
index 98f509050..6cfba567a 100644
--- a/lass/1systems/cloudkrebs.nix
+++ b/lass/1systems/cloudkrebs.nix
@@ -2,9 +2,8 @@
 
 let
   inherit (import ../4lib { inherit pkgs lib; }) getDefaultGateway;
-  inherit (lib) head;
 
-  ip = (head config.krebs.build.host.nets.internet.addrs4);
+  ip = config.krebs.build.host.nets.internet.ip4.addr;
 in {
   imports = [
     ../.
diff --git a/lass/1systems/echelon.nix b/lass/1systems/echelon.nix
index 2ff6dba70..80611ee80 100644
--- a/lass/1systems/echelon.nix
+++ b/lass/1systems/echelon.nix
@@ -2,9 +2,8 @@
 
 let
   inherit (import ../4lib { inherit pkgs lib; }) getDefaultGateway;
-  inherit (lib) head;
 
-  ip = (head config.krebs.build.host.nets.internet.addrs4);
+  ip = config.krebs.build.host.nets.internet.ip4.addr;
 in {
   imports = [
     ../.
diff --git a/lass/1systems/prism.nix b/lass/1systems/prism.nix
index 4d40c8d59..20c919b9b 100644
--- a/lass/1systems/prism.nix
+++ b/lass/1systems/prism.nix
@@ -1,9 +1,7 @@
 { config, lib, pkgs, ... }:
 
 let
-  inherit (lib) head;
-
-  ip = (head config.krebs.build.host.nets.internet.addrs4);
+  ip = config.krebs.build.host.nets.internet.ip4.addr;
 in {
   imports = [
     ../.
diff --git a/lass/2configs/privoxy-retiolum.nix b/lass/2configs/privoxy-retiolum.nix
index 3a3641ad8..9059bbac8 100644
--- a/lass/2configs/privoxy-retiolum.nix
+++ b/lass/2configs/privoxy-retiolum.nix
@@ -1,8 +1,7 @@
 { config, lib, ... }:
 
 let
-  r_ip = (head config.krebs.build.host.nets.retiolum.addrs4);
-  inherit (lib) head;
+  r_ip = config.krebs.build.host.nets.retiolum.ip4.addr;
 
 in {
   imports = [
diff --git a/lass/3modules/static_nginx.nix b/lass/3modules/static_nginx.nix
index 6e87e9853..6b5d19615 100644
--- a/lass/3modules/static_nginx.nix
+++ b/lass/3modules/static_nginx.nix
@@ -54,7 +54,7 @@ let
   user = config.services.nginx.user;
   group = config.services.nginx.group;
 
-  external-ip = head config.krebs.build.host.nets.internet.addrs4;
+  external-ip = config.krebs.build.host.nets.internet.ip4.addr;
 
   imp = {
     krebs.nginx.servers = flip mapAttrs cfg ( name: { domain, folder, ssl, ... }: {
diff --git a/makefu/1systems/gum.nix b/makefu/1systems/gum.nix
index 96a5f4854..17b2b5093 100644
--- a/makefu/1systems/gum.nix
+++ b/makefu/1systems/gum.nix
@@ -2,8 +2,8 @@
 
 with config.krebs.lib;
 let
-  external-ip = head config.krebs.build.host.nets.internet.addrs4;
-  internal-ip = head config.krebs.build.host.nets.retiolum.addrs4;
+  external-ip = config.krebs.build.host.nets.internet.ip4.addr;
+  internal-ip = config.krebs.build.host.nets.retiolum.ip4.addr;
 in {
   imports = [
       ../.
diff --git a/makefu/1systems/wry.nix b/makefu/1systems/wry.nix
index edaf1b803..d9f8ded83 100644
--- a/makefu/1systems/wry.nix
+++ b/makefu/1systems/wry.nix
@@ -3,8 +3,8 @@
 with config.krebs.lib;
 let
 
-  external-ip = head config.krebs.build.host.nets.internet.addrs4;
-  internal-ip = head config.krebs.build.host.nets.retiolum.addrs4;
+  external-ip = config.krebs.build.host.nets.internet.ip4.addr;
+  internal-ip = config.krebs.build.host.nets.retiolum.ip4.addr;
 in {
   imports = [
       ../.
diff --git a/makefu/2configs/deployment/mycube.connector.one.nix b/makefu/2configs/deployment/mycube.connector.one.nix
index 125b3dfff..8f51c91dd 100644
--- a/makefu/2configs/deployment/mycube.connector.one.nix
+++ b/makefu/2configs/deployment/mycube.connector.one.nix
@@ -3,7 +3,7 @@
 with config.krebs.lib;
 let
   hostname = config.krebs.build.host.name;
-  external-ip = head config.krebs.build.host.nets.internet.addrs4;
+  external-ip = config.krebs.build.host.nets.internet.ip4.addr;
   wsgi-sock = "${config.services.uwsgi.runDir}/uwsgi.sock";
 in {
   services.redis.enable = true;
diff --git a/makefu/2configs/iodined.nix b/makefu/2configs/iodined.nix
index 2e69d167c..d57c91ce8 100644
--- a/makefu/2configs/iodined.nix
+++ b/makefu/2configs/iodined.nix
@@ -10,7 +10,7 @@ in {
     enable = true;
     domain = domain;
     ip = "172.16.10.1/24";
-    extraConfig = "-P ${pw} -l ${pkgs.lib.head config.krebs.build.host.nets.internet.addrs4}";
+    extraConfig = "-P ${pw} -l ${config.krebs.build.host.nets.internet.ip4.addr}";
   };
 
 }
diff --git a/makefu/2configs/nginx/euer.blog.nix b/makefu/2configs/nginx/euer.blog.nix
index 9d08f4b9a..137c0b0e3 100644
--- a/makefu/2configs/nginx/euer.blog.nix
+++ b/makefu/2configs/nginx/euer.blog.nix
@@ -8,8 +8,8 @@ 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;
+  external-ip = config.krebs.build.host.nets.internet.ip4.addr;
+  internal-ip = config.krebs.build.host.nets.retiolum.ip4.addr;
   base-dir = "/var/www/blog.euer";
 in {
   # Prepare Blog directory
diff --git a/makefu/2configs/nginx/euer.test.nix b/makefu/2configs/nginx/euer.test.nix
index f7214e613..84b9bacda 100644
--- a/makefu/2configs/nginx/euer.test.nix
+++ b/makefu/2configs/nginx/euer.test.nix
@@ -5,8 +5,8 @@ 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;
+  external-ip = config.krebs.build.host.nets.internet.ip4.addr;
+  internal-ip = config.krebs.build.host.nets.retiolum.ip4.addr;
 in {
   krebs.nginx = {
     enable = mkDefault true;
diff --git a/makefu/2configs/nginx/euer.wiki.nix b/makefu/2configs/nginx/euer.wiki.nix
index a5572a519..10985c833 100644
--- a/makefu/2configs/nginx/euer.wiki.nix
+++ b/makefu/2configs/nginx/euer.wiki.nix
@@ -18,8 +18,8 @@ let
   #  user1 = pass1
   #  userN = passN
   tw-pass-file = "${sec}/tw-pass.ini";
-  external-ip = head config.krebs.build.host.nets.internet.addrs4;
-  internal-ip = head config.krebs.build.host.nets.retiolum.addrs4;
+  external-ip = config.krebs.build.host.nets.internet.ip4.addr;
+  internal-ip = config.krebs.build.host.nets.retiolum.ip4.addr;
 in {
   services.phpfpm = {
     # phpfpm does not have an enable option
diff --git a/makefu/2configs/nginx/update.connector.one.nix b/makefu/2configs/nginx/update.connector.one.nix
index ac5e6b17b..dde3e3a64 100644
--- a/makefu/2configs/nginx/update.connector.one.nix
+++ b/makefu/2configs/nginx/update.connector.one.nix
@@ -3,7 +3,7 @@
 with config.krebs.lib;
 let
   hostname = config.krebs.build.host.name;
-  external-ip = head config.krebs.build.host.nets.internet.addrs4;
+  external-ip = config.krebs.build.host.nets.internet.ip4.addr;
 in {
   krebs.nginx = {
     enable = mkDefault true;
diff --git a/makefu/2configs/omo-share.nix b/makefu/2configs/omo-share.nix
index b4bc710c0..7e9842e14 100644
--- a/makefu/2configs/omo-share.nix
+++ b/makefu/2configs/omo-share.nix
@@ -5,7 +5,7 @@ let
   hostname = config.krebs.build.host.name;
   # TODO local-ip from the nets config
   local-ip = "192.168.1.11";
-  # local-ip = head config.krebs.build.host.nets.retiolum.addrs4;
+  # local-ip = config.krebs.build.host.nets.retiolum.ip4.addr;
 in {
   krebs.nginx = {
     enable = mkDefault true;
diff --git a/shared/1systems/test-all-krebs-modules.nix b/shared/1systems/test-all-krebs-modules.nix
index 5c3ba9421..0084a7837 100644
--- a/shared/1systems/test-all-krebs-modules.nix
+++ b/shared/1systems/test-all-krebs-modules.nix
@@ -19,10 +19,11 @@ in {
       username = "lol";
       password = "wut";
     };
-    exim-retiolum = {
-      enable = true;
-      primary_hostname = "test.r";
-    };
+    # XXX exim-retiolum and exim-smarthost are mutually exclusive
+    #exim-retiolum = {
+    #  enable = true;
+    #  primary_hostname = "test.r";
+    #};
     exim-smarthost = {
       enable = true;
       primary_hostname = "test.r";
diff --git a/shared/1systems/wolf.nix b/shared/1systems/wolf.nix
index f0323dc2f..53334d6f1 100644
--- a/shared/1systems/wolf.nix
+++ b/shared/1systems/wolf.nix
@@ -1,8 +1,8 @@
 { config, lib, pkgs, ... }:
 
 let
-  shack-ip = lib.head config.krebs.build.host.nets.shack.addrs4;
-  internal-ip = lib.head config.krebs.build.host.nets.retiolum.addrs4;
+  shack-ip = config.krebs.build.host.nets.shack.ip4.addr;
+  internal-ip = config.krebs.build.host.nets.retiolum.ip4.addr;
 in
 {
   imports = [
diff --git a/tv/1systems/cd.nix b/tv/1systems/cd.nix
index 687f17951..32d956b8a 100644
--- a/tv/1systems/cd.nix
+++ b/tv/1systems/cd.nix
@@ -61,16 +61,16 @@ with config.krebs.lib;
     }
   ];
 
-  networking.interfaces.enp2s1.ip4 = [
-    {
-      address = "162.219.7.216";
+  networking = {
+    interfaces.enp2s1.ip4 = singleton {
+      address = let
+        addr = "45.62.237.203";
+      in assert config.krebs.build.host.nets.internet.ip4.addr == addr; addr;
       prefixLength = 24;
-    }
-  ];
-  networking.defaultGateway = "162.219.7.1";
-  networking.nameservers = [
-    "8.8.8.8"
-  ];
+    };
+    defaultGateway = "45.62.237.1";
+    nameservers = ["8.8.8.8"];
+  };
 
   environment.systemPackages = with pkgs; [
     htop
diff --git a/tv/1systems/mkdir.nix b/tv/1systems/mkdir.nix
index 58a8fdcb2..f46ed9547 100644
--- a/tv/1systems/mkdir.nix
+++ b/tv/1systems/mkdir.nix
@@ -7,12 +7,7 @@ let
   getDefaultGateway = ip:
     concatStringsSep "." (take 3 (splitString "." ip) ++ ["1"]);
 
-
-  primary-addr4 =
-    builtins.elemAt config.krebs.build.host.nets.internet.addrs4 0;
-
-  #secondary-addr4 =
-  #  builtins.elemAt config.krebs.build.host.nets.internet.addrs4 1;
+  primary-addr4 = config.krebs.build.host.nets.internet.ip4.addr;
 in
 
 {
@@ -55,10 +50,6 @@ in
       address = primary-addr4;
       prefixLength = 24;
     }
-    #{
-    #  address = secondary-addr4;
-    #  prefixLength = 24;
-    #}
   ];
 
   # TODO define gateway in krebs/3modules/default.nix
diff --git a/tv/1systems/rmdir.nix b/tv/1systems/rmdir.nix
index c54caa649..25fae2c36 100644
--- a/tv/1systems/rmdir.nix
+++ b/tv/1systems/rmdir.nix
@@ -7,12 +7,7 @@ let
   getDefaultGateway = ip:
     concatStringsSep "." (take 3 (splitString "." ip) ++ ["1"]);
 
-
-  primary-addr4 =
-    builtins.elemAt config.krebs.build.host.nets.internet.addrs4 0;
-
-  #secondary-addr4 =
-  #  builtins.elemAt config.krebs.build.host.nets.internet.addrs4 1;
+  primary-addr4 = config.krebs.build.host.nets.internet.ip4.addr;
 in
 
 {
diff --git a/tv/1systems/wu.nix b/tv/1systems/wu.nix
index 27dd12520..cebd7c9e4 100644
--- a/tv/1systems/wu.nix
+++ b/tv/1systems/wu.nix
@@ -183,7 +183,5 @@ with config.krebs.lib;
     KERNEL=="hpet", GROUP="audio"
   '';
 
-  services.tor.client.enable = true;
-  services.tor.enable = true;
   services.virtualboxHost.enable = true;
 }
diff --git a/tv/2configs/exim-retiolum.nix b/tv/2configs/exim-retiolum.nix
index dbe83dcf1..9197a3c30 100644
--- a/tv/2configs/exim-retiolum.nix
+++ b/tv/2configs/exim-retiolum.nix
@@ -4,9 +4,5 @@ with config.krebs.lib;
 
 {
   krebs.exim-retiolum.enable = true;
-  krebs.setuid.sendmail = {
-    filename = "${pkgs.exim}/bin/exim";
-    mode = "4111";
-  };
   tv.iptables.input-retiolum-accept-new-tcp = singleton "smtp";
 }
diff --git a/tv/2configs/exim-smarthost.nix b/tv/2configs/exim-smarthost.nix
index 280d8572b..3616a8f52 100644
--- a/tv/2configs/exim-smarthost.nix
+++ b/tv/2configs/exim-smarthost.nix
@@ -13,7 +13,7 @@ with config.krebs.lib;
       "shackspace.de"
       "viljetic.de"
     ];
-    relay_from_hosts = concatMap (host: host.nets.retiolum.addrs4) [
+    relay_from_hosts = map (host: host.nets.retiolum.ip4.addr) [
       config.krebs.hosts.nomic
       config.krebs.hosts.wu
       config.krebs.hosts.xu
@@ -43,9 +43,5 @@ with config.krebs.lib;
       { from = "mirko"; to = "mv"; }
     ];
   };
-  krebs.setuid.sendmail = {
-    filename = "${pkgs.exim}/bin/exim";
-    mode = "4111";
-  };
   tv.iptables.input-internet-accept-new-tcp = singleton "smtp";
 }
diff --git a/tv/2configs/git.nix b/tv/2configs/git.nix
index 4c1fba59a..2e5fc301b 100644
--- a/tv/2configs/git.nix
+++ b/tv/2configs/git.nix
@@ -71,13 +71,13 @@ let
   make-public-repo = name: { desc ? null, section ? null, ... }: {
     inherit name desc section;
     public = true;
-    hooks = {
+    hooks = optionalAttrs (config.krebs.build.host.name == "cd") {
       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 == "cd";
+        verbose = true;
       };
     };
   };
diff --git a/tv/3modules/charybdis/config.nix b/tv/3modules/charybdis/config.nix
index e4d754ff3..1b160926c 100644
--- a/tv/3modules/charybdis/config.nix
+++ b/tv/3modules/charybdis/config.nix
@@ -56,9 +56,9 @@ in toFile "charybdis.conf" ''
     /* On multi-homed hosts you may need the following. These define
      * the addresses we connect from to other servers. */
     /* for IPv4 */
-    vhost = ${concatMapStringsSep ", " toJSON config.krebs.build.host.nets.retiolum.addrs4};
+    vhost = ${toJSON config.krebs.build.host.nets.retiolum.ip4.addr};
     /* for IPv6 */
-    vhost6 = ${concatMapStringsSep ", " toJSON config.krebs.build.host.nets.retiolum.addrs6};
+    vhost6 = ${toJSON config.krebs.build.host.nets.retiolum.ip6.addr};
 
     /* ssl_private_key: our ssl private key */
     ssl_private_key = ${toJSON cfg.ssl_private_key.path};
@@ -160,10 +160,7 @@ in toFile "charybdis.conf" ''
     /* If you want to listen on a specific IP only, specify host.
      * host definitions apply only to the following port line.
      */
-    # XXX This is stupid because only one host is allowed[?]
-    #host = ''${concatMapStringsSep ", " toJSON (
-    #  config.krebs.build.host.nets.retiolum.addrs
-    #)};
+    #host = ${toJSON config.krebs.build.host.nets.retiolum.ip4.addr};
     port = ${toString cfg.port};
     sslport = ${toString cfg.sslport};
   };