summary refs log tree commit diff stats
path: root/system
diff options
context:
space:
mode:
Diffstat (limited to 'system')
-rw-r--r--system/linde.nix110
-rw-r--r--system/mba.nix9
-rwxr-xr-xsystem/nanopi.nix107
-rw-r--r--system/prefect.nix18
-rw-r--r--system/settings/darwin.nix4
-rw-r--r--system/settings/dev.nix59
-rw-r--r--system/settings/hardware/audio.nix2
-rw-r--r--system/settings/programs/docker.nix5
-rw-r--r--system/settings/services/git-server.nix24
-rw-r--r--system/settings/user-interface.nix1
10 files changed, 242 insertions, 97 deletions
diff --git a/system/linde.nix b/system/linde.nix
index 067d4dad..730e0a14 100644
--- a/system/linde.nix
+++ b/system/linde.nix
@@ -13,15 +13,17 @@ let
   net-gw = "172.31.1.1";
   net-ip6 = "2a01:4f8:c012:23a4::1";
   net-rdnsip = "2a01:4f8:c012:23a4::53";
+  net-acmeip = "2a01:4f8:c012:23a4::715";
   net-mask6 = "64";
   net-gw6 = "fe80::1";
+  domain = "alanpearce.eu";
   ts-domain = "hydra-pinecone.ts.net";
   golink = (builtins.getFlake (toString <golink>)).nixosModules.default;
 in
 {
   imports =
     [
-      <personal/modules/laminar.nix>
+      <personal/modules/nixos/laminar.nix>
       <home-manager/nixos>
       <agenix/modules/age.nix>
       <searchix/nix/modules>
@@ -155,6 +157,7 @@ in
 
   networking = {
     hostName = hostname;
+    inherit domain;
     useDHCP = false;
     dhcpcd.enable = false;
     nameservers = [
@@ -167,6 +170,7 @@ in
       ${net-ip4} = [ "${hostname}.alanpearce.eu" hostname ];
       ${net-ip6} = [ "${hostname}.alanpearce.eu" hostname ];
       ${net-rdnsip} = [ "dns" ];
+      ${net-acmeip} = [ "acme" ];
     };
     firewall = {
       enable = true;
@@ -224,6 +228,7 @@ in
         address = [
           "${net-ip6}/${net-mask6}"
           "${net-rdnsip}/${net-mask6}"
+          "${net-acmeip}/${net-mask6}"
         ];
         addresses = [{
           Address = "${net-ip4}/${net-mask4}";
@@ -344,6 +349,21 @@ in
   # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
   system.stateVersion = "23.05"; # Did you read the comment?
 
+  services.goatcounter = {
+    enable = true;
+    address = "localhost";
+    port = 8082;
+    proxy = true;
+    extraArgs = [
+      "-db"
+      "sqlite3+db/goatcounter.sqlite3"
+      "-websocket"
+      "-automigrate"
+      "-smtp"
+      "smtp://localhost:25"
+    ];
+  };
+
   services.powerdns =
     let
       inherit (lib.lists) flatten;
@@ -445,6 +465,24 @@ in
     };
   };
 
+  services.postfix =
+    let
+      localUser = "alan";
+      forwardingAddress = "alan@alanpearce.eu";
+    in
+    {
+      enable = true;
+      destination = [ ];
+      domain = config.networking.domain;
+      virtual = ''
+        @${config.networking.hostName}.${config.networking.domain} ${localUser}
+        ${localUser} ${forwardingAddress}
+      '';
+      config = {
+        inet_interfaces = "loopback-only";
+      };
+    };
+
   services.kresd = {
     enable = true;
     # package = pkgs.knot-resolver.override { extraFeatures = true; };
@@ -580,11 +618,37 @@ in
     };
   };
 
+  services.acme-dns = {
+    enable = true;
+    settings =
+      let
+        me = "acme.${domain}";
+      in
+      {
+        general = {
+          listen = "[${net-acmeip}]:53";
+          protocol = "both6";
+          domain = me;
+          nsname = me;
+          nsadmin = builtins.replaceStrings [ "@" ] [ "." ] config.security.acme.defaults.email;
+          records = [
+            "${me}. AAAA ${net-acmeip}"
+            "${me}. NS ${me}."
+          ];
+        };
+        api = {
+          ip = "[${net-acmeip}]";
+          tls = "letsencrypt";
+          port = 443;
+          notification-email = config.security.acme.defaults.email;
+        };
+      };
+  };
+
   security.acme = {
     defaults = {
       email = "alan@alanpearce.eu";
-      dnsProvider = "pdns";
-      dnsResolver = "1.1.1.1:53";
+      dnsProvider = "acme-dns";
       credentialsFile = config.age.secrets.acme.path;
       reloadServices = [ "caddy" ];
       validMinDays = 32;
@@ -597,6 +661,9 @@ in
       reloadServices = map (x: "kresd@${toString x}") (range 1 config.services.kresd.instances);
       group = "knot-resolver";
     };
+    certs."stats.alanpearce.eu" = {
+      extraDomainNames = [ "*.stats.alanpearce.eu" ];
+    };
   };
   users.groups.acme.members = [
     "caddy"
@@ -716,6 +783,7 @@ in
             ns = config.services.nix-serve;
           in
           {
+            useACMEHost = "alanpearce.eu";
             extraConfig = ''
               reverse_proxy ${ns.bindAddress}:${toString ns.port}
             '';
@@ -725,10 +793,31 @@ in
             srv = config.services.laminar;
           in
           {
+            useACMEHost = "alanpearce.eu";
             extraConfig = ''
               reverse_proxy ${srv.settings.bindHTTP}
             '';
           };
+        "stats.alanpearce.eu" =
+          let
+            srv = config.services.goatcounter;
+          in
+          {
+            useACMEHost = "stats.alanpearce.eu";
+            serverAliases = [ "*.stats.alanpearce.eu" ];
+            extraConfig = ''
+              reverse_proxy ${srv.address}:${toString srv.port}
+            '';
+          };
+        "go.alanpearce.eu" = {
+          useACMEHost = "alanpearce.eu";
+          extraConfig = ''
+            encode zstd gzip
+            ${security-headers {}}
+            root * /srv/http/go
+            file_server
+          '';
+        };
       };
   };
   systemd.services.caddy.serviceConfig = {
@@ -855,6 +944,9 @@ in
     enable = true;
     initialClusterState = "existing";
     dataDir = "/var/lib/etcd"; # TODO backup
+    extraConf = {
+      AUTO_COMPACTION_RETENTION = "1h";
+    };
   };
 
   services.dex =
@@ -926,17 +1018,17 @@ in
             {
               script-src = [
                 (baseURL + "/static/")
-                "https://gc.zgo.at"
+                "https://searchix.stats.alanpearce.eu"
                 "https://js-de.sentry-cdn.com"
                 "https://browser.sentry-cdn.com"
               ];
               img-src = [
                 self
-                "https://gc.zgo.at"
+                "https://searchix.stats.alanpearce.eu"
               ];
               connect-src = [
                 self
-                "https://searchix.goatcounter.com/count"
+                "https://searchix.stats.alanpearce.eu/count"
                 "*.sentry.io"
               ];
               worker-src = [
@@ -947,8 +1039,8 @@ in
             <script async
               src="https://js-de.sentry-cdn.com/d735e99613a86e1625fb85d0e8e762de.min.js"
               crossorigin="anonymous"></script>
-            <script data-goatcounter="https://searchix.goatcounter.com/count"
-                    async src="//gc.zgo.at/count.v4.js"
+            <script data-goatcounter="https://searchix.stats.alanpearce.eu/count"
+                    async src="//searchix.stats.alanpearce.eu/count.v4.js"
                     crossorigin="anonymous"
                     integrity="sha384-nRw6qfbWyJha9LhsOtSb2YJDyZdKvvCFh0fJYlkquSFjUxp9FVNugbfy8q1jdxI+"></script>
           '';
@@ -997,7 +1089,7 @@ in
     enable = true;
     path = with pkgs; [
       bash
-      stdenv
+      coreutils
       git
       cached-nix-shell
       nix
diff --git a/system/mba.nix b/system/mba.nix
index ca1b76d8..b1a17922 100644
--- a/system/mba.nix
+++ b/system/mba.nix
@@ -1,14 +1,19 @@
 { ... }: {
   imports = [
     ./settings/darwin.nix
-    ./settings/programs/base.nix
+    ./settings/dev.nix
     ./settings/programs/shell.nix
+    <personal/modules/darwin/caddy>
   ];
 
+  services.caddy = {
+    user = "root";
+    group = "wheel";
+  };
+
   networking = {
     hostName = "mba";
   };
-  services.tailscale.enable = true;
 
   services.activate-system.enable = true;
 
diff --git a/system/nanopi.nix b/system/nanopi.nix
index 5083f9e7..3a95ebfc 100755
--- a/system/nanopi.nix
+++ b/system/nanopi.nix
@@ -146,29 +146,12 @@ in
         ];
       };
       extraForwardRules = ''
-        iifname { "wlan0", "lte0" } oifname { "lan1", "lan2", "bridge0" } icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, mld-listener-query, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
-        iifname { "lan1", "lan2", "bridge0" } oifname { "wlan0", "lte0" } accept
         iifname "tailscale0" oifname "bridge0" accept
         iifname "bridge0" oifname "tailscale0" accept
       '';
     };
     nftables = {
       enable = true;
-      tables = {
-        firewall = {
-          family = "inet";
-          content = ''
-            chain postrouting {
-              type nat hook postrouting priority srcnat; policy accept;
-              oifname { "wlan0", "lte0" } masquerade
-            }
-            chain prerouting {
-              type nat hook prerouting priority dstnat;
-              iifname "wan0" tcp dport { 6922, 51413 } dnat ip to 10.0.0.42
-            }
-          '';
-        };
-      };
     };
     wireless = {
       enable = true;
@@ -284,12 +267,6 @@ in
           Name = "wlan0";
         };
       };
-      "10-name-lte0" = {
-        matchConfig.MACAddress = "34:4b:50:00:00:00";
-        linkConfig = {
-          Name = "lte0";
-        };
-      };
     };
     netdevs = {
       "20-bridge" = {
@@ -337,43 +314,13 @@ in
           Token = "::1";
         };
       };
-      "50-lte0" = {
-        matchConfig.Name = "lte0";
-        networkConfig = {
-          DHCP = "yes";
-          IPv6AcceptRA = true;
-          IPForward = "yes";
-        };
-        dhcpV4Config = {
-          UseDNS = false;
-          SendHostname = false;
-          UseRoutes = false;
-        };
-        ipv6AcceptRAConfig.UseDNS = false;
-        routes = [
-          {
-            Gateway = "_dhcp4";
-            Metric = 2048;
-            QuickAck = true;
-            InitialCongestionWindow = 30;
-            InitialAdvertisedReceiveWindow = 30;
-          }
-        ];
-        cakeConfig = {
-          Bandwidth = "1M";
-          OverheadBytes = 18;
-          MPUBytes = 64;
-          CompensationMode = "none";
-          NAT = true;
-          PriorityQueueingPreset = "diffserv8";
-        };
-      };
       "50-wan" = {
         matchConfig.Name = "wan0";
         networkConfig = {
           DHCP = "yes";
           IPv6AcceptRA = true;
-          IPForward = "yes";
+          IPv4Forwarding = true;
+          IPv6Forwarding = true;
         };
         dhcpV4Config = {
           UseDNS = false;
@@ -430,7 +377,8 @@ in
         matchConfig.MACAddress = "9c:53:22:33:bf:e9";
         networkConfig = {
           DHCP = "yes";
-          IPForward = "yes";
+          IPv4Forwarding = true;
+          IPv6Forwarding = true;
           IgnoreCarrierLoss = "3s";
         };
         dhcpV4Config = {
@@ -504,11 +452,9 @@ in
         "/ts.net/tailscale"
       ];
       localise-queries = true;
-      cname = [
-        "ha,home-assistant"
-      ];
       interface-name = [
         "nanopi.${domain},bridge0"
+        "ca.${domain},bridge0"
         "wan.${domain},wan0"
         "wlan.${domain},wlan0"
       ];
@@ -525,10 +471,6 @@ in
       # ];
       bind-interfaces = true;
 
-      # if this is false, a remote query for nanopi returns 127.0.0.2, because that's in /etc/hosts
-      no-hosts = false;
-      expand-hosts = true;
-
       dnssec = true;
       trust-anchor = ".,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D";
 
@@ -610,6 +552,45 @@ in
     };
   };
 
+  services.caddy = {
+    enable = true;
+    globalConfig = ''
+      pki {
+        ca home {
+          name "Home CA"
+        }
+      }
+    '';
+    virtualHosts = {
+      "nanopi.${domain}" = {
+        serverAliases = [ "nanopi.${ts_domain}" ];
+        extraConfig = ''
+          tls {
+            issuer internal {
+              ca home
+            }
+          }
+          root /var/lib/caddy/ca
+          file_server browse
+        '';
+      };
+      "ca.${domain}" = {
+        extraConfig = ''
+          tls {
+            issuer internal {
+              ca home
+            }
+          }
+          acme_server {
+            allow {
+              domains *.test *.${domain}
+            }
+          }
+        '';
+      };
+    };
+  };
+
   system.stateVersion = "23.05";
 
   programs.fish = {
diff --git a/system/prefect.nix b/system/prefect.nix
index 801692e3..e145c304 100644
--- a/system/prefect.nix
+++ b/system/prefect.nix
@@ -23,6 +23,7 @@
     ./settings/programs/kde.nix
     ./settings/programs/shell.nix
     ./settings/programs/docker.nix
+    ./settings/dev.nix
     ./settings/gaming.nix
     <nixos-hardware/common/cpu/amd>
     <nixos-hardware/common/cpu/amd/pstate.nix>
@@ -150,6 +151,7 @@
     };
     hosts = {
       "fd7a:115c:a1e0::53" = [ "tailscale" "ts" ];
+      "::1" = [ "alanpearce.test" "alanpearce.localhost" ];
     };
 
     nftables = {
@@ -178,6 +180,22 @@
 
   system.stateVersion = "23.05";
 
+  security.pki.certificates = [
+    ''
+      -----BEGIN CERTIFICATE-----
+      MIIBozCCAUqgAwIBAgIRAJ1slNK3lsucmYYUbtGRUvswCgYIKoZIzj0EAwIwMDEu
+      MCwGA1UEAxMlQ2FkZHkgTG9jYWwgQXV0aG9yaXR5IC0gMjAyNCBFQ0MgUm9vdDAe
+      Fw0yNDA2MjYxNTM3MTJaFw0zNDA1MDUxNTM3MTJaMDAxLjAsBgNVBAMTJUNhZGR5
+      IExvY2FsIEF1dGhvcml0eSAtIDIwMjQgRUNDIFJvb3QwWTATBgcqhkjOPQIBBggq
+      hkjOPQMBBwNCAAR1fc1TOhp9oNy/p40BfUd+E13b1/URwwocuZ5w0SKHTE/t8Hp+
+      7Zd9ZTYvQ7WxFfaVxmBCcFMUJsTm7bbYTEvlo0UwQzAOBgNVHQ8BAf8EBAMCAQYw
+      EgYDVR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQUcnlbpAM2ZCRsiCzdFiM5EjCm
+      aoEwCgYIKoZIzj0EAwIDRwAwRAIgcKf3vRiF87G0r2+vgBbyfWo4D2TDQWkSrfek
+      Q0f1Q5UCIEmyeqrifbp5JnZqtm3IlGVIEQcUeVygqnV/xW3xCAgT
+      -----END CERTIFICATE-----
+    ''
+  ];
+
   boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
   nix.settings.trusted-users = [ "root" "nixremote" ];
   services.displayManager.hiddenUsers = [ "nixremote" ];
diff --git a/system/settings/darwin.nix b/system/settings/darwin.nix
index 6d5b357d..0f507a31 100644
--- a/system/settings/darwin.nix
+++ b/system/settings/darwin.nix
@@ -19,10 +19,6 @@
   environment.darwinConfig = "$HOME/.config/nixpkgs/darwin-configuration.nix";
   nix = {
     daemonIOLowPriority = true;
-    gc = {
-      user = "alan";
-      options = "--max-freed $((25 * 1024**3 - 1024 * $(df -P -k /nix/store | tail -n 1 | awk '{ print $4 }')))";
-    };
     settings.extra-platforms = "aarch64-darwin x86_64-darwin";
 
     settings.trusted-users = [ "@admin" ];
diff --git a/system/settings/dev.nix b/system/settings/dev.nix
new file mode 100644
index 00000000..b1817914
--- /dev/null
+++ b/system/settings/dev.nix
@@ -0,0 +1,59 @@
+{ ... }: {
+  services.caddy = {
+    enable = true;
+    virtualHosts =
+      let
+        local_tls = ''
+          tls {
+            issuer internal {
+              ca local
+            }
+          }
+        '';
+      in
+      {
+        "localhost" = {
+          logFormat = "output discard";
+          extraConfig = ''
+            ${local_tls}
+            acme_server {
+              allow {
+                domains *.test *.localhost
+              }
+            }
+          '';
+        };
+        # need to test forwarding behaviour
+        "https://alanpearce.localhost" = {
+          logFormat = "output discard";
+          serverAliases = [
+            "http://alanpearce.localhost"
+
+            # remember to update /etc/hosts
+            "https://alanpearce.test"
+            "http://alanpearce.test"
+          ];
+          extraConfig = ''
+            ${local_tls}
+            reverse_proxy http://alanpearce.test:8080 {
+              transport http {
+                dial_timeout 1s
+                compression off
+              }
+            }
+          '';
+        };
+        "searchix.localhost" = {
+          logFormat = "output discard";
+          extraConfig = ''
+            reverse_proxy http://localhost:7331 {
+              transport http {
+                dial_timeout 1s
+                compression off
+              }
+            }
+          '';
+        };
+      };
+  };
+}
diff --git a/system/settings/hardware/audio.nix b/system/settings/hardware/audio.nix
index 0afb38bb..78c7775a 100644
--- a/system/settings/hardware/audio.nix
+++ b/system/settings/hardware/audio.nix
@@ -9,8 +9,6 @@
     pulse.enable = true;
   };
 
-  sound.enable = true;
-
   environment.systemPackages = with pkgs; [
     pamixer
   ];
diff --git a/system/settings/programs/docker.nix b/system/settings/programs/docker.nix
index 29c2ac73..bbe0e4fc 100644
--- a/system/settings/programs/docker.nix
+++ b/system/settings/programs/docker.nix
@@ -18,9 +18,4 @@
       };
     };
   };
