ctucx.git: nixfiles

ctucx' nixfiles

commit e944cd0130920993e257a64e20ab1106bfa7a293
parent 0f8cb14e3494f7fecb7c4eec54efe4dd29ea6d98
Author: Leah (ctucx) <git@ctu.cx>
Date: Fri, 28 Jun 2024 12:57:20 +0200

machines/briefkasten: act as router
13 files changed, 425 insertions(+), 102 deletions(-)
M
machines/briefkasten/default.nix
|
98
++++++++-----------------------------------------------------------------------
M
machines/briefkasten/gotosocial.nix
|
3
++-
A
machines/briefkasten/router/default.nix
|
23
+++++++++++++++++++++++
A
machines/briefkasten/router/dnsmasq.nix
|
117
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A
machines/briefkasten/router/nftables.nix
|
15
+++++++++++++++
A
machines/briefkasten/router/ruleset.nft
|
88
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A
machines/briefkasten/router/systemd-networkd.nix
|
151
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
M
machines/briefkasten/smarthome/influxdb2.nix
|
3
++-
M
machines/briefkasten/smarthome/mqtt-webui/default.nix
|
3
++-
M
machines/briefkasten/websites/audiobooks.home.ctu.cx.nix
|
3
++-
M
machines/briefkasten/websites/music.home.ctu.cx.nix
|
3
++-
M
machines/briefkasten/websites/wiki.home.ctu.cx.nix
|
3
++-
M
secrets/briefkasten/wireguard-privkey.age
|
17
+++++++++--------
diff --git a/machines/briefkasten/default.nix b/machines/briefkasten/default.nix
@@ -21,30 +21,22 @@
 
     ./scanner-sftp.nix
 
+    ./router
+
     ./websites
   ];
 
-  dns.zones."ctu.cx".subdomains."${config.networking.hostName}.home"  = lib.mkIf config.networking.usePBBUplink (pkgs.dns.lib.combinators.host config.networking.primaryIP4 config.networking.primaryIP);
-  dns.zones."ctu.cx".subdomains."${config.networking.hostName}".CNAME = lib.mkIf config.networking.usePBBUplink [ "${config.networking.hostName}.home" ];
-  dns.zones."ctu.cx".subdomains."home".CNAME                          = lib.mkIf config.networking.usePBBUplink [ "${config.networking.hostName}.home" ];
+  # dns.zones."ctu.cx".subdomains."${config.networking.hostName}.home"  = (pkgs.dns.lib.combinators.host config.networking.primaryIP4 config.networking.primaryIP);
+  # dns.zones."ctu.cx".subdomains."${config.networking.hostName}".CNAME = [ "${config.networking.hostName}.home" ];
+  # dns.zones."ctu.cx".subdomains."home".CNAME                          = [ "${config.networking.hostName}.home" ];
 
   age.secrets = {
     restic-server-briefkasten.file = ../../secrets/restic-server/briefkasten.age;
     restic-server-wanderduene.file = ../../secrets/restic-server/wanderduene.age;
-
-    wireguard-privkey.file         = ./. + "/../../secrets/${config.networking.hostName}/wireguard-privkey.age";
   };
 
   boot = {
 
-    kernel.sysctl = {
-      "net.ipv6.conf.all.forwarding"    = true;
-      "net.ipv4.conf.all.forwarding"    = true;
-      "net.ipv6.conf.enp1s0.forwarding" = lib.mkIf config.networking.usePBBUplink 0;
-      "net.ipv6.conf.enp1s0.autoconf"   = lib.mkIf config.networking.usePBBUplink 0;
-      "net.ipv6.conf.enp1s0.accept_ra"  = lib.mkIf config.networking.usePBBUplink 0;
-    };
-
     kernelModules = [ "intel_rapl_common" ];
 
     # seems to make realtek ethernet faster?

@@ -78,11 +70,11 @@
 
         ip addr add ${config.networking.primaryIP4}/28 dev enp1s0
         ip addr add ${config.networking.secondaryIP4}/8 dev enp1s0
-        ip route add default via 195.39.246.41 dev enp1s0 onlink
+#        ip route add default via 195.39.246.41 dev enp1s0 onlink
 
       '' + lib.optionalString config.networking.usePBBUplink ''
         ip addr add ${config.networking.primaryIP}/128 dev enp1s0
-        ip route add default via 2a0f:4ac0:acab::1 dev enp1s0 onlink
+#        ip route add default via 2a0f:4ac0:acab::1 dev enp1s0 onlink
       '';
     };
 

