From 0027566304e3a648103ada8c98950d31700a4fcd Mon Sep 17 00:00:00 2001 From: niten Date: Mon, 4 Dec 2023 17:10:57 -0800 Subject: [PATCH] Big commit --- config/domain-config/fudo.org.nix | 123 ++-- config/domain-config/fudo.org/authentik.nix | 10 +- config/domain-config/fudo.org/mail-server.nix | 5 + config/domain-config/fudo.org/nameserver.nix | 59 ++ config/domain-config/sea.fudo.org.nix | 51 +- config/domains/sea.fudo.org.nix | 2 + config/hardware/zbox.nix | 39 +- config/host-config/fimbria.nix | 171 ++++- config/host-config/germany.nix | 57 +- config/host-config/jazz.nix | 9 + config/host-config/legatus.nix | 14 +- config/host-config/limina.nix | 127 +++- config/host-config/nostromo.nix | 42 +- config/host-config/wormhole0.nix | 65 +- .../host-config/wormhole0/home-assistant.nix | 4 +- config/host-config/zbox.nix | 112 +++- config/host-config/zbox/pkgs/gasket.nix | 36 + .../zbox/pkgs/libedgetpu-stddef.diff | 12 + config/host-config/zbox/pkgs/libedgetpu.nix | 57 ++ config/service/authoritative-dns.nix | 226 ++++--- config/service/gitea-container.nix | 208 ++++++ config/service/local-network.nix | 3 +- config/service/postgresql.nix | 10 +- config/service/tattler.nix | 2 + config/services.nix | 1 + config/users.nix | 6 + flake.lock | 621 ++++++++++++------ flake.nix | 13 +- lib/instantiate-zone.nix | 18 + 29 files changed, 1582 insertions(+), 521 deletions(-) create mode 100644 config/domain-config/fudo.org/nameserver.nix create mode 100644 config/host-config/zbox/pkgs/gasket.nix create mode 100644 config/host-config/zbox/pkgs/libedgetpu-stddef.diff create mode 100644 config/host-config/zbox/pkgs/libedgetpu.nix create mode 100644 config/service/gitea-container.nix create mode 100644 lib/instantiate-zone.nix diff --git a/config/domain-config/fudo.org.nix b/config/domain-config/fudo.org.nix index 3f46fb9..f96acd1 100644 --- a/config/domain-config/fudo.org.nix +++ b/config/domain-config/fudo.org.nix @@ -6,7 +6,7 @@ let localDomain = "fudo.org"; serviceSecrets = config.fudo.secrets.files.service-secrets."${hostname}"; - inherit (pkgs.lib) getDomainHosts getHostIpv4 getHostFqdn; + inherit (pkgs.lib) getDomainHosts getHostIpv4 getHostIpv6 getHostFqdn; domain = config.fudo.domains."${localDomain}"; @@ -18,6 +18,15 @@ let mastodonHostname = "mastodon.fudo.org"; + servedDomains = [ + "fudo.org" + "test.fudo.org" + "selby.ca" + "fudo.ca" + "fudo.im" + "stewartsoundservices.ca" + ]; + in { imports = [ (import ./fudo.org/authentik.nix { inherit authentikHost; }) @@ -50,12 +59,12 @@ in { saslDomain = "FUDO.ORG"; authentikOutpostToken = config.fudo.secrets.files.domain-secrets."${primaryDomain}"."authentik-ldap.token"; - servedDomains = - [ "fudo.org" "fudo.ca" "fudo.im" "selby.ca" "selbyhomecentre.com" ]; + inherit servedDomains; # TODO: FIXME! dkimRecord = ""; })) ]; + config = { # All Fudo hosts should redirect selby.ca to the selbyhomecentre website. services.nginx.virtualHosts = { @@ -77,63 +86,67 @@ in { }; }; - fudo.services = { - jabber = { - domain = "jabber.fudo.org"; - ldap.servers = map (host: "${host}.${localDomain}") domain.ldap-servers; - }; - - authoritative-dns = { - enable = hostname == primaryNameserver; - - nameservers = { - primary = primaryNameserver; - external = map (hostname: { - inherit (config.fudo.zones."fudo.org".hosts."${hostname}") - ipv4-address ipv6-address description; - }) [ "ns2-fudo" "ns3-fudo" "ns4-fudo" ]; + fudo = { + services = { + jabber = { + domain = "jabber.fudo.org"; + ldap.servers = + map (host: "${host}.${localDomain}") domain.ldap-servers; }; - ip-host-map = let - networkHosts = getDomainHosts "fudo.org"; - ipHostPairs = - map (host: nameValuePair (getHostIpv4 host) (getHostFqdn host)) - networkHosts; - in listToAttrs ipHostPairs; + authoritative-dns = { + enable = hostname == primaryNameserver; - zones = let - defaultDeets = { - inherit (config.fudo.zones."fudo.org".hosts."${defaultHost}") - ipv4-address ipv6-address sshfp-records; - description = "fudo.org"; + container = { + hostname = "nameserver"; + interface = "enp5s0f0"; }; - in { - "fudo.org" = { - default-host = defaultDeets; - ksk = config.fudo.secrets.files.dns.key-signing-keys."fudo.org"; - reverse-zones = [ "208.81.1.128/28" "208.81.3.112/28" ]; + + nameservers = { + primary = primaryNameserver; + external = map (hostname: { + inherit (config.fudo.zones."fudo.org".hosts."${hostname}") + ipv4-address ipv6-address description; + }) [ "ns2-fudo" "ns3-fudo" "ns4-fudo" ]; }; - "test.fudo.org" = { - default-host = defaultDeets; - ksk = - config.fudo.secrets.files.dns.key-signing-keys."test.fudo.org"; - }; - "selby.ca" = { - default-host = defaultDeets; - ksk = config.fudo.secrets.files.dns.key-signing-keys."selby.ca"; - }; - "fudo.ca" = { - default-host = defaultDeets; - ksk = config.fudo.secrets.files.dns.key-signing-keys."fudo.ca"; - }; - "fudo.im" = { - default-host = defaultDeets; - ksk = config.fudo.secrets.files.dns.key-signing-keys."fudo.im"; - }; - "stewartsoundservices.ca" = { - default-host = defaultDeets; - ksk = - config.fudo.secrets.files.dns.key-signing-keys."stewartsoundservices.ca"; + + ip-host-map = let + networkHosts = getDomainHosts "fudo.org"; + ipHostPairs = + map (host: nameValuePair (getHostIpv4 host) (getHostFqdn host)) + networkHosts; + in listToAttrs ipHostPairs; + + zones = let + defaultDeets = { + inherit (config.fudo.zones."fudo.org".hosts."${defaultHost}") + ipv4-address ipv6-address sshfp-records; + description = "fudo.org"; + }; + + fudoMailservers = { + smtp-servers = [ "smtp.fudo.org." ]; + imap-servers = [ "imap.fudo.org." ]; + }; + + mkDomain = domain: extraConfig: + { + default-host = defaultDeets; + ksk = + config.fudo.secrets.files.dns.key-signing-keys."${domain}"; + } // extraConfig; + in { + "fudo.org" = mkDomain "fudo.org" { + reverse-zones = [ "208.81.1.128/28" "208.81.3.112/28" ]; + mail = fudoMailservers; + }; + "test.fudo.org" = mkDomain "test.fudo.org" { }; + "selby.ca" = mkDomain "selby.ca" { mail = fudoMailservers; }; + "fudo.ca" = mkDomain "fudo.ca" { mail = fudoMailservers; }; + "fudo.im" = mkDomain "fudo.im" { mail = fudoMailservers; }; + "stewartsoundservices.ca" = + mkDomain "stewartsoundservices.ca" { mail = fudoMailservers; }; + "fudo.live" = mkDomain "fudo.live" { mail = fudoMailservers; }; }; }; }; diff --git a/config/domain-config/fudo.org/authentik.nix b/config/domain-config/fudo.org/authentik.nix index 410d0d8..832e009 100644 --- a/config/domain-config/fudo.org/authentik.nix +++ b/config/domain-config/fudo.org/authentik.nix @@ -12,7 +12,13 @@ let authentikHostname = "authentik.${domainName}"; in { config = { - fudo.zones."${zoneName}".aliases.authentik = authentikHost; + fudo = { + users.authentik.ldap-hashed-passwd = + pkgs.lib.passwd.hash-ldap-passwd "authentik-smtp" + config.fudo.secrets.files.domain-secrets."${domainName}"."authentik-smtp.passwd"; + + zones."${zoneName}".aliases.authentik = authentikHost; + }; services = { authentikContainer = mkIf isAuthentik { @@ -25,7 +31,7 @@ in { smtp = { host = "mail.fudo.org"; password-file = - config.fudo.secrets.files.service-passwords."${authentikHost}".authentik-smtp; + config.fudo.secrets.files.domain-secrets."${domainName}"."authentik-smtp.passwd"; }; }; diff --git a/config/domain-config/fudo.org/mail-server.nix b/config/domain-config/fudo.org/mail-server.nix index 56c7ca6..0838535 100644 --- a/config/domain-config/fudo.org/mail-server.nix +++ b/config/domain-config/fudo.org/mail-server.nix @@ -11,6 +11,11 @@ let in { config = { + systemd.services.arion-mail-server = { + requires = [ "podman.service" ]; + after = [ "podman.service" ]; + }; + fudo = { acme.host-domains = { "imap.${primaryDomain}".extra-domain = [ "mail.${primaryDomain}" ]; diff --git a/config/domain-config/fudo.org/nameserver.nix b/config/domain-config/fudo.org/nameserver.nix new file mode 100644 index 0000000..ea13c68 --- /dev/null +++ b/config/domain-config/fudo.org/nameserver.nix @@ -0,0 +1,59 @@ +{ hostInterface, servedDomains, stateDirectory, ipHostMap, ... }: + +{ config, lib, pkgs, ... }: + +with lib; +let + inherit (pkgs.lib) getSiteGatewayV4; + + zoneName = "fudo.org"; + zone = config.fudo.zones."${zoneName}"; + nameserverDeets = zone.hosts."nameserver"; + siteName = config.instance.local-site; + +in { + config = { + systemd.tmpfiles.rules = [ "d ${stateDirectory} 700 root root - -" ]; + + containers.nameserver = { + autoStart = true; + # Needs to be able to set it's own IP(s) + additionalCapabilities = [ "CAP_NET_ADMIN" ]; + macvlans = [ hostInterface ]; + bindMounts."/var/lib/nsd".hostPath = stateDirectory; + + config = { + imports = [ pkgs.moduleRegistry.authoritativeDns ]; + + networking = { + defaultGateway = getSiteGatewayV4 siteName; + firewall = { + enable = true; + allowedTCPPorts = [ 53 ]; + allowedUDPPorts = [ 53 ]; + }; + interfaces."mv-${hostInterface}" = { + ipv4.addresses = optional (nameserverDeets.ipv4-address != null) { + address = nameserverDeets.ipv4-address; + prefixLength = getSiteV4PrefixLength siteName; + }; + ipv6.addresses = optional (nameserverDeets.ipv6-address != null) { + address = nameserverDeets.ipv6-address; + prefixLength = getSiteV6PrefixLength siteName; + }; + }; + }; + + services.authoritative-dns = { + enable = true; + identity = "nameserver.${zoneName}"; + listen-ips = [ nameserverDeets.ipv4-address ]; + state-directory = "/var/lib/nsd"; + timestamp = toString config.instance.build-timestamp; + ip-host-map = ipHostMap; + domains = servedDomains; + }; + }; + }; + }; +} diff --git a/config/domain-config/sea.fudo.org.nix b/config/domain-config/sea.fudo.org.nix index fff9d10..1a0c63f 100644 --- a/config/domain-config/sea.fudo.org.nix +++ b/config/domain-config/sea.fudo.org.nix @@ -1,3 +1,52 @@ { config, lib, pkgs, ... }: -{} +with lib; +let + hostname = config.instance.hostname; + hostSecrets = config.fudo.secrets.host-secrets."${hostname}"; + + frigateExternalHost = "sea-cam.fudo.link"; + frigateHost = "zbox"; + frigateDirectory = frigateCfg.state-directory; + frigateMqttPassword = + pkgs.lib.passwd.stablerandom-passwd-file "frigate-mqtt-passwd" + config.instance.build-seed; + +in { + config = { + fudo.zones."sea.fudo.org".aliases."frigate" = "zbox"; + fudo = { + services.mqtt.private.users.frigate = { + password-file = frigateMqttPassword; + acl = [ "frigate/#" ]; + }; + }; + + services = { + frigateContainer = { + enable = config.instance.hostname == frigateHost; + log-level = "info"; + images.frigate = "ghcr.io/blakeblackshear/frigate:0.13.0-beta5"; + cameras = + genAttrs [ "cam-steps" "cam-patio" "cam-entrance" "cam-driveway" ] + (cam: { + default = cam == "cam-driveway"; + streams = { + low = + "rtsp://frigate:{FRIGATE_RTSP_PASSWORD}@${cam}.sea.fudo.org:554/cam/realmonitor?channel=1&subtype=0"; + high = + "rtsp://frigate:{FRIGATE_RTSP_PASSWORD}@${cam}.sea.fudo.org:554/cam/realmonitor?channel=1&subtype=0"; + }; + }); + camera-password-file = + config.fudo.secrets.files.domain-secrets."sea.fudo.org".seattle-camera-password; + mqtt = { + host = config.fudo.services.mqtt.mqtt-hostname; + port = config.fudo.services.mqtt.private.port; + user = "frigate"; + password-file = frigateMqttPassword; + }; + }; + }; + }; +} diff --git a/config/domains/sea.fudo.org.nix b/config/domains/sea.fudo.org.nix index 2d1e0b4..77b084e 100644 --- a/config/domains/sea.fudo.org.nix +++ b/config/domains/sea.fudo.org.nix @@ -5,6 +5,8 @@ let fudo = config.fudo.domains."fudo.org"; in { config = { fudo = { + zones."sea.fudo.org" = { aliases.frigate = "zbox"; }; + domains."sea.fudo.org" = { local-networks = fudo.local-networks; diff --git a/config/hardware/zbox.nix b/config/hardware/zbox.nix index 559e2bd..627ce3f 100644 --- a/config/hardware/zbox.nix +++ b/config/hardware/zbox.nix @@ -16,44 +16,49 @@ extraModulePackages = [ ]; }; - system.stateVersion = "21.05"; + system.stateVersion = "23.05"; fileSystems = { "/" = { device = "zbox-root"; fsType = "tmpfs"; - options = [ "mode=755" ]; + options = [ "mode=755" "noexec" ]; }; "/boot" = { device = "/dev/disk/by-label/ZBOX-BOOT"; fsType = "vfat"; - options = [ "noexec" "noatime" "nodiratime" ]; + options = [ "noexec" "noatime" ]; }; "/state" = { device = "/dev/disk/by-label/zbox-data"; fsType = "btrfs"; - options = [ "noatime" "nodiratime" "compress=zstd" "subvol=@state" ]; + options = [ "noatime" "compress=zstd" "noexec" "subvol=@state" ]; }; "/nix" = { device = "/dev/disk/by-label/zbox-data"; fsType = "btrfs"; - options = [ "noatime" "nodiratime" "compress=zstd" "subvol=@nix" ]; + options = [ "noatime" "compress=zstd" "subvol=@nix" ]; }; "/var/log" = { device = "/dev/disk/by-label/zbox-data"; fsType = "btrfs"; - options = - [ "noatime" "nodiratime" "compress=zstd" "noexec" "subvol=@logs" ]; + options = [ "noatime" "compress=zstd" "noexec" "subvol=@log" ]; }; - "/home" = { + "/var/lib/containers" = { device = "/dev/disk/by-label/zbox-data"; fsType = "btrfs"; - options = [ "noatime" "nodiratime" "compress=zstd" "subvol=@home" ]; + options = [ "noatime" "compress=zstd" "noexec" "subvol=@containers" ]; + }; + + "/state/services/frigate" = { + device = "/dev/disk/by-label/zbox-recordings"; + fsType = "btrfs"; + options = [ "noatime" "compress=zstd" "noexec" ]; }; }; @@ -68,19 +73,16 @@ driSupport = true; driSupport32Bit = true; setLdLibraryPath = true; + extraPackages = with pkgs; [ nvidia-vaapi-driver vaapiVdpau ]; }; - pulseaudio = { - support32Bit = true; - package = pkgs.pulseaudioFull; + nvidia = { + package = config.boot.kernelPackages.nvidiaPackages.stable; + modesetting.enable = true; + powerManagement.enable = false; }; - enableRedistributableFirmware = true; - enableAllFirmware = true; - - # Required with Wayland? - nvidia.modesetting.enable = true; }; networking = { @@ -101,10 +103,7 @@ }; }; - services.xserver.videoDrivers = [ "nvidia" ]; - nix.settings.max-jobs = lib.mkDefault 8; - powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; systemd.targets = { sleep.enable = false; diff --git a/config/host-config/fimbria.nix b/config/host-config/fimbria.nix index 291c02d..0412d0d 100644 --- a/config/host-config/fimbria.nix +++ b/config/host-config/fimbria.nix @@ -1,7 +1,16 @@ { config, lib, pkgs, ... }: with lib; -let primaryIp = "10.0.0.2"; +let + primaryIp = "10.0.0.1"; + + hostname = config.instance.hostname; + domSecrets = + config.fudo.secrets.files.domain-secrets."${config.instance.local-domain}"; + hostSecrets = config.fudo.secrets.host-secrets."${hostname}"; + + authentikHost = "authentik.fudo.org"; + in { config = { networking = { @@ -26,7 +35,7 @@ in { firewall = { # Until it becomes the gateway, this is necessary - enable = mkForce true; + # enable = mkForce true; allowedTCPPorts = [ 80 443 25565 config.services.murmur.port ]; allowedUDPPorts = [ 25565 34197 ]; }; @@ -52,9 +61,62 @@ in { ]; }; + virtualisation = { + podman = { + enable = true; + dockerSocket.enable = true; + autoPrune.enable = true; + }; + docker.enable = false; + oci-containers = { + backend = "podman"; + containers = { + "sea-cam-auth-proxy" = { + image = "ghcr.io/goauthentik/proxy"; + autoStart = true; + environmentFiles = + [ hostSecrets.sea-cam-auth-proxy-env.target-file ]; + ports = [ "9000:9000" ]; + }; + "sea-red-auth-proxy" = { + image = "ghcr.io/goauthentik/proxy"; + autoStart = true; + environmentFiles = + [ hostSecrets.sea-red-auth-proxy-env.target-file ]; + ports = [ "9001:9000" ]; + }; + }; + }; + }; + fudo = { hosts.fimbria.external-interfaces = [ "enp1s0" ]; client.dns.external-interface = "enp1s0"; + + secrets.host-secrets."${hostname}" = { + sea-cam-auth-proxy-env = { + source-file = let + token = removeSuffix "\n" + (readFile domSecrets."seattle-camera-auth-proxy.token"); + in pkgs.writeText "sea-cam-auth-proxy.env" '' + AUTHENTIK_HOST=https://${authentikHost}/; + AUTHENTIK_TOKEN=${token} + AUTHENTIK_INSECURE=0 + ''; + target-file = "/run/sea-cam-auth-proxy/env"; + }; + sea-red-auth-proxy-env = { + source-file = let + token = removeSuffix "\n" + (readFile domSecrets."seattle-red-auth-proxy.token"); + in pkgs.writeText "sea-red-auth-proxy.env" '' + AUTHENTIK_HOST=https://${authentikHost}/; + AUTHENTIK_TOKEN=${token} + AUTHENTIK_INSECURE=0 + ''; + target-file = "/run/sea-red-auth-proxy/env"; + }; + }; services = { local-network = { enable = true; @@ -77,27 +139,92 @@ in { services = { ## TODO: enable when ready - # nginx = { - # enable = true; - # recommendedGzipSettings = true; - # recommendedOptimisation = true; - # recommendedProxySettings = true; + nginx = { + enable = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; - # virtualHosts = { - # "sea-home.fudo.link" = { - # enableACME = true; - # forceSSL = true; - # locations."/" = { - # proxyPass = "http://home-assist.sea.fudo.org/"; - # extraConfig = '' - # proxy_http_version 1.1; - # proxy_set_header Upgrade $http_upgrade; - # proxy_set_header Connection "Upgrade"; - # ''; - # }; - # }; - # }; - # }; + virtualHosts = let + authenticatedPassthrough = { target, authPort }: { + enableACME = true; + forceSSL = true; + locations = { + "/" = { + proxyPass = target; + proxyWebsockets = true; + extraConfig = '' + ############################## + # authentik-specific config + ############################## + auth_request /outpost.goauthentik.io/auth/nginx; + error_page 401 = @goauthentik_proxy_signin; + auth_request_set $auth_cookie $upstream_http_set_cookie; + add_header Set-Cookie $auth_cookie; + + # translate headers from the outposts back to the actual upstream + auth_request_set $authentik_username $upstream_http_x_authentik_username; + auth_request_set $authentik_groups $upstream_http_x_authentik_groups; + auth_request_set $authentik_email $upstream_http_x_authentik_email; + auth_request_set $authentik_name $upstream_http_x_authentik_name; + auth_request_set $authentik_uid $upstream_http_x_authentik_uid; + + proxy_set_header X-authentik-username $authentik_username; + proxy_set_header X-authentik-groups $authentik_groups; + proxy_set_header X-authentik-email $authentik_email; + proxy_set_header X-authentik-name $authentik_name; + proxy_set_header X-authentik-uid $authentik_uid; + ''; + }; + + "/outpost.goauthentik.io" = { + proxyPass = "http://127.0.0.1:${ + toString authPort + }/outpost.goauthentik.io"; + extraConfig = '' + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Original-URL $scheme://$http_host$request_uri; + add_header Set-Cookie $auth_cookie; + auth_request_set $auth_cookie $upstream_http_set_cookie; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + ''; + }; + + "@goauthentik_proxy_signin" = { + return = "302 /outpost.goauthentik.io/start?rd=$request_uri"; + extraConfig = '' + add_header Set-Cookie $auth_cookie; + internal; + ''; + }; + }; + }; + in { + "sea-home.fudo.link" = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://home-assist.sea.fudo.org/"; + extraConfig = '' + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + ''; + }; + }; + + "sea-cam.fudo.link" = authenticatedPassthrough { + target = "http://frigate.sea.fudo.org/"; + authPort = 9000; + }; + + "sea-red.fudo.link" = authenticatedPassthrough { + target = "http://node-red.sea.fudo.org/"; + authPort = 9001; + }; + }; + }; murmur = { enable = true; diff --git a/config/host-config/germany.nix b/config/host-config/germany.nix index 70ae693..a5c66ec 100644 --- a/config/host-config/germany.nix +++ b/config/host-config/germany.nix @@ -1,14 +1,16 @@ { config, lib, pkgs, ... }: +with pkgs.lib; let primary-ip = "208.81.3.116"; - dns-ip = "208.81.3.120"; hostname = config.instance.hostname; host = config.fudo.hosts."${hostname}"; domainName = host.domain; + domain = config.fudo.domains."${domainName}"; site = config.fudo.sites."${host.site}"; hostFqdn = "${hostname}.${domainName}"; hostSecrets = config.fudo.secrets.host-secrets."${hostname}"; + in { config = { networking = { @@ -25,16 +27,6 @@ in { prefixLength = 28; }]; }; - dnsif0 = { - ipv4.addresses = [{ - address = dns-ip; - prefixLength = 32; - }]; - }; - }; - firewall = { - enable = false; - interfaces.podman0.allowedUDPPorts = [ 53 ]; }; }; @@ -44,16 +36,24 @@ in { "d /state/services 0555 - - - -" ]; - services.fudo-mail-sync = { - path = with pkgs; [ rsync openssh ]; - serviceConfig = { - Type = "oneshot"; - ExecStart = pkgs.writeShellScript "fudo-mail-sync.sh" '' - ssh-add ~/.ssh/id_ed25519 - rsync -avz france.fudo.org:/srv/mail/mailboxes/ /state/services/mail/mail/ - chown 5025:5025 -R /state/services/mail/mail - chmod go-rwx -R /state/services/mail/mail - ''; + services = { + # This has been failing because NS keys aren't available yet + "container@nameserver" = { + after = [ "fudo-secrets.target" ]; + requires = [ "fudo-secrets.target" ]; + }; + + fudo-mail-sync = { + path = with pkgs; [ rsync openssh ]; + serviceConfig = { + Type = "oneshot"; + ExecStart = pkgs.writeShellScript "fudo-mail-sync.sh" '' + ssh-add ~/.ssh/id_ed25519 + rsync -avz france.fudo.org:/srv/mail/mailboxes/ /state/services/mail/mail/ + chown 5025:5025 -R /state/services/mail/mail + chmod go-rwx -R /state/services/mail/mail + ''; + }; }; }; @@ -92,6 +92,12 @@ in { nsd.zones."fudo.org".outgoingInterface = "extif0"; + # Necessary because germany isn't the default yet + postgresql = { + enable = true; + state-directory = "/state/services/postgresql"; + }; + services = { auth = { kerberos.state-directory = "/state/services/kerberos"; @@ -99,11 +105,18 @@ in { }; authoritative-dns.state-directory = "/state/services/dns"; jabber.state-directory = "/state/services/jabber"; + logging.loki.state-directory = "/state/services/loki"; metrics = { prometheus.state-directory = "/state/services/prometheus"; grafana.state-directory = "/state/services/grafana"; }; - logging.loki.state-directory = "/state/services/loki"; + postgresql = { + state-directory = "/state/services/postgresql"; + keytab = extractFudoKeytab { + realm = domain.gssapi-realm; + principals = [ "postgres/${hostFqdn}" ]; + }; + }; }; }; }; diff --git a/config/host-config/jazz.nix b/config/host-config/jazz.nix index a9fdcbb..c25b358 100644 --- a/config/host-config/jazz.nix +++ b/config/host-config/jazz.nix @@ -38,6 +38,15 @@ in { }; }; + fonts.fontconfig = { + hinting = { + enable = true; + style = "hintfull"; + }; + subpixel.lcdfilter = "default"; + antialias = true; + }; + environment.etc = { nixos.source = "/etc/nixos-live"; NIXOS.source = "${stateDir}/etc/NIXOS"; diff --git a/config/host-config/legatus.nix b/config/host-config/legatus.nix index 002abfc..4026ded 100644 --- a/config/host-config/legatus.nix +++ b/config/host-config/legatus.nix @@ -89,6 +89,7 @@ in { enable = true; dockerSocket.enable = true; autoPrune.enable = true; + defaultNetwork.settings.dns_enabled = true; }; }; @@ -154,19 +155,6 @@ in { external-interface = "extif0"; }; - # auth.kdc = { - # enable = true; - # realm = "FUDO.ORG"; - # bind-addresses = [ host-ipv4 "127.0.0.1" ]; - # master-key-file = - # secrets.heimdal-master-key.target-file; - # state-directory = "/state/kerberos"; - # slave-config = { - # master-host = "france"; - # ipropd-keytab = secrets.ipropd-keytab.target-file; - # }; - # }; - secure-dns-proxy = { enable = true; upstream-dns = diff --git a/config/host-config/limina.nix b/config/host-config/limina.nix index df621e6..b93f43b 100644 --- a/config/host-config/limina.nix +++ b/config/host-config/limina.nix @@ -10,6 +10,13 @@ let domain-name = host-config.domain; domain = config.fudo.domains.${domain-name}; + hostname = config.instance.hostname; + domSecrets = + config.fudo.secrets.files.domain-secrets."${config.instance.local-domain}"; + hostSecrets = config.fudo.secrets.host-secrets."${hostname}"; + + authentikHost = "authentik.fudo.org"; + # dns-proxy-port = 5335; in { @@ -84,6 +91,31 @@ in { }; fudo = { + secrets.host-secrets."${hostname}" = { + sea-cam-auth-proxy-env = { + source-file = let + token = removeSuffix "\n" + (readFile domSecrets."seattle-camera-auth-proxy.token"); + in pkgs.writeText "sea-cam-auth-proxy.env" '' + AUTHENTIK_HOST=https://${authentikHost}/; + AUTHENTIK_TOKEN=${token} + AUTHENTIK_INSECURE=0 + ''; + target-file = "/run/sea-cam-auth-proxy/env"; + }; + sea-red-auth-proxy-env = { + source-file = let + token = removeSuffix "\n" + (readFile domSecrets."seattle-red-auth-proxy.token"); + in pkgs.writeText "sea-red-auth-proxy.env" '' + AUTHENTIK_HOST=https://${authentikHost}/; + AUTHENTIK_TOKEN=${token} + AUTHENTIK_INSECURE=0 + ''; + target-file = "/run/sea-red-auth-proxy/env"; + }; + }; + hosts.limina.external-interfaces = [ "enp1s0" ]; client.dns.external-interface = "enp1s0"; @@ -139,6 +171,34 @@ in { systemd.services.nginx.requires = [ "bind.service" ]; + virtualisation = { + podman = { + enable = true; + dockerSocket.enable = true; + autoPrune.enable = true; + }; + docker.enable = false; + oci-containers = { + backend = "podman"; + containers = { + "sea-cam-auth-proxy" = { + image = "ghcr.io/goauthentik/proxy"; + autoStart = true; + environmentFiles = + [ hostSecrets.sea-cam-auth-proxy-env.target-file ]; + ports = [ "9000:9000" ]; + }; + "sea-red-auth-proxy" = { + image = "ghcr.io/goauthentik/proxy"; + autoStart = true; + environmentFiles = + [ hostSecrets.sea-red-auth-proxy-env.target-file ]; + ports = [ "9001:9000" ]; + }; + }; + }; + }; + services = { nginx = { enable = true; @@ -146,7 +206,62 @@ in { recommendedOptimisation = true; recommendedProxySettings = true; - virtualHosts = { + virtualHosts = let + authenticatedPassthrough = { target, authPort }: { + enableACME = true; + forceSSL = true; + locations = { + "/" = { + proxyPass = target; + proxyWebsockets = true; + extraConfig = '' + ############################## + # authentik-specific config + ############################## + auth_request /outpost.goauthentik.io/auth/nginx; + error_page 401 = @goauthentik_proxy_signin; + auth_request_set $auth_cookie $upstream_http_set_cookie; + add_header Set-Cookie $auth_cookie; + + # translate headers from the outposts back to the actual upstream + auth_request_set $authentik_username $upstream_http_x_authentik_username; + auth_request_set $authentik_groups $upstream_http_x_authentik_groups; + auth_request_set $authentik_email $upstream_http_x_authentik_email; + auth_request_set $authentik_name $upstream_http_x_authentik_name; + auth_request_set $authentik_uid $upstream_http_x_authentik_uid; + + proxy_set_header X-authentik-username $authentik_username; + proxy_set_header X-authentik-groups $authentik_groups; + proxy_set_header X-authentik-email $authentik_email; + proxy_set_header X-authentik-name $authentik_name; + proxy_set_header X-authentik-uid $authentik_uid; + ''; + }; + + "/outpost.goauthentik.io" = { + proxyPass = "http://127.0.0.1:${ + toString authPort + }/outpost.goauthentik.io"; + extraConfig = '' + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Original-URL $scheme://$http_host$request_uri; + add_header Set-Cookie $auth_cookie; + auth_request_set $auth_cookie $upstream_http_set_cookie; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + ''; + }; + + "@goauthentik_proxy_signin" = { + return = "302 /outpost.goauthentik.io/start?rd=$request_uri"; + extraConfig = '' + add_header Set-Cookie $auth_cookie; + internal; + ''; + }; + }; + }; + in { "sea-home.fudo.link" = { enableACME = true; forceSSL = true; @@ -159,6 +274,16 @@ in { ''; }; }; + + "sea-cam.fudo.link" = authenticatedPassthrough { + target = "http://frigate.sea.fudo.org/"; + authPort = 9000; + }; + + "sea-red.fudo.link" = authenticatedPassthrough { + target = "http://node-red.sea.fudo.org/"; + authPort = 9001; + }; }; }; diff --git a/config/host-config/nostromo.nix b/config/host-config/nostromo.nix index 9cebf91..8749c99 100644 --- a/config/host-config/nostromo.nix +++ b/config/host-config/nostromo.nix @@ -91,16 +91,6 @@ in { host-secrets = config.fudo.secrets.host-secrets.${hostname}; in { secrets.host-secrets.${hostname} = { - # grafana-database-password = { - # source-file = grafana-database-passwd-file; - # target-file = "/run/services/grafana/db.passwd"; - # user = config.systemd.services.grafana.serviceConfig.User; - # }; - # postgres-grafana-password = { - # source-file = grafana-database-passwd-file; - # target-file = "/run/services/postgres/db.passwd"; - # user = config.services.postgresql.superUser; - # }; pricebot-auth-token = { source-file = config.fudo.secrets.files.service-secrets.nostromo."pricebot-auth.token"; @@ -127,10 +117,6 @@ in { metrics.grafana = { state-directory = "/state/services/grafana"; smtp.hostname = "mail.fudo.org"; - # database = { - # user = "grafana"; - # password-file = host-secrets.grafana-database-password.target-file; - # }; ldap.base-dn = "dc=fudo,dc=org"; }; @@ -151,16 +137,26 @@ in { state-directory = "/state/services/postgresql"; databases.grafana.users = config.instance.local-admins; + }; - # users.grafana = { - # password-file = host-secrets.postgres-grafana-password.target-file; - # databases.grafana = { - # entity-access = { - # "ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES"; - # "ALL SEQUENCES IN SCHEMA public" = "ALL PRIVILEGES"; - # }; - # }; - # }; + services.gitea-container = { + enable = true; + site-name = "Seattle Fudo Git"; + hostname = "git.fudo.org"; + state-directory = "/state/services/gitea"; + trusted-networks = config.instance.local-networks; + openid-urls = [ "https://authentik.fudo.org/" ]; + secret-key-file = + pkgs.lib.passwd.stablerandom-passwd-file "gitea-seattle-secret-key" + config.instance.build-seed; + + networking = { + interface = "eno2"; + ipv4 = { + address = "10.0.0.15"; + prefixLength = 24; + }; + }; }; }; diff --git a/config/host-config/wormhole0.nix b/config/host-config/wormhole0.nix index c36d08e..e901b29 100644 --- a/config/host-config/wormhole0.nix +++ b/config/host-config/wormhole0.nix @@ -6,7 +6,6 @@ let primary-ip = "10.0.0.3"; state-dir = "/state"; zigbee2mqtt-statedir = "${state-dir}/services/zigbee2mqtt"; - home-assistant-port = 8123; zigbee2mqtt-user = config.systemd.services.zigbee2mqtt.serviceConfig.User; @@ -26,20 +25,20 @@ let pkgs.lib.passwd.stablerandom-passwd-file "node-red-mqtt-passwd" config.instance.build-seed; + homeAssistantPort = 8123; teslaMatePort = 4400; teslaGraphPort = 4401; - nodeRedPort = 1880; - host-secrets = config.fudo.secrets.host-secrets.${hostname}; - host-passwds = config.fudo.secrets.files.service-passwords.${hostname}; + host-secrets = config.fudo.secrets.host-secrets."${hostname}"; + host-passwds = config.fudo.secrets.files.service-passwords."${hostname}"; in { imports = [ (import ./wormhole0/home-assistant.nix { - homeAssistantImage = "ghcr.io/home-assistant/home-assistant:2023.9"; - nodeRedImage = "nodered/node-red:3.1.0-14"; - inherit nodeRedPort; + homeAssistantImage = "ghcr.io/home-assistant/home-assistant:2023.11.3"; + nodeRedImage = "nodered/node-red:3.1.1"; + inherit nodeRedPort homeAssistantPort; stateDirectory = "/state/services/arion-home-assistant"; }) ]; @@ -158,10 +157,9 @@ in { recommendedGzipSettings = true; virtualHosts = { - "home-assist.sea.fudo.org" = { locations."/" = { - proxyPass = "http://localhost:${toString home-assistant-port}"; + proxyPass = "http://localhost:${toString homeAssistantPort}"; proxyWebsockets = true; }; }; @@ -189,40 +187,6 @@ in { }; }; - # mosquitto = { - # enable = true; - # dataDir = mosquitto-statedir; - # listeners = [{ - # settings.allow_anonymous = false; - # port = 1883; - # address = "0.0.0.0"; - # users = { - # zigbee2mqtt = { - # passwordFile = - # host-secrets.mosquitto-zigbee2mqtt-passwd.target-file; - # acl = [ "readwrite #" ]; - # }; - # home-assistant = { - # passwordFile = - # host-secrets.mosquitto-home-assistant-passwd.target-file; - # acl = [ "readwrite #" ]; - # }; - # niten = { - # passwordFile = host-secrets.mosquitto-niten-passwd.target-file; - # acl = [ "readwrite #" ]; - # }; - # # xiaoxuan = { - # # passwordFile = host-secrets.mosquitto-xiaoxuan-passwd.target-file; - # # acl = [ "readwrite #" ]; - # # }; - # # wallfly = { - # # passwordFile = host-secrets.mosquitto-wallfly-passwd.target-file; - # # acl = [ "readwrite homeassistant/binary_sensor/#" ]; - # # }; - # }; - # }]; - # }; - zigbee2mqtt = { enable = true; dataDir = zigbee2mqtt-statedir; @@ -260,6 +224,7 @@ in { user = "tesla-mate"; password = readFile teslaMateMqttPasswdFile; }; + images.tesla-mate = "teslamate/teslamate:1.28.2"; port = teslaMatePort; grafana-port = teslaGraphPort; state-directory = "/state/services/tesla-mate"; @@ -280,20 +245,6 @@ in { }; arion.backend = "podman-socket"; - - # oci-containers = { - # backend = "podman"; - # containers = { - # home-assistant = { - # image = "homeassistant/home-assistant:stable"; - # autoStart = true; - # environment.TZ = config.time.timeZone; - # #ports = [ "${toString home-assistant-port}:8123" ]; - # volumes = [ "/state/services/home-assistant:/config" ]; - # extraOptions = [ "--network=host" ]; - # }; - # }; - # }; }; security.sudo.extraConfig = '' diff --git a/config/host-config/wormhole0/home-assistant.nix b/config/host-config/wormhole0/home-assistant.nix index f47642e..f4db4fb 100644 --- a/config/host-config/wormhole0/home-assistant.nix +++ b/config/host-config/wormhole0/home-assistant.nix @@ -1,4 +1,5 @@ -{ homeAssistantImage, nodeRedImage, nodeRedPort ? 1880, stateDirectory, ... }: +{ homeAssistantImage, nodeRedImage, nodeRedPort, homeAssistantPort +, stateDirectory, ... }: { config, lib, pkgs, ... }: @@ -56,6 +57,7 @@ in { "${stateDirectory}/config:/config" "/etc/localtime:/etc/localtime:ro" ]; + ports = [ "${toString homeAssistantPort}:8123" ]; user = "${toString homeAssistantUid}:${toString homeAssistantUid}"; network_mode = "host"; }; diff --git a/config/host-config/zbox.nix b/config/host-config/zbox.nix index 5a4e370..8272c14 100644 --- a/config/host-config/zbox.nix +++ b/config/host-config/zbox.nix @@ -1,51 +1,95 @@ { config, lib, pkgs, ... }: with lib; -let state-dir = "/state"; +let + primaryIp = pkgs.lib.getHostIpv4 "zbox"; + + openVinoModel = "ssdlite_mobilenet_v2"; + + libedgetpu = + config.boot.kernelPackages.callPackage ./zbox/pkgs/libedgetpu.nix { }; + in { config = { - fudo = { - slynk.enable = true; - wallfly.location = "family_room"; - }; - networking = { - interfaces.intif0.useDHCP = true; + useDHCP = false; + interfaces.intif0 = { + ipv4.addresses = [{ + address = primaryIp; + prefixLength = 22; + }]; + }; firewall.enable = false; - }; - - i18n.inputMethod = { - #enabled = "fcitx5"; - # fcitx5.addons = with pkgs; [ fcitx5-chinese-addons fcitx5-rime ]; - }; - - systemd.tmpfiles.rules = [ - "d ${state-dir}/lib/cups 755 root root - -" - "d ${state-dir}/lib/flatpak 0755 root root - -" - "d ${state-dir}/etc 0755 root root - -" - "L /var/lib/flatpak - - - - ${state-dir}/lib/flatpak" - "L /etc/adjtime - - - - ${state-dir}/etc/adjtime" - ]; - - fileSystems = { - "/var/lib/cups" = { - device = "${state-dir}/lib/cups"; - options = [ "bind" ]; + defaultGateway = { + address = "10.0.0.1"; + interface = "intif0"; }; }; - hardware = { - bluetooth = { + boot = let + gasket = + config.boot.kernelPackages.callPackage ./zbox/pkgs/gasket.nix { }; + in { + extraModulePackages = [ gasket ]; + kernelModules = [ "gasket" ]; + }; + + users.groups.plugdev = { }; + + virtualisation = { + podman = { enable = true; - package = pkgs.bluezFull; + dockerSocket.enable = true; + autoPrune.enable = true; + enableNvidia = true; }; - xpadneo.enable = true; + + arion.backend = "podman-socket"; }; - services.xserver = { - layout = "us"; - xkbVariant = mkForce ""; - xkbOptions = mkForce ""; + services = { + frigateContainer = { + state-directory = "/state/services/frigate"; + # hwaccel = "preset-vaapi"; + devices = [ "/dev/apex_0" "/dev/dri/renderD128" ]; + detectors = { + coral = { + type = "edgetpu"; + device = ""; + }; + }; + }; + udev = { + packages = [ "${libedgetpu}" ]; + extraRules = '' + SUBSYSTEM=="pci",ATTRS{device}=="089a",GROUP="plugdev" + SUBSYSTEM=="apex",ATTRS{device_type}=="apex",GROUP="plugdev" + ''; + }; + + xserver = { + enable = mkForce true; + videoDrivers = [ "nvidia" ]; + }; + + nginx = { + enable = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + + virtualHosts."frigate.sea.fudo.org" = { + locations."/" = { + proxyPass = "http://localhost:5000"; + proxyWebsockets = true; + }; + }; + }; }; + + security.sudo.extraConfig = '' + # Due to rollback, sudo will lecture after every reboot + Defaults lecture = never + ''; }; } diff --git a/config/host-config/zbox/pkgs/gasket.nix b/config/host-config/zbox/pkgs/gasket.nix new file mode 100644 index 0000000..4a2e23d --- /dev/null +++ b/config/host-config/zbox/pkgs/gasket.nix @@ -0,0 +1,36 @@ +{ stdenv, lib, fetchFromGitHub, kernel }: + +stdenv.mkDerivation rec { + pname = "gasket"; + version = "1.0-18"; + + src = fetchFromGitHub { + owner = "google"; + repo = "gasket-driver"; + rev = "97aeba584efd18983850c36dcf7384b0185284b3"; + sha256 = "pJwrrI7jVKFts4+bl2xmPIAD01VKFta2SRuElerQnTo="; + }; + + makeFlags = [ + "-C" + "${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" + "M=$(PWD)" + ]; + buildFlags = [ "modules" ]; + + installFlags = [ "INSTALL_MOD_PATH=${placeholder "out"}" ]; + installTargets = [ "modules_install" ]; + + sourceRoot = "source/src"; + hardeningDisable = [ "pic" "format" ]; + nativeBuildInputs = kernel.moduleBuildDependencies; + + meta = with lib; { + description = + "The Coral Gasket Driver allows usage of the Coral EdgeTPU on Linux systems."; + homepage = "https://github.com/google/gasket-driver"; + license = licenses.gpl2; + maintainers = [ lib.maintainers.kylehendricks ]; + platforms = platforms.linux; + }; +} diff --git a/config/host-config/zbox/pkgs/libedgetpu-stddef.diff b/config/host-config/zbox/pkgs/libedgetpu-stddef.diff new file mode 100644 index 0000000..37eebef --- /dev/null +++ b/config/host-config/zbox/pkgs/libedgetpu-stddef.diff @@ -0,0 +1,12 @@ +diff --git a/api/allocated_buffer.h b/api/allocated_buffer.h +index 97740f0..7bc0547 100644 +--- a/api/allocated_buffer.h ++++ b/api/allocated_buffer.h +@@ -16,6 +16,7 @@ + #define DARWINN_API_ALLOCATED_BUFFER_H_ + + #include ++#include + + namespace platforms { + namespace darwinn { diff --git a/config/host-config/zbox/pkgs/libedgetpu.nix b/config/host-config/zbox/pkgs/libedgetpu.nix new file mode 100644 index 0000000..94c2118 --- /dev/null +++ b/config/host-config/zbox/pkgs/libedgetpu.nix @@ -0,0 +1,57 @@ +{ stdenv, lib, fetchFromGitHub, libusb1, abseil-cpp, flatbuffers, xxd }: + +let + flatbuffers_1_12 = flatbuffers.overrideAttrs (oldAttrs: rec { + version = "1.12.0"; + NIX_CFLAGS_COMPILE = + "-Wno-error=class-memaccess -Wno-error=maybe-uninitialized"; + cmakeFlags = (oldAttrs.cmakeFlags or [ ]) + ++ [ "-DFLATBUFFERS_BUILD_SHAREDLIB=ON" ]; + NIX_CXXSTDLIB_COMPILE = "-std=c++17"; + configureFlags = (oldAttrs.configureFlags or [ ]) ++ [ "--enable-shared" ]; + src = fetchFromGitHub { + owner = "google"; + repo = "flatbuffers"; + rev = "v${version}"; + sha256 = "sha256-L1B5Y/c897Jg9fGwT2J3+vaXsZ+lfXnskp8Gto1p/Tg="; + }; + }); + +in stdenv.mkDerivation rec { + pname = "libedgetpu"; + version = "grouper"; + + src = fetchFromGitHub { + owner = "google-coral"; + repo = pname; + rev = "release-${version}"; + sha256 = "sha256-73hwItimf88Iqnb40lk4ul/PzmCNIfdt6Afi+xjNiBE="; + }; + + patches = [ ./libedgetpu-stddef.diff ]; + + makeFlags = [ "-f" "makefile_build/Makefile" "libedgetpu" ]; + + buildInputs = [ libusb1 abseil-cpp flatbuffers_1_12 ]; + + nativeBuildInputs = [ xxd ]; + + NIX_CXXSTDLIB_COMPILE = "-std=c++17"; + + TFROOT = "${fetchFromGitHub { + owner = "tensorflow"; + repo = "tensorflow"; + rev = "v2.7.4"; + sha256 = "sha256-liDbUAdaVllB0b74aBeqNxkYNu/zPy7k3CevzRF5dk0="; + }}"; + + enableParallelBuilding = false; + + installPhase = '' + mkdir -p $out/lib + cp out/direct/k8/libedgetpu.so.1.0 $out/lib + ln -s $out/lib/libedgetpu.so.1.0 $out/lib/libedgetpu.so.1 + mkdir -p $out/lib/udev/rules.d + cp debian/edgetpu-accelerator.rules $out/lib/udev/rules.d/99-edgetpu-accelerator.rules + ''; +} diff --git a/config/service/authoritative-dns.nix b/config/service/authoritative-dns.nix index d57c0ff..daa378d 100644 --- a/config/service/authoritative-dns.nix +++ b/config/service/authoritative-dns.nix @@ -6,51 +6,133 @@ let cfg = config.fudo.services.authoritative-dns; + inherit (pkgs.lib) + getHostIps getSiteGatewayV4 getSiteV4PrefixLength getSiteV6PrefixLength; + hostSecrets = config.fudo.secrets.host-secrets."${hostname}"; domainName = config.instance.local-domain; + primaryZone = config.fudo.domains."${domainName}".zone; + + siteName = config.instance.local-site; + zoneKeySecret = zone: "${zone}-ksk"; - networkHostOpts = { - options = with types; { - hostname = mkOption { - type = str; - description = "Hostname."; - }; - ipv4-address = mkOption { - type = nullOr str; - description = "The V4 IP of a given host, if any."; - default = null; - }; + containerModule = { pkgs, config, ... }: { + config = mkIf (cfg.enable && !isNull cfg.container) { + containers.nameserver = let + securedZones = + filterAttrs (_: zoneOpts: !isNull zoneOpts.ksk) cfg.zones; + in { + autoStart = true; + additionalCapabilities = [ "CAP_NET_ADMIN" ]; + macvlans = [ cfg.container.interface ]; + bindMounts = { + "/var/lib/nsd" = { + hostPath = cfg.state-directory; + isReadOnly = false; + }; + } // (mapAttrs' (zoneName: _: + let zoneKeyName = zoneKeySecret zoneName; + in nameValuePair "/run/nsd/keys/${zoneKeyName}" { + hostPath = hostSecrets."${zoneKeyName}".target-file; + }) securedZones); + config = let + nameserverHost = cfg.container.hostname; + nameserverDeets = + config.fudo.zones."${primaryZone}".hosts."${nameserverHost}"; + in { + imports = [ pkgs.moduleRegistry.authoritativeDns ]; + nixpkgs.pkgs = pkgs; + networking = { + defaultGateway = { + address = getSiteGatewayV4 siteName; + interface = "mv-${cfg.container.interface}"; + }; + firewall = { + enable = true; + allowedTCPPorts = [ 53 ]; + allowedUDPPorts = [ 53 ]; + }; + interfaces."mv-${cfg.container.interface}" = { + ipv4.addresses = optional (nameserverDeets.ipv4-address != null) { + address = trace "IP ADDRESS: ${nameserverDeets.ipv4-address}" + nameserverDeets.ipv4-address; + prefixLength = getSiteV4PrefixLength siteName; + }; + ipv6.addresses = optional (nameserverDeets.ipv6-address != null) { + address = nameserverDeets.ipv6-address; + prefixLength = getSiteV6PrefixLength siteName; + }; + }; + }; + services.authoritative-dns = { + enable = true; - ipv6-address = mkOption { - type = nullOr str; - description = "The V6 IP of a given host, if any."; - default = null; - }; + identity = "${nameserverHost}.${primaryZone}"; - mac-address = mkOption { - type = nullOr str; - description = - "The MAC address of a given host, if desired for IP reservation."; - default = null; - }; + listen-ips = getHostIps nameserverHost; - description = mkOption { - type = nullOr str; - description = "Description of the host."; - default = null; - }; + state-directory = "/var/lib/nsd"; - sshfp-records = mkOption { - type = listOf str; - description = "List of SSHFP records for this host."; - default = [ ]; + timestamp = toString config.instance.build-timestamp; + + ip-host-map = cfg.ip-host-map; + + domains = mapAttrs' (zoneName: zoneCfg: + nameValuePair zoneCfg.domain { + ksk.key-file = "/run/nsd/keys/${zoneKeySecret zoneName}"; + reverse-zones = zoneCfg.reverse-zones; + notify = mkIf cfg.enable-notifications { + ipv4 = concatMap + (ns: optional (ns.ipv4-address != null) ns.ipv4-address) + cfg.nameservers.external; + ipv6 = concatMap + (ns: optional (ns.ipv6-address != null) ns.ipv6-address) + cfg.nameservers.external; + }; + zone = config.fudo.zones."${zoneName}"; + }) cfg.zones; + }; + }; }; }; }; + hostModule = { config, ... }: { + config.services.authoritative-dns = + mkIf (cfg.enable && isNull cfg.container) { + enable = true; + + identity = "${hostname}.${primaryZone}"; + + listen-ips = getHostIps hostname; + + state-directory = "/var/lib/nsd"; + + timestamp = toString config.instance.build-timestamp; + + ip-host-map = cfg.ip-host-map; + + domains = mapAttrs' (zoneName: zoneCfg: + nameValuePair zoneCfg.domain { + ksk.key-file = mkIf (hasAttr (zoneKeySecret zoneName) hostSecrets) + hostSecrets."${zoneKeySecret zoneName}".target-file; + reverse-zones = zoneCfg.reverse-zones; + notify = mkIf cfg.enable-notifications { + ipv4 = concatMap + (ns: optional (ns.ipv4-address != null) ns.ipv4-address) + cfg.nameservers.external; + ipv6 = concatMap + (ns: optional (ns.ipv6-address != null) ns.ipv6-address) + cfg.nameservers.external; + }; + zone = config.fudo.zones."${zoneName}"; + }) cfg.zones; + }; + }; + zoneOpts = { name, ... }: let zoneName = name; in { @@ -62,7 +144,7 @@ let }; default-host = mkOption { - type = nullOr (submodule networkHostOpts); + type = nullOr (submodule pkgs.lib.fudo-types.networkHost); description = "Host which will respond to requests for the base domain."; default = null; @@ -123,6 +205,27 @@ in { options.fudo.services.authoritative-dns = with types; { enable = mkEnableOption "Enable Authoritative DNS server."; + container = mkOption { + type = nullOr (submodule { + options = { + interface = mkOption { + type = str; + description = "Interface on which to listen for DNS traffic."; + }; + + hostname = mkOption { + type = str; + description = '' + Hostname (in the zone) of the container nameserver. + + The associated IP(s) will be assigned to the container, + and must be accessible. + ''; + }; + }; + }); + }; + enable-notifications = mkEnableOption "Enable notifications to secondary servers."; @@ -152,7 +255,7 @@ in { }; external = mkOption { - type = listOf (submodule networkHostOpts); + type = listOf (submodule pkgs.lib.fudo-types.networkHost); description = "List of external secondary nameserver attributes."; default = [ ]; }; @@ -165,15 +268,23 @@ in { }; }; - config = { + imports = [ hostModule containerModule ]; + + config = mkIf cfg.enable { + systemd.tmpfiles.rules = [ "d ${cfg.state-directory} 700 root root - -" ]; + + fileSystems."/var/lib/nsd" = mkIf (isNull cfg.container) { + device = cfg.state-directory; + options = [ "bind" ]; + }; + fudo = { - secrets.host-secrets."${hostname}" = mkIf cfg.enable (mapAttrs' - (zone: zoneCfg: - nameValuePair (zoneKeySecret zone) { - source-file = zoneCfg.ksk.private-key; - target-file = "/run/nsd/${baseNameOf zoneCfg.ksk.private-key}"; - user = config.fudo.nsd.user; - }) (filterAttrs (_: zoneCfg: zoneCfg.ksk != null) cfg.zones)); + secrets.host-secrets."${hostname}" = mapAttrs' (zone: zoneCfg: + nameValuePair (zoneKeySecret zone) { + source-file = zoneCfg.ksk.private-key; + target-file = "/run/nsd/${baseNameOf zoneCfg.ksk.private-key}"; + user = config.fudo.nsd.user; + }) (filterAttrs (_: zoneCfg: zoneCfg.ksk != null) cfg.zones); zones = mapAttrs (zone-name: zoneCfg: let @@ -256,38 +367,5 @@ in { ]; }) cfg.zones; }; - - services = { - authoritative-dns = { - enable = cfg.enable; - - identity = "${hostname}.${domainName}"; - - listen-ips = - optionals cfg.enable (pkgs.lib.network.host-ips config hostname); - - state-directory = cfg.state-directory; - - timestamp = toString config.instance.build-timestamp; - - ip-host-map = cfg.ip-host-map; - - domains = mapAttrs' (zoneName: zoneCfg: - nameValuePair zoneCfg.domain { - ksk.key-file = mkIf (hasAttr (zoneKeySecret zoneName) hostSecrets) - hostSecrets."${zoneKeySecret zoneName}".target-file; - reverse-zones = zoneCfg.reverse-zones; - notify = mkIf cfg.enable-notifications { - ipv4 = concatMap - (ns: optional (ns.ipv4-address != null) ns.ipv4-address) - cfg.nameservers.external; - ipv6 = concatMap - (ns: optional (ns.ipv6-address != null) ns.ipv6-address) - cfg.nameservers.external; - }; - zone = config.fudo.zones."${zoneName}"; - }) cfg.zones; - }; - }; }; } diff --git a/config/service/gitea-container.nix b/config/service/gitea-container.nix new file mode 100644 index 0000000..6e4a544 --- /dev/null +++ b/config/service/gitea-container.nix @@ -0,0 +1,208 @@ +{ config, lib, pkgs, ... }: + +with lib; +let cfg = config.fudo.services.gitea-container; + +in { + options.fudo.services.gitea-container = with types; { + enable = mkEnableOption "Enable Gitea running in a container."; + + site-name = mkOption { + type = str; + description = "Name of this Gitea instance."; + }; + + hostname = mkOption { + type = str; + description = "Hostname at which the server is reachable."; + }; + + state-directory = mkOption { + type = str; + description = "Path at which to store Gitea state."; + }; + + secret-key-file = mkOption { + type = str; + description = + "Path to file containing Gitea secret key, for encrypting secrets."; + }; + + trusted-networks = mkOption { + type = listOf str; + description = + "List of networks to be considered trusted (for metrics access)."; + default = [ ]; + }; + + openid-urls = mkOption { + type = listOf str; + description = "List of authorized OpenID providers."; + }; + + networking = { + interface = mkOption { + type = str; + description = "Parent host interface on which to listen."; + }; + + ipv4 = mkOption { + type = nullOr (submodule { + options = { + address = mkOption { + type = str; + description = "IP address."; + }; + prefixLength = mkOption { + type = int; + description = "Significant bits in the address."; + }; + }; + }); + default = null; + }; + + ipv6 = mkOption { + type = nullOr (submodule { + options = { + address = mkOption { + type = str; + description = "IP address."; + }; + prefixLength = mkOption { + type = int; + description = "Significant bits in the address."; + }; + }; + }); + default = null; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.tmpfiles.rules = [ "d ${cfg.state-directory} 700 root root - -" ]; + + containers.gitea = { + autoStart = true; + additionalCapabilities = [ "CAP_NET_ADMIN" ]; + macvlans = [ cfg.networking.interface ]; + bindMounts = { + "/state" = { + hostPath = cfg.state-directory; + isReadOnly = false; + }; + }; + config = { + nixpkgs.pkgs = pkgs; + + systemd = { tmpfiles.rules = [ "d /state 0755 root root - -" ]; }; + + networking = { + defaultGateway = config.networking.defaultGateway; + enableIPv6 = !isNull cfg.networking.ipv6; + firewall = { + enable = true; + allowedTCPPorts = [ 22 80 443 ]; + }; + interfaces."mv-${cfg.networking.interface}" = { + ipv4.addresses = optional (!isNull cfg.networking.ipv4) { + address = cfg.networking.ipv4.address; + prefixLength = cfg.networking.ipv4.prefixLength; + }; + ipv6.addresses = optional (!isNull cfg.networking.ipv6) { + address = cfg.networking.ipv6.address; + prefixLength = cfg.networking.ipv6.prefixLength; + }; + }; + }; + + services = { + gitea = { + enable = true; + appName = cfg.site-name; + database = { + createDatabase = true; + type = "sqlite3"; + }; + repositoryRoot = "/state/repositories"; + stateDir = "/state/gitea"; + settings = { + service.DISABLE_REGISTRATION = true; + security = { + INSTALL_LOCK = true; + SECRET_KEY = "file:${cfg.secret-key-file}"; + LOGIN_REMEMBER_DAYS = 30; + }; + metrics.ENABLED = cfg.trusted-networks != [ ]; + server = { + START_SSH_SERVER = true; + + # Host & port to display in the clone URL + SSH_DOMAIN = cfg.hostname; + SSH_PORT = 22; + + SSH_LISTEN_PORT = 2222; + SSH_LISTEN_HOST = "0.0.0.0"; + + DOMAIN = cfg.hostname; + ROOT_URL = "https://${cfg.hostname}"; + + HTTP_ADDR = "127.0.0.1"; + HTTP_PORT = 8080; + }; + openid = { + ENABLE_OPENID_SIGNIN = true; + WHITELISTED_URIS = cfg.openid-urls; + }; + oauth2_client = { + REGISTER_EMAIL_CONFIRM = false; + OPENID_CONNECT_SCOPES = [ "email" "profile" ]; + ENABLE_AUTO_REGISTRATION = true; + USERNAME = "email"; + UPDATE_AVATAR = true; + ACCOUNT_LINKING = "login"; + }; + }; + }; + + xinetd = { + enable = true; + services = [{ + name = "ssh"; + # port = 22; + # protocol = "tcp"; + extraConfig = '' + redirect = localhost 2222 + wait = no + socket_type = stream + ''; + user = "nobody"; + # Must be defined, but not used + server = "/usr/bin/env"; + # unlisted = true; + }]; + }; + + nginx = { + enable = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + recommendedGzipSettings = true; + virtualHosts."${cfg.hostname}" = { + # enableACME = true; + # forceSSL = true; + locations."/".proxyPass = "http://127.0.0.1:8080"; + locations."/metrics" = mkIf (cfg.trusted-networks != [ ]) (let + networkAllowClauses = + map (net: "allow ${net};") cfg.trusted-networks; + in concatStringsSep "\n" + (networkAllowClauses ++ [ "deny all;" ])); + }; + }; + }; + }; + }; + }; +} diff --git a/config/service/local-network.nix b/config/service/local-network.nix index f2480e7..90360cc 100644 --- a/config/service/local-network.nix +++ b/config/service/local-network.nix @@ -134,11 +134,12 @@ in { dns = { listen-ips = [ "127.0.0.1" ]; listen-port = agp.dns-listen-port; + reverse-dns = [ (host-ipv4 gateway-host) ]; }; local-domain-name = domain-name; }; - zones.${zone-name} = { + zones."${zone-name}" = { aliases = { "${agp.http-host-alias}" = mkIf (agp.enable) (fqdn gateway-host); ns = (fqdn nameserver-host); diff --git a/config/service/postgresql.nix b/config/service/postgresql.nix index 6661de7..6e1c920 100644 --- a/config/service/postgresql.nix +++ b/config/service/postgresql.nix @@ -38,8 +38,8 @@ in { config = mkIf postgresEnabled { fudo = { - acme.host-domains.${hostname} = mkIf (publicNetwork && isPostgresHost) { - ${postgresql-hostname}.local-copies = { + acme.host-domains."${hostname}" = mkIf (publicNetwork && isPostgresHost) { + "${postgresql-hostname}".local-copies = { postgresql = { user = postgresUser; dependent-services = [ "postgresql.service" ]; @@ -48,15 +48,15 @@ in { }; }; - secrets.host-secrets.${hostname}.postgres-keytab = + secrets.host-secrets."${hostname}".postgres-keytab = mkIf (cfg.keytab != null) { source-file = cfg.keytab; target-file = "/run/postgresql/postgres.keytab"; user = postgresUser; }; - zones.${zone-name}.aliases.postgresql = - "${domain.postgresql-server}.${domain-name}."; + zones."${zone-name}".aliases.postgresql = + pkgs.lib.getHostFqdn domain.postgresql-server; postgresql = mkIf isPostgresHost (let ssl-config = optionalAttrs publicNetwork (let diff --git a/config/service/tattler.nix b/config/service/tattler.nix index 96938af..5b41b1d 100644 --- a/config/service/tattler.nix +++ b/config/service/tattler.nix @@ -38,6 +38,8 @@ in { }; config = mkIf cfg.enable { + systemd.services.snooper.after = mkIf isSnooper [ "fudo-secrets.target" ]; + fudo = { secrets.host-secrets."${hostname}" = { snooper-passwd = mkIf isSnooper { diff --git a/config/services.nix b/config/services.nix index 14035f1..deb665f 100644 --- a/config/services.nix +++ b/config/services.nix @@ -8,6 +8,7 @@ ./service/chute.nix ./service/dns.nix ./service/fudo-auth.nix + ./service/gitea-container.nix ./service/jabber.nix ./service/lemmy.nix ./service/local-network.nix diff --git a/config/users.nix b/config/users.nix index ea62f0d..0f02896 100644 --- a/config/users.nix +++ b/config/users.nix @@ -633,6 +633,12 @@ with lib; { ldap-hashed-passwd = "{SSHA}mok5LrQtJ4pny2QTaN3sMmOZx6X0eg5R"; email = "jasper@selby.ca"; }; + + authentik = { + uid = 10117; + primary-group = "fudo"; + common-name = "Fudo Authentik"; + }; }; groupDomainMap = { diff --git a/flake.lock b/flake.lock index 85a6625..45bd4aa 100644 --- a/flake.lock +++ b/flake.lock @@ -10,11 +10,11 @@ ] }, "locked": { - "lastModified": 1692787336, - "narHash": "sha256-WabgeYsUiMRbpb1bCT3oY6GJEciZQIf3tYD8RQAUf2c=", + "lastModified": 1701196744, + "narHash": "sha256-ZCuplnqMIIPs5zCPgYEp+m7mHqFh8Fy0lJD3ybZ/h0w=", "owner": "hercules-ci", "repo": "arion", - "rev": "28902d348807c494115177595f812a3e54cc913b", + "rev": "39030b95666e018230dc9b85d76dc6e5b617ab87", "type": "github" }, "original": { @@ -28,14 +28,35 @@ "flake-parts": "flake-parts_4", "haskell-flake": "haskell-flake_3", "hercules-ci-effects": "hercules-ci-effects_2", - "nixpkgs": "nixpkgs_17" + "nixpkgs": "nixpkgs_5" }, "locked": { - "lastModified": 1692787336, - "narHash": "sha256-WabgeYsUiMRbpb1bCT3oY6GJEciZQIf3tYD8RQAUf2c=", + "lastModified": 1701196744, + "narHash": "sha256-ZCuplnqMIIPs5zCPgYEp+m7mHqFh8Fy0lJD3ybZ/h0w=", "owner": "hercules-ci", "repo": "arion", - "rev": "28902d348807c494115177595f812a3e54cc913b", + "rev": "39030b95666e018230dc9b85d76dc6e5b617ab87", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "arion", + "type": "github" + } + }, + "arion_3": { + "inputs": { + "flake-parts": "flake-parts_7", + "haskell-flake": "haskell-flake_5", + "hercules-ci-effects": "hercules-ci-effects_3", + "nixpkgs": "nixpkgs_19" + }, + "locked": { + "lastModified": 1701196744, + "narHash": "sha256-ZCuplnqMIIPs5zCPgYEp+m7mHqFh8Fy0lJD3ybZ/h0w=", + "owner": "hercules-ci", + "repo": "arion", + "rev": "39030b95666e018230dc9b85d76dc6e5b617ab87", "type": "github" }, "original": { @@ -54,11 +75,11 @@ ] }, "locked": { - "lastModified": 1697266532, - "narHash": "sha256-eMEo7+gfw/6ECwepRVH3yj2E6Uu1nL38HtCI7XhxZIY=", + "lastModified": 1701468840, + "narHash": "sha256-g20HI6QFYCm9+QSvqith/2nHOr8w6u6/8t+Su5bOgy4=", "ref": "refs/heads/master", - "rev": "abbcb42878cde0733bee50cf1553ef292ad9bc53", - "revCount": 14, + "rev": "799fd044465e903120df2ae33a315cc752eda0d6", + "revCount": 20, "type": "git", "url": "https://git.fudo.org/fudo-nix/authentik-container.git" }, @@ -69,16 +90,17 @@ }, "authoritative-dns": { "inputs": { + "fudo-lib": "fudo-lib", "nixpkgs": [ "nixpkgs" ] }, "locked": { - "lastModified": 1699566671, - "narHash": "sha256-KHqewz+ZXx70MvSgFLFjuW9+hK6ZN+8+XJk6/2chqVM=", + "lastModified": 1700444903, + "narHash": "sha256-UAkNtgkB1qI2gWjjCh0dedtGoPJWhjjfUTu7oCrFOD8=", "ref": "refs/heads/master", - "rev": "68184b1f23b371f90d3c3b74f90de1e967127595", - "revCount": 85, + "rev": "1671cece1cde85578be9aee9c84b0ff7a0793c76", + "revCount": 91, "type": "git", "url": "https://git.fudo.org/fudo-public/authoritative-dns.git" }, @@ -554,7 +576,7 @@ "clj2nix_10": { "inputs": { "flake-compat": "flake-compat_11", - "nixpkgs": "nixpkgs_19", + "nixpkgs": "nixpkgs_21", "utils": "utils_25" }, "locked": { @@ -574,7 +596,7 @@ "clj2nix_11": { "inputs": { "flake-compat": "flake-compat_12", - "nixpkgs": "nixpkgs_20", + "nixpkgs": "nixpkgs_22", "utils": "utils_28" }, "locked": { @@ -594,7 +616,7 @@ "clj2nix_12": { "inputs": { "flake-compat": "flake-compat_13", - "nixpkgs": "nixpkgs_22", + "nixpkgs": "nixpkgs_24", "utils": "utils_34" }, "locked": { @@ -614,7 +636,7 @@ "clj2nix_13": { "inputs": { "flake-compat": "flake-compat_14", - "nixpkgs": "nixpkgs_23", + "nixpkgs": "nixpkgs_25", "utils": "utils_37" }, "locked": { @@ -634,7 +656,7 @@ "clj2nix_14": { "inputs": { "flake-compat": "flake-compat_15", - "nixpkgs": "nixpkgs_24", + "nixpkgs": "nixpkgs_26", "utils": "utils_40" }, "locked": { @@ -654,7 +676,7 @@ "clj2nix_15": { "inputs": { "flake-compat": "flake-compat_16", - "nixpkgs": "nixpkgs_25", + "nixpkgs": "nixpkgs_27", "utils": "utils_42" }, "locked": { @@ -694,7 +716,7 @@ "clj2nix_3": { "inputs": { "flake-compat": "flake-compat_4", - "nixpkgs": "nixpkgs_4", + "nixpkgs": "nixpkgs_6", "utils": "utils_5" }, "locked": { @@ -714,7 +736,7 @@ "clj2nix_4": { "inputs": { "flake-compat": "flake-compat_5", - "nixpkgs": "nixpkgs_6", + "nixpkgs": "nixpkgs_8", "utils": "utils_7" }, "locked": { @@ -734,7 +756,7 @@ "clj2nix_5": { "inputs": { "flake-compat": "flake-compat_6", - "nixpkgs": "nixpkgs_9", + "nixpkgs": "nixpkgs_11", "utils": "utils_9" }, "locked": { @@ -754,7 +776,7 @@ "clj2nix_6": { "inputs": { "flake-compat": "flake-compat_7", - "nixpkgs": "nixpkgs_11", + "nixpkgs": "nixpkgs_13", "utils": "utils_11" }, "locked": { @@ -774,7 +796,7 @@ "clj2nix_7": { "inputs": { "flake-compat": "flake-compat_8", - "nixpkgs": "nixpkgs_12", + "nixpkgs": "nixpkgs_14", "utils": "utils_14" }, "locked": { @@ -794,7 +816,7 @@ "clj2nix_8": { "inputs": { "flake-compat": "flake-compat_9", - "nixpkgs": "nixpkgs_13", + "nixpkgs": "nixpkgs_15", "utils": "utils_17" }, "locked": { @@ -814,7 +836,7 @@ "clj2nix_9": { "inputs": { "flake-compat": "flake-compat_10", - "nixpkgs": "nixpkgs_18", + "nixpkgs": "nixpkgs_20", "utils": "utils_22" }, "locked": { @@ -1310,8 +1332,8 @@ "dnssec-ksks": { "flake": false, "locked": { - "lastModified": 1699562562, - "narHash": "sha256-PCCAHweKPWTuqdGi/J7jSAfXd4/niAiJDd0+MvOwOgY=", + "lastModified": 1701289728, + "narHash": "sha256-BLTUmmiXcMwsKcU30myaBMnq1VfulNchzorPshlaBxQ=", "path": "/secrets/dnssec", "type": "path" }, @@ -1323,8 +1345,8 @@ "domain-secrets": { "flake": false, "locked": { - "lastModified": 1697492400, - "narHash": "sha256-kSxkncbrCfCqArzNHYnRSIFr4NkpY3EDIldyajD6wDY=", + "lastModified": 1701451798, + "narHash": "sha256-Pk2zKPHHaOkToQ+ZkCpNdQTWlOVdldrijwTHYIYQiyI=", "path": "/secrets/domain-secrets", "type": "path" }, @@ -1365,11 +1387,11 @@ "ws-butler": "ws-butler" }, "locked": { - "lastModified": 1697814738, - "narHash": "sha256-mwQmykamvRuHmO6I2VTm8+TOIhhmgy2g5YrMjoCHawY=", + "lastModified": 1701264882, + "narHash": "sha256-MBXR7x7Ua8qystlGr+lenwjQd7dsFNFpEFmtHhh10zM=", "owner": "nix-community", "repo": "nix-doom-emacs", - "rev": "c1c99cf41694440d76e31126dc394f52faeb691e", + "rev": "f7413022370f24bb53cb450bfb2803233510113e", "type": "github" }, "original": { @@ -1446,15 +1468,15 @@ }, "entities": { "inputs": { - "fudo-lib": "fudo-lib_3", - "nixpkgs": "nixpkgs_8" + "fudo-lib": "fudo-lib_4", + "nixpkgs": "nixpkgs_10" }, "locked": { - "lastModified": 1699558182, - "narHash": "sha256-kWbn5DqGLUtdV2nFmVIQ9w6HExqHuYSi3stK+auWtz8=", + "lastModified": 1701289452, + "narHash": "sha256-zQ9HNhGHR6HBBwcqJsesLsCG/CTFRer2Jyd4PvLERvo=", "ref": "refs/heads/master", - "rev": "4688003535cb66705e772141ce9df0fd589056a1", - "revCount": 187, + "rev": "2702e5b50fbcec8b69995bb5f2cc7b41189338bb", + "revCount": 207, "type": "git", "url": "https://git.fudo.org/fudo-nix/entities.git" }, @@ -1876,7 +1898,7 @@ "flake-parts_4": { "inputs": { "nixpkgs-lib": [ - "mail-server", + "frigate-container", "arion", "nixpkgs" ] @@ -1913,6 +1935,69 @@ } }, "flake-parts_6": { + "inputs": { + "nixpkgs-lib": [ + "frigate-container", + "arion", + "hercules-ci-effects", + "hercules-ci-agent", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688466019, + "narHash": "sha256-VeM2akYrBYMsb4W/MmBo1zmaMfgbL4cH3Pu8PGyIwJ0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "8e8d955c22df93dbe24f19ea04f47a74adbdc5ec", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_7": { + "inputs": { + "nixpkgs-lib": [ + "mail-server", + "arion", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1675933616, + "narHash": "sha256-/rczJkJHtx16IFxMmAWu5nNYcSXNg1YYXTHoGjLrLUA=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "47478a4a003e745402acf63be7f9a092d51b83d7", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_8": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_3" + }, + "locked": { + "lastModified": 1688466019, + "narHash": "sha256-VeM2akYrBYMsb4W/MmBo1zmaMfgbL4cH3Pu8PGyIwJ0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "8e8d955c22df93dbe24f19ea04f47a74adbdc5ec", + "type": "github" + }, + "original": { + "id": "flake-parts", + "type": "indirect" + } + }, + "flake-parts_9": { "inputs": { "nixpkgs-lib": [ "mail-server", @@ -2226,19 +2311,40 @@ "type": "github" } }, - "fudo-entities": { + "frigate-container": { "inputs": { - "fudo-lib": "fudo-lib", + "arion": "arion_2", "nixpkgs": [ "nixpkgs" ] }, "locked": { - "lastModified": 1699981257, - "narHash": "sha256-6ChJQ12nQDOEKiEJKP9FgeChlpsd/+CClYyCotk6sg8=", + "lastModified": 1701302959, + "narHash": "sha256-4AhEM9KNT2WG2HrYqzlr1GgG3y+N+RnUJaWtkEqwki0=", "ref": "refs/heads/master", - "rev": "16e3ad53e9b707a8c7903f2a5bb9a19c65214829", - "revCount": 192, + "rev": "91032aa4fc2ded188b049d97523093cd0ae867fd", + "revCount": 23, + "type": "git", + "url": "https://git.fudo.org/fudo-public/frigate-container.git" + }, + "original": { + "type": "git", + "url": "https://git.fudo.org/fudo-public/frigate-container.git" + } + }, + "fudo-entities": { + "inputs": { + "fudo-lib": "fudo-lib_2", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1701668465, + "narHash": "sha256-BbvMoFJIwfNtjLfHYbwVjJ/ImNcOB74nkJQ+kQ6Oa/E=", + "ref": "refs/heads/master", + "rev": "17edbe8436aeb23bd5f8a22cabfa837bcd913955", + "revCount": 212, "type": "git", "url": "https://git.fudo.org/fudo-nix/entities.git" }, @@ -2259,11 +2365,11 @@ ] }, "locked": { - "lastModified": 1699903682, - "narHash": "sha256-agoWZQ/EORRiHiJt0f40GrkJbJEQ/+duCXniu59yOZs=", + "lastModified": 1701721194, + "narHash": "sha256-wGO4YajCCJKxvSZfa099didLmL90cySLB9FYhBNaU3o=", "ref": "refs/heads/master", - "rev": "6b29e60a8792b29f4e7db4c28a1e0513ffef5aa3", - "revCount": 403, + "rev": "e341ba3b2236de5a109d10dfbb2aa7cd7e29d283", + "revCount": 407, "type": "git", "url": "https://git.fudo.org/fudo-nix/home.git" }, @@ -2274,11 +2380,11 @@ }, "fudo-lib": { "locked": { - "lastModified": 1695450044, - "narHash": "sha256-o73ia/vQjo51yVcnyA9xdSif45HxXPgU3Gq8OCDlcbY=", + "lastModified": 1700242449, + "narHash": "sha256-LfetCw18YI5SFAWSHzKcZq4G1ClwiKBh4qhxZcj7IWQ=", "ref": "refs/heads/master", - "rev": "49009f67e7ac58c1ed088629837d42469104c5c8", - "revCount": 149, + "rev": "04263beb7f170a1c535832461901173410ca81d8", + "revCount": 176, "type": "git", "url": "https://git.fudo.org/fudo-nix/lib.git" }, @@ -2289,11 +2395,11 @@ }, "fudo-lib_2": { "locked": { - "lastModified": 1699113600, - "narHash": "sha256-EX36PJZXNEmmtRA+M30FkWq1AD3ytI07VVCEu9maOYY=", + "lastModified": 1701117898, + "narHash": "sha256-tw8fml3PTK4lJNd79ZBbzR5nnepoXHX1i/hFpKjWsyU=", "ref": "refs/heads/master", - "rev": "d4044d886a9b3e8b3964095a3307f784bae8aac0", - "revCount": 175, + "rev": "cf4b24da9941d208ff67868f52b2b1c97313e380", + "revCount": 178, "type": "git", "url": "https://git.fudo.org/fudo-nix/lib.git" }, @@ -2304,11 +2410,26 @@ }, "fudo-lib_3": { "locked": { - "lastModified": 1695450044, - "narHash": "sha256-o73ia/vQjo51yVcnyA9xdSif45HxXPgU3Gq8OCDlcbY=", + "lastModified": 1701117898, + "narHash": "sha256-tw8fml3PTK4lJNd79ZBbzR5nnepoXHX1i/hFpKjWsyU=", "ref": "refs/heads/master", - "rev": "49009f67e7ac58c1ed088629837d42469104c5c8", - "revCount": 149, + "rev": "cf4b24da9941d208ff67868f52b2b1c97313e380", + "revCount": 178, + "type": "git", + "url": "https://git.fudo.org/fudo-nix/lib.git" + }, + "original": { + "type": "git", + "url": "https://git.fudo.org/fudo-nix/lib.git" + } + }, + "fudo-lib_4": { + "locked": { + "lastModified": 1701117898, + "narHash": "sha256-tw8fml3PTK4lJNd79ZBbzR5nnepoXHX1i/hFpKjWsyU=", + "ref": "refs/heads/master", + "rev": "cf4b24da9941d208ff67868f52b2b1c97313e380", + "revCount": 178, "type": "git", "url": "https://git.fudo.org/fudo-nix/lib.git" }, @@ -2323,11 +2444,11 @@ "unstableNixpkgs": "unstableNixpkgs" }, "locked": { - "lastModified": 1697077575, - "narHash": "sha256-UUkJhYv9L+Tj2EGupz54RMhdY5V7i6ai4spwjMC3y3M=", + "lastModified": 1700531038, + "narHash": "sha256-AAAYO9Skf78FiTkMLyUlQ14dBKCWO8CNW/OdGr6GK1k=", "ref": "refs/heads/master", - "rev": "2cf977ff51b51771240afe930dbe65e3985f7504", - "revCount": 249, + "rev": "dfc2c766878dc27ddf7cac8e241fa62238a3883d", + "revCount": 250, "type": "git", "url": "https://git.fudo.org/fudo-nix/pkgs.git" }, @@ -2342,11 +2463,11 @@ "unstableNixpkgs": "unstableNixpkgs_2" }, "locked": { - "lastModified": 1697077575, - "narHash": "sha256-UUkJhYv9L+Tj2EGupz54RMhdY5V7i6ai4spwjMC3y3M=", + "lastModified": 1700531038, + "narHash": "sha256-AAAYO9Skf78FiTkMLyUlQ14dBKCWO8CNW/OdGr6GK1k=", "ref": "refs/heads/master", - "rev": "2cf977ff51b51771240afe930dbe65e3985f7504", - "revCount": 249, + "rev": "dfc2c766878dc27ddf7cac8e241fa62238a3883d", + "revCount": 250, "type": "git", "url": "https://git.fudo.org/fudo-nix/pkgs.git" }, @@ -2361,11 +2482,11 @@ "unstableNixpkgs": "unstableNixpkgs_3" }, "locked": { - "lastModified": 1697077575, - "narHash": "sha256-UUkJhYv9L+Tj2EGupz54RMhdY5V7i6ai4spwjMC3y3M=", + "lastModified": 1700531038, + "narHash": "sha256-AAAYO9Skf78FiTkMLyUlQ14dBKCWO8CNW/OdGr6GK1k=", "ref": "refs/heads/master", - "rev": "2cf977ff51b51771240afe930dbe65e3985f7504", - "revCount": 249, + "rev": "dfc2c766878dc27ddf7cac8e241fa62238a3883d", + "revCount": 250, "type": "git", "url": "https://git.fudo.org/fudo-nix/pkgs.git" }, @@ -2385,7 +2506,7 @@ "filesystem-keys": "filesystem-keys", "fudo-pkgs": "fudo-pkgs_3", "nexus": "nexus", - "nixpkgs": "nixpkgs_15", + "nixpkgs": "nixpkgs_17", "service-passwords": "service-passwords", "service-secrets": "service-secrets", "site-secrets": "site-secrets", @@ -2393,8 +2514,8 @@ "utils": "utils_21" }, "locked": { - "lastModified": 1699563326, - "narHash": "sha256-8u1+uLT1vtpQOZs1uq91BSTrnR5RS6o7C92RcECwsEg=", + "lastModified": 1701464793, + "narHash": "sha256-uZX5EqmiAYxzfVbmHdaV4LiwPSVWvcLcaYy8aIfKvak=", "path": "/secrets", "type": "path" }, @@ -2531,11 +2652,43 @@ "type": "github" } }, + "haskell-flake_5": { + "locked": { + "lastModified": 1675296942, + "narHash": "sha256-u1X1sblozi5qYEcLp1hxcyo8FfDHnRUVX3dJ/tW19jY=", + "owner": "srid", + "repo": "haskell-flake", + "rev": "c2cafce9d57bfca41794dc3b99c593155006c71e", + "type": "github" + }, + "original": { + "owner": "srid", + "ref": "0.1.0", + "repo": "haskell-flake", + "type": "github" + } + }, + "haskell-flake_6": { + "locked": { + "lastModified": 1684780604, + "narHash": "sha256-2uMZsewmRn7rRtAnnQNw1lj0uZBMh4m6Cs/7dV5YF08=", + "owner": "srid", + "repo": "haskell-flake", + "rev": "74210fa80a49f1b6f67223debdbf1494596ff9f2", + "type": "github" + }, + "original": { + "owner": "srid", + "ref": "0.3.0", + "repo": "haskell-flake", + "type": "github" + } + }, "helpers": { "inputs": { "clj-nix": "clj-nix", "clj2nix": "clj2nix_3", - "nixpkgs": "nixpkgs_5", + "nixpkgs": "nixpkgs_7", "utils": "utils_6" }, "locked": { @@ -2655,7 +2808,7 @@ "inputs": { "clj-nix": "clj-nix_2", "clj2nix": "clj2nix_4", - "nixpkgs": "nixpkgs_7", + "nixpkgs": "nixpkgs_9", "utils": "utils_8" }, "locked": { @@ -2676,7 +2829,7 @@ "inputs": { "clj-nix": "clj-nix_3", "clj2nix": "clj2nix_5", - "nixpkgs": "nixpkgs_10", + "nixpkgs": "nixpkgs_12", "utils": "utils_10" }, "locked": { @@ -2869,7 +3022,26 @@ "inputs": { "flake-parts": "flake-parts_6", "haskell-flake": "haskell-flake_4", - "nixpkgs": "nixpkgs_16" + "nixpkgs": "nixpkgs_4" + }, + "locked": { + "lastModified": 1688568579, + "narHash": "sha256-ON0M56wtY/TIIGPkXDlJboAmuYwc73Hi8X9iJGtxOhM=", + "owner": "hercules-ci", + "repo": "hercules-ci-agent", + "rev": "367dd8cd649b57009a6502e878005a1e54ad78c5", + "type": "github" + }, + "original": { + "id": "hercules-ci-agent", + "type": "indirect" + } + }, + "hercules-ci-agent_3": { + "inputs": { + "flake-parts": "flake-parts_9", + "haskell-flake": "haskell-flake_6", + "nixpkgs": "nixpkgs_18" }, "locked": { "lastModified": 1688568579, @@ -2911,6 +3083,30 @@ "inputs": { "flake-parts": "flake-parts_5", "hercules-ci-agent": "hercules-ci-agent_2", + "nixpkgs": [ + "frigate-container", + "arion", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1689397210, + "narHash": "sha256-fVxZnqxMbsDkB4GzGAs/B41K0wt/e+B/fLxmTFF/S20=", + "owner": "hercules-ci", + "repo": "hercules-ci-effects", + "rev": "0a63bfa3f00a3775ea3a6722b247880f1ffe91ce", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "hercules-ci-effects", + "type": "github" + } + }, + "hercules-ci-effects_3": { + "inputs": { + "flake-parts": "flake-parts_8", + "hercules-ci-agent": "hercules-ci-agent_3", "nixpkgs": [ "mail-server", "arion", @@ -2939,11 +3135,11 @@ ] }, "locked": { - "lastModified": 1699748081, - "narHash": "sha256-MOmMapBydd7MTjhX4eeQZzKlCABWw8W6iSHSG4OeFKE=", + "lastModified": 1700392168, + "narHash": "sha256-v5LprEFx3u4+1vmds9K0/i7sHjT0IYGs7u9v54iz/OA=", "owner": "nix-community", "repo": "home-manager", - "rev": "04bac349d585c9df38d78e0285b780a140dc74a4", + "rev": "28535c3a34d79071f2ccb68671971ce0c0984d7e", "type": "github" }, "original": { @@ -2978,7 +3174,7 @@ }, "mail-server": { "inputs": { - "arion": "arion_2", + "arion": "arion_3", "nixpkgs": [ "nixpkgs" ] @@ -3068,7 +3264,7 @@ "nexus-client": "nexus-client", "nexus-crypto": "nexus-crypto", "nexus-server": "nexus-server", - "nixpkgs": "nixpkgs_14", + "nixpkgs": "nixpkgs_16", "utils": "utils_20" }, "locked": { @@ -3253,11 +3449,11 @@ "niten-doom-config": { "flake": false, "locked": { - "lastModified": 1699894688, - "narHash": "sha256-Kp0qfQGDkGxkcyk4GL9HBQZcunKBSdOig+8q4NiZKVs=", + "lastModified": 1701721033, + "narHash": "sha256-CKiF65CntCah8xtxdc1eodzvo2G6RHI/PkK2Gd5ZPj0=", "ref": "refs/heads/master", - "rev": "92718c3f315411abfb7ef623cc4239204dbc4b19", - "revCount": 68, + "rev": "f4ad408a0043b77ca1158fe0bed61f0dceb9b866", + "revCount": 70, "type": "git", "url": "https://git.fudo.org/niten/doom-emacs.git" }, @@ -3334,6 +3530,24 @@ "type": "github" } }, + "nixpkgs-lib_3": { + "locked": { + "dir": "lib", + "lastModified": 1688049487, + "narHash": "sha256-100g4iaKC9MalDjUW9iN6Jl/OocTDtXdeAj7pEGIRh4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4bc72cae107788bf3f24f30db2e2f685c9298dc9", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs2111": { "locked": { "lastModified": 1659446231, @@ -3351,11 +3565,11 @@ }, "nixpkgsUnstable": { "locked": { - "lastModified": 1699781429, - "narHash": "sha256-UYefjidASiLORAjIvVsUHG6WBtRhM67kTjEY4XfZOFs=", + "lastModified": 1701436327, + "narHash": "sha256-tRHbnoNI8SIM5O5xuxOmtSLnswEByzmnQcGGyNRjxsE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "e44462d6021bfe23dfb24b775cc7c390844f773d", + "rev": "91050ea1e57e50388fa87a3302ba12d188ef723a", "type": "github" }, "original": { @@ -3366,16 +3580,14 @@ }, "nixpkgs_10": { "locked": { - "lastModified": 1677624842, - "narHash": "sha256-4DF9DbDuK4/+KYx0L6XcPBeDHUFVCtzok2fWtwXtb5w=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "d70f5cd5c3bef45f7f52698f39e7cc7a89daa7f0", - "type": "github" + "lastModified": 1699291058, + "narHash": "sha256-5ggduoaAMPHUy4riL+OrlAZE14Kh7JWX4oLEs22ZqfU=", + "path": "/nix/store/3s69yxbbl116zwga3i6cy7prplywq0bn-source", + "rev": "41de143fda10e33be0f47eab2bfe08a50f234267", + "type": "path" }, "original": { "id": "nixpkgs", - "ref": "nixos-22.11", "type": "indirect" } }, @@ -3396,17 +3608,17 @@ }, "nixpkgs_12": { "locked": { - "lastModified": 1673785507, - "narHash": "sha256-EPUT8yVdvJhhjhbgnFWXXd4IUPKSOmww2+z4AmOdyPI=", + "lastModified": 1677624842, + "narHash": "sha256-4DF9DbDuK4/+KYx0L6XcPBeDHUFVCtzok2fWtwXtb5w=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d06d765eeac716d8f1ca80f0935fd6fc951816ad", + "rev": "d70f5cd5c3bef45f7f52698f39e7cc7a89daa7f0", "type": "github" }, "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "type": "github" + "id": "nixpkgs", + "ref": "nixos-22.11", + "type": "indirect" } }, "nixpkgs_13": { @@ -3425,6 +3637,36 @@ } }, "nixpkgs_14": { + "locked": { + "lastModified": 1673785507, + "narHash": "sha256-EPUT8yVdvJhhjhbgnFWXXd4IUPKSOmww2+z4AmOdyPI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d06d765eeac716d8f1ca80f0935fd6fc951816ad", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_15": { + "locked": { + "lastModified": 1673785507, + "narHash": "sha256-EPUT8yVdvJhhjhbgnFWXXd4IUPKSOmww2+z4AmOdyPI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d06d765eeac716d8f1ca80f0935fd6fc951816ad", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_16": { "locked": { "lastModified": 1693771906, "narHash": "sha256-32EnPCaVjOiEERZ+o/2Ir7JH9pkfwJZJ27SKHNvt4yk=", @@ -3439,7 +3681,7 @@ "type": "indirect" } }, - "nixpkgs_15": { + "nixpkgs_17": { "locked": { "lastModified": 1685573264, "narHash": "sha256-Zffu01pONhs/pqH07cjlF10NnMDLok8ix5Uk4rhOnZQ=", @@ -3454,7 +3696,7 @@ "type": "indirect" } }, - "nixpkgs_16": { + "nixpkgs_18": { "locked": { "lastModified": 1688322751, "narHash": "sha256-eW62dC5f33oKZL7VWlomttbUnOTHrAbte9yNUNW8rbk=", @@ -3470,7 +3712,7 @@ "type": "github" } }, - "nixpkgs_17": { + "nixpkgs_19": { "locked": { "lastModified": 1676300157, "narHash": "sha256-1HjRzfp6LOLfcj/HJHdVKWAkX9QRAouoh6AjzJiIerU=", @@ -3486,36 +3728,6 @@ "type": "github" } }, - "nixpkgs_18": { - "locked": { - "lastModified": 1673785507, - "narHash": "sha256-EPUT8yVdvJhhjhbgnFWXXd4IUPKSOmww2+z4AmOdyPI=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "d06d765eeac716d8f1ca80f0935fd6fc951816ad", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_19": { - "locked": { - "lastModified": 1673785507, - "narHash": "sha256-EPUT8yVdvJhhjhbgnFWXXd4IUPKSOmww2+z4AmOdyPI=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "d06d765eeac716d8f1ca80f0935fd6fc951816ad", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "type": "github" - } - }, "nixpkgs_2": { "locked": { "lastModified": 1637881340, @@ -3548,17 +3760,17 @@ }, "nixpkgs_21": { "locked": { - "lastModified": 1699994397, - "narHash": "sha256-xxNeIcMNMXH2EA9IAX6Cny+50mvY22LhIBiGZV363gc=", + "lastModified": 1673785507, + "narHash": "sha256-EPUT8yVdvJhhjhbgnFWXXd4IUPKSOmww2+z4AmOdyPI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d4b5a67bbe9ef750bd2fdffd4cad400dd5553af8", + "rev": "d06d765eeac716d8f1ca80f0935fd6fc951816ad", "type": "github" }, "original": { - "id": "nixpkgs", - "ref": "nixos-23.05", - "type": "indirect" + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" } }, "nixpkgs_22": { @@ -3578,17 +3790,17 @@ }, "nixpkgs_23": { "locked": { - "lastModified": 1673785507, - "narHash": "sha256-EPUT8yVdvJhhjhbgnFWXXd4IUPKSOmww2+z4AmOdyPI=", + "lastModified": 1701540982, + "narHash": "sha256-5ajSy6ODgGmAbmymRdHnjfVnuVrACjI8wXoGVvrtvww=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d06d765eeac716d8f1ca80f0935fd6fc951816ad", + "rev": "6386d8aafc28b3a7ed03880a57bdc6eb4465491d", "type": "github" }, "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "type": "github" + "id": "nixpkgs", + "ref": "nixos-23.05", + "type": "indirect" } }, "nixpkgs_24": { @@ -3621,6 +3833,36 @@ "type": "github" } }, + "nixpkgs_26": { + "locked": { + "lastModified": 1673785507, + "narHash": "sha256-EPUT8yVdvJhhjhbgnFWXXd4IUPKSOmww2+z4AmOdyPI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d06d765eeac716d8f1ca80f0935fd6fc951816ad", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_27": { + "locked": { + "lastModified": 1673785507, + "narHash": "sha256-EPUT8yVdvJhhjhbgnFWXXd4IUPKSOmww2+z4AmOdyPI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d06d765eeac716d8f1ca80f0935fd6fc951816ad", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs_3": { "locked": { "lastModified": 1637881340, @@ -3638,32 +3880,34 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1673785507, - "narHash": "sha256-EPUT8yVdvJhhjhbgnFWXXd4IUPKSOmww2+z4AmOdyPI=", + "lastModified": 1688322751, + "narHash": "sha256-eW62dC5f33oKZL7VWlomttbUnOTHrAbte9yNUNW8rbk=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d06d765eeac716d8f1ca80f0935fd6fc951816ad", + "rev": "0fbe93c5a7cac99f90b60bdf5f149383daaa615f", "type": "github" }, "original": { "owner": "NixOS", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } }, "nixpkgs_5": { "locked": { - "lastModified": 1677624842, - "narHash": "sha256-4DF9DbDuK4/+KYx0L6XcPBeDHUFVCtzok2fWtwXtb5w=", + "lastModified": 1676300157, + "narHash": "sha256-1HjRzfp6LOLfcj/HJHdVKWAkX9QRAouoh6AjzJiIerU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d70f5cd5c3bef45f7f52698f39e7cc7a89daa7f0", + "rev": "545c7a31e5dedea4a6d372712a18e00ce097d462", "type": "github" }, "original": { - "id": "nixpkgs", - "ref": "nixos-22.11", - "type": "indirect" + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" } }, "nixpkgs_6": { @@ -3697,19 +3941,6 @@ } }, "nixpkgs_8": { - "locked": { - "lastModified": 1695559356, - "narHash": "sha256-kXZ1pUoImD9OEbPCwpTz4tHsNTr4CIyIfXb3ocuR8sI=", - "path": "/nix/store/dn5wzc9a8hrpml66i6kz5f3q6dr3jjmk-source", - "rev": "261abe8a44a7e8392598d038d2e01f7b33cf26d0", - "type": "path" - }, - "original": { - "id": "nixpkgs", - "type": "indirect" - } - }, - "nixpkgs_9": { "locked": { "lastModified": 1673785507, "narHash": "sha256-EPUT8yVdvJhhjhbgnFWXXd4IUPKSOmww2+z4AmOdyPI=", @@ -3724,6 +3955,21 @@ "type": "github" } }, + "nixpkgs_9": { + "locked": { + "lastModified": 1677624842, + "narHash": "sha256-4DF9DbDuK4/+KYx0L6XcPBeDHUFVCtzok2fWtwXtb5w=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d70f5cd5c3bef45f7f52698f39e7cc7a89daa7f0", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-22.11", + "type": "indirect" + } + }, "nose": { "flake": false, "locked": { @@ -3910,9 +4156,10 @@ "authoritative-dns": "authoritative-dns", "chute": "chute", "chuteUnstable": "chuteUnstable", + "frigate-container": "frigate-container", "fudo-entities": "fudo-entities", "fudo-home": "fudo-home", - "fudo-lib": "fudo-lib_2", + "fudo-lib": "fudo-lib_3", "fudo-pkgs": "fudo-pkgs_2", "fudo-secrets": "fudo-secrets", "lemmy-docker": "lemmy-docker", @@ -3921,7 +4168,7 @@ "matrix-module": "matrix-module", "nextcloud-container": "nextcloud-container", "nexus": "nexus_2", - "nixpkgs": "nixpkgs_21", + "nixpkgs": "nixpkgs_23", "nixpkgs2111": "nixpkgs2111", "nixpkgsUnstable": "nixpkgsUnstable", "objectifier": "objectifier", @@ -3953,8 +4200,8 @@ "service-passwords": { "flake": false, "locked": { - "lastModified": 1696023956, - "narHash": "sha256-iDq6nTM69C826hxQPghqN2ZEshqNKDraXYysdy1Rg5s=", + "lastModified": 1701451798, + "narHash": "sha256-2+ue3o/qKM0tVBkjHy3eLMNFSH/F+nJS39u9fCWAoDg=", "path": "/secrets/service-passwords", "type": "path" }, @@ -4014,11 +4261,11 @@ "utils": "utils_36" }, "locked": { - "lastModified": 1697581984, - "narHash": "sha256-ypR4v0GfoyrXqgRIS/lSqcaIDcLLDIg2WP+//csRr7E=", + "lastModified": 1701133174, + "narHash": "sha256-RwrqP8c89vSvBb7EPVtho++2DG1j6/aJXUYEi/2vxWc=", "ref": "refs/heads/master", - "rev": "ade2e1caa0b8a6e8182a2bd54aa5dc82ac1c60b6", - "revCount": 12, + "rev": "a206cfdb9cb08bbf85096ffc0448be35f2fb0253", + "revCount": 13, "type": "git", "url": "https://git.fudo.org/fudo-public/snooper.git" }, @@ -4260,11 +4507,11 @@ ] }, "locked": { - "lastModified": 1697147143, - "narHash": "sha256-PkmcfgfGgwDu5MCiwLpUQnRAeNx+e1GmVET34pXuSTo=", + "lastModified": 1701222400, + "narHash": "sha256-qOPB34MZVDGlcnRzvAgaYL/VW/7JFvMCtRj5n2Z0XmU=", "ref": "refs/heads/master", - "rev": "8ebaa4cae47f1d8beb9aa58690c75b706b215b3e", - "revCount": 17, + "rev": "ebf75ad5a32766c49b7d0bec4511c682efaae635", + "revCount": 19, "type": "git", "url": "https://git.fudo.org/fudo-public/tesla-mate-container.git" }, diff --git a/flake.nix b/flake.nix index a910251..74347e7 100644 --- a/flake.nix +++ b/flake.nix @@ -131,6 +131,11 @@ inputs.nixpkgs.follows = "nixpkgs"; }; + frigate-container = { + url = "git+https://git.fudo.org/fudo-public/frigate-container.git"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + textfiles = { url = "git+https://git.informis.land/informis/textfiles.git"; flake = false; @@ -142,7 +147,7 @@ , wallfly, objectifier, nexus, suanni, snooper, tattler, lemmy-docker , tesla-mate-container, mastodon-container, authentik-container , nextcloud-container, textfiles, matrix-module, mail-server - , authoritative-dns, ... }@inputs: + , authoritative-dns, frigate-container, ... }@inputs: with nixpkgs.lib; let fudo-nixos-hosts = filterAttrs (hostname: hostOpts: hostOpts.nixos-system) @@ -167,10 +172,11 @@ "openssl-1.1.1w" "python3.10-requests-2.28.2" "python3.10-cryptography-40.0.1" + "gitea-1.19.4" ]; }; overlays = [ - fudo-lib.overlay + fudo-lib.overlays.default fudo-pkgs.overlays.default fudo-secrets.overlays.default fudo-entities.overlays.default @@ -211,7 +217,7 @@ imports = [ fudo-home.nixosModules.default fudo-secrets.nixosModules.default - fudo-lib.nixosModule + fudo-lib.nixosModules.default fudo-entities.nixosModule pricebot.nixosModules.default wallfly.nixosModule @@ -227,6 +233,7 @@ matrix-module.nixosModules.default mail-server.nixosModules.default authoritative-dns.nixosModules.default + frigate-container.nixosModules.default nexus.nixosModules.nexus-client nexus.nixosModules.nexus-server diff --git a/lib/instantiate-zone.nix b/lib/instantiate-zone.nix new file mode 100644 index 0000000..dcb6593 --- /dev/null +++ b/lib/instantiate-zone.nix @@ -0,0 +1,18 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + mkSrvRecord = host: port: { inherit host port; }; + + instantiateZone = zoneName: + { primaryNameserver, secondaryNameservers ? [ ], externalNameservers ? [ ] + , smtpServers, imapServers, ... }: { + gssapi-realm = gssapiRealm; + mx = smtpServers; + dmarc-report-address = "dmarc-report@${zoneName}"; + default-host = defaultHost; + verbatim-dns-records = + mkIf (ksk != null) [ ksk.public-key-record ksk.ds ]; + }; + +in { inherit instantiateZone; }