-  # TODO: autoPrune doesn't affect rootless
-  # systemd.timers.docker-prune.timerConfig = {
-  #   Persistent = true;
-  #   RandomizedDelaySec = 1800;
-  # };
 }
diff --git a/system/settings/services/git-server.nix b/system/settings/services/git-server.nix
index 54e8560c..1560e8f5 100644
--- a/system/settings/services/git-server.nix
+++ b/system/settings/services/git-server.nix
@@ -4,7 +4,7 @@
 , ...
 }:
 let
-  inherit (lib) pipe flatten concatMapAttrs mergeAttrsList mapAttrsToList;
+  inherit (lib) pipe flatten concatMapAttrs mapAttrsToList;
   inherit (import ../../../lib/caddy.nix { inherit lib; }) security-headers;
   repos = "${config.services.gitolite.dataDir}/repositories";
 
@@ -64,13 +64,16 @@ let
   mkMirrorWants = repo: map (target: "mirror-to-${target}@${repo}.path");
 in
 {
-  services.fcgiwrap = {
-    enable = true;
-    user = "gitolite";
-    group = "gitolite";
-    preforkProcesses = 2;
-    socketType = "tcp6";
-    socketAddress = "[::1]:9000";
+  services.fcgiwrap.instances.gitolite = {
+    process = {
+      user = "gitolite";
+      group = "gitolite";
+      prefork = 2;
+    };
+    socket = {
+      type = "tcp6";
+      address = "[::1]:9000";
+    };
   };
   services.gitolite = {
     enable = true;
@@ -114,8 +117,8 @@ in
   services.caddy.virtualHosts = {
     "git.alanpearce.eu" =
       let
-        fcgi = config.services.fcgiwrap;
-        fcgisocket = "${fcgi.socketType}/${fcgi.socketAddress}";
+        fcgi = config.services.fcgiwrap.instances.gitolite;
+        fcgisocket = "${fcgi.socket.type}/${fcgi.socket.address}";
       in
       {
         useACMEHost = "alanpearce.eu";
@@ -173,7 +176,6 @@ in
                   enable-log-linecount=1
                   max-stats=year
                   snapshots=tar.lz tar.zst zip
-                  cache-size=10240
                   enable-http-clone=1
                   enable-commit-graph=1
                   mimetype-file=${pkgs.nginx}/conf/mime.types
diff --git a/system/settings/user-interface.nix b/system/settings/user-interface.nix
index d9d3297f..d8ae301a 100644
--- a/system/settings/user-interface.nix
+++ b/system/settings/user-interface.nix
@@ -58,7 +58,6 @@
       extraArgs = "--keep-since 14d";
     };
   };
-  nix.gc.automatic = ! config.programs.nh.enable;
 
   imports = [
     ./services/xserver.nix