@@ -113,81 +105,11 @@
     useNetworkd  = true;
     usePBBUplink = true;
 
-    primaryIP    = "2a0f:4ac0:acab::45";
-    primaryIP4   = "195.39.246.45";
-    secondaryIP4 = "10.0.0.45";
+    primaryIP    = "2a0f:4ac0:acab::1";
+    primaryIP4   = "195.39.246.42";
+    secondaryIP4 = "10.0.0.1";
 
     domain       = "home.ctu.cx";
-
-    nameservers  = [ "195.39.246.41" "2a0f:4ac0:acab::1" ];
-
-    defaultGateway.address   = "195.39.246.41";
-    defaultGateway.interface = "enp1s0";
-
-    defaultGateway6 = lib.mkIf config.networking.usePBBUplink{
-      address   = "2a0f:4ac0:acab::1";
-      interface = "enp1s0";
-    };
-
-    vlans.vlan10 = {
-      id        = 10;
-      interface = "enp1s0";
-    };
-
-    bridges.bruplink = {
-      interfaces = [ "vlan10" "iphone" ];
-    };
-
-    interfaces.enp1s0 = {
-      ipv4.addresses = [
-        (lib.mkIf config.networking.usePBBUplink {
-          address = config.networking.primaryIP4;
-          prefixLength = 28;
-        })
-        {
-          address = config.networking.secondaryIP4;
-          prefixLength = 8;
-        }
-      ];
-
-      ipv6.addresses = lib.mkIf config.networking.usePBBUplink [{
-        address      = config.networking.primaryIP;
-        prefixLength = 62;
-      }];
-    };
-
-    wireguard = {
-      enable = true;
-
-      interfaces.wg-wanderduene = {
-        listenPort             = 51820;
-        privateKeyFile         = config.age.secrets.wireguard-privkey.path;
-        generatePrivateKeyFile = true;
-        postSetup              = "ip link set dev wg-wanderduene mtu 1500";
-        ips                    = [ "172.17.0.2/24" ];
-
-        peers = [
-          {
-            persistentKeepalive = 10;
-            endpoint            = "46.38.253.139:51821";
-            allowedIPs          = [ "172.17.0.0/24" ];
-            publicKey           = "hOUeP8RFchzJXyy8DceTFKN9f1VHi9GzZQii0dX2zww=";
-          }
-        ];
-      };
-    };
-
-    firewall.allowedTCPPorts = [ 5201 ];
-    firewall.allowedUDPPorts = [ 5201 51820 ];
-    firewall.trustedInterfaces = [ "wg-wanderduene" "vlan10" "bruplink" ];
-    firewall.extraCommands = ''
-      iptables  -A nixos-fw -p tcp -s 10.0.0.0/8          -j nixos-fw-accept
-      iptables  -A nixos-fw -p udp -s 10.0.0.0/8          -j nixos-fw-accept
-      iptables  -A nixos-fw -p tcp -s 195.39.246.32/28    -j nixos-fw-accept
-      iptables  -A nixos-fw -p udp -s 195.39.246.32/28    -j nixos-fw-accept
-      ip6tables -A nixos-fw -p tcp -s 2a0f:4ac0:acab::/48 -j nixos-fw-accept
-      ip6tables -A nixos-fw -p udp -s 2a0f:4ac0:acab::/48 -j nixos-fw-accept
-    '';
   };
 
   services = {
diff --git a/machines/briefkasten/gotosocial.nix b/machines/briefkasten/gotosocial.nix
@@ -5,7 +5,8 @@ let
 
 in {
 
-  dns.zones."ctu.cx".subdomains."fedi.home".CNAME = lib.mkIf config.networking.usePBBUplink [ "${config.networking.fqdn}." ];
+#  dns.zones."ctu.cx".subdomains."fedi.home".CNAME = [ "${config.networking.fqdn}." ];
+  services.dnsmasq.settings.cname                 = [ "fedi.home.ctu.cx, ${config.networking.fqdn}" ];
 
   age.secrets.restic-gotosocial.file = ./. + "/../../secrets/${config.networking.hostName}/restic/gotosocial.age";
   age.secrets.gotosocial-env.file    = ./. + "/../../secrets/${config.networking.hostName}/gotosocial-env.age";
diff --git a/machines/briefkasten/router/default.nix b/machines/briefkasten/router/default.nix
@@ -0,0 +1,23 @@
+{ pkgs, ... }:
+
+{
+
+  imports = [
+    ./systemd-networkd.nix
+    ./nftables.nix
+    ./dnsmasq.nix
+  ];
+
+  boot = {
+    kernel.sysctl."net.ipv4.ip_forward"          = true;
+    kernel.sysctl."net.ipv6.conf.all.forwarding" = true;
+  };
+
+  environment.systemPackages = with pkgs; [
+    wireguard-tools
+  ];
+
+  services.avahi.interfaces = [ "brlan" ];
+  networking.useDHCP        = false;
+
+}
diff --git a/machines/briefkasten/router/dnsmasq.nix b/machines/briefkasten/router/dnsmasq.nix
@@ -0,0 +1,117 @@
+{ config, pkgs, ... }:
+
+{
+
+  dns.zones."ctu.cx".subdomains = with pkgs.dns.lib.combinators; {
+    home.NS   = [ "home.ctu.cx." ];
+    home.A    = [ (a "195.39.246.42") ];
+    home.AAAA = [ "2a0f:4ac0:acab::1" ];
+  };
+
+  systemd.services.dnsmasq.onFailure = [ "email-notify@%i.service" ];
+
+  services = {
+
+    resolved.enable = false;
+
+    dnsmasq = {
+      enable      = true;
+      settings = {
+        local-service = true;
+        no-resolv     = true;
+        no-hosts      = true;
+        domain-needed = true;
+        bogus-priv    = true;
+
+        enable-ra     = true;
+        quiet-ra      = true;
+
+        server = [ "1.1.1.1" "1.0.0.1" "8.8.8.8" "8.8.4.4" ];
+
+        local  = "/home.ctu.cx/";
+        domain = "home.ctu.cx";
+
+        auth-ttl    = 600;
+        auth-server = "home.ctu.cx,         195.39.246.42,                     2a0f:4ac0:acab::1";
+        auth-zone   = "home.ctu.cx,         10.0.0.1/24,   195.39.246.32/28,   2a0f:4ac0:acab::1/64";
+
+        host-record = [
+          "home.ctu.cx,                  195.39.246.42,      2a0f:4ac0:acab::1"
+        ];
+
+        cname = [
+          "briefkasten.home.ctu.cx,      home.ctu.cx"
+          "dnsmasq.home.ctu.cx,          home.ctu.cx"
+        ];
+
+        address = [
+          "/briefkasten/10.0.0.1"
+          "/ads1700w/10.0.0.10"
+          "/scanner/10.0.0.10"
+        ];
+
+        dhcp-authoritative = true;
+        dhcp-rapid-commit  = true;
+        dhcp-sequential-ip = true;
+
+        dhcp-range = [
+          "private, 10.0.0.100,          10.0.0.200,                           255.255.255.0,                  48h"
+          "public,  195.39.246.34,       static,                               255.255.255.240, 195.39.246.47, 48h"
+          "         2a0f:4ac0:acab::100, 2a0f:4ac0:acab::01ff, ra-names,slaac, 64,                             48h"
+        ];
+
+        dhcp-option = [
+          "option6:information-refresh-time, 6h"
+          "option6:dns-server,               [2a0f:4ac0:acab::1]"
+
+          "private, option:router,           10.0.0.1"
+          "private, option:dns-server,       10.0.0.1"
+
+          "public,  option:router,           195.39.246.42"
+          "public,  option:dns-server,       195.39.246.42"
+        ];
+
+
+        dhcp-host = [
+          "48:a9:8a:8e:dd:0b,                   accesspoint,        10.0.0.2"
+          "5c:f3:70:b9:35:9c,                   ctux-ads1700w,      10.0.0.10"
+          "34:31:c4:46:88:31,                   pbx,                10.0.0.20"
+
+          "id:bc:6e:e2:03:99:40,                nadia-work,         [2a0f:4ac0:acab::37]"
+          "bc:6e:e2:03:99:40,                   nadia-work,         195.39.246.37"
+
+          "id:1c:57:dc:40:dc:b2,                blechkasten,        [2a0f:4ac0:acab::43]"
+          "1c:57:dc:40:dc:b2,                   blechkasten,        195.39.246.43"
+
+          "id:00:e0:4c:02:13:75,                desktop,            [2a0f:4ac0:acab::44]"
+          "00:e0:4c:02:13:75,                   desktop,            195.39.246.44"
+
+          "id:f4:3b:d8:cb:7c:49,                coladose,           [2a0f:4ac0:acab::45]"
+          "f4:3b:d8:cb:7c:49,                   coladose,           195.39.246.45"
+        ];
+      };
+    };
+
+    fcgiwrap.enable = true;
+
+    nginx = {
+      enable = true;
+      virtualHosts."dnsmasq.home.ctu.cx" = {
+        enableACME = true;
+        forceSSL   = true;
+        kTLS       = true;
+        locations  = {
+          "/".extraConfig = ''
+            include "${pkgs.nginx}/conf/fastcgi_params";
+            fastcgi_param SCRIPT_FILENAME "${pkgs.dnsmasq-lease-overview}/bin/overview";
+            fastcgi_param LEASE_PATH      "/var/lib/dnsmasq/dnsmasq.leases";
+            fastcgi_param QUERY_STRING    $args;
+            fastcgi_pass  unix:${config.services.fcgiwrap.socketAddress};
+          '';
+        };
+      };
+    };
+
+  };
+
+}
diff --git a/machines/briefkasten/router/nftables.nix b/machines/briefkasten/router/nftables.nix
@@ -0,0 +1,14 @@
+{ ... }:
+
+{
+
+  networking = {
+    firewall.enable = false;
+
+    nftables = {
+      enable      = true;
+      rulesetFile = ./ruleset.nft;
+    };
+  };
+
+}+
\ No newline at end of file
diff --git a/machines/briefkasten/router/ruleset.nft b/machines/briefkasten/router/ruleset.nft
@@ -0,0 +1,87 @@
+flush ruleset
+
+table inet firewall {
+    chain inbound {
+        # By default, drop all traffic unless it meets a filter
+        # criteria specified by the rules that follow below.
+        type filter hook input priority 0;
+        policy drop;
+
+        # Allow traffic from established and related packets.
+        ct state established,related accept
+
+        # Drop invalid packets.
+        ct state invalid drop
+
+        # Allow local connections.
+        iifname lo accept
+        iifname brlan accept
+
+        # Allow all ICMP and IGMP traffic, but enforce a rate limit
+        # to help prevent some types of flood attacks.
+        ip protocol icmp limit rate 5/second accept
+        ip protocol igmp limit rate 5/second accept
+        #ip6 protocol ipv6-icmp icmpv6-type redirect drop
+        #ip6 protocol ipv6-icmp icmpv6-type 139 drop
+        ip6 nexthdr ipv6-icmp limit rate 5/second accept
+
+        # Allow some ports
+        tcp dport ssh accept comment "ssh"
+        tcp dport domain accept comment "dns (tcp)"
+        udp dport domain accept comment "dns (udp)"
+        tcp dport http   accept comment "http"
+        tcp dport https  accept comment "https"
+        tcp dport 22000  accept comment "syncthing"
+        udp dport 21027  accept comment "syncthing"
+        tcp dport 5201   accept comment "iperf3 (tcp)"
+        udp dport 5201   accept comment "iperf3 (udp)"
+    }
+
+    chain forward {
+        # By default, drop all traffic unless it meets a filter
+        type filter hook forward priority 0;
+        policy drop;
+
+        # Allow traffic from established and related packets.
+        ct state established,related accept
+
+        # Drop invalid packets.
+        ct state invalid drop
+
+        # local clients can do whatever
+        iifname brlan accept
+
+        # Allow all ICMP and IGMP traffic, but enforce a rate limit
+        # to help prevent some types of flood attacks.
+        ip  protocol icmp limit rate 5/second accept
+        ip6 nexthdr  ipv6-icmp limit rate 5/second accept
+        ip  protocol igmp limit rate 5/second accept
+
+        # drop incomming netbios traffic
+        tcp dport {139, 445} counter drop comment "silently drop NetBios"
+        udp dport {137, 138} counter drop comment "silently drop NetBios"
+
+        #make public ips world accessible 
+        ip daddr 195.39.246.33/28 accept
+    }
+
+    chain outbound {
+        # Allow all outbound traffic
+        type filter hook output priority 0
+        policy accept
+    }
+
+}
+
+table ip nat {
+    chain prerouting {
+        type nat hook prerouting priority -100
+        policy accept
+    }
+
+    chain postrouting {
+        type nat hook postrouting priority 0
+        policy accept
+        oifname iphone masquerade
+    }
+}+
\ No newline at end of file
diff --git a/machines/briefkasten/router/systemd-networkd.nix b/machines/briefkasten/router/systemd-networkd.nix
@@ -0,0 +1,150 @@
+{ config, ... }:
+
+{
+
+  age.secrets.wireguard-privkey = {
+    file  = ./. + "../../../../secrets/${config.networking.hostName}/wireguard-privkey.age";
+    mode  = "640";
+    owner = "root";
+    group = "systemd-network";
+  };
+
+  systemd.network = {
+    enable             = true;
+    wait-online.enable = false;
+
+    links = {
+      "10-iphone" = {
+        matchConfig.PermanentMACAddress = "aa:ab:b5:18:95:d9";
+        linkConfig.Name = "iphone";
+      };
+    };
+
+    netdevs = {
+
+      "20-brlan" = {
+        netdevConfig = {
+          Kind = "bridge";
+          Name = "brlan";
+        };
+      };
+
+      # "30-enp1s0.5" = {
+      #   netdevConfig = {
+      #     Kind = "vlan";
+      #     Name = "enp1s0.5";
+      #   };
+      #   vlanConfig = {
+      #     Id = 5;
+      #   };
+      # };
+
+      "40-wg-pbb" = {
+        netdevConfig = {
+          Kind = "wireguard";
+          Name = "wg-pbb";
+        };
+        wireguardConfig = {
+          PrivateKeyFile = config.age.secrets.wireguard-privkey.path;
+          ListenPort     = 51820;
+          FirewallMark   = 51820;
+        };
+        wireguardPeers = [{
+          wireguardPeerConfig={
+            Endpoint            = "195.39.247.161:51820";
+            PublicKey           = "kih/GnR4Bov/DM/7Rd21wK+PFQRUNH6sywVuNKkUAkk=";
+            AllowedIPs          = [ "0.0.0.0/0" "::/0" ];
+            PersistentKeepalive = 10;
+#            RouteTable          = "off";
+          };
+        }];
+      };
+
+    };
+
+    networks = {
+
+      "10-iphone" = {
+        matchConfig = {
+          Name = "iphone";
+        };
+        DHCP    = "yes";
+      };
+
+      # "10-enp1s0.5" = {
+      #   matchConfig = {
+      #     Name = "enp1s0.5";
+      #   };
+      #   DHCP    = "yes";
+      # };
+
+      "10-enp1s0" = {
+        matchConfig = {
+          Name = "enp1s0";
+        };
+        bridge = [ "brlan" ];
+#        vlan = [ "enp1s0.5" ];
+      };
+
+      "20-brlan" = {
+        matchConfig = {
+          Name   = "brlan";
+          Driver = "bridge";
+        };
+        networkConfig = {
+          IPv6AcceptRA        = "no";
+          DHCP                = "no";
+        };
+        address = [
+          "10.0.0.1/24"
+          "195.39.246.42/28"
+          "2a0f:4ac0:acab::1/62"
+        ];
+        routingPolicyRules = [
+          { routingPolicyRuleConfig = {
+            From                 = "195.39.246.32/28";
+            Table                = 254;
+            Priority             = 1900;
+            SuppressPrefixLength = 0;
+          };}
+          { routingPolicyRuleConfig = {
+            From                 = "2a0f:4ac0:acab::/62";
+            Table                = 254;
+            Priority             = 1900;
+            SuppressPrefixLength = 0;
+          };}
+          { routingPolicyRuleConfig = {
+            From     = "195.39.246.32/28";
+            Table    = 1234;
+            Priority = 2000;
+          };}
+          { routingPolicyRuleConfig = {
+            From     = "2a0f:4ac0:acab::/62";
+            Table    = 1234;
+            Priority = 2000;
+          };}
+        ];
+      };
+
+      "30-wg-pbb" = {
+        matchConfig = {
+          Name = "wg-pbb";
+        };
+        linkConfig = {
+          MTUBytes = "1500";
+        };
+        routes = [
+          { routeConfig = {
+            Destination = "0.0.0.0/0";
+            Table       = "1234";
+          };}
+          { routeConfig = {
+            Destination = "::/0";
+            Table       = "1234";
+          };}
+        ];
+      };
+
+    };
+  };
+}+
\ No newline at end of file
diff --git a/machines/briefkasten/smarthome/influxdb2.nix b/machines/briefkasten/smarthome/influxdb2.nix
@@ -5,7 +5,8 @@
   age.secrets.restic-influxdb.file   = ./. + "/../../../secrets/${config.networking.hostName}/restic/influxdb.age";
   age.secrets.influx-backup-env.file = ./. + "/../../../secrets/${config.networking.hostName}/influx/backup_env.age";
 
-  dns.zones."ctu.cx".subdomains."influx.home".CNAME = lib.mkIf config.networking.usePBBUplink [ "${config.networking.fqdn}." ];
+#  dns.zones."ctu.cx".subdomains."influx.home".CNAME = [ "${config.networking.fqdn}." ];
+  services.dnsmasq.settings.cname                   = [ "influx.home.ctu.cx, ${config.networking.fqdn}" ];
 
   systemd.services.restic-backup-influxdb.serviceConfig.EnvironmentFile = config.age.secrets.influx-backup-env.path;
 
diff --git a/machines/briefkasten/smarthome/mqtt-webui/default.nix b/machines/briefkasten/smarthome/mqtt-webui/default.nix
@@ -6,7 +6,8 @@ let
 
 in {
 
-  dns.zones."ctu.cx".subdomains."smart.home".CNAME = lib.mkIf config.networking.usePBBUplink [ "${config.networking.fqdn}." ];
+#  dns.zones."ctu.cx".subdomains."smart.home".CNAME = [ "${config.networking.fqdn}." ];
+  services.dnsmasq.settings.cname                  = [ "smart.home.ctu.cx, ${config.networking.fqdn}" ];
 
 
   services = {
diff --git a/machines/briefkasten/websites/audiobooks.home.ctu.cx.nix b/machines/briefkasten/websites/audiobooks.home.ctu.cx.nix
@@ -2,7 +2,8 @@
 
 {
 
-  dns.zones."ctu.cx".subdomains."audiobooks.home".CNAME = lib.mkIf config.networking.usePBBUplink [  "${config.networking.fqdn}." ];
+#  dns.zones."ctu.cx".subdomains."audiobooks.home".CNAME = [ "${config.networking.fqdn}." ];
+  services.dnsmasq.settings.cname                       = [ "audiobooks.home.ctu.cx, ${config.networking.fqdn}" ];
 
   fileSystems."/mnt/audiobooks" = {
     device = "/nix/persist/home/leah/syncthing/Audiobooks";
diff --git a/machines/briefkasten/websites/music.home.ctu.cx.nix b/machines/briefkasten/websites/music.home.ctu.cx.nix
@@ -9,7 +9,8 @@ let
 
 in {
 
-  dns.zones."ctu.cx".subdomains."music.home".CNAME = lib.mkIf config.networking.usePBBUplink [  "${config.networking.fqdn}." ];
+#  dns.zones."ctu.cx".subdomains."music.home".CNAME = [ "${config.networking.fqdn}." ];
+  services.dnsmasq.settings.cname                  = [ "music.home.ctu.cx, ${config.networking.fqdn}" ];
 
   fileSystems."/mnt/music_originals" = {
     device = "/nix/persist/home/leah/syncthing/Music (Originals)";
diff --git a/machines/briefkasten/websites/wiki.home.ctu.cx.nix b/machines/briefkasten/websites/wiki.home.ctu.cx.nix
@@ -2,7 +2,8 @@
 
 {
 
-  dns.zones."ctu.cx".subdomains."wiki.home".CNAME = lib.mkIf config.networking.usePBBUplink [ "${config.networking.fqdn}." ];
+#  dns.zones."ctu.cx".subdomains."wiki.home".CNAME = [ "${config.networking.fqdn}." ];
+  services.dnsmasq.settings.cname                 = [ "wiki.home.ctu.cx, ${config.networking.fqdn}" ];
 
   fileSystems."/mnt/wiki" = {
     device = "/nix/persist/home/leah/syncthing/Wiki";
diff --git a/secrets/briefkasten/wireguard-privkey.age b/secrets/briefkasten/wireguard-privkey.age
@@ -1,10 +1,11 @@
 -----BEGIN AGE ENCRYPTED FILE-----
-YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnQk1jbTlsaCtSaE1BU21s
-UlRTRHUyaFpQbFhDN1Q4MlVGMWxYOUJCZXgwCjRtZjlXRTBpblpLeHc5bi9DMThl
-ZmxseklHc3VGZnltWnlhN0hxelZCTTgKLT4gc3NoLWVkMjU1MTkgNGhLQ013IGpH
-bXNCR0hoNU9nQ0IxZDNvNldkRTNCOFJEaitaVUxBRi9OUURqMmlGRDgKNFBkWHZ6
-OUJtMUlrOUpGL280Vmk4MVVZOHlSZ3d1ejJqVmluQi9FbjlMRQotPiB2ZS1ncmVh
-c2UgLS9QCmFVWGkwWjZCCi0tLSAyNWZtQnJ3aDlnbXFwbGwvT2FLN2VHNWVjOTZ6
-eGJHWDVsQmluUndKVlVrCuTFDs+3riA4XGKIxseSSIGgClejnpBMSWr9cKEBlQTh
-J8SqmwY1AysWI4fLpvtpLvbljjpLb9eHW+et5adopPnHKchVpM8TM8VcHEDM
+YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwamJHZDJIbVM2OEJUM1Bo
+V2VTRnU1T0NIamdFWVQzVlRMZG1mSFU3cFF3CmlVR2M1dnM5eEVsV3NwOVR4N2lZ
+dXpVajZ5Z2xYNDNZRDMwMDY4WnhHSVUKLT4gc3NoLWVkMjU1MTkgNGhLQ013IFRL
+ZUxmUW5VQ0Jhd3A2dk10UkVUVG1USERlS0lCeU9XQkh0T050VXpURDQKVllaTkhB
+K2VHblYzYjlXOXJVUStvQnRKeTNWU3NMTXVGT2dwUEZuQy95OAotPiBwLWdyZWFz
+ZSAiNzxidSAoOiVSCjFiQkI3bTc0c3FZCi0tLSBDVmowUEt3RDlENlB1V2NkaWMv
+NVZ5akVYSTVCMGVDbWdtZFE5NDd2dDRRCtdDEf/ug4fzXOZwPrf6zmKRfpG4tFi9
+YT610Z0H/DMjoqwD/WdLid4MXG61bShM/I/zJHjq4M2/q0HUL7Mg/qEVs2adBfl5
+4dglMFw=
 -----END AGE ENCRYPTED FILE-----