diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs deleted file mode 100644 index 40e5d59..0000000 --- a/.git-blame-ignore-revs +++ /dev/null @@ -1,14 +0,0 @@ -# Run this command to always ignore formatting commits in `git blame` -# git config blame.ignoreRevsFile .git-blame-ignore-revs - -# Switch to nixfmt formatting -04f7a7ef1d38906163afc9cddfa8ce2b0ebf3b45 - -# Switch to nixpkgs-fmt formatting -fd138d45e6a2cad89fead6e9f246ba282070d6b7 - -# Switch to alejandra formatting -046a88905ddfa7f9edc3291c310dbb985dee34f9 - -# Apply wide linting -63b3cbe00be80ccb4b221aad64eb657ae5c96d70 diff --git a/.gitignore b/.gitignore index 7512d76..dbee5b9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ /result *.qcow2 -/gcroots/ diff --git a/.sops.yaml b/.sops.yaml index bed2365..7444d2c 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -1,5 +1,5 @@ keys: - - &tlater B9C7AE554602D82B1AC2CFD0BC7BB2DB17C78E42! + - &tlater 535B61015823443941C744DD12264F6BBDFABA89 - &server_tlaternet 8a3737d48f1035fe6c3a0a8fd6a1976ca74c7f3b - &server_hetzner1 0af7641adb8aa843136cf6d047f71da3e5ad79f9 - &server_staging 2f5caa73e7ceea4fcc8d2881fde587e6737d2dbc diff --git a/checks/default.nix b/checks/default.nix deleted file mode 100644 index f3db4ce..0000000 --- a/checks/default.nix +++ /dev/null @@ -1,61 +0,0 @@ -{ - self, - nixpkgs, - deploy-rs, - system, - ... -}: -let - pkgs = nixpkgs.legacyPackages.${system}; - - statix' = pkgs.statix.overrideAttrs (old: { - patches = old.patches ++ [ - (pkgs.fetchpatch { - url = "https://github.com/oppiliappan/statix/commit/925dec39bb705acbbe77178b4d658fe1b752abbb.patch"; - hash = "sha256-0wacO6wuYJ4ufN9PGucRVJucFdFFNF+NoHYIrLXsCWs="; - }) - ]; - }); - - runNuCheck = - { - name, - packages, - check, - }: - pkgs.stdenvNoCC.mkDerivation { - inherit name; - - src = nixpkgs.lib.cleanSourceWith { - src = self; - filter = nixpkgs.lib.cleanSourceFilter; - }; - - dontPatch = true; - dontConfigure = true; - dontBuild = true; - dontInstall = true; - dontFixup = true; - doCheck = true; - - checkInputs = nixpkgs.lib.singleton pkgs.nushell ++ packages; - - checkPhase = '' - nu ${check} - ''; - }; -in -nixpkgs.lib.recursiveUpdate { - lints = runNuCheck { - name = "lints"; - - packages = [ - pkgs.deadnix - pkgs.nixfmt-rfc-style - pkgs.shellcheck - statix' - ]; - - check = ./lints.nu; - }; -} (deploy-rs.lib.${system}.deployChecks self.deploy) diff --git a/checks/lints.nu b/checks/lints.nu deleted file mode 100644 index ffc2047..0000000 --- a/checks/lints.nu +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env nu - -let shell_files = ls **/*.sh | get name -let nix_files = ls **/*.nix | where name !~ "hardware-configuration.nix|_sources" | get name - -let linters = [ - ([shellcheck] ++ $shell_files) - ([nixfmt --check --strict] ++ $nix_files) - ([deadnix --fail] ++ $nix_files) - ([statix check] ++ $nix_files) -] - -mkdir $env.out - -def run-linter [linterArgs: list<string>] { - print $'Running ($linterArgs.0)...' - - let exit_code = try { - ^$linterArgs.0 ...($linterArgs | skip 1) - $env.LAST_EXIT_CODE - } catch {|e| $e.exit_code} - - [$linterArgs.0, $exit_code] -} - -let results = $linters | each {|linter| run-linter $linter} - -print 'Linter results:' - -let success = $results | each {|result| - match $result.1 { - 0 => {print $'(ansi green)($result.0)(ansi reset)'} - _ => {print $'(ansi red)($result.0)(ansi reset)'} - } - - $result.1 -} | math sum - -exit $success diff --git a/configuration/default.nix b/configuration/default.nix index 0377e9c..556d81e 100644 --- a/configuration/default.nix +++ b/configuration/default.nix @@ -1,10 +1,11 @@ { config, + pkgs, + lib, modulesPath, flake-inputs, ... -}: -{ +}: { imports = [ flake-inputs.disko.nixosModules.disko flake-inputs.sops-nix.nixosModules.sops @@ -13,40 +14,49 @@ "${modulesPath}/profiles/minimal.nix" (import ../modules) + ./services/afvalcalendar.nix + ./services/auth.nix ./services/backups.nix ./services/battery-manager.nix - ./services/conduit - ./services/crowdsec.nix + ./services/conduit.nix + ./services/fail2ban.nix ./services/foundryvtt.nix ./services/gitea.nix - ./services/immich.nix ./services/metrics ./services/nextcloud.nix ./services/webserver.nix ./services/wireguard.nix - # ./services/starbound.nix -- Not currently used + ./services/starbound.nix ./services/postgres.nix ./nginx.nix ./sops.nix ]; - nixpkgs.overlays = [ (_: prev: { local = import ../pkgs { pkgs = prev; }; }) ]; + nixpkgs.overlays = [ + (final: prev: { + local = import ../pkgs { + pkgs = prev; + lib = prev.lib; + }; + }) + ]; nix = { + package = pkgs.nixFlakes; extraOptions = '' experimental-features = nix-command flakes ''; # Enable remote builds from tlater - settings.trusted-users = [ "@wheel" ]; + settings.trusted-users = ["@wheel"]; }; + nixpkgs.config.allowUnfreePredicate = pkg: + builtins.elem (lib.getName pkg) ["steam-original" "steam-runtime" "steam-run" "steamcmd"]; + # Optimization for minecraft servers, see: # https://bugs.mojang.com/browse/MC-183518 - boot.kernelParams = [ - "highres=off" - "nohz=off" - ]; + boot.kernelParams = ["highres=off" "nohz=off"]; networking = { usePredictableInterfaceNames = false; @@ -97,15 +107,15 @@ users.users.tlater = { isNormalUser = true; - extraGroups = [ "wheel" ]; - openssh.authorizedKeys.keyFiles = [ ../keys/tlater.pub ]; + extraGroups = ["wheel"]; + openssh.authorizedKeys.keyFiles = [../keys/tlater.pub]; }; services = { openssh = { enable = true; allowSFTP = false; - ports = [ 2222 ]; + ports = [2222]; startWhenNeeded = true; settings = { @@ -124,14 +134,14 @@ pam = { sshAgentAuth = { enable = true; - authorizedKeysFiles = [ "/etc/ssh/authorized_keys.d/%u" ]; + authorizedKeysFiles = ["/etc/ssh/authorized_keys.d/%u"]; }; services.sudo.sshAgentAuth = true; }; }; # Remove some unneeded packages - environment.defaultPackages = [ ]; + environment.defaultPackages = []; system.stateVersion = "20.09"; } diff --git a/configuration/hardware-specific/hetzner/default.nix b/configuration/hardware-specific/hetzner/default.nix index 3e35eb0..5ecf63a 100644 --- a/configuration/hardware-specific/hetzner/default.nix +++ b/configuration/hardware-specific/hetzner/default.nix @@ -8,7 +8,7 @@ # disables it by default. # # TODO(tlater): See if would be useful for anything? - boot.kernelParams = [ "nosgx" ]; + boot.kernelParams = ["nosgx"]; networking.hostName = "hetzner-1"; services.nginx.domain = "tlater.net"; @@ -19,11 +19,15 @@ addresses = [ # IPv4 { - Address = "116.202.158.55/32"; - Peer = "116.202.158.1/32"; # Gateway + addressConfig = { + Address = "116.202.158.55/32"; + Peer = "116.202.158.1/32"; # Gateway + }; } # IPv6 - { Address = "2a01:4f8:10b:3c85::2/64"; } + { + addressConfig.Address = "2a01:4f8:10b:3c85::2/64"; + } ]; networkConfig = { diff --git a/configuration/hardware-specific/hetzner/disko.nix b/configuration/hardware-specific/hetzner/disko.nix index 7e1acd7..e404688 100644 --- a/configuration/hardware-specific/hetzner/disko.nix +++ b/configuration/hardware-specific/hetzner/disko.nix @@ -1,106 +1,82 @@ { - disko.devices.disk = - let - bootPartition = { - size = "1M"; - type = "EF02"; + disko.devices.disk = let + bootPartition = { + size = "1M"; + type = "EF02"; + }; + + swapPartition = { + # 8G is apparently recommended for this much RAM, but we set up + # 4G on both disks for mirroring purposes. + # + # That'll still be 8G during normal operation, and it's probably + # not too bad to have slightly less swap if a disk dies. + size = "4G"; + content = { + type = "swap"; + randomEncryption = true; }; + }; - swapPartition = { - # 8G is apparently recommended for this much RAM, but we set up - # 4G on both disks for mirroring purposes. - # - # That'll still be 8G during normal operation, and it's probably - # not too bad to have slightly less swap if a disk dies. - size = "4G"; - content = { - type = "swap"; - randomEncryption = true; - }; - }; + mountOptions = ["compress=zstd" "noatime"]; + in { + sda = { + type = "disk"; + device = "/dev/sda"; + content = { + type = "gpt"; + partitions = { + boot = bootPartition; + swap = swapPartition; - mountOptions = [ - "compress=zstd" - "noatime" - ]; - in - { - sda = { - type = "disk"; - device = "/dev/sda"; - content = { - type = "gpt"; - partitions = { - boot = bootPartition; - swap = swapPartition; - - disk1 = { - size = "100%"; - # Empty partition to combine in RAID0 with the other disk - }; + disk1 = { + size = "100%"; + # Empty partition to combine in RAID0 with the other disk }; }; }; + }; - sdb = { - type = "disk"; - device = "/dev/sdb"; - content = { - type = "gpt"; - partitions = { - boot = bootPartition; - swap = swapPartition; + sdb = { + type = "disk"; + device = "/dev/sdb"; + content = { + type = "gpt"; + partitions = { + boot = bootPartition; + swap = swapPartition; - disk2 = { - size = "100%"; - content = { - type = "btrfs"; - # Hack to get multi-device btrfs going - # See https://github.com/nix-community/disko/issues/99 - extraArgs = [ - "-d" - "raid1" - "-m" - "raid1" - "--runtime-features" - "quota" - "/dev/sda3" - ]; - subvolumes = { - "/volume" = { }; - "/volume/root" = { - inherit mountOptions; - mountpoint = "/"; - }; - "/volume/home" = { - inherit mountOptions; - mountpoint = "/home"; - }; - "/volume/var" = { - inherit mountOptions; - mountpoint = "/var"; - }; - "/volume/var/lib/private/matrix-conduit" = { - mountOptions = [ - # Explicitly don't compress here, since - # conduwuit's database does compression by - # itself, and relies on being able to read the - # raw file data from disk (which is impossible - # if btrfs compresses it) - "noatime" - ]; - mountpoint = "/var/lib/private/matrix-conduit"; - }; - "/volume/nix-store" = { - inherit mountOptions; - mountpoint = "/nix"; - }; - "/snapshots" = { }; + disk2 = { + size = "100%"; + content = { + type = "btrfs"; + # Hack to get multi-device btrfs going + # See https://github.com/nix-community/disko/issues/99 + extraArgs = ["-d" "raid1" "-m" "raid1" "--runtime-features" "quota" "/dev/sda3"]; + subvolumes = { + "/volume" = {}; + "/volume/root" = { + inherit mountOptions; + mountpoint = "/"; }; + "/volume/home" = { + inherit mountOptions; + mountpoint = "/home"; + }; + "/volume/var" = { + inherit mountOptions; + mountpoint = "/var"; + }; + "/volume/nix-store" = { + inherit mountOptions; + mountpoint = "/nix"; + }; + "/snapshots" = {}; }; }; }; }; }; }; + }; } diff --git a/configuration/hardware-specific/vm.nix b/configuration/hardware-specific/vm.nix index 71870fb..7f1fcf1 100644 --- a/configuration/hardware-specific/vm.nix +++ b/configuration/hardware-specific/vm.nix @@ -1,35 +1,19 @@ -{ lib, ... }: -{ +{lib, ...}: { users.users.tlater.password = "insecure"; # Disable graphical tty so -curses works - boot.kernelParams = [ "nomodeset" ]; + boot.kernelParams = ["nomodeset"]; networking.hostName = "testvm"; - - services = { - # Sets the base domain for nginx to a local domain so that we can - # easily test locally with the VM. - nginx.domain = "dev.local"; - - # Don't run this - batteryManager.enable = lib.mkForce false; - - openssh.hostKeys = lib.mkForce [ - { - type = "rsa"; - bits = 4096; - path = "/etc/staging.key"; - } - ]; - }; + # Sets the base domain for nginx to a local domain so that we can + # easily test locally with the VM. + services.nginx.domain = "dev.local"; # Use the staging secrets sops.defaultSopsFile = lib.mkOverride 99 ../../keys/staging.yaml; systemd.network.networks."10-eth0" = { matchConfig.Name = "eth0"; - gateway = [ "192.168.9.1" ]; networkConfig = { Address = "192.168.9.2/24"; }; @@ -43,6 +27,14 @@ source = ../../keys/hosts/staging.key; }; + services.openssh.hostKeys = lib.mkForce [ + { + type = "rsa"; + bits = 4096; + path = "/etc/staging.key"; + } + ]; + virtualisation.vmVariant = { virtualisation = { memorySize = 3941; diff --git a/configuration/nginx.nix b/configuration/nginx.nix index 3abef7f..82baab0 100644 --- a/configuration/nginx.nix +++ b/configuration/nginx.nix @@ -1,78 +1,67 @@ -{ config, lib, ... }: { - services = { - nginx = { - enable = true; - recommendedTlsSettings = true; - recommendedOptimisation = true; - recommendedGzipSettings = true; - recommendedProxySettings = true; - clientMaxBodySize = "10G"; + config, + lib, + ... +}: { + services.nginx = { + enable = true; + recommendedTlsSettings = true; + recommendedOptimisation = true; + recommendedGzipSettings = true; + recommendedProxySettings = true; + clientMaxBodySize = "10G"; - statusPage = true; # For metrics, should be accessible only from localhost + statusPage = true; # For metrics, should be accessible only from localhost - commonHttpConfig = '' - log_format upstream_time '$remote_addr - $remote_user [$time_local] ' - '"$request" $status $body_bytes_sent ' - '"$http_referer" "$http_user_agent" ' - 'rt=$request_time uct="$upstream_connect_time" ' - 'uht="$upstream_header_time" urt="$upstream_response_time"'; - ''; - }; - - logrotate.settings = - { - # Override the default, just keep fewer logs - nginx.rotate = 6; - } - // lib.mapAttrs' ( - virtualHost: _: - lib.nameValuePair "/var/log/nginx/${virtualHost}/access.log" { - frequency = "daily"; - rotate = 2; - compress = true; - delaycompress = true; - su = "${config.services.nginx.user} ${config.services.nginx.group}"; - postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`"; - } - ) config.services.nginx.virtualHosts; - - backups.acme = { - user = "acme"; - paths = lib.mapAttrsToList ( - virtualHost: _: "/var/lib/acme/${virtualHost}" - ) config.services.nginx.virtualHosts; - }; + commonHttpConfig = '' + log_format upstream_time '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent" ' + 'rt=$request_time uct="$upstream_connect_time" ' + 'uht="$upstream_header_time" urt="$upstream_response_time"'; + ''; }; - systemd.tmpfiles.rules = lib.mapAttrsToList ( - virtualHost: _: - # - "d /var/log/nginx/${virtualHost} 0750 ${config.services.nginx.user} ${config.services.nginx.group}" - ) config.services.nginx.virtualHosts; + services.logrotate.settings = + { + # Override the default, just keep fewer logs + nginx.rotate = 6; + } + // lib.mapAttrs' (virtualHost: _: + lib.nameValuePair "/var/log/nginx/${virtualHost}/access.log" { + frequency = "daily"; + rotate = 2; + compress = true; + delaycompress = true; + su = "${config.services.nginx.user} ${config.services.nginx.group}"; + postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`"; + }) + config.services.nginx.virtualHosts; + + systemd.tmpfiles.rules = + lib.mapAttrsToList ( + virtualHost: _: + # + "d /var/log/nginx/${virtualHost} 0750 ${config.services.nginx.user} ${config.services.nginx.group}" + ) + config.services.nginx.virtualHosts; security.acme = { defaults.email = "tm@tlater.net"; acceptTerms = true; certs."tlater.net" = { - extraDomainNames = [ - "*.tlater.net" - "tlater.com" - "*.tlater.com" - ]; - dnsProvider = "porkbun"; - group = "ssl-cert"; - credentialFiles = { - PORKBUN_API_KEY_FILE = config.sops.secrets."porkbun/api-key".path; - PORKBUN_SECRET_API_KEY_FILE = config.sops.secrets."porkbun/secret-api-key".path; - }; + extraDomainNames = ["*.tlater.net"]; + dnsProvider = "hetzner"; + group = "nginx"; + credentialFiles."HETZNER_API_KEY_FILE" = config.sops.secrets."hetzner-api".path; }; }; - users.groups.ssl-cert = { }; - - systemd.services.nginx.serviceConfig.SupplementaryGroups = [ - config.security.acme.certs."tlater.net".group - ]; + services.backups.acme = { + user = "acme"; + paths = + lib.mapAttrsToList (virtualHost: _: "/var/lib/acme/${virtualHost}") + config.services.nginx.virtualHosts; + }; } diff --git a/configuration/services/afvalcalendar.nix b/configuration/services/afvalcalendar.nix new file mode 100644 index 0000000..e27ba62 --- /dev/null +++ b/configuration/services/afvalcalendar.nix @@ -0,0 +1,67 @@ +{ + pkgs, + config, + ... +}: { + systemd.services.afvalcalendar = { + description = "Enschede afvalcalendar -> ical converter"; + wantedBy = ["multi-user.target"]; + after = ["network.target"]; + + script = '' + ${pkgs.local.afvalcalendar}/bin/afvalcalendar > /srv/afvalcalendar/afvalcalendar.ical + ''; + + startAt = "daily"; + + serviceConfig = { + DynamicUser = true; + ProtectHome = true; # Override the default (read-only) + PrivateDevices = true; + PrivateIPC = true; + PrivateUsers = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"]; + RestrictNamespaces = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = ["@system-service" "~@privileged @resources @setuid @keyring"]; + + Umask = 0002; + SupplementaryGroups = "afvalcalendar-hosting"; + + ReadWritePaths = "/srv/afvalcalendar"; + }; + }; + + services.nginx.virtualHosts."afvalcalendar.${config.services.nginx.domain}" = { + forceSSL = true; + useACMEHost = "tlater.net"; + enableHSTS = true; + + root = "/srv/afvalcalendar"; + }; + + users.groups.afvalcalendar-hosting = {}; + systemd.tmpfiles.settings."10-afvalcalendar" = { + "/srv/afvalcalendar".d = { + user = "nginx"; + group = "afvalcalendar-hosting"; + mode = "0775"; + }; + + "/srv/afvalcalendar/afvalcalendar.ical".f = { + user = "nginx"; + group = "afvalcalendar-hosting"; + mode = "0775"; + }; + }; +} diff --git a/configuration/services/auth.nix b/configuration/services/auth.nix new file mode 100644 index 0000000..cd78111 --- /dev/null +++ b/configuration/services/auth.nix @@ -0,0 +1,95 @@ +{ + pkgs, + config, + ... +}: let + user = config.services.authelia.instances.main.user; + domain = "auth.${config.services.nginx.domain}"; +in { + services.authelia.instances.main = { + enable = true; + settings = { + theme = "auto"; + + access_control.default_policy = "one_factor"; + + authentication_backend = { + password_reset.disable = true; + file.path = "/var/lib/authelia-main/users.yml"; + }; + + notifier.filesystem.filename = "/var/lib/authelia-main/notification.txt"; + + session = { + domain = config.services.nginx.domain; + redis.host = config.services.redis.servers.authelia.unixSocket; + }; + + storage.postgres = { + host = "/run/postgresql"; + port = 5432; + database = user; + username = user; + + password = "unnecessary"; + }; + }; + + secrets = { + storageEncryptionKeyFile = config.sops.secrets."authelia/storageEncryptionKey".path; # Database + sessionSecretFile = config.sops.secrets."authelia/sessionSecret".path; # Redis + jwtSecretFile = config.sops.secrets."authelia/jwtSecret".path; + }; + }; + + systemd.services.authelia-main.after = ["postgresql.service"]; + + services.nginx = { + # TODO(tlater): Possibly remove on next authelia release + additionalModules = with pkgs.nginxModules; [ + develkit + set-misc + ]; + + virtualHosts."${domain}" = { + forceSSL = true; + enableACME = true; + enableHSTS = true; + + locations = { + "/" = { + proxyPass = "http://127.0.0.1:9091"; + recommendedProxySettings = false; + enableAutheliaProxy = true; + }; + + "/api/verify" = { + proxyPass = "http://127.0.0.1:9091"; + recommendedProxySettings = false; + }; + }; + }; + }; + + services.redis.servers.authelia = { + inherit user; + enable = true; + }; + + sops.secrets = { + "authelia/storageEncryptionKey" = { + owner = user; + group = user; + }; + + "authelia/sessionSecret" = { + owner = user; + group = user; + }; + + "authelia/jwtSecret" = { + owner = user; + group = user; + }; + }; +} diff --git a/configuration/services/backups.nix b/configuration/services/backups.nix index baa61e3..98aa473 100644 --- a/configuration/services/backups.nix +++ b/configuration/services/backups.nix @@ -3,33 +3,27 @@ pkgs, lib, ... -}: -let +}: let inherit (lib) types optional singleton; - mkShutdownScript = - service: + mkShutdownScript = service: pkgs.writeShellScript "backup-${service}-shutdown" '' if systemctl is-active --quiet '${service}'; then touch '/tmp/${service}-was-active' systemctl stop '${service}' fi ''; - mkRestartScript = - service: + mkRestartScript = service: pkgs.writeShellScript "backup-${service}-restart" '' if [ -f '/tmp/${service}-was-active' ]; then rm '/tmp/${service}-was-active' systemctl start '${service}' fi ''; - writeScript = - name: packages: text: - lib.getExe ( - pkgs.writeShellApplication { - inherit name text; - runtimeInputs = packages; - } - ); + writeScript = name: packages: text: + lib.getExe (pkgs.writeShellApplication { + inherit name text; + runtimeInputs = packages; + }); # *NOT* a TOML file, for some reason quotes are interpreted # *literally @@ -48,98 +42,96 @@ let RESTIC_REPOSITORY = "rclone:storagebox:backups"; RCLONE_CONFIG = rcloneConfig; }; -in -{ +in { options = { services.backups = lib.mkOption { description = lib.mdDoc '' Configure restic backups with a specific tag. ''; - type = types.attrsOf ( - types.submodule ( - { name, ... }: - { - options = { - user = lib.mkOption { - type = types.str; - description = '' - The user as which to run the backup. - ''; - }; - paths = lib.mkOption { - type = types.listOf types.str; - description = '' - The paths to back up. - ''; - }; - tag = lib.mkOption { - type = types.str; - description = '' - The restic tag to mark the backup with. - ''; - default = name; - }; - preparation = { - packages = lib.mkOption { - type = types.listOf types.package; - default = [ ]; - description = '' - The list of packages to make available in the - preparation script. - ''; - }; - text = lib.mkOption { - type = types.nullOr types.str; - default = null; - description = '' - The preparation script to run before the backup. - - This should include things like database dumps and - enabling maintenance modes. If a service needs to be - shut down for backups, use `pauseServices` instead. - ''; - }; - }; - cleanup = { - packages = lib.mkOption { - type = types.listOf types.package; - default = [ ]; - description = '' - The list of packages to make available in the - cleanup script. - ''; - }; - text = lib.mkOption { - type = types.nullOr types.str; - default = null; - description = '' - The cleanup script to run after the backup. - - This should do things like cleaning up database dumps - and disabling maintenance modes. - ''; - }; - }; - pauseServices = lib.mkOption { - type = types.listOf types.str; - default = [ ]; - description = '' - The systemd services that need to be shut down before - the backup can run. Services will be restarted after the - backup is complete. - - This is intended to be used for services that do not - support hot backups. - ''; - }; + type = types.attrsOf (types.submodule ({ + config, + name, + ... + }: { + options = { + user = lib.mkOption { + type = types.str; + description = '' + The user as which to run the backup. + ''; + }; + paths = lib.mkOption { + type = types.listOf types.str; + description = '' + The paths to back up. + ''; + }; + tag = lib.mkOption { + type = types.str; + description = '' + The restic tag to mark the backup with. + ''; + default = name; + }; + preparation = { + packages = lib.mkOption { + type = types.listOf types.package; + default = []; + description = '' + The list of packages to make available in the + preparation script. + ''; }; - } - ) - ); + text = lib.mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The preparation script to run before the backup. + + This should include things like database dumps and + enabling maintenance modes. If a service needs to be + shut down for backups, use `pauseServices` instead. + ''; + }; + }; + cleanup = { + packages = lib.mkOption { + type = types.listOf types.package; + default = []; + description = '' + The list of packages to make available in the + cleanup script. + ''; + }; + text = lib.mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The cleanup script to run after the backup. + + This should do things like cleaning up database dumps + and disabling maintenance modes. + ''; + }; + }; + pauseServices = lib.mkOption { + type = types.listOf types.str; + default = []; + description = '' + The systemd services that need to be shut down before + the backup can run. Services will be restarted after the + backup is complete. + + This is intended to be used for services that do not + support hot backups. + ''; + }; + }; + })); }; }; - config = lib.mkIf (config.services.backups != { }) { + config = lib.mkIf (config.services.backups != {}) { systemd.services = { restic-prune = { @@ -172,15 +164,16 @@ in }; }; } - // lib.mapAttrs' ( - name: backup: + // lib.mapAttrs' (name: backup: lib.nameValuePair "backup-${name}" { # Don't want to restart mid-backup restartIfChanged = false; - environment = resticEnv // { - RESTIC_CACHE_DIR = "%C/backup-${name}"; - }; + environment = + resticEnv + // { + RESTIC_CACHE_DIR = "%C/backup-${name}"; + }; path = with pkgs; [ coreutils @@ -203,60 +196,47 @@ in PrivateTmp = true; ExecStart = [ - (lib.concatStringsSep " " ( - [ - "${pkgs.restic}/bin/restic" - "backup" - "--tag" - name - ] - ++ backup.paths - )) + (lib.concatStringsSep " " (["${pkgs.restic}/bin/restic" "backup" "--tag" name] ++ backup.paths)) ]; ExecStartPre = map (service: "+${mkShutdownScript service}") backup.pauseServices - ++ singleton ( - writeScript "backup-${name}-repo-init" [ ] '' - restic snapshots || restic init - '' - ) - ++ optional (backup.preparation.text != null) ( - writeScript "backup-${name}-prepare" backup.preparation.packages backup.preparation.text - ); + ++ singleton (writeScript "backup-${name}-repo-init" [] '' + restic snapshots || restic init + '') + ++ optional (backup.preparation.text != null) + (writeScript "backup-${name}-prepare" backup.preparation.packages backup.preparation.text); # TODO(tlater): Add repo pruning/checking ExecStopPost = map (service: "+${mkRestartScript service}") backup.pauseServices - ++ optional (backup.cleanup.text != null) ( - writeScript "backup-${name}-cleanup" backup.cleanup.packages backup.cleanup.text - ); + ++ optional (backup.cleanup.text != null) + (writeScript "backup-${name}-cleanup" backup.cleanup.packages backup.cleanup.text); }; - } - ) config.services.backups; + }) + config.services.backups; systemd.timers = { restic-prune = { - wantedBy = [ "timers.target" ]; + wantedBy = ["timers.target"]; timerConfig.OnCalendar = "Thursday 03:00:00 UTC"; # Don't make this persistent, in case the server was offline # for a while. This job cannot run at the same time as any # of the backup jobs. }; } - // lib.mapAttrs' ( - name: _: + // lib.mapAttrs' (name: backup: lib.nameValuePair "backup-${name}" { - wantedBy = [ "timers.target" ]; + wantedBy = ["timers.target"]; timerConfig = { OnCalendar = "Wednesday 02:30:00 UTC"; RandomizedDelaySec = "1h"; FixedRandomDelay = true; Persistent = true; }; - } - ) config.services.backups; + }) + config.services.backups; users = { # This user is only used to own the ssh key, because apparently @@ -265,7 +245,7 @@ in group = "backup"; isSystemUser = true; }; - groups.backup = { }; + groups.backup = {}; }; }; } diff --git a/configuration/services/battery-manager.nix b/configuration/services/battery-manager.nix index 9da7e32..7f27931 100644 --- a/configuration/services/battery-manager.nix +++ b/configuration/services/battery-manager.nix @@ -1,16 +1,17 @@ -{ config, flake-inputs, ... }: { - imports = [ flake-inputs.sonnenshift.nixosModules.default ]; + config, + flake-inputs, + ... +}: { + imports = [ + flake-inputs.sonnenshift.nixosModules.default + ]; services.batteryManager = { enable = true; + battery = "3ca39300-c523-4315-b9a3-d030f85a9373"; emailFile = "${config.sops.secrets."battery-manager/email".path}"; passwordFile = "${config.sops.secrets."battery-manager/password".path}"; - - settings = { - battery_id = "3ca39300-c523-4315-b9a3-d030f85a9373"; - log_level = "DEBUG"; - }; }; } diff --git a/configuration/services/conduit.nix b/configuration/services/conduit.nix new file mode 100644 index 0000000..2462d9b --- /dev/null +++ b/configuration/services/conduit.nix @@ -0,0 +1,254 @@ +{ + pkgs, + config, + lib, + ... +}: let + inherit (lib.strings) concatMapStringsSep; + + cfg = config.services.matrix-conduit; + domain = "matrix.${config.services.nginx.domain}"; + turn-realm = "turn.${config.services.nginx.domain}"; +in { + services.matrix-conduit = { + enable = true; + settings.global = { + address = "127.0.0.1"; + server_name = domain; + database_backend = "rocksdb"; + + turn_uris = let + address = "${config.services.coturn.realm}:${toString config.services.coturn.listening-port}"; + tls-address = "${config.services.coturn.realm}:${toString config.services.coturn.tls-listening-port}"; + in [ + "turn:${address}?transport=udp" + "turn:${address}?transport=tcp" + "turns:${tls-address}?transport=udp" + "turns:${tls-address}?transport=tcp" + ]; + }; + }; + + systemd.services.heisenbridge = let + replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret"; + registrationFile = builtins.toFile "heisenbridge-registration.yaml" (builtins.toJSON { + id = "heisenbridge"; + url = "http://127.0.0.1:9898"; + as_token = "@AS_TOKEN@"; + hs_token = "@HS_TOKEN@"; + rate_limited = false; + sender_localpart = "heisenbridge"; + namespaces = { + users = [ + { + regex = "@irc_.*"; + exclusive = true; + } + { + regex = "@heisenbridge:.*"; + exclusive = true; + } + ]; + aliases = []; + rooms = []; + }; + }); + + # TODO(tlater): Starting with systemd 253 it will become possible + # to do the credential setup as part of ExecStartPre/preStart + # instead. + # + # This will also make it possible to actually set caps on the + # heisenbridge process using systemd, so that we can run the + # identd process. + execScript = pkgs.writeShellScript "heisenbridge" '' + cp ${registrationFile} "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml" + chmod 600 $RUNTIME_DIRECTORY/heisenbridge-registration.yaml + ${replaceSecretBin} '@AS_TOKEN@' "$CREDENTIALS_DIRECTORY/heisenbridge_as-token" "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml" + ${replaceSecretBin} '@HS_TOKEN@' "$CREDENTIALS_DIRECTORY/heisenbridge_hs-token" "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml" + chmod 400 $RUNTIME_DIRECTORY/heisenbridge-registration.yaml + + ${pkgs.heisenbridge}/bin/heisenbridge \ + --config $RUNTIME_DIRECTORY/heisenbridge-registration.yaml \ + --owner @tlater:matrix.tlater.net \ + 'http://localhost:${toString cfg.settings.global.port}' + ''; + in { + description = "Matrix<->IRC bridge"; + wantedBy = ["multi-user.target"]; + after = ["conduit.service"]; + + serviceConfig = { + Type = "simple"; + + LoadCredential = "heisenbridge:/run/secrets/heisenbridge"; + + ExecStart = execScript; + + DynamicUser = true; + RuntimeDirectory = "heisenbridge"; + RuntimeDirectoryMode = "0700"; + + RestrictNamespaces = true; + PrivateUsers = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + RestrictAddressFamilies = ["AF_INET AF_INET6"]; + LockPersonality = true; + RestrictRealtime = true; + ProtectProc = "invisible"; + ProcSubset = "pid"; + UMask = 0077; + + # For the identd port + # CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE"]; + # AmbientCapabilities = ["CAP_NET_BIND_SERVICE"]; + }; + }; + + # Pass in the TURN secret via EnvironmentFile, not supported by + # upstream module currently. + # + # See also https://gitlab.com/famedly/conduit/-/issues/314 + systemd.services.conduit.serviceConfig.EnvironmentFile = config.sops.secrets."turn/env".path; + + services.coturn = { + enable = true; + no-cli = true; + use-auth-secret = true; + static-auth-secret-file = config.sops.secrets."turn/secret".path; + realm = turn-realm; + relay-ips = [ + "116.202.158.55" + ]; + + # SSL config + # + # TODO(tlater): Switch to letsencrypt once google fix: + # https://github.com/vector-im/element-android/issues/1533 + pkey = config.sops.secrets."turn/ssl-key".path; + cert = config.sops.secrets."turn/ssl-cert".path; + + # Based on suggestions from + # https://github.com/matrix-org/synapse/blob/develop/docs/turn-howto.md + # and + # https://www.foxypossibilities.com/2018/05/19/setting-up-a-turn-sever-for-matrix-on-nixos/ + no-tcp-relay = true; + secure-stun = true; + extraConfig = '' + # Deny various local IP ranges, see + # https://www.rtcsec.com/article/cve-2020-26262-bypass-of-coturns-access-control-protection/ + no-multicast-peers + denied-peer-ip=0.0.0.0-0.255.255.255 + denied-peer-ip=10.0.0.0-10.255.255.255 + denied-peer-ip=100.64.0.0-100.127.255.255 + denied-peer-ip=127.0.0.0-127.255.255.255 + denied-peer-ip=169.254.0.0-169.254.255.255 + denied-peer-ip=172.16.0.0-172.31.255.255 + denied-peer-ip=192.0.0.0-192.0.0.255 + denied-peer-ip=192.0.2.0-192.0.2.255 + denied-peer-ip=192.88.99.0-192.88.99.255 + denied-peer-ip=192.168.0.0-192.168.255.255 + denied-peer-ip=198.18.0.0-198.19.255.255 + denied-peer-ip=198.51.100.0-198.51.100.255 + denied-peer-ip=203.0.113.0-203.0.113.255 + denied-peer-ip=240.0.0.0-255.255.255.255 denied-peer-ip=::1 + denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff + denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255 + denied-peer-ip=100::-100::ffff:ffff:ffff:ffff + denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff + + # *Allow* any IP addresses that we explicitly set as relay IPs + ${concatMapStringsSep "\n" (ip: "allowed-peer-ip=${ip}") config.services.coturn.relay-ips} + + # Various other security settings + no-tlsv1 + no-tlsv1_1 + + # Monitoring + prometheus + ''; + }; + + services.nginx.virtualHosts."${domain}" = { + useACMEHost = "tlater.net"; + + listen = [ + { + addr = "0.0.0.0"; + port = 80; + } + { + addr = "[::0]"; + port = 80; + } + { + addr = "0.0.0.0"; + port = 443; + ssl = true; + } + { + addr = "[::0]"; + port = 443; + ssl = true; + } + { + addr = "0.0.0.0"; + port = 8448; + ssl = true; + } + { + addr = "[::0]"; + port = 8448; + ssl = true; + } + ]; + + forceSSL = true; + enableHSTS = true; + extraConfig = '' + merge_slashes off; + ''; + + locations = { + "/_matrix" = { + proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}"; + # Recommended by conduit + extraConfig = '' + proxy_buffering off; + ''; + }; + + # Add Element X support + # TODO(tlater): Remove when no longer required: https://github.com/vector-im/element-x-android/issues/1085 + "=/.well-known/matrix/client" = { + alias = pkgs.writeText "well-known-matrix-client" (builtins.toJSON { + "m.homeserver".base_url = "https://${domain}"; + "org.matrix.msc3575.proxy".url = "https://${domain}"; + }); + + extraConfig = '' + default_type application/json; + add_header Access-Control-Allow-Origin "*"; + ''; + }; + }; + }; + + services.backups.conduit = { + user = "root"; + paths = [ + "/var/lib/private/matrix-conduit/" + ]; + # Other services store their data in conduit, so no other services + # need to be shut down currently. + pauseServices = ["conduit.service"]; + }; +} diff --git a/configuration/services/conduit/default.nix b/configuration/services/conduit/default.nix deleted file mode 100644 index 4ba5271..0000000 --- a/configuration/services/conduit/default.nix +++ /dev/null @@ -1,182 +0,0 @@ -{ - pkgs, - config, - lib, - ... -}: -let - inherit (lib.strings) concatMapStringsSep; - - cfg = config.services.matrix-conduit; - domain = "matrix.${config.services.nginx.domain}"; - turn-realm = "turn.${config.services.nginx.domain}"; -in -{ - imports = [ - ./heisenbridge.nix - ./matrix-hookshot.nix - ]; - - services = { - matrix-conduit = { - enable = true; - package = pkgs.matrix-continuwuity; - settings.global = { - address = "127.0.0.1"; - server_name = domain; - new_user_displayname_suffix = "🦆"; - allow_check_for_updates = true; - - # Set up delegation: https://docs.conduit.rs/delegation.html#automatic-recommended - # This is primarily to make sliding sync work - well_known = { - client = "https://${domain}"; - server = "${domain}:443"; - }; - - turn_uris = - let - address = "${config.services.coturn.realm}:${toString config.services.coturn.listening-port}"; - tls-address = "${config.services.coturn.realm}:${toString config.services.coturn.tls-listening-port}"; - in - [ - "turn:${address}?transport=udp" - "turn:${address}?transport=tcp" - "turns:${tls-address}?transport=udp" - "turns:${tls-address}?transport=tcp" - ]; - }; - }; - - coturn = { - enable = true; - no-cli = true; - use-auth-secret = true; - static-auth-secret-file = config.sops.secrets."turn/secret".path; - realm = turn-realm; - relay-ips = [ "116.202.158.55" ]; - - # SSL config - pkey = "${config.security.acme.certs."tlater.net".directory}/key.pem"; - cert = "${config.security.acme.certs."tlater.net".directory}/fullchain.pem"; - - # Based on suggestions from - # https://github.com/matrix-org/synapse/blob/develop/docs/turn-howto.md - # and - # https://www.foxypossibilities.com/2018/05/19/setting-up-a-turn-sever-for-matrix-on-nixos/ - no-tcp-relay = true; - secure-stun = true; - extraConfig = '' - # Deny various local IP ranges, see - # https://www.rtcsec.com/article/cve-2020-26262-bypass-of-coturns-access-control-protection/ - no-multicast-peers - denied-peer-ip=0.0.0.0-0.255.255.255 - denied-peer-ip=10.0.0.0-10.255.255.255 - denied-peer-ip=100.64.0.0-100.127.255.255 - denied-peer-ip=127.0.0.0-127.255.255.255 - denied-peer-ip=169.254.0.0-169.254.255.255 - denied-peer-ip=172.16.0.0-172.31.255.255 - denied-peer-ip=192.0.0.0-192.0.0.255 - denied-peer-ip=192.0.2.0-192.0.2.255 - denied-peer-ip=192.88.99.0-192.88.99.255 - denied-peer-ip=192.168.0.0-192.168.255.255 - denied-peer-ip=198.18.0.0-198.19.255.255 - denied-peer-ip=198.51.100.0-198.51.100.255 - denied-peer-ip=203.0.113.0-203.0.113.255 - denied-peer-ip=240.0.0.0-255.255.255.255 denied-peer-ip=::1 - denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff - denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255 - denied-peer-ip=100::-100::ffff:ffff:ffff:ffff - denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff - denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff - denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff - denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff - - # *Allow* any IP addresses that we explicitly set as relay IPs - ${concatMapStringsSep "\n" (ip: "allowed-peer-ip=${ip}") config.services.coturn.relay-ips} - - # Various other security settings - no-tlsv1 - no-tlsv1_1 - - # Monitoring - prometheus - ''; - }; - - nginx.virtualHosts."${domain}" = { - useACMEHost = "tlater.net"; - - listen = [ - { - addr = "0.0.0.0"; - port = 80; - } - { - addr = "[::0]"; - port = 80; - } - { - addr = "0.0.0.0"; - port = 443; - ssl = true; - } - { - addr = "[::0]"; - port = 443; - ssl = true; - } - { - addr = "0.0.0.0"; - port = 8448; - ssl = true; - } - { - addr = "[::0]"; - port = 8448; - ssl = true; - } - ]; - - forceSSL = true; - enableHSTS = true; - extraConfig = '' - merge_slashes off; - ''; - - locations = { - "/_matrix" = { - proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}"; - # Recommended by conduit - extraConfig = '' - proxy_buffering off; - ''; - }; - "/.well-known/matrix" = { - proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}"; - }; - }; - }; - - backups.conduit = { - user = "root"; - paths = [ "/var/lib/private/matrix-conduit/" ]; - # Other services store their data in conduit, so no other services - # need to be shut down currently. - pauseServices = [ "conduit.service" ]; - }; - }; - - systemd.services.conduit.serviceConfig = { - ExecStart = lib.mkForce "${config.services.matrix-conduit.package}/bin/conduwuit"; - # Pass in the TURN secret via EnvironmentFile, not supported by - # upstream module currently. - # - # See also https://gitlab.com/famedly/conduit/-/issues/314 - EnvironmentFile = config.sops.secrets."turn/env".path; - }; - - systemd.services.coturn.serviceConfig.SupplementaryGroups = [ - config.security.acme.certs."tlater.net".group - ]; -} diff --git a/configuration/services/conduit/heisenbridge.nix b/configuration/services/conduit/heisenbridge.nix deleted file mode 100644 index f0f7e49..0000000 --- a/configuration/services/conduit/heisenbridge.nix +++ /dev/null @@ -1,78 +0,0 @@ -{ - pkgs, - lib, - config, - ... -}: -let - conduitCfg = config.services.matrix-conduit; - matrixLib = pkgs.callPackage ./lib.nix { }; -in -{ - systemd.services.heisenbridge = - let - registration = matrixLib.writeRegistrationScript { - id = "heisenbridge"; - url = "http://127.0.0.1:9898"; - sender_localpart = "heisenbridge"; - - namespaces = { - users = [ - { - regex = "@irc_.*"; - exclusive = true; - } - { - regex = "@heisenbridge:.*"; - exclusive = true; - } - ]; - - aliases = [ ]; - rooms = [ ]; - }; - }; - in - { - description = "Matrix<->IRC bridge"; - wantedBy = [ "multi-user.target" ]; - after = [ "conduit.service" ]; - - serviceConfig = { - Type = "exec"; - - LoadCredential = "heisenbridge:/run/secrets/heisenbridge"; - - inherit (registration) ExecStartPre; - ExecStart = lib.concatStringsSep " " [ - "${lib.getExe pkgs.heisenbridge}" - "--config \${RUNTIME_DIRECTORY}/heisenbridge-registration.yaml" - "--owner @tlater:matrix.tlater.net" - "http://localhost:${toString conduitCfg.settings.global.port}" - ]; - - DynamicUser = true; - RuntimeDirectory = "heisenbridge"; - RuntimeDirectoryMode = "0700"; - - RestrictNamespaces = true; - PrivateUsers = true; - ProtectHostname = true; - ProtectClock = true; - ProtectKernelTunables = true; - ProtectKernelModules = true; - ProtectKernelLogs = true; - ProtectControlGroups = true; - RestrictAddressFamilies = [ "AF_INET AF_INET6" ]; - LockPersonality = true; - RestrictRealtime = true; - ProtectProc = "invisible"; - ProcSubset = "pid"; - UMask = 77; - - # For the identd port - # CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; - # AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; - }; - }; -} diff --git a/configuration/services/conduit/lib.nix b/configuration/services/conduit/lib.nix deleted file mode 100644 index ef407cf..0000000 --- a/configuration/services/conduit/lib.nix +++ /dev/null @@ -1,67 +0,0 @@ -{ - lib, - writeShellScript, - formats, - replace-secret, -}: -let - replaceSecretBin = "${lib.getExe replace-secret}"; -in -{ - # Write a script that will set up the service's registration.yaml - # with secrets from systemd credentials. - # - # The credentials should be named `${id}_as-token` and - # `${id}_hs-token`. - # - # This registration file needs to be manually added to conduit by - # messaging the admin with the yaml file. - # - # TODO(tlater): Conduwuit seems to support a CLI interface for this, - # may want to migrate to that sometime. - writeRegistrationScript = - { - id, # Must be unique among all registered appservices/bots - url, # The URL on which the service listens - sender_localpart, - rate_limited ? false, - namespaces ? { - aliases = [ ]; - rooms = [ ]; - users = [ ]; - }, - extraSettings ? { }, - # The location to place the file; assumes systemd runtime dir - runtimeRegistration ? "$RUNTIME_DIRECTORY/${id}-registration.yaml", - }: - let - registrationFile = (formats.yaml { }).generate "${id}-registration.yaml" ( - { - inherit - id - url - sender_localpart - rate_limited - namespaces - ; - - as_token = "@AS_TOKEN@"; - hs_token = "@HS_TOKEN@"; - } - // extraSettings - ); - in - { - inherit runtimeRegistration; - ExecStartPre = writeShellScript "${id}-registration-setup.sh" '' - cp -f ${registrationFile} "${runtimeRegistration}" - chmod 600 "${runtimeRegistration}" - - # Write actual secrets into config - ${replaceSecretBin} '@AS_TOKEN@' "$CREDENTIALS_DIRECTORY/${id}_as-token" "${runtimeRegistration}" - ${replaceSecretBin} '@HS_TOKEN@' "$CREDENTIALS_DIRECTORY/${id}_hs-token" "${runtimeRegistration}" - - chmod 400 "${runtimeRegistration}" - ''; - }; -} diff --git a/configuration/services/conduit/matrix-hookshot.nix b/configuration/services/conduit/matrix-hookshot.nix deleted file mode 100644 index 6b788b2..0000000 --- a/configuration/services/conduit/matrix-hookshot.nix +++ /dev/null @@ -1,166 +0,0 @@ -{ - pkgs, - lib, - config, - ... -}: -let - matrixLib = pkgs.callPackage ./lib.nix { }; - - cfg = config.services.matrix-hookshot; - conduitCfg = config.services.matrix-conduit; - - domain = conduitCfg.settings.global.server_name; - - registration = matrixLib.writeRegistrationScript { - id = "matrix-hookshot"; - url = "http://127.0.0.1:9993"; - sender_localpart = "hookshot"; - - namespaces = { - aliases = [ ]; - rooms = [ ]; - users = [ - { - regex = "@${cfg.settings.generic.userIdPrefix}.*:${domain}"; - exclusive = true; - } - ]; - }; - - # Encryption support - # TODO(tlater): Enable when - # https://github.com/matrix-org/matrix-hookshot/issues/1060 is - # fixed - # extraSettings = { - # "de.sorunome.msc2409.push_ephemeral" = true; - # push_ephemeral = true; - # "org.matrix.msc3202" = true; - # }; - - runtimeRegistration = "${cfg.registrationFile}"; - }; -in -{ - # users = { - # users.matrix-hookshot = { - # home = "/run/matrix-hookshot"; - # group = "matrix-hookshot"; - # isSystemUser = true; - # }; - - # groups.matrix-hookshot = { }; - # }; - - systemd.services.matrix-hookshot = { - serviceConfig = { - Type = lib.mkForce "exec"; - - LoadCredential = "matrix-hookshot:/run/secrets/matrix-hookshot"; - inherit (registration) ExecStartPre; - - # Some library in matrix-hookshot wants a home directory - Environment = [ "HOME=/run/matrix-hookshot" ]; - - # User = "matrix-hookshot"; - DynamicUser = true; - StateDirectory = "matrix-hookshot"; - RuntimeDirectory = "matrix-hookshot"; - RuntimeDirectoryMode = "0700"; - - RestrictNamespaces = true; - PrivateUsers = true; - ProtectHostname = true; - ProtectClock = true; - ProtectKernelTunables = true; - ProtectKernelModules = true; - ProtectKernelLogs = true; - ProtectControlGroups = true; - RestrictAddressFamilies = [ - # "AF_UNIX" - "AF_INET" - "AF_INET6" - ]; - LockPersonality = true; - RestrictRealtime = true; - ProtectProc = "invisible"; - ProcSubset = "pid"; - UMask = 77; - }; - }; - - # services.redis.servers.matrix-hookshot = { - # enable = true; - # user = "matrix-hookshot"; - # }; - - services.matrix-hookshot = { - enable = true; - - serviceDependencies = [ "conduit.service" ]; - - registrationFile = "/run/matrix-hookshot/registration.yaml"; - - settings = { - bridge = { - inherit domain; - url = "http://localhost:${toString conduitCfg.settings.global.port}"; - mediaUrl = conduitCfg.settings.global.well_known.client; - port = 9993; - bindAddress = "127.0.0.1"; - }; - - bot.displayname = "Hookshot"; - - # cache.redisUri = "redis://${config.services.redis.servers.matrix-hookshot.unixSocket}"; - - generic = { - enabled = true; - outbound = false; - # Only allow webhooks from localhost for the moment - urlPrefix = "http://127.0.0.1:9000/webhook"; - userIdPrefix = "_webhooks_"; - allowJsTransformationFunctions = true; - }; - - # TODO(tlater): Enable when - # https://github.com/matrix-org/matrix-hookshot/issues/1060 is - # fixed - # encryption.storagePath = "/var/lib/matrix-hookshot/cryptostore"; - - permissions = [ - { - actor = "matrix.tlater.net"; - services = [ - { - service = "*"; - level = "notifications"; - } - ]; - } - { - actor = "@tlater:matrix.tlater.net"; - services = [ - { - service = "*"; - level = "admin"; - } - ]; - } - ]; - - listeners = [ - { - port = 9000; - resources = [ "webhooks" ]; - } - { - port = 9001; - resources = [ "metrics" ]; - } - ]; - - metrics.enabled = true; - }; - }; -} diff --git a/configuration/services/crowdsec.nix b/configuration/services/crowdsec.nix deleted file mode 100644 index b736047..0000000 --- a/configuration/services/crowdsec.nix +++ /dev/null @@ -1,82 +0,0 @@ -{ - pkgs, - config, - lib, - ... -}: -{ - security.crowdsec = { - enable = true; - - parserWhitelist = [ "10.45.249.2" ]; - - extraGroups = [ - "systemd-journal" - "nginx" - ]; - - acquisitions = [ - { - source = "journalctl"; - labels.type = "syslog"; - journalctl_filter = [ "SYSLOG_IDENTIFIER=Nextcloud" ]; - } - - { - source = "journalctl"; - labels.type = "syslog"; - journalctl_filter = [ "SYSLOG_IDENTIFIER=sshd-session" ]; - } - - { - labels.type = "nginx"; - filenames = - [ "/var/log/nginx/*.log" ] - ++ lib.mapAttrsToList ( - vHost: _: "/var/log/nginx/${vHost}/access.log" - ) config.services.nginx.virtualHosts; - } - ]; - - remediationComponents.firewallBouncer = { - enable = true; - settings.prometheus = { - enabled = true; - listen_addr = "127.0.0.1"; - listen_port = "60601"; - }; - }; - }; - - # Add whitelists for matrix - systemd.tmpfiles.settings."10-matrix" = - let - stateDir = config.security.crowdsec.stateDirectory; - in - { - "${stateDir}/config/postoverflows".d = { - user = "crowdsec"; - group = "crowdsec"; - mode = "0700"; - }; - - "${stateDir}/config/postoverflows/s01-whitelist".d = { - user = "crowdsec"; - group = "crowdsec"; - mode = "0700"; - }; - - "${stateDir}/config/postoverflows/s01-whitelist/matrix-whitelist.yaml"."L+".argument = - ((pkgs.formats.yaml { }).generate "crowdsec-matrix-whitelist.yaml" { - name = "tetsumaki/matrix"; - description = "custom matrix whitelist"; - whitelist = { - reason = "whitelist false positive for matrix"; - expression = [ - "evt.Overflow.Alert.Events[0].GetMeta('target_fqdn') == '${config.services.matrix-conduit.settings.global.server_name}'" - "evt.Overflow.Alert.GetScenario() in ['crowdsecurity/http-probing', 'crowdsecurity/http-crawl-non_statics']" - ]; - }; - }).outPath; - }; -} diff --git a/configuration/services/fail2ban.nix b/configuration/services/fail2ban.nix new file mode 100644 index 0000000..ace3219 --- /dev/null +++ b/configuration/services/fail2ban.nix @@ -0,0 +1,42 @@ +{pkgs, ...}: { + services.fail2ban = { + enable = true; + extraPackages = [pkgs.ipset]; + banaction = "iptables-ipset-proto6-allports"; + bantime-increment.enable = true; + + jails = { + nginx-botsearch = '' + enabled = true + logpath = /var/log/nginx/access.log + ''; + }; + + ignoreIP = [ + "127.0.0.0/8" + "10.0.0.0/8" + "172.16.0.0/12" + "192.168.0.0/16" + ]; + }; + + # Allow metrics services to connect to the socket as well + users.groups.fail2ban = {}; + systemd.services.fail2ban.serviceConfig = { + ExecStartPost = + "+" + + (pkgs.writeShellScript "fail2ban-post-start" '' + while ! [ -S /var/run/fail2ban/fail2ban.sock ]; do + sleep 1 + done + + while ! ${pkgs.netcat}/bin/nc -zU /var/run/fail2ban/fail2ban.sock; do + sleep 1 + done + + ${pkgs.coreutils}/bin/chown root:fail2ban /var/run/fail2ban /var/run/fail2ban/fail2ban.sock + ${pkgs.coreutils}/bin/chmod 660 /var/run/fail2ban/fail2ban.sock + ${pkgs.coreutils}/bin/chmod 710 /var/run/fail2ban + ''); + }; +} diff --git a/configuration/services/foundryvtt.nix b/configuration/services/foundryvtt.nix index 6c475a3..ac206fc 100644 --- a/configuration/services/foundryvtt.nix +++ b/configuration/services/foundryvtt.nix @@ -2,48 +2,42 @@ lib, config, flake-inputs, - pkgs, ... -}: -let +}: let domain = "foundryvtt.${config.services.nginx.domain}"; -in -{ - imports = [ flake-inputs.foundryvtt.nixosModules.foundryvtt ]; +in { + imports = [flake-inputs.foundryvtt.nixosModules.foundryvtt]; - services = { - foundryvtt = { - enable = true; - hostName = domain; - minifyStaticFiles = true; - proxySSL = true; - proxyPort = 443; - package = flake-inputs.foundryvtt.packages.${pkgs.system}.foundryvtt_13; - }; - - nginx.virtualHosts."${domain}" = - let - inherit (config.services.foundryvtt) port; - in - { - forceSSL = true; - useACMEHost = "tlater.net"; - enableHSTS = true; - - locations."/" = { - proxyWebsockets = true; - proxyPass = "http://localhost:${toString port}"; - }; - }; - - backups.foundryvtt = { - user = "foundryvtt"; - paths = [ config.services.foundryvtt.dataDir ]; - pauseServices = [ "foundryvtt.service" ]; - }; + services.foundryvtt = { + enable = true; + hostName = domain; + minifyStaticFiles = true; + proxySSL = true; + proxyPort = 443; }; # Want to start it manually when I need it, not have it constantly # running - systemd.services.foundryvtt.wantedBy = lib.mkForce [ ]; + systemd.services.foundryvtt.wantedBy = lib.mkForce []; + + services.nginx.virtualHosts."${domain}" = let + inherit (config.services.foundryvtt) port; + in { + forceSSL = true; + useACMEHost = "tlater.net"; + enableHSTS = true; + + locations."/" = { + proxyWebsockets = true; + proxyPass = "http://localhost:${toString port}"; + }; + }; + + services.backups.foundryvtt = { + user = "foundryvtt"; + paths = [ + config.services.foundryvtt.dataDir + ]; + pauseServices = ["foundryvtt.service"]; + }; } diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix index 613d30c..26fe2f8 100644 --- a/configuration/services/gitea.nix +++ b/configuration/services/gitea.nix @@ -3,81 +3,93 @@ config, lib, ... -}: -let +}: let domain = "gitea.${config.services.nginx.domain}"; -in -{ - services = { - forgejo = { - enable = true; - database.type = "postgres"; +in { + services.forgejo = { + enable = true; + database.type = "postgres"; - settings = { - server = { - DOMAIN = domain; - HTTP_ADDR = "127.0.0.1"; - ROOT_URL = "https://${domain}/"; - SSH_PORT = 2222; - }; - - metrics = { - ENABLED = true; - TOKEN = "#metricstoken#"; - }; - service.DISABLE_REGISTRATION = true; - session.COOKIE_SECURE = true; - }; - }; - - # Set up SSL - nginx.virtualHosts."${domain}" = - let - httpAddress = config.services.forgejo.settings.server.HTTP_ADDR; - httpPort = config.services.forgejo.settings.server.HTTP_PORT; - in - { - forceSSL = true; - useACMEHost = "tlater.net"; - enableHSTS = true; - - locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}"; - locations."/metrics" = { - extraConfig = '' - access_log off; - allow 127.0.0.1; - ${lib.optionalString config.networking.enableIPv6 "allow ::1;"} - deny all; - ''; - }; + settings = { + server = { + DOMAIN = domain; + HTTP_ADDR = "127.0.0.1"; + ROOT_URL = "https://${domain}/"; + SSH_PORT = 2222; }; - backups.forgejo = { - user = "forgejo"; - paths = [ - "/var/lib/forgejo/forgejo-db.sql" - "/var/lib/forgejo/repositories/" - "/var/lib/forgejo/data/" - "/var/lib/forgejo/custom/" - # Conf is backed up via nix - ]; - preparation = { - packages = [ config.services.postgresql.package ]; - text = "pg_dump ${config.services.forgejo.database.name} --file=/var/lib/forgejo/forgejo-db.sql"; + metrics = { + ENABLED = true; + TOKEN = "#metricstoken#"; }; - cleanup = { - packages = [ pkgs.coreutils ]; - text = "rm /var/lib/forgejo/forgejo-db.sql"; - }; - pauseServices = [ "forgejo.service" ]; + service.DISABLE_REGISTRATION = true; + session.COOKIE_SECURE = true; }; }; - systemd.services.forgejo.serviceConfig.ExecStartPre = - let - replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret"; - secretPath = config.sops.secrets."forgejo/metrics-token".path; - runConfig = "${config.services.forgejo.customDir}/conf/app.ini"; - in - [ "+${replaceSecretBin} '#metricstoken#' '${secretPath}' '${runConfig}'" ]; + systemd.services.forgejo.serviceConfig.ExecStartPre = let + replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret"; + secretPath = config.sops.secrets."forgejo/metrics-token".path; + runConfig = "${config.services.forgejo.customDir}/conf/app.ini"; + in [ + "+${replaceSecretBin} '#metricstoken#' '${secretPath}' '${runConfig}'" + ]; + + # Set up SSL + services.nginx.virtualHosts."${domain}" = let + httpAddress = config.services.forgejo.settings.server.HTTP_ADDR; + httpPort = config.services.forgejo.settings.server.HTTP_PORT; + in { + forceSSL = true; + useACMEHost = "tlater.net"; + enableHSTS = true; + + locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}"; + locations."/metrics" = { + extraConfig = '' + access_log off; + allow 127.0.0.1; + ${lib.optionalString config.networking.enableIPv6 "allow ::1;"} + deny all; + ''; + }; + }; + + # Block repeated failed login attempts + # + # TODO(tlater): Update this - we switched to forgejo, who knows what + # the new matches are. + # environment.etc = { + # "fail2ban/filter.d/gitea.conf".text = '' + # [Definition] + # failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST> + # journalmatch = _SYSTEMD_UNIT=forgejo.service + _COMM=forgejo + SYSLOG_IDENTIFIER=forgejo + # ''; + # }; + + # services.fail2ban.jails = { + # gitea = '' + # enabled = true + # ''; + # }; + + services.backups.forgejo = { + user = "forgejo"; + paths = [ + "/var/lib/forgejo/forgejo-db.sql" + "/var/lib/forgejo/repositories/" + "/var/lib/forgejo/data/" + "/var/lib/forgejo/custom/" + # Conf is backed up via nix + ]; + preparation = { + packages = [config.services.postgresql.package]; + text = "pg_dump ${config.services.forgejo.database.name} --file=/var/lib/forgejo/forgejo-db.sql"; + }; + cleanup = { + packages = [pkgs.coreutils]; + text = "rm /var/lib/forgejo/forgejo-db.sql"; + }; + pauseServices = ["forgejo.service"]; + }; } diff --git a/configuration/services/immich.nix b/configuration/services/immich.nix deleted file mode 100644 index 516ea3e..0000000 --- a/configuration/services/immich.nix +++ /dev/null @@ -1,67 +0,0 @@ -{ - pkgs, - config, - lib, - ... -}: -let - hostName = "immich.${config.services.nginx.domain}"; -in -{ - services = { - immich = { - enable = true; - settings.server.externalDomain = "https://${hostName}"; - - environment.IMMICH_TELEMETRY_INCLUDE = "all"; - }; - - nginx.virtualHosts.${hostName} = - let - local = "http://${config.services.immich.host}:${toString config.services.immich.port}"; - in - { - forceSSL = true; - useACMEHost = "tlater.net"; - enableHSTS = true; - - locations."/" = { - proxyPass = local; - proxyWebsockets = true; - }; - locations."/metrics" = { - extraConfig = '' - access_log off; - allow 127.0.0.1; - ${lib.optionalString config.networking.enableIPv6 "allow ::1;"} - deny all; - ''; - }; - }; - - backups.immich = - let - db-dump = "${config.services.immich.mediaLocation}/immich-db.sql"; - in - { - user = "immich"; - paths = [ config.services.immich.mediaLocation ]; - - preparation = { - packages = [ config.services.postgresql.package ]; - text = '' - pg_dump ${config.services.immich.database.name} --clean --if-exists --file=${db-dump} - ''; - }; - - cleanup = { - packages = [ pkgs.coreutils ]; - text = "rm ${db-dump}"; - }; - pauseServices = [ - "immich-server.service" - "immich-machine-learning.service" - ]; - }; - }; -} diff --git a/configuration/services/metrics/default.nix b/configuration/services/metrics/default.nix index fe250fe..84e126a 100644 --- a/configuration/services/metrics/default.nix +++ b/configuration/services/metrics/default.nix @@ -5,6 +5,5 @@ ./exporters.nix ./grafana.nix ./victoriametrics.nix - ./victorialogs.nix ]; } diff --git a/configuration/services/metrics/exporters.nix b/configuration/services/metrics/exporters.nix index 52c2a46..f3054db 100644 --- a/configuration/services/metrics/exporters.nix +++ b/configuration/services/metrics/exporters.nix @@ -3,49 +3,23 @@ pkgs, lib, ... -}: -let - yaml = pkgs.formats.yaml { }; -in -{ +}: let + yaml = pkgs.formats.yaml {}; +in { services.prometheus = { exporters = { - blackbox = { - enable = true; - listenAddress = "127.0.0.1"; - configFile = yaml.generate "blackbox.yaml" { - modules = { - http_2xx = { - prober = "http"; - timeout = "5s"; - http.preferred_ip_protocol = "ip4"; - }; - - turn_server = { - prober = "tcp"; - timeout = "5s"; - tcp = { - preferred_ip_protocol = "ip4"; - source_ip_address = "116.202.158.55"; - tls = true; - }; - }; - }; - }; - }; - # Periodically check domain registration status domain = { enable = true; listenAddress = "127.0.0.1"; - extraFlags = - let - conf.domains = [ - "tlater.net" - "tlater.com" - ]; - in - [ "--config=${yaml.generate "domains.yml" conf}" ]; + extraFlags = let + conf.domains = [ + "tlater.net" + "tlater.com" + ]; + in [ + "--config=${yaml.generate "domains.yml" conf}" + ]; }; # System statistics @@ -74,29 +48,54 @@ in listenAddress = "127.0.0.1"; group = "nginx"; - settings.namespaces = lib.mapAttrsToList (name: _: { - inherit name; - metrics_override.prefix = "nginxlog"; - namespace_label = "vhost"; + settings.namespaces = + lib.mapAttrsToList (name: virtualHost: { + inherit name; + metrics_override.prefix = "nginxlog"; + namespace_label = "vhost"; - format = lib.concatStringsSep " " [ - "$remote_addr - $remote_user [$time_local]" - ''"$request" $status $body_bytes_sent'' - ''"$http_referer" "$http_user_agent"'' - ''rt=$request_time uct="$upstream_connect_time"'' - ''uht="$upstream_header_time" urt="$upstream_response_time"'' - ]; + format = lib.concatStringsSep " " [ + "$remote_addr - $remote_user [$time_local]" + ''"$request" $status $body_bytes_sent'' + ''"$http_referer" "$http_user_agent"'' + ''rt=$request_time uct="$upstream_connect_time"'' + ''uht="$upstream_header_time" urt="$upstream_response_time"'' + ]; - source.files = [ "/var/log/nginx/${name}/access.log" ]; - }) config.services.nginx.virtualHosts; + source.files = [ + "/var/log/nginx/${name}/access.log" + ]; + }) + config.services.nginx.virtualHosts; + }; + }; + + extraExporters = { + fail2ban = let + cfg = config.services.prometheus.extraExporters.fail2ban; + in { + port = 9191; + serviceOpts = { + after = ["fail2ban.service"]; + requires = ["fail2ban.service"]; + serviceConfig = { + Group = "fail2ban"; + RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"]; + ExecStart = lib.concatStringsSep " " [ + "${pkgs.local.prometheus-fail2ban-exporter}/bin/fail2ban-prometheus-exporter" + "--collector.f2b.socket=/var/run/fail2ban/fail2ban.sock" + "--web.listen-address='${cfg.listenAddress}:${toString cfg.port}'" + "--collector.f2b.exit-on-socket-connection-error=true" + ]; + }; + }; }; }; # TODO(tlater): # - wireguard (?) # - postgres (?) + # - blackbox (?) (curl to see if http and similar is up) # - ssl_exporter (?) }; - - services.dbus.implementation = "broker"; } diff --git a/configuration/services/metrics/grafana.nix b/configuration/services/metrics/grafana.nix index b30806c..1136a17 100644 --- a/configuration/services/metrics/grafana.nix +++ b/configuration/services/metrics/grafana.nix @@ -1,15 +1,10 @@ -{ pkgs, config, ... }: -let +{config, ...}: let domain = "metrics.${config.services.nginx.domain}"; -in -{ +in { services.grafana = { enable = true; settings = { - server = { - http_port = 3001; # Default overlaps with gitea - root_url = "https://metrics.tlater.net"; - }; + server.http_port = 3001; # Default overlaps with gitea security = { admin_user = "tlater"; @@ -28,11 +23,6 @@ in }; }; - declarativePlugins = [ - pkgs.grafanaPlugins.victoriametrics-metrics-datasource - pkgs.grafanaPlugins.victoriametrics-logs-datasource - ]; - provision = { enable = true; @@ -40,16 +30,7 @@ in { name = "Victoriametrics - tlater.net"; url = "http://localhost:8428"; - type = "victoriametrics-metrics-datasource"; - access = "proxy"; - isDefault = true; - } - - { - name = "Victorialogs - tlater.net"; - url = "http://${config.services.victorialogs.bindAddress}"; - type = "victoriametrics-logs-datasource"; - access = "proxy"; + type = "prometheus"; } ]; }; @@ -59,12 +40,7 @@ in forceSSL = true; useACMEHost = "tlater.net"; enableHSTS = true; - locations = { - "/".proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}"; - "/api/live" = { - proxyWebsockets = true; - proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}"; - }; - }; + enableAuthorization = true; + locations."/".proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}"; }; } diff --git a/configuration/services/metrics/options.nix b/configuration/services/metrics/options.nix index e1b0761..81f0865 100644 --- a/configuration/services/metrics/options.nix +++ b/configuration/services/metrics/options.nix @@ -3,235 +3,202 @@ config, lib, ... -}: -let +}: let inherit (lib) types mkOption mkDefault; - yaml = pkgs.formats.yaml { }; -in -{ + yaml = pkgs.formats.yaml {}; +in { options = { services.prometheus = { extraExporters = mkOption { - default = { }; - type = types.attrsOf ( - types.submodule { - options = { - port = mkOption { - type = types.int; - description = "The port on which this exporter listens."; - }; - listenAddress = mkOption { - type = types.str; - default = "127.0.0.1"; - description = "Address to listen on."; - }; - serviceOpts = mkOption { - type = types.attrs; - description = "An attrset to be merged with the exporter's systemd service."; - }; + type = types.attrsOf (types.submodule { + options = { + port = mkOption { + type = types.int; + description = "The port on which this exporter listens."; }; - } - ); + listenAddress = mkOption { + type = types.str; + default = "127.0.0.1"; + description = "Address to listen on."; + }; + serviceOpts = mkOption { + type = types.attrs; + description = "An attrset to be merged with the exporter's systemd service."; + }; + }; + }); }; }; services.victoriametrics.scrapeConfigs = mkOption { - type = types.attrsOf ( - types.submodule ( - { name, ... }: - { - options = { - job_name = mkOption { - type = types.str; - default = name; + type = types.attrsOf (types.submodule ({ + name, + self, + ... + }: { + options = { + job_name = mkOption { + type = types.str; + default = name; + }; + + extraSettings = mkOption { + type = types.anything; + description = '' + Other settings to set for this scrape config. + ''; + default = {}; + }; + + targets = mkOption { + type = types.listOf types.str; + description = lib.mdDoc '' + Addresses scrape targets for this config listen on. + + Shortcut for `static_configs = lib.singleton {targets = [<targets>];}` + ''; + default = []; + }; + + static_configs = mkOption { + default = []; + type = types.listOf (types.submodule { + options = { + targets = mkOption { + type = types.listOf types.str; + description = lib.mdDoc '' + The addresses scrape targets for this config listen on. + + Must in `listenAddress:port` format. + ''; + }; + labels = mkOption { + type = types.attrsOf types.str; + description = lib.mdDoc '' + Labels to apply to all targets defined for this static config. + ''; + default = {}; + }; }; - - extraSettings = mkOption { - inherit (pkgs.formats.yaml { }) type; - description = '' - Other settings to set for this scrape config. - ''; - default = { }; - }; - - targets = mkOption { - type = types.listOf types.str; - description = lib.mdDoc '' - Addresses scrape targets for this config listen on. - - Shortcut for `static_configs = lib.singleton {targets = [<targets>];}` - ''; - default = [ ]; - }; - - static_configs = mkOption { - default = [ ]; - type = types.listOf ( - types.submodule { - options = { - targets = mkOption { - type = types.listOf types.str; - description = lib.mdDoc '' - The addresses scrape targets for this config listen on. - - Must in `listenAddress:port` format. - ''; - }; - labels = mkOption { - type = types.attrsOf types.str; - description = lib.mdDoc '' - Labels to apply to all targets defined for this static config. - ''; - default = { }; - }; - }; - } - ); - }; - }; - } - ) - ); + }); + }; + }; + })); }; }; config = { systemd.services = lib.mkMerge [ - (lib.mapAttrs' ( - name: exporter: - lib.nameValuePair "prometheus-${name}-exporter" ( - lib.mkMerge [ - { - # Shamelessly copied from upstream because the upstream - # module is an intractable mess - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - serviceConfig = { - Restart = mkDefault "always"; - PrivateTmp = mkDefault true; - WorkingDirectory = mkDefault /tmp; - DynamicUser = mkDefault true; - # Hardening - CapabilityBoundingSet = mkDefault [ "" ]; - DeviceAllow = [ "" ]; - LockPersonality = true; - MemoryDenyWriteExecute = true; - NoNewPrivileges = true; - PrivateDevices = mkDefault true; - ProtectClock = mkDefault true; - ProtectControlGroups = true; - ProtectHome = true; - ProtectHostname = true; - ProtectKernelLogs = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - ProtectSystem = mkDefault "strict"; - RemoveIPC = true; - RestrictAddressFamilies = [ - "AF_INET" - "AF_INET6" - ]; - RestrictNamespaces = true; - RestrictRealtime = true; - RestrictSUIDSGID = true; - SystemCallArchitectures = "native"; - UMask = "0077"; - }; - } - exporter.serviceOpts - ] - ) - ) config.services.prometheus.extraExporters) + (lib.mapAttrs' (name: exporter: + lib.nameValuePair "prometheus-${name}-exporter" (lib.mkMerge [ + { + # Shamelessly copied from upstream because the upstream + # module is an intractable mess + wantedBy = ["multi-user.target"]; + after = ["network.target"]; + serviceConfig.Restart = mkDefault "always"; + serviceConfig.PrivateTmp = mkDefault true; + serviceConfig.WorkingDirectory = mkDefault /tmp; + serviceConfig.DynamicUser = mkDefault true; + # Hardening + serviceConfig.CapabilityBoundingSet = mkDefault [""]; + serviceConfig.DeviceAllow = [""]; + serviceConfig.LockPersonality = true; + serviceConfig.MemoryDenyWriteExecute = true; + serviceConfig.NoNewPrivileges = true; + serviceConfig.PrivateDevices = mkDefault true; + serviceConfig.ProtectClock = mkDefault true; + serviceConfig.ProtectControlGroups = true; + serviceConfig.ProtectHome = true; + serviceConfig.ProtectHostname = true; + serviceConfig.ProtectKernelLogs = true; + serviceConfig.ProtectKernelModules = true; + serviceConfig.ProtectKernelTunables = true; + serviceConfig.ProtectSystem = mkDefault "strict"; + serviceConfig.RemoveIPC = true; + serviceConfig.RestrictAddressFamilies = ["AF_INET" "AF_INET6"]; + serviceConfig.RestrictNamespaces = true; + serviceConfig.RestrictRealtime = true; + serviceConfig.RestrictSUIDSGID = true; + serviceConfig.SystemCallArchitectures = "native"; + serviceConfig.UMask = "0077"; + } + exporter.serviceOpts + ])) + config.services.prometheus.extraExporters) { - vmagent-scrape-exporters = - let - inherit (config.services.victoriametrics) listenAddress; - vmAddr = (lib.optionalString (lib.hasPrefix ":" listenAddress) "127.0.0.1") + listenAddress; - promscrape = yaml.generate "prometheus.yml" { - scrape_configs = lib.mapAttrsToList ( - _: scrape: - lib.recursiveUpdate { - inherit (scrape) job_name; - static_configs = - scrape.static_configs - ++ lib.optional (scrape.targets != [ ]) { inherit (scrape) targets; }; - } scrape.extraSettings - ) config.services.victoriametrics.scrapeConfigs; - }; - in - { - enable = true; - path = [ pkgs.victoriametrics ]; - wantedBy = [ "multi-user.target" ]; - after = [ - "network.target" - "victoriametrics.service" - ]; - serviceConfig = { - ExecStart = [ - (lib.concatStringsSep " " [ - "${pkgs.victoriametrics}/bin/vmagent" - "-promscrape.config=${promscrape}" - "-remoteWrite.url=http://${vmAddr}/api/v1/write" - "-remoteWrite.tmpDataPath=%t/vmagent" - ]) - ]; - SupplementaryGroups = "metrics"; - - DynamicUser = true; - RuntimeDirectory = "vmagent"; - CapabilityBoundingSet = [ "" ]; - DeviceAllow = [ "" ]; - LockPersonality = true; - MemoryDenyWriteExecute = true; - NoNewPrivileges = true; - PrivateDevices = true; - ProtectClock = true; - ProtectControlGroups = true; - ProtectHome = true; - ProtectHostname = true; - ProtectKernelLogs = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - ProtectSystem = "strict"; - RemoveIPC = true; - RestrictAddressFamilies = [ - "AF_INET" - "AF_INET6" - ]; - RestrictNamespaces = true; - RestrictRealtime = true; - RestrictSUIDSGID = true; - SystemCallArchitectures = "native"; - UMask = "0077"; - }; + vmagent-scrape-exporters = let + listenAddress = config.services.victoriametrics.listenAddress; + vmAddr = (lib.optionalString (lib.hasPrefix ":" listenAddress) "127.0.0.1") + listenAddress; + promscrape = yaml.generate "prometheus.yml" { + scrape_configs = lib.mapAttrsToList (_: scrape: + lib.recursiveUpdate { + inherit (scrape) job_name; + static_configs = + scrape.static_configs + ++ lib.optional (scrape.targets != []) {targets = scrape.targets;}; + } + scrape.extraSettings) + config.services.victoriametrics.scrapeConfigs; }; + in { + enable = true; + path = [pkgs.victoriametrics]; + wantedBy = ["multi-user.target"]; + after = ["network.target" "victoriametrics.service"]; + serviceConfig = { + ExecStart = [ + (lib.concatStringsSep " " [ + "${pkgs.victoriametrics}/bin/vmagent" + "-promscrape.config=${promscrape}" + "-remoteWrite.url=http://${vmAddr}/api/v1/write" + "-remoteWrite.tmpDataPath=%t/vmagent" + ]) + ]; + SupplementaryGroups = "metrics"; + + DynamicUser = true; + RuntimeDirectory = "vmagent"; + CapabilityBoundingSet = [""]; + DeviceAllow = [""]; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = "strict"; + RemoveIPC = true; + RestrictAddressFamilies = ["AF_INET" "AF_INET6"]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + UMask = "0077"; + }; + }; } ]; - users.groups.metrics = { }; + users.groups.metrics = {}; - services.victoriametrics.scrapeConfigs = - let - allExporters = lib.mapAttrs (_: exporter: { inherit (exporter) listenAddress port; }) ( - (lib.filterAttrs ( - name: exporter: - # A bunch of deprecated exporters that need to be ignored - !(builtins.elem name [ - "blackbox" - "minio" - "tor" - "unifi-poller" - ]) - && builtins.isAttrs exporter - && exporter.enable - ) config.services.prometheus.exporters) - // config.services.prometheus.extraExporters - ); - in + services.victoriametrics.scrapeConfigs = let + allExporters = + lib.mapAttrs (name: exporter: { + inherit (exporter) listenAddress port; + }) ((lib.filterAttrs (_: exporter: builtins.isAttrs exporter && exporter.enable) + config.services.prometheus.exporters) + // config.services.prometheus.extraExporters); + in lib.mapAttrs (_: exporter: { - targets = [ "${exporter.listenAddress}:${toString exporter.port}" ]; - }) allExporters; + targets = ["${exporter.listenAddress}:${toString exporter.port}"]; + }) + allExporters; }; } diff --git a/configuration/services/metrics/victorialogs.nix b/configuration/services/metrics/victorialogs.nix deleted file mode 100644 index 413659a..0000000 --- a/configuration/services/metrics/victorialogs.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ config, lib, ... }: -let - cfg = config.services.victorialogs; -in -{ - options.services.victorialogs.bindAddress = lib.mkOption { - readOnly = true; - type = lib.types.str; - description = '' - Final address on which victorialogs listens. - ''; - }; - - config = { - services.victorialogs = { - enable = true; - bindAddress = - (lib.optionalString (lib.hasPrefix ":" cfg.listenAddress) "127.0.0.1") + cfg.listenAddress; - }; - - services.journald.upload = { - enable = true; - settings.Upload = { - URL = "http://${cfg.bindAddress}/insert/journald"; - NetworkTimeoutSec = "20s"; - }; - }; - systemd.services."systemd-journal-upload".after = [ "victorialogs.service" ]; - }; -} diff --git a/configuration/services/metrics/victoriametrics.nix b/configuration/services/metrics/victoriametrics.nix index f37b8b0..daf3f94 100644 --- a/configuration/services/metrics/victoriametrics.nix +++ b/configuration/services/metrics/victoriametrics.nix @@ -1,99 +1,16 @@ -{ config, lib, ... }: -let - blackbox_host = config.services.prometheus.exporters.blackbox.listenAddress; - blackbox_port = config.services.prometheus.exporters.blackbox.port; -in -{ +{config, ...}: { config.services.victoriametrics = { enable = true; - extraOptions = [ "-storage.minFreeDiskSpaceBytes=5GB" ]; + extraOptions = [ + "-storage.minFreeDiskSpaceBytes=5GB" + ]; scrapeConfigs = { forgejo = { - targets = [ "127.0.0.1:${toString config.services.forgejo.settings.server.HTTP_PORT}" ]; + targets = ["127.0.0.1:${toString config.services.forgejo.settings.server.HTTP_PORT}"]; extraSettings.authorization.credentials_file = config.sops.secrets."forgejo/metrics-token".path; }; - - blackbox = { - static_configs = lib.singleton { - targets = lib.mapAttrsToList (vHost: _: "https://${vHost}") config.services.nginx.virtualHosts; - }; - - extraSettings = { - metrics_path = "/probe"; - params.module = [ "http_2xx" ]; - - relabel_configs = [ - { - source_labels = [ "__address__" ]; - target_label = "__param_target"; - } - { - source_labels = [ "__param_target" ]; - target_label = "instance"; - } - { - target_label = "__address__"; - replacement = "${blackbox_host}:${toString blackbox_port}"; - } - ]; - }; - }; - - blackbox_turn = { - targets = [ "turn.tlater.net:${toString config.services.coturn.tls-listening-port}" ]; - - extraSettings = { - metrics_path = "/probe"; - params.module = [ "turn_server" ]; - - relabel_configs = [ - { - source_labels = [ "__address__" ]; - target_label = "__param_target"; - } - { - source_labels = [ "__param_target" ]; - target_label = "instance"; - } - { - target_label = "__address__"; - replacement = "${blackbox_host}:${toString blackbox_port}"; - } - ]; - }; - }; - - blackbox_exporter.targets = [ "${blackbox_host}:${toString blackbox_port}" ]; - - coturn.targets = [ "127.0.0.1:9641" ]; - - crowdsec.targets = - let - address = config.security.crowdsec.settings.prometheus.listen_addr; - port = config.security.crowdsec.settings.prometheus.listen_port; - in - [ "${address}:${toString port}" ]; - - csFirewallBouncer.targets = - let - address = - config.security.crowdsec.remediationComponents.firewallBouncer.settings.prometheus.listen_addr; - port = - config.security.crowdsec.remediationComponents.firewallBouncer.settings.prometheus.listen_port; - in - [ "${address}:${toString port}" ]; - - immich.targets = [ - "127.0.0.1:8081" - "127.0.0.1:8082" - ]; - - # Configured in the hookshot listeners, but it's hard to filter - # the correct values out of that config. - matrixHookshot.targets = [ "127.0.0.1:9001" ]; - - victorialogs.targets = [ config.services.victorialogs.bindAddress ]; + coturn.targets = ["127.0.0.1:9641"]; }; }; } diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix index 4af77a9..2c7fe4f 100644 --- a/configuration/services/nextcloud.nix +++ b/configuration/services/nextcloud.nix @@ -1,103 +1,105 @@ { pkgs, config, - lib, ... -}: -let - nextcloud = pkgs.nextcloud31; +}: let + # Update pending on rewrite of nextcloud news, though there is an + # alpha to switch to if it becomes necessary: + # https://github.com/nextcloud/news/issues/2610 + nextcloud = pkgs.nextcloud27; hostName = "nextcloud.${config.services.nginx.domain}"; -in -{ - services = { - nextcloud = { - inherit hostName; +in { + services.nextcloud = { + inherit hostName; - package = nextcloud; - phpPackage = lib.mkForce ( - pkgs.php.override { - packageOverrides = _: prev: { - extensions = prev.extensions // { - pgsql = prev.extensions.pgsql.overrideAttrs (_: { - configureFlags = [ "--with-pgsql=${lib.getDev config.services.postgresql.package.pg_config}" ]; - }); - pdo_pgsql = prev.extensions.pdo_pgsql.overrideAttrs (_: { - configureFlags = [ "--with-pdo-pgsql=${lib.getDev config.services.postgresql.package.pg_config}" ]; - }); - }; - }; - } - ); - enable = true; - maxUploadSize = "2G"; - https = true; + package = nextcloud; + enable = true; + maxUploadSize = "2G"; + https = true; - configureRedis = true; + configureRedis = true; - config = { - dbtype = "pgsql"; - dbhost = "/run/postgresql"; + config = { + dbtype = "pgsql"; + dbhost = "/run/postgresql"; - adminuser = "tlater"; - adminpassFile = config.sops.secrets."nextcloud/tlater".path; - }; - - settings = { - default_phone_region = "AT"; - overwriteprotocol = "https"; - }; - - phpOptions = { - "opcache.interned_strings_buffer" = "16"; - }; - - extraApps = { - inherit (config.services.nextcloud.package.packages.apps) - calendar - contacts - cookbook - news - ; - }; + adminuser = "tlater"; + adminpassFile = config.sops.secrets."nextcloud/tlater".path; }; - # Set up SSL - nginx.virtualHosts."${hostName}" = { - forceSSL = true; - useACMEHost = "tlater.net"; - # The upstream module already adds HSTS + settings = { + default_phone_region = "AT"; + overwriteprotocol = "https"; }; - backups.nextcloud = { - user = "nextcloud"; - paths = [ - "/var/lib/nextcloud/nextcloud-db.sql" - "/var/lib/nextcloud/data/" - "/var/lib/nextcloud/config/config.php" - ]; - preparation = { - packages = [ - config.services.postgresql.package - config.services.nextcloud.occ - ]; - text = '' - nextcloud-occ maintenance:mode --on - pg_dump ${config.services.nextcloud.config.dbname} --file=/var/lib/nextcloud/nextcloud-db.sql - ''; - }; - cleanup = { - packages = [ - pkgs.coreutils - config.services.nextcloud.occ - ]; - text = '' - rm /var/lib/nextcloud/nextcloud-db.sql - nextcloud-occ maintenance:mode --off - ''; - }; + phpOptions = { + "opcache.interned_strings_buffer" = "16"; + }; + + extraApps = { + inherit (pkgs.local) bookmarks calendar contacts cookbook news notes; }; }; # Ensure that this service doesn't start before postgres is ready - systemd.services.nextcloud-setup.after = [ "postgresql.service" ]; + systemd.services.nextcloud-setup.after = ["postgresql.service"]; + + # Set up SSL + services.nginx.virtualHosts."${hostName}" = { + forceSSL = true; + useACMEHost = "tlater.net"; + # The upstream module already adds HSTS + }; + + # Block repeated failed login attempts + environment.etc = { + "fail2ban/filter.d/nextcloud.conf".text = '' + [Definition] + _groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*) + failregex = \{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed: + \{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error. + datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?" + journalmatch = SYSLOG_IDENTIFIER=Nextcloud + ''; + }; + + services.fail2ban.jails = { + nextcloud = '' + enabled = true + + # Nextcloud does some throttling already, so we need to set + # these to something bigger. + findtime = 43200 + bantime = 86400 + ''; + }; + + services.backups.nextcloud = { + user = "nextcloud"; + paths = [ + "/var/lib/nextcloud/nextcloud-db.sql" + "/var/lib/nextcloud/data/" + "/var/lib/nextcloud/config/config.php" + ]; + preparation = { + packages = [ + config.services.postgresql.package + config.services.nextcloud.occ + ]; + text = '' + nextcloud-occ maintenance:mode --on + pg_dump ${config.services.nextcloud.config.dbname} --file=/var/lib/nextcloud/nextcloud-db.sql + ''; + }; + cleanup = { + packages = [ + pkgs.coreutils + config.services.nextcloud.occ + ]; + text = '' + rm /var/lib/nextcloud/nextcloud-db.sql + nextcloud-occ maintenance:mode --off + ''; + }; + }; } diff --git a/configuration/services/postgres.nix b/configuration/services/postgres.nix index 85a6843..4ec1e83 100644 --- a/configuration/services/postgres.nix +++ b/configuration/services/postgres.nix @@ -1,5 +1,8 @@ -{ pkgs, ... }: { + config, + pkgs, + ... +}: { services.postgresql = { package = pkgs.postgresql_14; enable = true; @@ -25,11 +28,16 @@ name = "nextcloud"; ensureDBOwnership = true; } + { + name = config.services.authelia.instances.main.user; + ensureDBOwnership = true; + } ]; ensureDatabases = [ "grafana" "nextcloud" + config.services.authelia.instances.main.user ]; }; } diff --git a/configuration/services/starbound.nix b/configuration/services/starbound.nix index f5b23c3..6da890e 100644 --- a/configuration/services/starbound.nix +++ b/configuration/services/starbound.nix @@ -1,14 +1,16 @@ -{ pkgs, lib, ... }: -let - inherit (lib) concatStringsSep; -in { + pkgs, + lib, + ... +}: let + inherit (lib) concatStringsSep; +in { # Sadly, steam-run requires some X libs environment.noXlibs = false; systemd.services.starbound = { description = "Starbound"; - after = [ "network.target" ]; + after = ["network.target"]; serviceConfig = { ExecStart = "${pkgs.local.starbound}/bin/launch-starbound ${./configs/starbound.json}"; @@ -65,7 +67,7 @@ in # Game servers shouldn't use cgroups themselves either ProtectControlGroups = true; # Most game servers will never need other socket types - RestrictAddressFamilies = [ "AF_UNIX AF_INET AF_INET6" ]; + RestrictAddressFamilies = ["AF_UNIX AF_INET AF_INET6"]; # Also a no-brainer, no game server should ever need this LockPersonality = true; # Some game servers will probably try to set this, but they @@ -111,7 +113,9 @@ in services.backups.starbound = { user = "root"; - paths = [ "/var/lib/private/starbound/storage/universe/" ]; - pauseServices = [ "starbound.service" ]; + paths = [ + "/var/lib/private/starbound/storage/universe/" + ]; + pauseServices = ["starbound.service"]; }; } diff --git a/configuration/services/webserver.nix b/configuration/services/webserver.nix index 864f6c0..387df57 100644 --- a/configuration/services/webserver.nix +++ b/configuration/services/webserver.nix @@ -1,8 +1,6 @@ -{ config, ... }: -let - inherit (config.services.nginx) domain; -in -{ +{config, ...}: let + domain = config.services.nginx.domain; +in { services.tlaternet-webserver = { enable = true; listen = { @@ -12,17 +10,15 @@ in }; # Set up SSL - services.nginx.virtualHosts."${domain}" = - let - inherit (config.services.tlaternet-webserver.listen) addr port; - in - { - serverAliases = [ "www.${domain}" ]; + services.nginx.virtualHosts."${domain}" = let + inherit (config.services.tlaternet-webserver.listen) addr port; + in { + serverAliases = ["www.${domain}"]; - forceSSL = true; - useACMEHost = "tlater.net"; - enableHSTS = true; + forceSSL = true; + useACMEHost = "tlater.net"; + enableHSTS = true; - locations."/".proxyPass = "http://${addr}:${toString port}"; - }; + locations."/".proxyPass = "http://${addr}:${toString port}"; + }; } diff --git a/configuration/services/wireguard.nix b/configuration/services/wireguard.nix index bbab22e..1ae6aac 100644 --- a/configuration/services/wireguard.nix +++ b/configuration/services/wireguard.nix @@ -1,5 +1,4 @@ -{ config, ... }: -{ +{config, ...}: { # iptables needs to permit forwarding from wg0 to wg0 networking.firewall.extraCommands = '' iptables -A FORWARD -i wg0 -o wg0 -j ACCEPT @@ -24,10 +23,20 @@ }; wireguardPeers = [ - # yui { - AllowedIPs = [ "10.45.249.2/32" ]; - PublicKey = "5mlnqEVJWks5OqgeFA2bLIrvST9TlCE81Btl+j4myz0="; + # yui + wireguardPeerConfig = { + AllowedIPs = ["10.45.249.2/32"]; + PublicKey = "5mlnqEVJWks5OqgeFA2bLIrvST9TlCE81Btl+j4myz0="; + }; + } + + { + # yuanyuan + wireguardPeerConfig = { + AllowedIPs = ["10.45.249.10/32"]; + PublicKey = "0UsFE2atz/O5P3OKQ8UHyyyGQNJbp1MeIWUJLuoerwE="; + }; } ]; }; @@ -38,23 +47,23 @@ matchConfig.Name = "wg0"; networkConfig = { - Description = "VLAN"; - Address = [ "10.45.249.1/32" # TODO(tlater): Add IPv6 whenever that becomes relevant ]; - IPv4Forwarding = "yes"; + IPForward = "yes"; IPv4ProxyARP = "yes"; }; routes = [ { - Source = "10.45.249.0/24"; - Destination = "10.45.249.0/24"; - Gateway = "10.45.249.1"; - GatewayOnLink = "no"; + routeConfig = { + Source = "10.45.249.0/24"; + Destination = "10.45.249.0/24"; + Gateway = "10.45.249.1"; + GatewayOnLink = "no"; + }; } ]; diff --git a/configuration/sops.nix b/configuration/sops.nix index 0337438..0746133 100644 --- a/configuration/sops.nix +++ b/configuration/sops.nix @@ -3,9 +3,15 @@ defaultSopsFile = ../keys/production.yaml; secrets = { - "battery-manager/email" = { }; + "battery-manager/email" = { + owner = "battery-manager"; + group = "battery-manager"; + }; - "battery-manager/password" = { }; + "battery-manager/password" = { + owner = "battery-manager"; + group = "battery-manager"; + }; # Gitea "forgejo/metrics-token" = { @@ -25,12 +31,12 @@ }; # Heisenbridge - "heisenbridge/as-token" = { }; - "heisenbridge/hs-token" = { }; + "heisenbridge/as-token" = {}; + "heisenbridge/hs-token" = {}; - # Matrix-hookshot - "matrix-hookshot/as-token" = { }; - "matrix-hookshot/hs-token" = { }; + "hetzner-api" = { + owner = "acme"; + }; # Nextcloud "nextcloud/tlater" = { @@ -38,14 +44,6 @@ group = "nextcloud"; }; - # Porkbub/ACME - "porkbun/api-key" = { - owner = "acme"; - }; - "porkbun/secret-api-key" = { - owner = "acme"; - }; - # Restic "restic/local-backups" = { owner = "root"; @@ -64,10 +62,10 @@ }; # Steam - "steam/tlater" = { }; + "steam/tlater" = {}; # Turn - "turn/env" = { }; + "turn/env" = {}; "turn/secret" = { owner = "turnserver"; }; diff --git a/flake.lock b/flake.lock index 885b579..3f8dcb9 100644 --- a/flake.lock +++ b/flake.lock @@ -1,206 +1,5 @@ { "nodes": { - "cachix": { - "inputs": { - "devenv": [ - "sonnenshift", - "crate2nix" - ], - "flake-compat": [ - "sonnenshift", - "crate2nix" - ], - "nixpkgs": "nixpkgs_3", - "pre-commit-hooks": [ - "sonnenshift", - "crate2nix" - ] - }, - "locked": { - "lastModified": 1709700175, - "narHash": "sha256-A0/6ZjLmT9qdYzKHmevnEIC7G+GiZ4UCr8v0poRPzds=", - "owner": "cachix", - "repo": "cachix", - "rev": "be97b37989f11b724197b5f4c7ffd78f12c8c4bf", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "latest", - "repo": "cachix", - "type": "github" - } - }, - "cachix_2": { - "inputs": { - "devenv": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable" - ], - "flake-compat": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable" - ], - "nixpkgs": "nixpkgs_4", - "pre-commit-hooks": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable" - ] - }, - "locked": { - "lastModified": 1716549461, - "narHash": "sha256-lHy5kgx6J8uD+16SO47dPrbob98sh+W1tf4ceSqPVK4=", - "owner": "cachix", - "repo": "cachix", - "rev": "e2bb269fb8c0828d5d4d2d7b8d09ea85abcacbd4", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "latest", - "repo": "cachix", - "type": "github" - } - }, - "cachix_3": { - "inputs": { - "devenv": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable", - "crate2nix_stable" - ], - "flake-compat": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable", - "crate2nix_stable" - ], - "nixpkgs": "nixpkgs_5", - "pre-commit-hooks": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable", - "crate2nix_stable" - ] - }, - "locked": { - "lastModified": 1716549461, - "narHash": "sha256-lHy5kgx6J8uD+16SO47dPrbob98sh+W1tf4ceSqPVK4=", - "owner": "cachix", - "repo": "cachix", - "rev": "e2bb269fb8c0828d5d4d2d7b8d09ea85abcacbd4", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "latest", - "repo": "cachix", - "type": "github" - } - }, - "crate2nix": { - "inputs": { - "cachix": "cachix", - "crate2nix_stable": "crate2nix_stable", - "devshell": "devshell_3", - "flake-compat": "flake-compat_4", - "flake-parts": "flake-parts_3", - "nix-test-runner": "nix-test-runner_3", - "nixpkgs": [ - "sonnenshift", - "nixpkgs" - ], - "pre-commit-hooks": "pre-commit-hooks_3" - }, - "locked": { - "lastModified": 1739473963, - "narHash": "sha256-ItAhpjNUzEWd/cgZVyW/jvoGbCec4TK29e1Mnmn1oJE=", - "owner": "nix-community", - "repo": "crate2nix", - "rev": "be31feae9a82c225c0fd1bdf978565dc452a483a", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "crate2nix", - "type": "github" - } - }, - "crate2nix_stable": { - "inputs": { - "cachix": "cachix_2", - "crate2nix_stable": "crate2nix_stable_2", - "devshell": "devshell_2", - "flake-compat": "flake-compat_3", - "flake-parts": "flake-parts_2", - "nix-test-runner": "nix-test-runner_2", - "nixpkgs": "nixpkgs_7", - "pre-commit-hooks": "pre-commit-hooks_2" - }, - "locked": { - "lastModified": 1719760004, - "narHash": "sha256-esWhRnt7FhiYq0CcIxw9pvH+ybOQmWBfHYMtleaMhBE=", - "owner": "nix-community", - "repo": "crate2nix", - "rev": "1dee214bb20855fa3e1e7bb98d28922ddaff8c57", - "type": "github" - }, - "original": { - "owner": "nix-community", - "ref": "0.14.1", - "repo": "crate2nix", - "type": "github" - } - }, - "crate2nix_stable_2": { - "inputs": { - "cachix": "cachix_3", - "crate2nix_stable": "crate2nix_stable_3", - "devshell": "devshell", - "flake-compat": "flake-compat_2", - "flake-parts": "flake-parts", - "nix-test-runner": "nix-test-runner", - "nixpkgs": "nixpkgs_6", - "pre-commit-hooks": "pre-commit-hooks" - }, - "locked": { - "lastModified": 1712821484, - "narHash": "sha256-rGT3CW64cJS9nlnWPFWSc1iEa3dNZecVVuPVGzcsHe8=", - "owner": "nix-community", - "repo": "crate2nix", - "rev": "42883afcad3823fa5811e967fb7bff54bc3c9d6d", - "type": "github" - }, - "original": { - "owner": "nix-community", - "ref": "0.14.0", - "repo": "crate2nix", - "type": "github" - } - }, - "crate2nix_stable_3": { - "inputs": { - "flake-utils": "flake-utils" - }, - "locked": { - "lastModified": 1702842982, - "narHash": "sha256-A9AowkHIjsy1a4LuiPiVP88FMxyCWK41flZEZOUuwQM=", - "owner": "nix-community", - "repo": "crate2nix", - "rev": "75ac2973affa6b9b4f661a7b592cba6e4f51d426", - "type": "github" - }, - "original": { - "owner": "nix-community", - "ref": "0.12.0", - "repo": "crate2nix", - "type": "github" - } - }, "deploy-rs": { "inputs": { "flake-compat": "flake-compat", @@ -208,11 +7,11 @@ "utils": "utils" }, "locked": { - "lastModified": 1727447169, - "narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=", + "lastModified": 1711973905, + "narHash": "sha256-UFKME/N1pbUtn+2Aqnk+agUt8CekbpuqwzljivfIme8=", "owner": "serokell", "repo": "deploy-rs", - "rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76", + "rev": "88b3059b020da69cbe16526b8d639bd5e0b51c8b", "type": "github" }, "original": { @@ -221,78 +20,6 @@ "type": "github" } }, - "devshell": { - "inputs": { - "flake-utils": "flake-utils_2", - "nixpkgs": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable", - "crate2nix_stable", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1717408969, - "narHash": "sha256-Q0OEFqe35fZbbRPPRdrjTUUChKVhhWXz3T9ZSKmaoVY=", - "owner": "numtide", - "repo": "devshell", - "rev": "1ebbe68d57457c8cae98145410b164b5477761f4", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "devshell", - "type": "github" - } - }, - "devshell_2": { - "inputs": { - "flake-utils": "flake-utils_3", - "nixpkgs": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1717408969, - "narHash": "sha256-Q0OEFqe35fZbbRPPRdrjTUUChKVhhWXz3T9ZSKmaoVY=", - "owner": "numtide", - "repo": "devshell", - "rev": "1ebbe68d57457c8cae98145410b164b5477761f4", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "devshell", - "type": "github" - } - }, - "devshell_3": { - "inputs": { - "flake-utils": "flake-utils_4", - "nixpkgs": [ - "sonnenshift", - "crate2nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1711099426, - "narHash": "sha256-HzpgM/wc3aqpnHJJ2oDqPBkNsqWbW0WfWUO8lKu8nGk=", - "owner": "numtide", - "repo": "devshell", - "rev": "2d45b54ca4a183f2fdcf4b19c895b64fbf620ee8", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "devshell", - "type": "github" - } - }, "disko": { "inputs": { "nixpkgs": [ @@ -300,11 +27,11 @@ ] }, "locked": { - "lastModified": 1747742835, - "narHash": "sha256-kYL4GCwwznsypvsnA20oyvW8zB/Dvn6K5G/tgMjVMT4=", + "lastModified": 1714103775, + "narHash": "sha256-kcBiIrmqzt3bNTr2GMBfAyA+on8BEKO1iKzzDFQZkjI=", "owner": "nix-community", "repo": "disko", - "rev": "df522e787fdffc4f32ed3e1fca9ed0968a384d62", + "rev": "285e26465a0bae510897ca04da26ce6307c652b4", "type": "github" }, "original": { @@ -315,16 +42,16 @@ }, "dream2nix": { "inputs": { - "nixpkgs": "nixpkgs_8", + "nixpkgs": "nixpkgs_3", "purescript-overlay": "purescript-overlay", "pyproject-nix": "pyproject-nix" }, "locked": { - "lastModified": 1735160684, - "narHash": "sha256-n5CwhmqKxifuD4Sq4WuRP/h5LO6f23cGnSAuJemnd/4=", + "lastModified": 1702457430, + "narHash": "sha256-8NQiXtYCOiC7XFayy6GPGDudCBrPROry3mfWjpdVj5g=", "owner": "nix-community", "repo": "dream2nix", - "rev": "8ce6284ff58208ed8961681276f82c2f8f978ef4", + "rev": "262198033e23e9ee832f0cc8133d38f07598f555", "type": "github" }, "original": { @@ -342,11 +69,11 @@ "rust-analyzer-src": "rust-analyzer-src" }, "locked": { - "lastModified": 1737181903, - "narHash": "sha256-lvp77MhGzSN+ICd0MugppCjQR6cmlM2iAC5cjy2ZsaA=", + "lastModified": 1704003651, + "narHash": "sha256-bA3d4E1CX5G7TVbKwJOm9jZfVOGOPp6u5CKEUzNsE8E=", "owner": "nix-community", "repo": "fenix", - "rev": "ac79bb490b8c1af4bbc587b84c76f9527d6b14f7", + "rev": "c6d82e087ac96f24b90c5787a17e29a72566c2b4", "type": "github" }, "original": { @@ -372,48 +99,6 @@ } }, "flake-compat_2": { - "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "revCount": 57, - "type": "tarball", - "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz" - }, - "original": { - "type": "tarball", - "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz" - } - }, - "flake-compat_3": { - "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "revCount": 57, - "type": "tarball", - "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz" - }, - "original": { - "type": "tarball", - "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz" - } - }, - "flake-compat_4": { - "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "revCount": 57, - "type": "tarball", - "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz" - }, - "original": { - "type": "tarball", - "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz" - } - }, - "flake-compat_5": { "flake": false, "locked": { "lastModified": 1696426674, @@ -429,151 +114,10 @@ "type": "github" } }, - "flake-parts": { - "inputs": { - "nixpkgs-lib": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable", - "crate2nix_stable", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1719745305, - "narHash": "sha256-xwgjVUpqSviudEkpQnioeez1Uo2wzrsMaJKJClh+Bls=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "c3c5ecc05edc7dafba779c6c1a61cd08ac6583e9", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-parts_2": { - "inputs": { - "nixpkgs-lib": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1719745305, - "narHash": "sha256-xwgjVUpqSviudEkpQnioeez1Uo2wzrsMaJKJClh+Bls=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "c3c5ecc05edc7dafba779c6c1a61cd08ac6583e9", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-parts_3": { - "inputs": { - "nixpkgs-lib": [ - "sonnenshift", - "crate2nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1712014858, - "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, "flake-utils": { "inputs": { "systems": "systems_2" }, - "locked": { - "lastModified": 1694529238, - "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_2": { - "inputs": { - "systems": "systems_3" - }, - "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_3": { - "inputs": { - "systems": "systems_4" - }, - "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_4": { - "inputs": { - "systems": "systems_5" - }, - "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_5": { - "inputs": { - "systems": "systems_6" - }, "locked": { "lastModified": 1710146030, "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", @@ -588,6 +132,24 @@ "type": "github" } }, + "flake-utils_2": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "foundryvtt": { "inputs": { "nixpkgs": [ @@ -595,11 +157,11 @@ ] }, "locked": { - "lastModified": 1746877938, - "narHash": "sha256-N9J96pSPg4vbozV+ZZ++dwLnMIf2Le6ONNMO0kZCj1M=", + "lastModified": 1712623723, + "narHash": "sha256-jPD5+M+QPyMRk52zfFMIeHdv7yXYJ/yNGqwS0PhYF+E=", "owner": "reckenrode", "repo": "nix-foundryvtt", - "rev": "f1b401831d796dd94cf5a11b65fd169a199d4ff0", + "rev": "6025615b431170558c3c13f16b549fc0126425e1", "type": "github" }, "original": { @@ -608,123 +170,25 @@ "type": "github" } }, - "gitignore": { + "nix-github-actions": { "inputs": { "nixpkgs": [ "sonnenshift", - "crate2nix", - "crate2nix_stable", - "crate2nix_stable", - "pre-commit-hooks", + "poetry2nixi", "nixpkgs" ] }, "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "lastModified": 1703863825, + "narHash": "sha256-rXwqjtwiGKJheXB43ybM8NwWB8rO2dSRrEqes0S7F5Y=", + "owner": "nix-community", + "repo": "nix-github-actions", + "rev": "5163432afc817cf8bd1f031418d1869e4c9d5547", "type": "github" }, "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "gitignore_2": { - "inputs": { - "nixpkgs": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable", - "pre-commit-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "gitignore_3": { - "inputs": { - "nixpkgs": [ - "sonnenshift", - "crate2nix", - "pre-commit-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "nix-test-runner": { - "flake": false, - "locked": { - "lastModified": 1588761593, - "narHash": "sha256-FKJykltAN/g3eIceJl4SfDnnyuH2jHImhMrXS2KvGIs=", - "owner": "stoeffel", - "repo": "nix-test-runner", - "rev": "c45d45b11ecef3eb9d834c3b6304c05c49b06ca2", - "type": "github" - }, - "original": { - "owner": "stoeffel", - "repo": "nix-test-runner", - "type": "github" - } - }, - "nix-test-runner_2": { - "flake": false, - "locked": { - "lastModified": 1588761593, - "narHash": "sha256-FKJykltAN/g3eIceJl4SfDnnyuH2jHImhMrXS2KvGIs=", - "owner": "stoeffel", - "repo": "nix-test-runner", - "rev": "c45d45b11ecef3eb9d834c3b6304c05c49b06ca2", - "type": "github" - }, - "original": { - "owner": "stoeffel", - "repo": "nix-test-runner", - "type": "github" - } - }, - "nix-test-runner_3": { - "flake": false, - "locked": { - "lastModified": 1588761593, - "narHash": "sha256-FKJykltAN/g3eIceJl4SfDnnyuH2jHImhMrXS2KvGIs=", - "owner": "stoeffel", - "repo": "nix-test-runner", - "rev": "c45d45b11ecef3eb9d834c3b6304c05c49b06ca2", - "type": "github" - }, - "original": { - "owner": "stoeffel", - "repo": "nix-test-runner", + "owner": "nix-community", + "repo": "nix-github-actions", "type": "github" } }, @@ -744,103 +208,61 @@ "type": "github" } }, - "nixpkgs_2": { + "nixpkgs-stable": { "locked": { - "lastModified": 1748085680, - "narHash": "sha256-XG90Q/040NiV70gAVvoYbXg1lULbiwIzfkWmwSINyGQ=", + "lastModified": 1713638189, + "narHash": "sha256-q7APLfB6FmmSMI1Su5ihW9IwntBsk2hWNXh8XtSdSIk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "74574c38577914733b4f7a775dd77d24245081dd", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "release-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1714253743, + "narHash": "sha256-mdTQw2XlariysyScCv2tTE45QSU9v/ezLcHJ22f0Nxc=", "owner": "nixos", "repo": "nixpkgs", - "rev": "4e6eeca5ed45465087274fc9dc6bc2011254a0f3", + "rev": "58a1abdbae3217ca6b702f03d3b35125d88a2994", "type": "github" }, "original": { "owner": "nixos", - "ref": "nixos-25.05-small", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1718208800, + "narHash": "sha256-US1tAChvPxT52RV8GksWZS415tTS7PV42KTc2PNDBmc=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "cc54fb41d13736e92229c21627ea4f22199fee6b", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-24.05", "repo": "nixpkgs", "type": "github" } }, "nixpkgs_3": { "locked": { - "lastModified": 1700612854, - "narHash": "sha256-yrQ8osMD+vDLGFX7pcwsY/Qr5PUd6OmDMYJZzZi0+zc=", + "lastModified": 1702272962, + "narHash": "sha256-D+zHwkwPc6oYQ4G3A1HuadopqRwUY/JkMwHz1YF7j4Q=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "19cbff58383a4ae384dea4d1d0c823d72b49d614", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_4": { - "locked": { - "lastModified": 1715534503, - "narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "2057814051972fa1453ddfb0d98badbea9b83c06", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_5": { - "locked": { - "lastModified": 1715534503, - "narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "2057814051972fa1453ddfb0d98badbea9b83c06", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_6": { - "locked": { - "lastModified": 1719506693, - "narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=", - "path": "/nix/store/4p0avw1s3vf27hspgqsrqs37gxk4i83i-source", - "rev": "b2852eb9365c6de48ffb0dc2c9562591f652242a", - "type": "path" - }, - "original": { - "id": "nixpkgs", - "type": "indirect" - } - }, - "nixpkgs_7": { - "locked": { - "lastModified": 1719506693, - "narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=", - "path": "/nix/store/4p0avw1s3vf27hspgqsrqs37gxk4i83i-source", - "rev": "b2852eb9365c6de48ffb0dc2c9562591f652242a", - "type": "path" - }, - "original": { - "id": "nixpkgs", - "type": "indirect" - } - }, - "nixpkgs_8": { - "locked": { - "lastModified": 1729850857, - "narHash": "sha256-WvLXzNNnnw+qpFOmgaM3JUlNEH+T4s22b5i2oyyCpXE=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "41dea55321e5a999b17033296ac05fe8a8b5a257", + "rev": "e97b3e4186bcadf0ef1b6be22b8558eab1cdeb5d", "type": "github" }, "original": { @@ -850,118 +272,55 @@ "type": "github" } }, - "pre-commit-hooks": { + "nvfetcher": { "inputs": { - "flake-compat": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable", - "crate2nix_stable", - "flake-compat" - ], - "gitignore": "gitignore", + "flake-compat": "flake-compat_2", + "flake-utils": "flake-utils", "nixpkgs": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable", - "crate2nix_stable", - "nixpkgs" - ], - "nixpkgs-stable": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable", - "crate2nix_stable", "nixpkgs" ] }, "locked": { - "lastModified": 1719259945, - "narHash": "sha256-F1h+XIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4=", - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07", + "lastModified": 1713333471, + "narHash": "sha256-sIVQKOXzruxtTYiBRHZa8UQH+CSIa9K5MZlY6vavYfA=", + "owner": "berberman", + "repo": "nvfetcher", + "rev": "2a824322dc6a755ffda83a13b948d42304521e4d", "type": "github" }, "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", + "owner": "berberman", + "repo": "nvfetcher", "type": "github" } }, - "pre-commit-hooks_2": { + "poetry2nixi": { "inputs": { - "flake-compat": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable", - "flake-compat" - ], - "gitignore": "gitignore_2", + "flake-utils": "flake-utils_2", + "nix-github-actions": "nix-github-actions", "nixpkgs": [ "sonnenshift", - "crate2nix", - "crate2nix_stable", "nixpkgs" ], - "nixpkgs-stable": [ - "sonnenshift", - "crate2nix", - "crate2nix_stable", - "nixpkgs" - ] + "systems": "systems_4", + "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1719259945, - "narHash": "sha256-F1h+XIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4=", - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07", + "lastModified": 1708589824, + "narHash": "sha256-2GOiFTkvs5MtVF65sC78KNVxQSmsxtk0WmV1wJ9V2ck=", + "owner": "nix-community", + "repo": "poetry2nix", + "rev": "3c92540611f42d3fb2d0d084a6c694cd6544b609", "type": "github" }, "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "type": "github" - } - }, - "pre-commit-hooks_3": { - "inputs": { - "flake-compat": [ - "sonnenshift", - "crate2nix", - "flake-compat" - ], - "flake-utils": "flake-utils_5", - "gitignore": "gitignore_3", - "nixpkgs": [ - "sonnenshift", - "crate2nix", - "nixpkgs" - ], - "nixpkgs-stable": [ - "sonnenshift", - "crate2nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1712055707, - "narHash": "sha256-4XLvuSIDZJGS17xEwSrNuJLL7UjDYKGJSbK1WWX2AK8=", - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "e35aed5fda3cc79f88ed7f1795021e559582093a", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", + "owner": "nix-community", + "repo": "poetry2nix", "type": "github" } }, "purescript-overlay": { "inputs": { - "flake-compat": "flake-compat_5", "nixpkgs": [ "tlaternet-webserver", "dream2nix", @@ -970,11 +329,11 @@ "slimlock": "slimlock" }, "locked": { - "lastModified": 1728546539, - "narHash": "sha256-Sws7w0tlnjD+Bjck1nv29NjC5DbL6nH5auL9Ex9Iz2A=", + "lastModified": 1696022621, + "narHash": "sha256-eMjFmsj2G1E0Q5XiibUNgFjTiSz0GxIeSSzzVdoN730=", "owner": "thomashoneyman", "repo": "purescript-overlay", - "rev": "4ad4c15d07bd899d7346b331f377606631eb0ee4", + "rev": "047c7933abd6da8aa239904422e22d190ce55ead", "type": "github" }, "original": { @@ -1006,6 +365,8 @@ "disko": "disko", "foundryvtt": "foundryvtt", "nixpkgs": "nixpkgs_2", + "nixpkgs-unstable": "nixpkgs-unstable", + "nvfetcher": "nvfetcher", "sonnenshift": "sonnenshift", "sops-nix": "sops-nix", "tlaternet-webserver": "tlaternet-webserver" @@ -1014,11 +375,11 @@ "rust-analyzer-src": { "flake": false, "locked": { - "lastModified": 1737140097, - "narHash": "sha256-m4SN8DeKzsP10EQFS7+2zgGfCrMhTfTt1H0QRNesD08=", + "lastModified": 1703965384, + "narHash": "sha256-3iyouqkBvhh/E48TkBlt4JmmcIEyfQwY7pokKBx9WNg=", "owner": "rust-lang", "repo": "rust-analyzer", - "rev": "f61bfa4d7feb84d07538d361fe77d34a29e3b375", + "rev": "e872f5085cf5b0e44558442365c1c033d486eff2", "type": "github" }, "original": { @@ -1038,11 +399,11 @@ ] }, "locked": { - "lastModified": 1688756706, - "narHash": "sha256-xzkkMv3neJJJ89zo3o2ojp7nFeaZc2G0fYwNXNJRFlo=", + "lastModified": 1688610262, + "narHash": "sha256-Wg0ViDotFWGWqKIQzyYCgayeH8s4U1OZcTiWTQYdAp4=", "owner": "thomashoneyman", "repo": "slimlock", - "rev": "cf72723f59e2340d24881fd7bf61cb113b4c407c", + "rev": "b5c6cdcaf636ebbebd0a1f32520929394493f1a6", "type": "github" }, "original": { @@ -1053,21 +414,22 @@ }, "sonnenshift": { "inputs": { - "crate2nix": "crate2nix", "nixpkgs": [ "nixpkgs" - ] + ], + "poetry2nixi": "poetry2nixi" }, "locked": { - "lastModified": 1740082109, - "narHash": "sha256-WdRNkwsIotFOSymee/yQyH46RmYtuxd1FENhvGL4KRc=", - "ref": "refs/heads/main", - "rev": "a1b48cf2ba194054e2d8816c94a84cebc4fb5de0", - "revCount": 23, + "lastModified": 1712437610, + "narHash": "sha256-U0xIqSupo6yBVWQcHIcLPDKg5ShQIkV/0Ay+Xg3GIlk=", + "ref": "tlater/implement-nix-module", + "rev": "43c4f591328f194ca989b86cea49773104f75549", + "revCount": 7, "type": "git", "url": "ssh://git@github.com/sonnenshift/battery-manager" }, "original": { + "ref": "tlater/implement-nix-module", "type": "git", "url": "ssh://git@github.com/sonnenshift/battery-manager" } @@ -1076,14 +438,15 @@ "inputs": { "nixpkgs": [ "nixpkgs" - ] + ], + "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1747603214, - "narHash": "sha256-lAblXm0VwifYCJ/ILPXJwlz0qNY07DDYdLD+9H+Wc8o=", + "lastModified": 1713892811, + "narHash": "sha256-uIGmA2xq41vVFETCF1WW4fFWFT2tqBln+aXnWrvjGRE=", "owner": "Mic92", "repo": "sops-nix", - "rev": "8d215e1c981be3aa37e47aeabd4e61bb069548fd", + "rev": "f1b0adc27265274e3b0c9b872a8f476a098679bd", "type": "github" }, "original": { @@ -1147,39 +510,8 @@ "type": "github" }, "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "systems_5": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "systems_6": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" + "id": "systems", + "type": "indirect" } }, "tlaternet-webserver": { @@ -1191,11 +523,11 @@ ] }, "locked": { - "lastModified": 1737271785, - "narHash": "sha256-yVdaaawYK1/q9V5btfGpxVCQBdyQx1WcFHYO0yX5bP8=", + "lastModified": 1704840002, + "narHash": "sha256-ik2LeuRjcnRXwBLoRSOyGEMXscE+coO8G79IFhZhdJk=", "ref": "refs/heads/master", - "rev": "5d3d84836101ec9b9867a5f754c9ee1b9d4dc538", - "revCount": 76, + "rev": "d14f50c8dcc8ab30a5e5fa907b392ac0df6c7b52", + "revCount": 73, "type": "git", "url": "https://gitea.tlater.net/tlaternet/tlaternet.git" }, @@ -1204,6 +536,28 @@ "url": "https://gitea.tlater.net/tlaternet/tlaternet.git" } }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "sonnenshift", + "poetry2nixi", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1708335038, + "narHash": "sha256-ETLZNFBVCabo7lJrpjD6cAbnE11eDOjaQnznmg/6hAE=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "e504621290a1fd896631ddbc5e9c16f4366c9f65", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, "utils": { "inputs": { "systems": "systems" diff --git a/flake.nix b/flake.nix index da8455f..09a74ac 100644 --- a/flake.nix +++ b/flake.nix @@ -2,7 +2,8 @@ description = "tlater.net host configuration"; inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05-small"; + nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05"; + nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable"; disko = { url = "github:nix-community/disko"; inputs.nixpkgs.follows = "nixpkgs"; @@ -12,6 +13,10 @@ url = "github:Mic92/sops-nix"; inputs.nixpkgs.follows = "nixpkgs"; }; + nvfetcher = { + url = "github:berberman/nvfetcher"; + inputs.nixpkgs.follows = "nixpkgs"; + }; tlaternet-webserver = { url = "git+https://gitea.tlater.net/tlaternet/tlaternet.git"; inputs.nixpkgs.follows = "nixpkgs"; @@ -22,146 +27,131 @@ }; sonnenshift = { - url = "git+ssh://git@github.com/sonnenshift/battery-manager"; + url = "git+ssh://git@github.com/sonnenshift/battery-manager?ref=tlater/implement-nix-module"; inputs.nixpkgs.follows = "nixpkgs"; }; }; - outputs = - { - self, - nixpkgs, - sops-nix, - deploy-rs, - ... - }@inputs: - let - system = "x86_64-linux"; - pkgs = nixpkgs.legacyPackages.${system}; - - vm = nixpkgs.lib.nixosSystem { + outputs = { + self, + nixpkgs, + sops-nix, + nvfetcher, + deploy-rs, + ... + } @ inputs: let + system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages.${system}; + in { + ################## + # Configurations # + ################## + nixosConfigurations = { + # The actual system definition + hetzner-1 = nixpkgs.lib.nixosSystem { inherit system; specialArgs.flake-inputs = inputs; modules = [ ./configuration - ./configuration/hardware-specific/vm.nix - ]; - }; - in - { - ################## - # Configurations # - ################## - nixosConfigurations = { - # The actual system definition - hetzner-1 = nixpkgs.lib.nixosSystem { - inherit system; - specialArgs.flake-inputs = inputs; - - modules = [ - ./configuration - ./configuration/hardware-specific/hetzner - ]; - }; - }; - - ############################ - # Deployment configuration # - ############################ - deploy.nodes = { - hetzner-1 = { - hostname = "116.202.158.55"; - - profiles.system = { - user = "root"; - path = deploy-rs.lib.${system}.activate.nixos self.nixosConfigurations.hetzner-1; - }; - - sshUser = "tlater"; - sshOpts = [ - "-p" - "2222" - "-o" - "ForwardAgent=yes" - ]; - }; - }; - - ######### - # Tests # - ######### - checks.${system} = import ./checks (inputs // { inherit system; }); - - ########################### - # Garbage collection root # - ########################### - - packages.${system} = - let - localPkgs = import ./pkgs { inherit pkgs; }; - in - { - default = vm.config.system.build.vm; - crowdsec-hub = localPkgs.crowdsec.hub; - crowdsec-firewall-bouncer = localPkgs.crowdsec.firewall-bouncer; - }; - - ################### - # Utility scripts # - ################### - apps.${system} = { - default = self.apps.${system}.run-vm; - - run-vm = { - type = "app"; - program = - (pkgs.writeShellScript "" '' - ${vm.config.system.build.vm.outPath}/bin/run-testvm-vm - '').outPath; - }; - - update-crowdsec-packages = - let - git = pkgs.lib.getExe pkgs.git; - nvfetcher = pkgs.lib.getExe pkgs.nvfetcher; - in - { - type = "app"; - program = - (pkgs.writeShellScript "update-crowdsec-packages" '' - cd "$(${git} rev-parse --show-toplevel)" - cd ./pkgs/crowdsec - ${nvfetcher} - echo 'Remember to update the vendorHash of any go packages!' - '').outPath; - }; - }; - - ########################### - # Development environment # - ########################### - devShells.${system}.default = nixpkgs.legacyPackages.${system}.mkShell { - sopsPGPKeyDirs = [ - "./keys/hosts/" - "./keys/users/" - ]; - nativeBuildInputs = [ sops-nix.packages.${system}.sops-import-keys-hook ]; - - packages = with pkgs; [ - sops-nix.packages.${system}.sops-init-gpg-key - deploy-rs.packages.${system}.default - - nixpkgs-fmt - - cargo - clippy - rustc - rustfmt - rust-analyzer - pkg-config - openssl + ./configuration/hardware-specific/hetzner ]; }; }; + + ############################ + # Deployment configuration # + ############################ + deploy.nodes = { + hetzner-1 = { + hostname = "116.202.158.55"; + + profiles.system = { + user = "root"; + path = deploy-rs.lib.${system}.activate.nixos self.nixosConfigurations.hetzner-1; + }; + + sshUser = "tlater"; + sshOpts = ["-p" "2222" "-o" "ForwardAgent=yes"]; + }; + }; + + ######### + # Tests # + ######### + checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib; + + ################### + # Utility scripts # + ################### + apps.${system} = { + default = self.apps.${system}.run-vm; + + run-vm = { + type = "app"; + program = let + vm = nixpkgs.lib.nixosSystem { + inherit system; + specialArgs.flake-inputs = inputs; + + modules = [ + ./configuration + ./configuration/hardware-specific/vm.nix + ]; + }; + in + (pkgs.writeShellScript "" '' + ${vm.config.system.build.vm.outPath}/bin/run-testvm-vm + '') + .outPath; + }; + + update-pkgs = { + type = "app"; + program = let + nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher"; + in + (pkgs.writeShellScript "update-pkgs" '' + cd "$(git rev-parse --show-toplevel)/pkgs" + ${nvfetcher-bin} -o _sources_pkgs -c nvfetcher.toml + '') + .outPath; + }; + + update-nextcloud-apps = { + type = "app"; + program = let + nvfetcher-bin = "${nvfetcher.packages.${system}.default}/bin/nvfetcher"; + in + (pkgs.writeShellScript "update-nextcloud-apps" '' + cd "$(git rev-parse --show-toplevel)/pkgs" + ${nvfetcher-bin} -o _sources_nextcloud -c nextcloud-apps.toml + '') + .outPath; + }; + }; + + ########################### + # Development environment # + ########################### + devShells.${system}.default = nixpkgs.legacyPackages.${system}.mkShell { + sopsPGPKeyDirs = ["./keys/hosts/" "./keys/users/"]; + nativeBuildInputs = [ + sops-nix.packages.${system}.sops-import-keys-hook + ]; + + packages = with pkgs; [ + sops-nix.packages.${system}.sops-init-gpg-key + deploy-rs.packages.${system}.default + + cargo + clippy + rustc + rustfmt + rust-analyzer + pkg-config + openssl + ]; + }; + }; } diff --git a/keys/production.yaml b/keys/production.yaml index 0e906bd..43b3578 100644 --- a/keys/production.yaml +++ b/keys/production.yaml @@ -1,6 +1,6 @@ -porkbun: - api-key: ENC[AES256_GCM,data:p3lqvGc8m2U/12rBPjoNR7hxQyD52CyEen/V8q59k5CSJZSqzZS8M5vEXFBsUMjz2lrmKM4pgtz4wa2fWK6Ty4LJCaI=,iv:OQC3FpwTtPmqHvDbA41mWF7LGYwC/jD2ZMBsE8ktNOg=,tag:kq5hUR7TBgczuGcXpsdu2A==,type:str] - secret-api-key: ENC[AES256_GCM,data:zV5PTKf45Zab8uW8mbuXmPNzciq6tV9OF0wUND7YnRk/DjZneYWItAsNBVoM+iHA+XsUPDoeKo6hoJiGkH/cCQ8WvuM=,iv:yr1M5DlgI8k6BgzNz3HRnqspHOrQuf2PmoZS1HGp0v8=,tag:JkNNziMMfKFZV2hnx5lXRg==,type:str] +authelia: + storageEncryptionKey: ENC[AES256_GCM,data:OUCC+6Gcr6U7Mub1+DaIyswTV6da1wd1u0WGEm4wpJ8L0mi7WSpEmVjH79YyRhp7AmiZhdFFDXFeEYthBb2AZl+xoS9gqs6rWyfU4ezaCbXBiS/dIhsA5foPg13wq5A33qJWtPTy7DJEgqHaIonnaBuVJIBwH3wzPTHc3bDvBo4=,iv:intiZzngz5cMTtjEI9rTKMW0Xv3KB3ZEgtYN3amwKCE=,tag:AKxfbeZlPs54esHCsVnNCg==,type:str] + sessionSecret: ENC[AES256_GCM,data:GEMWhBltOIOs0g9FsWk3OQGs6dMcbwz3ZuhlyBFYROylsIZb4xTXWLgNwIpHwQukQU3TgvIxbCW/fGRWiALPanE2koSVAHNx0UU0hj1mVNRFQGK4H3EL10tPp7l4PofrcdeCbLPrOwM/xLOuPt+52sKlcbL2Awz5/MmpUVpCKXc=,iv:kWX2ptOpTgW3obBgri0MvVv6gCEPR3o77sldOXFQeks=,tag:je4pqLcEOhuBTQkoZHYNCw==,type:str] battery-manager: email: ENC[AES256_GCM,data:rYLUACXR/n+bLBmZ,iv:sUBEkh2+7qGjHZ5R23e/hoCiyTA7GTL4bJvXmxjZ5Sw=,tag:fdPMllaQQfRgX0WZKIre4g==,type:str] password: ENC[AES256_GCM,data:7cokZa6Q6ahSeiFPz+cV,iv:vz405P0IcG9FsAQXlY7mi78GuushQUKJm2irG6buGzc=,tag:JLHG2jTkJDGbinAq9dXRsQ==,type:str] @@ -16,9 +16,6 @@ steam: heisenbridge: as-token: ENC[AES256_GCM,data:+2yo6T18j34622H8ZWblAFB2phLw1q0k0vUQEZ5sFj7dQaRnkEiAMi0R3p17Zq0pOtGEC0RRZuPLYkcZ1oKP0w==,iv:lGwrQYp//FufpmJocrLIVyy9RK7lEEVcpAi0wmkjr34=,tag:yV06UbhAYJQz36O2XdhY+A==,type:str] hs-token: ENC[AES256_GCM,data:u52WpkQFd/J7JFoE/rfNluebyZQLOokvkVdL7+AEAvrhJhrkJli1ztkD79lbC+6tGUH4tT3T+nX9wvGKnrRUQg==,iv:as+9fVuvMg2IoE2WIKD9mHi+znhNcWRh5Zq+yr0xcDQ=,tag:mZ7fh7U0MfgI8hyq/28Bcg==,type:str] -matrix-hookshot: - as-token: ENC[AES256_GCM,data:nXTanPhDyDF7R3AllLqpM5dzljBrHwlh1KJnTGIi5PhbDY2lPj4+uXkMEwvm1u+hQjPyM7vKZPfK+0/dms6Y7A==,iv:fSakJN+yai0gfOJKFxxaxgyUtk0pNmIeqVgrdq92/24=,tag:Qc7+SUnm5/Nq5+QIScR9kQ==,type:str] - hs-token: ENC[AES256_GCM,data:Bwyj0JTTN0NNnwOs1zA8CqbtZSNcvlINeT7QVc2eJiHda92J6vQk7bSxy6KuqCN9DxlUsK13ggYjNORY2vic5w==,iv:Npnp8arYQ3Yb6CXrnKgE03hD7ZjGINPa/DwFI8D+5tA=,tag:FqNE6yI0nF4puEUw9MGAjQ==,type:str] wireguard: server-key: ENC[AES256_GCM,data:mXb7ZznJHf5CgV8rI4uzPBATMRbmd7LimgtCkQM9kAjbIaGwUBqJZBN3fXs=,iv:3Po1Orinzov9rnEm9cLzgJY1PeD+5Jl9115MriABHh8=,tag:E/2CjDO1JCvJzxCnqKcNyw==,type:str] restic: @@ -37,63 +34,63 @@ sops: azure_kv: [] hc_vault: [] age: [] - lastmodified: "2025-02-07T19:44:49Z" - mac: ENC[AES256_GCM,data:+0hpd/E7GxK/27f2Itf0hDV+3Ga4gHb8xxLutJ32HLBWLZ5Y+dN03xgkz8jBTiM+BeHwS4gz70Cs9X3zLMHbosWVuIV9DLuRaHRq/IU9KiADwqmCySZALqCf3+T5QKZr3Qs4AZJHwaAXkRX9HbnRFriIAFDJW/BGdIHdoROquxY=,iv:TeXI8LGqHVa5wo61sGdNbZ2nJvSlPdgn9R3Lq5qUggU=,tag:TFort5wxVTdi9LMlMeT/DQ==,type:str] + lastmodified: "2024-04-11T23:38:56Z" + mac: ENC[AES256_GCM,data:GjIB0EbWsh4o+QoFSyIXgGYnNhRlvfSmue1LyTt6oUlIjNgODhdIB8px8LnRo0rmm/f1YHbDq2MFOxlgdm3PTNaqm/MoKyW3r/wuAeWADsYayQszLNxyhTMXcjWtfm6zCRIuc/+YyM44pXRfVrOZRAin9B6pmJZsRJwBAZpogbU=,iv:r/ZQZvrP0E9dOW5fhBH2I21Z0uv2e3njdEGmadxEALg=,tag:iZvbGTvRJFo80n8aoKSSmQ==,type:str] pgp: - - created_at: "2025-01-21T17:55:44Z" + - created_at: "2024-03-18T04:02:00Z" enc: |- -----BEGIN PGP MESSAGE----- - hQEMA7x7stsXx45CAQf6AjhhYCHhRvJx4xxiXPMTfpIpAvseB1CXVfuhfj2r2yrf - 3HfJnNOSDBcmHdp9fiLJattqfsykcGisUDVIplCeA7cIJjH3sf8MuIJXDTLmvE0Z - BmV8LuwP/UPQSZzY3w1eTAoYT/by35gfJm4ofipft2qyIjQuBgOlrg/0swvBl7LK - 47mI6mVdds8RutHw/xhJZeNjKF/5tADPJ2CHjOHbCQhLji13Kpm3yObOnM8K2SfV - P9uVudCFN/ZBiTlVkB7PsuitwZx1fW0SR3jcWxbRd17M2k2RAQQDUCqPKaoJ3T3f - r2ExwmyO4j7G2vkFv1RgQnhAoHqqRZ1nSjNw1+27MNJeAbT1ddia2TC5Q2zjRZY9 - tRJi2pNZH9A424lpIBLnkPl5rpCR/UZ+bqhaQ9C2kFMldSldPn8dMiBy8XG0Trji - B6X44Q/0RCsJD3FS61GASIjaWdEX0DdSOdhtbtBLLQ== - =yLOx + hQEMA7x7stsXx45CAQf7BjF+HR3WKdMyAV6R1M0+lqDz6hBHKyGH7YBB/QZBqRbK + 3hdABIwWUsqpHjleEOp/Gj0VhZqwagqHxK4Fp5G0r3QBupbAO8u/+DNI8wll0Nva + dlOh0Jqp4E17TkERMQL02rrQ1ZmpOYmPkCd2//xkmWAQ1LatHWeRVSRxQBuMtPQi + btrefcQNjQCvS9/60dp8oTu8nxlFA4iHCBQKNIKVGqQH7jkdIfMPdUILjCkCiyCc + h+OxlHZZnpU6U9A+hjMBinvCzebSkZh48VX/T33Kr+4b0CBr1gR9MSXKG9f2MPQP + PMl6rPvqSqG6ddN9QDI+0HEHYaRvxPIV8uDS36tVxNJeAQHB5/6Lt7hJdYWgwf5E + TLgbZ0IxB17++6K++GlaG8WHO65l1jzmkPlN+ZGcwnhibDxnZjP6kqGqDFcZP4ge + cnV0KnhYcC59IooQYrWKzAJex9rnwPo7MGKV6XwZOQ== + =Hy9T -----END PGP MESSAGE----- - fp: B9C7AE554602D82B1AC2CFD0BC7BB2DB17C78E42! - - created_at: "2025-01-21T17:55:44Z" + fp: 535B61015823443941C744DD12264F6BBDFABA89 + - created_at: "2024-03-18T04:02:00Z" enc: |- -----BEGIN PGP MESSAGE----- - hQIMA9ahl2ynTH87AQ/9F/lyLXn60X5Slcd9I7VPdM6x4IjFI0UwMAhMVv0GeimD - 9Mj1vKW+l1v0gFtqCGjANEEYpXMr109CES+m6z7dNXcIQeR6pyjW6uCTiPUK/ZO/ - ZQyhJR0zsT15BTHc6c9Eso9YedsggpRAbjjVIlmrTJx52LfqYYGoRA0XqcLE6LUS - 6v6KR/299zzSHsTFVon6wac9wY7i1XvL0Q7JiYSNV2cNADiCJdCIBw1UkaSVH1uz - sTVdoEoQ1m7hu9pgg4UksUzi9IV3xBpte82tlEK9p0M+RXK/02fjMTWcx3q5fnjN - pBu3HkVzLpAjAQHMQ/O2cgbjFmwgjp5APUhn3IBx5M3F2ypGICnAvsrjfzalTChN - nkCmTfLynNIL1bX7PViABX2Q/yXGzPqFDe96pPw2hGjOXmxjKxjDoLT2IHixYp4D - cxb5519/WmOMrFd4SJeGiUR2Ph/VBZBVGafRfGAKMzxi666igWjwSU0YSDYeEUW/ - BalkkWoz/KQZ5HgQwL9dyp26/cjDtpIwe8jLKVNI6aWhZ2ZmBxFwNEB6fE1txOjf - ceIJAfm8y2qIolw3TpBAFk6s53jir17SrEux9VzfiEfFeQ0g5q7cjAs5HfhTOMfh - iuUnHcCFy27wd+8bPxEaRYR57u7hneenTn3BMuu1CZputDFJWRvweMZk3cH8tiXS - WAGpXw7aKGIOpxe7Ye5X+T3xvYCBN77aFQKkrOmHMWFCbkr2QfnwVanxmmL9BwxF - rf8pG+H0URxBAsy9RZzSC+dXugnwnNBse3wupXf5YkipLx3rX9gtz4Y= - =a7xO + hQIMA9ahl2ynTH87AQ/+LNXxC3acjs2+c38gHZRW6Am4XFx1t/4tfxIgaaK/Boq8 + PGU5CFNOMDGv8u/cwyDbfNM7GuL5g7vrLmBXzSV5ErZqc6bJ0+ZCNPTRIxP1Vxph + tWiDIyTwuqUzxWpOlSzii2Sqhlp8CyiWzBe95eIr96XzDCCtfzyCZ0BYyKgpHHxB + BltH0/+0JZFiR19zvf6M99AHwM8OddRQkXav+mRIJQpA87ovVZcAv5skYGJgNCqN + 55fbskuYmqEnloQCZVJ2+2ZXK5Qn/uq4fLJCiIdZm4YsctJnV5spzZIL+dcOty65 + Plk77BWzLaU5UOKCBAJWrK8oZSTGOrp4VZqb62DuqMRejG0JXmneIVk7p79yn5eA + ANVMGRF4b8RP9YUhzE8HACFzQebKpUU8XKv9+qsmO9Le5jUhU3UQeCSSzT/T5Dr8 + kLDNtmW+mliQnxFlKcVWq2JIG+HaQD1KLOAl0JBNCOSLif2ofaHahuZ15agbYeis + hyrBY92EhzqYXHk/Kzv4ff4r+WUs9NN7R4Gg+wfWvMcTtVfbi4Ht+pjjTtCZwK1C + M8JebQn0NZSpVi3e7Xaz1fQ5Tqrg8PHZtkYGoIHLRPJQwLn9PHYtGzC3rFAk+Fqq + 5WWHELxfcsZ6DakAGSXPK/80QhEZkpGmKizTwrEde+7fpEPxjdzUqlmH3rv7mFzS + WAGSiBIMjLR6ofb65vpghbwh6gXkpCtgUyINRhx/D+Kj5Z4lGD1u1I05DT1xD6VJ + FAbnH7oZ3PJecoAXgRT05FndFA1xfPMCkugmec8ML/sEZt+c3kbrXaA= + =MqS3 -----END PGP MESSAGE----- fp: 8a3737d48f1035fe6c3a0a8fd6a1976ca74c7f3b - - created_at: "2025-01-21T17:55:44Z" + - created_at: "2024-03-18T04:02:00Z" enc: |- -----BEGIN PGP MESSAGE----- - hQIMA0f3HaPlrXn5ARAAph6bpRqnO1TKEE7K6cMCxCA9k3xj7hknBdHN1KlIQkeb - LUOW9lvxh96q/fQ3NvZXpEQqZoEgdhnYTHgr/Hqx7VSksSicOkJLorrBLELjP1Xo - FKTxRYQmgZmgmBc0u7+lF2t0VLey6DfsC9ehY2LQcRuY9WxxCp2nDjjR4wrfmMKi - i/SbpaM9Q29DpdNpwkSlTe2sKr+uMDVA2rCrjpisSDiUBgPe2eJEYPQJ7DHFxB4N - 26NHS+QtUgZhAA1DOGYZvrXzqcZSeAPGk8WXY44KA7o2iRFw+TczpF/VaMHRR5vN - M62IoXGqnMIBau+tsiE1JEVg60DIHpBjsEY/WUgbNX02zfaHcp1OenxU4p7W19Xn - Y8psPm7JNzmi3+nItB2i3+OLQrumk6VaT021ykterc52tR/3ejCzQCsfbqDLnc/6 - r2SvNVDiKpxQ/iFyHb0uLHWy0Jx0lYwmMUrThe1f4k/+m9fEPrA5v/1kTGY5o1Iy - aTuHE19VtB6V+g1H6ZRPr8g8wn/3pg1nC2vUoRzT+oUudxrijrUH8SSlwhu59y1z - 7SrdMmtqA1/JsGNMawCLWd63u+/3GC9LmZzK2h/bV/R4DG5f8tsCpy9BrFAHqTMs - lZ3SONUUeM3uMOggQ/JT26EVxECmNGYIX1TYLOxcqisRXLbfco5LEc6T8PJvdivS - WAFr6kBMdoeWhUT8MdT5AJBm9mo95A0WM8I14pGrszaezfgo9zc2zs0ebdLEjhI4 - jlTf4tXgK3RG455CRWOd9OA3ukR83W7UW6LYjoNaDWHw2RXZlb+hv8E= - =+MFT + hQIMA0f3HaPlrXn5AQ/+N5NK5UJdtw5e7O9T4hfIhtMXci/og1cJiI64daSyNeDH + jq+CPJ8e73yiTPwu6wHHqfuEhlEuI6sJY0ZJVFU+h4SIBtG21veGEz7GzlYgBCJm + xvJHXjtM8AprqnFVO7Fj9QA/ik5QBP6ZpkOY7j8/qf1G7alOIne/MYRALXDvvIMH + HTWE+Y2N57yZK55Pokmdw10hawbrn/N1nt2Y7sa1+5TlRNtuA/+zLkXtEjRr5U3N + DId+hqCKgXDqKLBMkh4mZUTGOGsk8eeKAWwyPp9+8A5/0rfy+xOJYEjjHICXQMSE + zfe6qvj/fRJKGzT5lEzD+ZKHlR0zHEwGRfHqrVUTdPcPdKj3DZILjsoe5ba4VlAp + sS0CAYTg3YuWMT4iHuOQlY5IoQxHHrn7k8ox5iZULFecg58f6r6iJL3AepDYWAey + gtQXYBeaeCm5Ddwmd6TBVz8Q4bCVYIrHbVeAhSDkxfrWLc5UORggvLEWiXilGDJi + DzAv0MVHE2Wa3eOJLq05K2/LBqRBD1XYM3dcS6JSdFxWWMzvLdUOB4dAuPt9gpl9 + liaA13Blw/ev+U4ADxptrl+QuYRbWz3z6rniYpluSrTbVCKFRoHXSGFPy5u8/N6O + QyjfoovIBxXKnbUq2kMoFa/qFpc1pDUn0sjQNsUBdtorAu3Up4icyoih7qwx2J3S + WAGB1jHWMfcsBJqPwjRYkqBf6MuwHAZWdd+zvj/fKfft9jtxLcCGOIM6QdfiWbl0 + Wq4gHdH7OhSy+ZgRnaBRt/GAkzkHvfG68HfulviHZ1h2mrQN1y3mxpg= + =RCYB -----END PGP MESSAGE----- fp: 0af7641adb8aa843136cf6d047f71da3e5ad79f9 unencrypted_suffix: _unencrypted - version: 3.9.2 + version: 3.8.1 diff --git a/keys/staging.yaml b/keys/staging.yaml index 876d60e..ebdd628 100644 --- a/keys/staging.yaml +++ b/keys/staging.yaml @@ -1,6 +1,7 @@ -porkbun: - api-key: ENC[AES256_GCM,data:A5J1sqwq6hs=,iv:77Mar3IX7mq7z7x6s9sSeGNVYc1Wv78HptJElEC7z3Q=,tag:eM/EF9TxKu+zcbJ1SYXiuA==,type:str] - secret-api-key: ENC[AES256_GCM,data:8Xv+jWYaWMI=,iv:li4tdY0pch5lksftMmfMVS729caAwfaacoztaQ49az0=,tag:KhfElBGzVH4ByFPfuQsdhw==,type:str] +authelia: + storageEncryptionKey: ENC[AES256_GCM,data:8X6Zvq7ct1MkMH+lc5kTTHXOo6rGyhSzc3aWxGRA5tnBet+TGcENo0RYTYmactsPGVpTIUGGplaG7B7dqRPhkdDHhbCCZCm2nLaYjpVJ241DrpUNKHn8lvg/bMxUQ/Dvw76ByYuWN6bREr3XRaBztBSPzld8zTSYx71I0CKY7vk=,iv:cJSwfuVWO39qqKCGt2Mvw7pN8+hD6kRH9v4c/u4hLuk=,tag:YhdlXuX2ETxjb443RI8MsA==,type:str] + sessionSecret: ENC[AES256_GCM,data:dnoWmc4HND62w3jMXL+akncAEb61c/I70DgRytx55Wxcn4rMiswp6zCkRdsP4CkouTQ1lyAcQrubp5I8M9Kyow/KBMYz9dPkr4+2xJ9w0SEmAVhyPe2DFvYos3x0Uvx5S0B3o1mXoXqbg78e4w5yEIbALiJT8VPGrWK8Cl4nVPo=,iv:FHDXUW2DWUmEZzWUYkYduogdVOtvMlRH4/fVg05cZaI=,tag:u282WQnHpBsZGYJH7mFFKA==,type:str] + jwtSecret: ENC[AES256_GCM,data:0M3AyoMp+orrljl5NsxmthzrHMmu0REcz7+9fpFKbwwqV6KqlpgGddjYZIsTpHEWEq9zhZ2YWLJkMxKdDgROVHUFZGKut28JPSAjjY+1V0wxNBnfSCnxEv5BUw2+cCxcpCwYQyNfRK6SotTt8aqpxvda4oRXpzxV6SW7ogDjc6E=,iv:D57SynZkW2JuFyX6bpZYkxpR2KtkOmKaySg1Bxim0r8=,tag:JCPGZaumdHrtgcH16A7b+g==,type:str] battery-manager: email: ENC[AES256_GCM,data:LM/EGzWHfVQ=,iv:jFaoUQuUfuGoOyj/GFpdI8TerH/c8D9fjvio+IEt2Tc=,tag:IWLiN011JEnHRLIXWQgfmA==,type:str] password: ENC[AES256_GCM,data:SUxjqS7SJHM=,iv:LvdKk88S+nSImh6/ZezbFGLCUBu1Lpdu+neF2xyHdBg=,tag:rcMyZuW4FVNbcbz00wQKBg==,type:str] @@ -16,9 +17,6 @@ steam: heisenbridge: as-token: ENC[AES256_GCM,data:tXbOeo7nv8I=,iv:wJAKcOXX9nGIw4n38ThOoj29u7dUWhsxSQG/p79JlEw=,tag:rTVaGS2UuWcea1uBa8YX2g==,type:str] hs-token: ENC[AES256_GCM,data:VBwvwomv0Xg=,iv:q6INtJ+rg+QiXj8uBdBzQYQZUBBXp+9odxDHwvu8Jxc=,tag:XKhm8nxygAkKaiVPJ2Fcdg==,type:str] -matrix-hookshot: - as-token: ENC[AES256_GCM,data:uSUOo4f2KqA=,iv:Xb9G8Ecv6m59m51kDw2bOfq3SMJt4g9/6/EdH74R+KM=,tag:K9MSfO2c2Y4rlf0eYrmTnw==,type:str] - hs-token: ENC[AES256_GCM,data:0KsyA06InL4=,iv:zAR0Y1fk8SyodcSLBHlQ8I+BAmttz9Hkd8Q3OREFqs4=,tag:t1Et8N/3seq95DeGoUd7Sw==,type:str] wireguard: server-key: ENC[AES256_GCM,data:FvY897XdKoa/mckE8JQLCkklsnYD6Wz1wpsu5t3uhEnW3iarnDQxF9msuYU=,iv:jqGXfekM+Vs+J9b5nlZ5Skd1ZKHajoUo2Dc4tMYPm1w=,tag:EehikjI/FCU8wqtpvJRamQ==,type:str] restic: @@ -37,43 +35,43 @@ sops: azure_kv: [] hc_vault: [] age: [] - lastmodified: "2025-02-07T17:43:24Z" - mac: ENC[AES256_GCM,data:akmD/bfgeTyFzW1quvM16cdj0fC6+CbJ8WyX9173H11yKGxvE1USQYcErpl1SHOx9Jk8LVb7f+MsUm2fjQF1MEq6xaWI74jem12lZ9CGXFaTL7e87JvfbK7pV+aKpxSBBNFyJgbYm30ibdUwxwKmNVfPb1e0HT9qwenvoV7RobM=,iv:mKqOW0ULXL711uczUbRf9NPo6uPTQoS/IbR46S+JID4=,tag:vE6NYzYLbQHDImov1XGTcg==,type:str] + lastmodified: "2024-04-12T01:00:31Z" + mac: ENC[AES256_GCM,data:fVnMwfvGi7vtP1Fg4NLrhGvLF2PcIgZPOcwk4Ssm4iw5iSj0K1npOX3pd5BWzyszqchfYYRHY99GllAump0bZmprVAld9rf70B2HZIVvowBPuUXfc9Cz/5q0z+s8bQ5vCdElW1Bh7h8W/POePdc8cFGAyBS4i1ZVNheIDOHdDjI=,iv:Bi6rekXOx3/dwwPRryF3CoAoQi3D06ABysRF1oBeG5A=,tag:0TCra+AkhBDczj4uvAzKMw==,type:str] pgp: - - created_at: "2025-01-21T17:55:30Z" - enc: |- + - created_at: "2023-12-29T15:25:27Z" + enc: | -----BEGIN PGP MESSAGE----- - hQEMA7x7stsXx45CAQf9ELnm9TdXCIO6fTPiSCkKthx0tSHqBWX/s63158k4IUu7 - v0WWgQy0SKFU3AwIFuVaAYEXB32SaOWKq2WbVAbFZU+xhyUmNe9asg9Fl24+zjGI - oYnPzv3lz/5vcI6Q9rZi8F2uIi2GQZnbscS1XfjA5u17uOalQpb0hjUXr0LMaUvU - Sggm1ZMKE1o1mHAWK6ZT9SrTMIroWFArJRZLS1eY/vI9ja7I5YR3z0MkLqIvdIp+ - B4DsOXLlqAqtVoPGcK1CixQiXzzwyQAYHyJc3JFDpaF9Y4S5/bkMLGyQVMA259a+ - W7ge+EngdJdXV8Unj4s7ndB1e1iM87Jc+4YOcA7jC9JeAR98n8GL+MN9vE8q2AsB - qSOXiGSwmAkhq7+ZwJHWlivlB1In0coyJ4eMd/yhyBuc2NrstO0t595HlA93GcLN - 5JsXIFMqklqGSzE2KgEXhxa2aUoJxcpApVz2BLFPvg== - =X72N + hQEMA7x7stsXx45CAQf/RWxP6z7xjV5TqiA6lFhtygjrH9x3y1DUWG9aUb/dO+xH + zDbGMYqGe9RPlgi5sWPstdKXvCgs+AKNj93qJYMwEtaasJOinYXCGeAQmzg90+pt + bS6SoBHhGIxAvvLKKPtYx0V50I2reYR+32ux9bcrnzwIsV0P7/SSp1Cl8H+sotB8 + yf+0ULXcpC+SYECmZqzR9qQ3S+3I6/+QS+QgWj4NsyF+apxnE9oQDcBLdYP4aKgR + JHERA9HYfDTKoS137pFHxgINqHkFRY6lhoZdz1yDzOjiPxd8YVfPdKyf022Rg+cX + J/Q2P+OhNZEG3gapNATp6wH3niovA89KwZKSmbTZOdJeAZ6NV6TiUP+TgGg5+CmV + pSLaGel2NZRnFVNdDFi0dsOwhHv3FpKhIpALJh08/jsmAAslfE7vVlcEnaoUJPTS + 3v86AACUC5D/gUxmFrrED1qoxbELCmZ17xTwjQzxwg== + =KzdF -----END PGP MESSAGE----- - fp: B9C7AE554602D82B1AC2CFD0BC7BB2DB17C78E42! - - created_at: "2025-01-21T17:55:30Z" - enc: |- + fp: 535B61015823443941C744DD12264F6BBDFABA89 + - created_at: "2023-12-29T15:25:27Z" + enc: | -----BEGIN PGP MESSAGE----- - hQIMA/3lh+ZzfS28AQ//TPVk5x8wZtKnNcbZjqmXUvi7FzaDMGYFNtiX+bQ17Lkm - qdo9TcH8gZI+xni6wlROQBVmu5MAVkT+NWnZIyxN7pokQPmb2v9zo7oyUPV70owU - dD/LDNVqgyFTVzWKco4wr8CUwQWhOJI9wM0sjTCOTTbCT5hYVnJOLe630sNG9G5b - cJYvaQFxKJeHKJq/DL1I9wT02gOE7vu2xh2OyEozEz3SlB7Bp2mGTLNSiOZBhbzh - DNwFRTeDc1Z/ACQJyoGEXkmj1VLyBFuCfXu4UvUQSmlfyCXKTD1/CUo2uiw1N44W - sYh5UpIrCU2eVAAXAiD1nB6dHxiau3QlapNQfbY2sOZVSnsB21yIja9C3aQN/0Q5 - gRrKYcwULzLZ0Z3oQqQxQG9acU8L9CwjKJ1vOKgPVF7hcWkba2bLVsMMaK6seVNc - jazp9gDAj440S2aE86CdQvgcOEsfgPhBZrulYglbhW8ZaIN2SdjDN/xP1Tn5PadP - gS2DVgqILKPRMF4VavzV3uhEA77QF39Hr18SeToNWcDmfqNPNNf7HpnogstGPf3y - xrFAysLbD8IClU4LqI5M19akODON8qeQa5QD+jHOJmAYnMYNRmY/IwHb/SC5WyIm - EPNZg5E+q9cNrTKtEIuWec0SObqpaUz2E/Vt9+dge0uVgTA/QqPvMP7x19XBrRDS - WAFiKkv7MxImNgcqqe7D3StZoeNm+RXJiULaxxuR8qmMnmvaC+L7ggI4QR3TPQw2 - mSoi7SkdjQUCa8ut15UwNHTGO+smbRs9aonGP4G7c1cOH90YYvR+BTs= - =q2IG + hQIMA/3lh+ZzfS28ARAAm729dMouF7juUeHAb+aHMoyZVKsXapxnxebkjE/LSIbz + IEZwegTNrtxQJLclV4Km2gUaBTcE4vLJCpB7YxZvk7JV9OdVKi97o9PcXUXbz9ej + /WomnEvFyyxTZGTiHU+L4kNudl8UAKhTt3P4fR3PLpTily75Kn53tzLFJuCO8fAY + I/YwQAzayxhPcxk3FuPsD/ONiG7mW8n2ZwfwgOkKXwnrlJv7DreKJRYzu/EeuvX/ + d4oz+k+xofniOeZmQjZllzR7/++MBg/e1U9VocN1EAWpWHP5taLiThfnVSGDhlQM + +4WT5ezH6EuUQlAyQNpDaCincBvCHInhrNlUPOpW51nHMb0y3n4x2hMtZA0JbYEu + mkWTYDe65cHjImHXQk9oO2/v4oIyq7ywHX7g2hqVbbiLHZqqTaGfV8lP30+r6/UQ + 29iAdWac1hY5HDzwbqpY6b38i60j4bkiS83xqrGYBy037bCFk1oHJqwxp5P7vrzr + rTv5NBr95BlwF+s8xPEPZneaEu7N3UnhhSzDWp1jgsCxN9b/XHarchNt70xEt2VS + xpgs9GEXhsJcbrFNPYqTkFb8vjLFI+poGPTfadW17j4Pp5ftIBRNdKvDG0ni/AIp + K98R/nvaHEFuX31SkL8ZUIRqhJm3JVqilFxLAJrqGuSN3jA6wKrimUYpK+t+64jS + WAEN9jHYFQDTVHix3g15S5YTGh5ROyqxouDhvSDFTmGtbm5W/HYgnkZmh53TgVeJ + Rph/O9QptculzTN+nEqshBhbjhl/uDsLsjLYo/O1AyCwTUSd3OKn6uU= + =zThh -----END PGP MESSAGE----- fp: 2f5caa73e7ceea4fcc8d2881fde587e6737d2dbc unencrypted_suffix: _unencrypted - version: 3.9.2 + version: 3.8.1 diff --git a/keys/users/tlater.asc b/keys/users/tlater.asc index d94a304..d9c50dd 100644 --- a/keys/users/tlater.asc +++ b/keys/users/tlater.asc @@ -11,230 +11,62 @@ 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 -GmeDneCrlseO -=ncr2 +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 +PhCB2Dz76iQ5nDY4MQ== +=R7Pm -----END PGP PUBLIC KEY BLOCK----- diff --git a/modules/crowdsec/default.nix b/modules/crowdsec/default.nix deleted file mode 100644 index 44e6bc5..0000000 --- a/modules/crowdsec/default.nix +++ /dev/null @@ -1,383 +0,0 @@ -{ - pkgs, - lib, - config, - ... -}: -let - cfg = config.security.crowdsec; - settingsFormat = pkgs.formats.yaml { }; - - hub = pkgs.fetchFromGitHub { - owner = "crowdsecurity"; - repo = "hub"; - rev = "7a3b4753f4577257c0cbeb8f8f90c7f17d2ae008"; - hash = "sha256-HB4jHyhiO8gjBkLmpo6bDbwhfm5m5nAtNlKhDkZjt2I="; - }; - - cscli = pkgs.writeShellScriptBin "cscli" '' - export PATH="$PATH:${cfg.package}/bin/" - - sudo=exec - if [ "$USER" != "crowdsec" ]; then - sudo='exec /run/wrappers/bin/sudo -u crowdsec' - fi - - $sudo ${cfg.package}/bin/cscli "$@" - ''; - - acquisitions = '' - --- - ${lib.concatMapStringsSep "\n---\n" builtins.toJSON cfg.acquisitions} - --- - ''; -in -{ - imports = [ ./remediations ]; - - options.security.crowdsec = - let - inherit (lib.types) - nullOr - listOf - package - path - str - ; - in - { - enable = lib.mkEnableOption "crowdsec"; - - package = lib.mkOption { - type = package; - default = pkgs.crowdsec; - }; - - stateDirectory = lib.mkOption { - type = path; - readOnly = true; - - description = '' - The state directory of the crowdsec instance. Cannot be - changed, but is exposed for downstream use. - ''; - }; - - settings = lib.mkOption { - inherit (settingsFormat) type; - default = { }; - - description = '' - The crowdsec configuration. Refer to - <https://docs.crowdsec.net/docs/next/configuration/crowdsec_configuration/> - for details on supported values. - ''; - }; - - parserWhitelist = lib.mkOption { - type = listOf str; - default = [ ]; - description = '' - Set of IP addresses to add to a parser-based whitelist. - - Addresses can be specified either as plain IP addresses or - in CIDR notation. - ''; - }; - - acquisitions = lib.mkOption { - type = listOf settingsFormat.type; - default = [ ]; - description = '' - Log acquisitions. - ''; - }; - - extraGroups = lib.mkOption { - type = listOf str; - default = [ ]; - description = '' - Additional groups to make the service part of. - - Required to permit reading from various log sources. - ''; - }; - - hubConfigurations = { - collections = lib.mkOption { - type = listOf str; - description = '' - List of pre-made crowdsec collections to install. - ''; - }; - - scenarios = lib.mkOption { - type = listOf str; - description = '' - List of pre-made crowdsec scenarios to install. - ''; - }; - - parsers = lib.mkOption { - type = listOf str; - description = '' - List of pre-made crowdsec parsers to install. - ''; - }; - - postoverflows = lib.mkOption { - type = listOf str; - description = '' - List of pre-made crowdsec postoverflows to install. - ''; - }; - - appsecConfigs = lib.mkOption { - type = listOf str; - description = '' - List of pre-made crowdsec appsec configurations to install. - ''; - }; - - appsecRules = lib.mkOption { - type = listOf str; - description = '' - List of pre-made crowdsec appsec rules to install. - ''; - }; - }; - - centralApiCredentials = lib.mkOption { - type = nullOr path; - default = null; - - description = '' - The API key to access crowdsec's central API - this is - required to access any of the shared blocklists. - - Use of this feature is optional, entering no API key (the - default) turns all sharing or receiving of blocked IPs off. - - Note that adding the API key by itself does not enable - sharing of blocked IPs with the central API. This limits the - types of blocklists this instance can access. - - To also turn sharing blocked IPs on, set - `api.server.online_client.sharing = true;`. - ''; - }; - - ctiApiKey = lib.mkOption { - type = nullOr path; - default = null; - - description = '' - The API key for crowdsec's CTI offering. - ''; - }; - }; - - config = lib.mkIf cfg.enable { - # Set up default settings; anything that *shouldn't* be changed is - # set to the default priority so that users need to use - # `lib.mkForce`. - security.crowdsec = { - stateDirectory = "/var/lib/crowdsec"; - - settings = { - common = { - daemonize = true; - # The default logs to files, which isn't the preferred way - # on NixOS - log_media = "stdout"; - }; - - config_paths = { - config_dir = "${cfg.stateDirectory}/config/"; - data_dir = "${cfg.stateDirectory}/data/"; - # This "config" file is intended to be written to using the - # cscli tool, so you can temporarily make it so rules don't - # do anything but log what they *would* do for - # experimentation. - simulation_path = "${cfg.stateDirectory}/config/simulation.yaml"; - - pattern_dir = lib.mkDefault "${cfg.package}/share/crowdsec/config/patterns"; - - hub_dir = hub; - index_path = "${hub}/.index.json"; - - # Integrations aren't supported for now - notification_dir = lib.mkDefault "/var/empty/"; - plugin_dir = lib.mkDefault "/var/empty/"; - }; - - crowdsec_service.acquisition_path = - # Using an if/else here because `mkMerge` does not work in - # YAML-type options - if cfg.acquisitions == [ ] then - "${cfg.package}/share/crowdsec/config/acquis.yaml" - else - pkgs.writeText "acquis.yaml" acquisitions; - - cscli = { - prometheus_uri = lib.mkDefault "127.0.0.1:6060"; - }; - - db_config = { - type = lib.mkDefault "sqlite"; - db_path = lib.mkDefault "${cfg.stateDirectory}/data/crowdsec.db"; - use_wal = lib.mkDefault true; - flush = { - max_items = lib.mkDefault 5000; - max_age = lib.mkDefault "7d"; - }; - }; - - api = { - cti = { - enabled = cfg.ctiApiKey != null; - key = cfg.ctiApiKey; - }; - client.credentials_path = "${cfg.stateDirectory}/local_credentials.yaml"; - server = { - listen_uri = lib.mkDefault "127.0.0.1:8080"; - profiles_path = lib.mkDefault "${cfg.package}/share/crowdsec/config/profiles.yaml"; - console_path = lib.mkDefault "${cfg.package}/share/crowdsec/config/console.yaml"; - - online_client = { - # By default, we don't let crowdsec phone home, since - # this is usually within NixOS users' concerns. - sharing = lib.mkDefault false; - credentials_path = cfg.centralApiCredentials; - }; - }; - }; - - # We enable prometheus by default, since cscli relies on it - # for metrics - prometheus = { - enabled = lib.mkDefault true; - level = lib.mkDefault "full"; - listen_addr = lib.mkDefault "127.0.0.1"; - listen_port = lib.mkDefault 6060; - }; - }; - }; - - systemd.packages = [ cfg.package ]; - - environment = { - systemPackages = [ - # To add completions; sadly need to hand-roll this since - # neither `symlinkJoin` nor `buildEnv` have collision - # handling. - (pkgs.runCommandNoCCLocal "cscli" { } '' - mkdir -p $out - ln -s ${cscli}/bin $out/bin - ln -s ${cfg.package}/share $out/share - '') - ]; - - etc."crowdsec/config.yaml".source = settingsFormat.generate "crowdsec-settings.yaml" cfg.settings; - }; - - systemd = { - tmpfiles.settings."10-crowdsec" = { - "${cfg.stateDirectory}".d = { - user = "crowdsec"; - group = "crowdsec"; - mode = "0700"; - }; - - # This must be created for the setup service to work - "${cfg.stateDirectory}/config".d = { - user = "crowdsec"; - group = "crowdsec"; - mode = "0700"; - }; - - "${cfg.stateDirectory}/config/parsers".d = lib.mkIf (cfg.parserWhitelist != [ ]) { - user = "crowdsec"; - group = "crowdsec"; - mode = "0700"; - }; - - "${cfg.stateDirectory}/config/parsers/s02-enrich".d = lib.mkIf (cfg.parserWhitelist != [ ]) { - user = "crowdsec"; - group = "crowdsec"; - mode = "0700"; - }; - - "${cfg.stateDirectory}/config/parsers/s02-enrich/nixos-whitelist.yaml" = - lib.mkIf (cfg.parserWhitelist != [ ]) - { - "L+".argument = - (settingsFormat.generate "crowdsec-nixos-whitelist.yaml" { - name = "nixos/parser-whitelist"; - description = "Parser whitelist generated by the crowdsec NixOS module"; - whitelist = { - reason = "Filtered by NixOS whitelist"; - ip = lib.lists.filter (ip: !(lib.hasInfix "/" ip)) cfg.parserWhitelist; - cidr = lib.lists.filter (ip: lib.hasInfix "/" ip) cfg.parserWhitelist; - }; - }).outPath; - }; - }; - - services = { - crowdsec-setup = { - # TODO(tlater): Depend on tmpfiles path for - # /var/lib/crowdsec/config - description = "Crowdsec database and config preparation"; - - script = '' - if [ ! -e '${cfg.settings.config_paths.simulation_path}' ]; then - cp '${cfg.package}/share/crowdsec/config/simulation.yaml' '${cfg.settings.config_paths.simulation_path}' - fi - - if [ ! -e '${cfg.settings.api.client.credentials_path}' ]; then - ${cfg.package}/bin/cscli machines add --auto --file '${cfg.settings.api.client.credentials_path}' - fi - ''; - - serviceConfig = { - User = "crowdsec"; - Group = "crowdsec"; - StateDirectory = "crowdsec"; - - Type = "oneshot"; - RemainAfterExit = true; - }; - }; - - # Note that the service basics are already defined upstream - crowdsec = { - enable = true; - - after = [ "crowdsec-setup.service" ]; - bindsTo = [ "crowdsec-setup.service" ]; - wantedBy = [ "multi-user.target" ]; - - serviceConfig = { - User = "crowdsec"; - Group = "crowdsec"; - SupplementaryGroups = cfg.extraGroups; - - StateDirectory = "crowdsec"; - }; - }; - }; - }; - - users = { - users.crowdsec = { - isSystemUser = true; - home = cfg.stateDirectory; - group = "crowdsec"; - }; - groups = { - crowdsec = { }; - }; - }; - }; -} diff --git a/modules/crowdsec/remediations/cs-firewall-bouncer.nix b/modules/crowdsec/remediations/cs-firewall-bouncer.nix deleted file mode 100644 index 42accc6..0000000 --- a/modules/crowdsec/remediations/cs-firewall-bouncer.nix +++ /dev/null @@ -1,87 +0,0 @@ -{ - flake-inputs, - pkgs, - lib, - config, - ... -}: -let - inherit (flake-inputs.self.packages.${pkgs.system}) crowdsec-firewall-bouncer; - - crowdsecCfg = config.security.crowdsec; - cfg = crowdsecCfg.remediationComponents.firewallBouncer; - settingsFormat = pkgs.formats.yaml { }; -in -{ - options.security.crowdsec.remediationComponents.firewallBouncer = { - enable = lib.mkEnableOption "cs-firewall-bouncer"; - - settings = lib.mkOption { - inherit (settingsFormat) type; - default = { }; - - description = '' - The bouncer configuration. Refer to - <https://docs.crowdsec.net/u/bouncers/firewall/> for details - on supported values. - ''; - }; - }; - - config = lib.mkIf cfg.enable { - security.crowdsec.remediationComponents.firewallBouncer.settings = { - mode = lib.mkDefault "${if config.networking.nftables.enable then "nftables" else "iptables"}"; - log_mode = "stdout"; - iptables_chains = [ "nixos-fw" ]; - - # Don't let users easily override this; unfortunately we need to - # set up this key through substitution at runtime. - api_key = lib.mkForce "\${API_KEY}"; - api_url = lib.mkDefault "http://${crowdsecCfg.settings.api.server.listen_uri}"; - }; - - systemd = { - packages = [ crowdsec-firewall-bouncer ]; - - services = { - crowdsec-firewall-bouncer-setup = { - description = "Crowdsec firewall bouncer config preparation"; - script = '' - if [ ! -e '${crowdsecCfg.stateDirectory}/firewall_bouncer_credentials.yaml' ]; then - ${crowdsecCfg.package}/bin/cscli -oraw bouncers add "cs-firewall-bouncer-$(${pkgs.coreutils}/bin/date +%s)" > \ - ${crowdsecCfg.stateDirectory}/firewall_bouncer_credentials.yaml - fi - - # Stdout redirection is deliberately used to forcibly - # overwrite the file if it exists - API_KEY="$(<${crowdsecCfg.stateDirectory}/firewall_bouncer_credentials.yaml)" \ - ${lib.getExe pkgs.envsubst} \ - -i ${settingsFormat.generate "crowdsec-firewall-bouncer.yaml" cfg.settings} \ - > /var/lib/crowdsec/config/crowdsec-firewall-bouncer.yaml - ''; - - serviceConfig = { - User = "crowdsec"; - Group = "crowdsec"; - - Type = "oneshot"; - RemainAfterExit = true; - }; - }; - - crowdsec-firewall-bouncer = { - enable = true; - - after = [ "crowdsec-firewall-bouncer-setup.service" ]; - bindsTo = [ "crowdsec-firewall-bouncer-setup.service" ]; - requiredBy = [ "crowdsec.service" ]; - - path = - lib.optionals (cfg.settings.mode == "ipset" || cfg.settings.mode == "iptables") [ pkgs.ipset ] - ++ lib.optional (cfg.settings.mode == "iptables") pkgs.iptables - ++ lib.optional (cfg.settings.mode == "nftables") pkgs.nftables; - }; - }; - }; - }; -} diff --git a/modules/crowdsec/remediations/default.nix b/modules/crowdsec/remediations/default.nix deleted file mode 100644 index c3c0790..0000000 --- a/modules/crowdsec/remediations/default.nix +++ /dev/null @@ -1 +0,0 @@ -{ imports = [ ./cs-firewall-bouncer.nix ]; } diff --git a/modules/default.nix b/modules/default.nix index 89f1752..9341a5a 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -1,6 +1,5 @@ { imports = [ - ./crowdsec ./nginxExtensions.nix ]; } diff --git a/modules/nginxExtensions.nix b/modules/nginxExtensions.nix index bd505d3..8c19cc0 100644 --- a/modules/nginxExtensions.nix +++ b/modules/nginxExtensions.nix @@ -3,57 +3,156 @@ pkgs, lib, ... -}: -{ +}: { options = { services.nginx.domain = lib.mkOption { type = lib.types.str; description = "The base domain name to append to virtual domain names"; }; - services.nginx.virtualHosts = - let - extraVirtualHostOptions = - { name, config, ... }: - { - options = { - enableHSTS = lib.mkEnableOption "Enable HSTS"; + services.nginx.virtualHosts = let + autheliaDomain = "auth.${config.services.nginx.domain}"; + extraLocationOptions = {config, ...}: { + options = { + enableAutheliaProxy = lib.mkEnableOption "Enable recommended authelia proxy settings"; + enableAuthorization = lib.mkEnableOption "Enable authorization via authelia"; + }; - addAccessLog = lib.mkOption { - type = lib.types.bool; - default = true; - description = '' - Add special logging to `/var/log/nginx/''${serverName}` - ''; - }; - }; + config = { + recommendedProxySettings = lib.mkIf config.enableAutheliaProxy false; - config = { - extraConfig = lib.concatStringsSep "\n" [ - (lib.optionalString config.enableHSTS '' - add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; - '') - (lib.optionalString config.addAccessLog '' - access_log /var/log/nginx/${name}/access.log upstream_time; - '') - ]; + extraConfig = lib.concatStringsSep "\n" [ + (lib.optionalString config.enableAutheliaProxy '' + proxy_set_header Host $host; + proxy_set_header X-Original-URL $scheme://$http_host$request_uri; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $http_host; + proxy_set_header X-Forwarded-URI $request_uri; + proxy_set_header X-Forwarded-Ssl on; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Connection ""; + + client_body_buffer_size 128k; + proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; + proxy_redirect http:// $scheme://; + proxy_http_version 1.1; + proxy_cache_bypass $cookie_session; + proxy_no_cache $cookie_session; + proxy_buffers 64 256k; + + real_ip_header X-Forwarded-For; + real_ip_recursive on; + + send_timeout 5m; + proxy_read_timeout 360; + proxy_send_timeout 360; + proxy_connect_timeout 360; + '') + (lib.optionalString config.enableAuthorization '' + auth_request /authelia; + + set_escape_uri $target_url $scheme://$http_host$request_uri; + + auth_request_set $user $upstream_http_remote_user; + auth_request_set $groups $upstream_http_remote_groups; + auth_request_set $name $upstream_http_remote_name; + auth_request_set $email $upstream_http_remote_email; + + proxy_set_header Remote-User $user; + proxy_set_header Remote-Groups $groups; + proxy_set_header Remote-Email $email; + proxy_set_header Remote-Name $name; + + error_page 401 =302 https://${autheliaDomain}/?rd=$target_url; + '') + ]; + }; + }; + + extraVirtualHostOptions = { + name, + config, + ... + }: { + options = { + enableAuthorization = lib.mkEnableOption "Enable authorization via authelia"; + enableHSTS = lib.mkEnableOption "Enable HSTS"; + + addAccessLog = lib.mkOption { + type = lib.types.bool; + default = true; + description = '' + Add special logging to `/var/log/nginx/''${serverName}` + ''; + }; + + locations = lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule extraLocationOptions); + }; + }; + + config = { + extraConfig = lib.concatStringsSep "\n" [ + (lib.optionalString config.enableHSTS '' + add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; + '') + (lib.optionalString config.addAccessLog '' + access_log /var/log/nginx/${name}/access.log upstream_time; + '') + ]; + + locations = lib.mkIf config.enableAuthorization { + "/".enableAuthorization = true; + "/authelia" = { + proxyPass = "http://127.0.0.1:9091/api/verify"; + recommendedProxySettings = false; + extraConfig = '' + internal; + + proxy_set_header X-Original-URL $scheme://$http_host$request_uri; + proxy_set_header X-Original-Method $request_method; + proxy_set_header X-Forwarded-Method $request_method; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $http_host; + proxy_set_header X-Forwarded-Uri $request_uri; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Content-Length ""; + proxy_set_header Connection ""; + + proxy_pass_request_body off; + proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; + proxy_redirect http:// $scheme://; + proxy_http_version 1.1; + proxy_cache_bypass $cookie_session; + proxy_no_cache $cookie_session; + proxy_buffers 4 32k; + client_body_buffer_size 128k; + + send_timeout 5m; + proxy_read_timeout 240; + proxy_send_timeout 240; + proxy_connect_timeout 240; + ''; }; }; - in - lib.mkOption { type = lib.types.attrsOf (lib.types.submodule extraVirtualHostOptions); }; + }; + }; + in + lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule extraVirtualHostOptions); + }; }; config = { # Don't attempt to run acme if the domain name is not tlater.net - systemd.services = - let - confirm = ''[[ "tlater.net" = ${config.services.nginx.domain} ]]''; - in - lib.mapAttrs' ( - cert: _: + systemd.services = let + confirm = ''[[ "tlater.net" = ${config.services.nginx.domain} ]]''; + in + lib.mapAttrs' (cert: _: lib.nameValuePair "acme-${cert}" { serviceConfig.ExecCondition = ''${pkgs.runtimeShell} -c '${confirm}' ''; - } - ) config.security.acme.certs; + }) + config.security.acme.certs; }; } diff --git a/pkgs/_sources_nextcloud/generated.json b/pkgs/_sources_nextcloud/generated.json new file mode 100644 index 0000000..ce9ac04 --- /dev/null +++ b/pkgs/_sources_nextcloud/generated.json @@ -0,0 +1,86 @@ +{ + "bookmarks": { + "cargoLocks": null, + "date": null, + "extract": null, + "name": "bookmarks", + "passthru": null, + "pinned": false, + "src": { + "sha256": "sha256-JXNQNnWXoii71QhtKktuEBEIqzmONVetULBhpSjM9xo=", + "type": "tarball", + "url": "https://github.com/nextcloud/bookmarks/releases/download/v13.1.3/bookmarks-13.1.3.tar.gz" + }, + "version": "13.1.3" + }, + "calendar": { + "cargoLocks": null, + "date": null, + "extract": null, + "name": "calendar", + "passthru": null, + "pinned": false, + "src": { + "sha256": "sha256-hZfjWAMi/0qs5xMMgOlcoSXG6kcZ2aeDaez+NqSZFKI=", + "type": "tarball", + "url": "https://github.com/nextcloud-releases/calendar/releases/download/v4.6.7/calendar-v4.6.7.tar.gz" + }, + "version": "v4.6.7" + }, + "contacts": { + "cargoLocks": null, + "date": null, + "extract": null, + "name": "contacts", + "passthru": null, + "pinned": false, + "src": { + "sha256": "sha256-HCEjiAqn6sTNXKW6O5X6Ta9Ll4ehvzmGZUj1c0ue2Xc=", + "type": "tarball", + "url": "https://github.com/nextcloud-releases/contacts/releases/download/v5.5.3/contacts-v5.5.3.tar.gz" + }, + "version": "v5.5.3" + }, + "cookbook": { + "cargoLocks": null, + "date": null, + "extract": null, + "name": "cookbook", + "passthru": null, + "pinned": false, + "src": { + "sha256": "sha256-TE/w8SgyIPaGl5wZUAsG234nxoPj25QoRPF3zjbMoRk=", + "type": "tarball", + "url": "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.10.5/Cookbook-0.10.5.tar.gz" + }, + "version": "0.10.5" + }, + "news": { + "cargoLocks": null, + "date": null, + "extract": null, + "name": "news", + "passthru": null, + "pinned": false, + "src": { + "sha256": "sha256-cfJkKRNSz15L4E3w1tnEb+t4MrVwVzb8lb6vCOA4cK4=", + "type": "tarball", + "url": "https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz" + }, + "version": "24.0.0" + }, + "notes": { + "cargoLocks": null, + "date": null, + "extract": null, + "name": "notes", + "passthru": null, + "pinned": false, + "src": { + "sha256": "sha256-ydpxatwuZUz7XIgK8FMklZlxNQklpsP8Uqpxvt3iK0k=", + "type": "tarball", + "url": "https://github.com/nextcloud/notes/releases/download/v4.10.0/notes.tar.gz" + }, + "version": "v4.10.0" + } +} \ No newline at end of file diff --git a/pkgs/_sources_nextcloud/generated.nix b/pkgs/_sources_nextcloud/generated.nix new file mode 100644 index 0000000..c77aa9c --- /dev/null +++ b/pkgs/_sources_nextcloud/generated.nix @@ -0,0 +1,52 @@ +# This file was generated by nvfetcher, please do not modify it manually. +{ fetchgit, fetchurl, fetchFromGitHub, dockerTools }: +{ + bookmarks = { + pname = "bookmarks"; + version = "13.1.3"; + src = fetchTarball { + url = "https://github.com/nextcloud/bookmarks/releases/download/v13.1.3/bookmarks-13.1.3.tar.gz"; + sha256 = "sha256-JXNQNnWXoii71QhtKktuEBEIqzmONVetULBhpSjM9xo="; + }; + }; + calendar = { + pname = "calendar"; + version = "v4.6.7"; + src = fetchTarball { + url = "https://github.com/nextcloud-releases/calendar/releases/download/v4.6.7/calendar-v4.6.7.tar.gz"; + sha256 = "sha256-hZfjWAMi/0qs5xMMgOlcoSXG6kcZ2aeDaez+NqSZFKI="; + }; + }; + contacts = { + pname = "contacts"; + version = "v5.5.3"; + src = fetchTarball { + url = "https://github.com/nextcloud-releases/contacts/releases/download/v5.5.3/contacts-v5.5.3.tar.gz"; + sha256 = "sha256-HCEjiAqn6sTNXKW6O5X6Ta9Ll4ehvzmGZUj1c0ue2Xc="; + }; + }; + cookbook = { + pname = "cookbook"; + version = "0.10.5"; + src = fetchTarball { + url = "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v0.10.5/Cookbook-0.10.5.tar.gz"; + sha256 = "sha256-TE/w8SgyIPaGl5wZUAsG234nxoPj25QoRPF3zjbMoRk="; + }; + }; + news = { + pname = "news"; + version = "24.0.0"; + src = fetchTarball { + url = "https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz"; + sha256 = "sha256-cfJkKRNSz15L4E3w1tnEb+t4MrVwVzb8lb6vCOA4cK4="; + }; + }; + notes = { + pname = "notes"; + version = "v4.10.0"; + src = fetchTarball { + url = "https://github.com/nextcloud/notes/releases/download/v4.10.0/notes.tar.gz"; + sha256 = "sha256-ydpxatwuZUz7XIgK8FMklZlxNQklpsP8Uqpxvt3iK0k="; + }; + }; +} diff --git a/pkgs/_sources_pkgs/generated.json b/pkgs/_sources_pkgs/generated.json new file mode 100644 index 0000000..fc6c343 --- /dev/null +++ b/pkgs/_sources_pkgs/generated.json @@ -0,0 +1,21 @@ +{ + "prometheus-fail2ban-exporter": { + "cargoLocks": null, + "date": null, + "extract": null, + "name": "prometheus-fail2ban-exporter", + "passthru": null, + "pinned": false, + "src": { + "deepClone": false, + "fetchSubmodules": false, + "leaveDotGit": false, + "name": null, + "rev": "v0.10.1", + "sha256": "sha256-zGEhDy3uXIbvx4agSA8Mx7bRtiZZtoDZGbNbHc9L+yI=", + "type": "git", + "url": "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter" + }, + "version": "v0.10.1" + } +} \ No newline at end of file diff --git a/pkgs/_sources_pkgs/generated.nix b/pkgs/_sources_pkgs/generated.nix new file mode 100644 index 0000000..39dc6d0 --- /dev/null +++ b/pkgs/_sources_pkgs/generated.nix @@ -0,0 +1,16 @@ +# This file was generated by nvfetcher, please do not modify it manually. +{ fetchgit, fetchurl, fetchFromGitHub, dockerTools }: +{ + prometheus-fail2ban-exporter = { + pname = "prometheus-fail2ban-exporter"; + version = "v0.10.1"; + src = fetchgit { + url = "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter"; + rev = "v0.10.1"; + fetchSubmodules = false; + deepClone = false; + leaveDotGit = false; + sha256 = "sha256-zGEhDy3uXIbvx4agSA8Mx7bRtiZZtoDZGbNbHc9L+yI="; + }; + }; +} diff --git a/pkgs/afvalcalendar/Cargo.lock b/pkgs/afvalcalendar/Cargo.lock new file mode 100644 index 0000000..24cace4 --- /dev/null +++ b/pkgs/afvalcalendar/Cargo.lock @@ -0,0 +1,1430 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "afvalcalendar" +version = "0.1.0" +dependencies = [ + "chrono", + "hostname", + "icalendar", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "tokio", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] +name = "bumpalo" +version = "3.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.0", +] + +[[package]] +name = "cookie" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "cookie_store" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387461abbc748185c3a6e1673d826918b450b87ff22639429c694619a83b6cf6" +dependencies = [ + "cookie", + "idna 0.3.0", + "log", + "publicsuffix", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "h2" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "hermit-abi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icalendar" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4ffbcf3325ae94554c5259ce0b8907d37133c066cb3d424a2fa96aa1f10088" +dependencies = [ + "chrono", + "iso8601", + "nom", + "uuid", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "iso8601" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924e5d73ea28f59011fec52a0d12185d496a9b075d360657aed2a5707f701153" +dependencies = [ + "nom", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "js-sys" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.4.2", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae94056a791d0e1217d18b6cbdccb02c61e3054fc69893607f4067e3bb0b1fd1" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + +[[package]] +name = "publicsuffix" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457" +dependencies = [ + "idna 0.3.0", + "psl-types", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "reqwest" +version = "0.11.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" +dependencies = [ + "base64", + "bytes", + "cookie", + "cookie_store", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +dependencies = [ + "bitflags 2.4.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64", +] + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.196" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.196" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "syn" +version = "2.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "time" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna 0.5.0", + "percent-encoding", +] + +[[package]] +name = "uuid" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" +dependencies = [ + "getrandom", + "wasm-bindgen", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" + +[[package]] +name = "web-sys" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] diff --git a/pkgs/afvalcalendar/Cargo.toml b/pkgs/afvalcalendar/Cargo.toml new file mode 100644 index 0000000..f37dff1 --- /dev/null +++ b/pkgs/afvalcalendar/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "afvalcalendar" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +icalendar = "0.16.0" +serde = { version = "1.0.195", features = ["derive"] } +tokio = { version = "1.35.1", features = ["macros", "rt-multi-thread"] } +reqwest = { version = "0.11", features = ["cookies", "json"] } +chrono = { version = "0.4.34", features = ["serde"] } +serde_json = "1.0.114" +serde_repr = "0.1.18" +hostname = "0.3.1" diff --git a/pkgs/afvalcalendar/default.nix b/pkgs/afvalcalendar/default.nix new file mode 100644 index 0000000..12e2af5 --- /dev/null +++ b/pkgs/afvalcalendar/default.nix @@ -0,0 +1,20 @@ +{ + pkgs, + rustPlatform, + ... +}: +rustPlatform.buildRustPackage { + pname = "afvalcalendar"; + version = "0.1.0"; + src = ./.; + + nativeBuildInputs = with pkgs; [ + pkg-config + ]; + + buildInputs = with pkgs; [ + openssl + ]; + + cargoHash = "sha256-JXx6aUKdKbUTBCwlBw5i1hZy8ofCfSrhLCwFzqdA8cI="; +} diff --git a/pkgs/afvalcalendar/src/calendar.rs b/pkgs/afvalcalendar/src/calendar.rs new file mode 100644 index 0000000..2c76d7f --- /dev/null +++ b/pkgs/afvalcalendar/src/calendar.rs @@ -0,0 +1,43 @@ +use chrono::{Duration, NaiveDate}; +use icalendar::{Alarm, Calendar, Component, Event, EventLike, Property}; + +use crate::trash::TrashType; + +pub(crate) fn calendar_from_pickup_dates(dates: Vec<(TrashType, NaiveDate)>) -> Calendar { + let mut ical = Calendar::new(); + ical.name("Twente Milieu Afvalkalender"); + + let events = dates.iter().map(|date| { + let description = match date.0 { + TrashType::Grey => "Restafval wordt opgehaald", + TrashType::Green => "GFT wordt opgehaald", + TrashType::Paper => "Papier wordt opgehaald", + TrashType::Packages => "Verpakkingen worden opgehaald", + }; + + let color = Property::new( + "COLOR", + match date.0 { + TrashType::Grey => "darkgray", + TrashType::Green => "darkgreen", + TrashType::Paper => "royalblue", + TrashType::Packages => "darkorange", + }, + ); + + let reminder = Alarm::display(description, -Duration::hours(5)); + + Event::new() + .all_day(date.1) + .summary(description) + .append_property(color) + .alarm(reminder) + .done() + }); + + for event in events { + ical.push(event); + } + + ical.done() +} diff --git a/pkgs/afvalcalendar/src/main.rs b/pkgs/afvalcalendar/src/main.rs new file mode 100644 index 0000000..e8023f7 --- /dev/null +++ b/pkgs/afvalcalendar/src/main.rs @@ -0,0 +1,15 @@ +mod calendar; +mod trash; + +#[tokio::main] +async fn main() { + match trash::get_pickup_dates().await { + Ok(dates) => { + let calendar = calendar::calendar_from_pickup_dates(dates); + calendar.print().unwrap(); + } + Err(error) => { + eprintln!("{}", error); + } + } +} diff --git a/pkgs/afvalcalendar/src/trash.rs b/pkgs/afvalcalendar/src/trash.rs new file mode 100644 index 0000000..89a84d0 --- /dev/null +++ b/pkgs/afvalcalendar/src/trash.rs @@ -0,0 +1,59 @@ +use chrono::{Months, NaiveDate, NaiveDateTime, Utc}; +use serde::Deserialize; +use serde_repr::Deserialize_repr; + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +struct CalendarAPIDatum { + pickup_dates: Vec<NaiveDateTime>, + pickup_type: TrashType, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +struct CalendarAPIResponse { + data_list: Vec<CalendarAPIDatum>, +} + +#[derive(Copy, Clone, Deserialize_repr, Debug)] +#[repr(u8)] +pub(crate) enum TrashType { + Grey = 0, + Green = 1, + Paper = 2, + Packages = 10, +} + +pub(crate) async fn get_pickup_dates() -> Result<Vec<(TrashType, NaiveDate)>, reqwest::Error> { + let today = Utc::now().date_naive(); + let next_month = (today + Months::new(1)).to_string(); + let today = today.to_string(); + + let client = reqwest::Client::new(); + + let params = [ + ("companyCode", "8d97bb56-5afd-4cbc-a651-b4f7314264b4"), + ("uniqueAddressID", "1300002485"), + ("startDate", &today), + ("endDate", &next_month), + ]; + + let calendar = client + .post("https://twentemilieuapi.ximmio.com/api/GetCalendar") + .form(¶ms) + .send() + .await? + .json::<CalendarAPIResponse>() + .await?; + + Ok(calendar + .data_list + .iter() + .flat_map(|datum| { + datum + .pickup_dates + .iter() + .map(|date| (datum.pickup_type, NaiveDate::from(*date))) + }) + .collect::<Vec<(TrashType, NaiveDate)>>()) +} diff --git a/pkgs/afvalcalendar/test.rest b/pkgs/afvalcalendar/test.rest new file mode 100644 index 0000000..d2d409e --- /dev/null +++ b/pkgs/afvalcalendar/test.rest @@ -0,0 +1,4 @@ +POST https://twentemilieuapi.ximmio.com/api/GetCalendar +Content-Type: application/x-www-form-urlencoded + +companyCode=8d97bb56-5afd-4cbc-a651-b4f7314264b4&uniqueAddressID=1300002485&startDate=2024-02-01&endDate=2024-02-29 diff --git a/pkgs/crowdsec/_sources/generated.json b/pkgs/crowdsec/_sources/generated.json deleted file mode 100644 index f3c8f01..0000000 --- a/pkgs/crowdsec/_sources/generated.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "crowdsec-firewall-bouncer": { - "cargoLocks": null, - "date": null, - "extract": null, - "name": "crowdsec-firewall-bouncer", - "passthru": null, - "pinned": false, - "src": { - "deepClone": false, - "fetchSubmodules": false, - "leaveDotGit": false, - "name": null, - "owner": "crowdsecurity", - "repo": "cs-firewall-bouncer", - "rev": "v0.0.31", - "sha256": "sha256-59MWll8v00CF4WA53gjHZSTFc8hpYaHENg9O7LgTCrA=", - "type": "github" - }, - "version": "v0.0.31" - }, - "crowdsec-hub": { - "cargoLocks": null, - "date": "2025-05-17", - "extract": null, - "name": "crowdsec-hub", - "passthru": null, - "pinned": false, - "src": { - "deepClone": false, - "fetchSubmodules": false, - "leaveDotGit": false, - "name": null, - "owner": "crowdsecurity", - "repo": "hub", - "rev": "850614b9fcd4298f559b422c5ac685a69aa2e5ff", - "sha256": "sha256-96MMwFN5KongQA3YJVSuk7Kanbr1gR94CCyiflmez2k=", - "type": "github" - }, - "version": "850614b9fcd4298f559b422c5ac685a69aa2e5ff" - } -} \ No newline at end of file diff --git a/pkgs/crowdsec/_sources/generated.nix b/pkgs/crowdsec/_sources/generated.nix deleted file mode 100644 index 19a7f5a..0000000 --- a/pkgs/crowdsec/_sources/generated.nix +++ /dev/null @@ -1,27 +0,0 @@ -# This file was generated by nvfetcher, please do not modify it manually. -{ fetchgit, fetchurl, fetchFromGitHub, dockerTools }: -{ - crowdsec-firewall-bouncer = { - pname = "crowdsec-firewall-bouncer"; - version = "v0.0.31"; - src = fetchFromGitHub { - owner = "crowdsecurity"; - repo = "cs-firewall-bouncer"; - rev = "v0.0.31"; - fetchSubmodules = false; - sha256 = "sha256-59MWll8v00CF4WA53gjHZSTFc8hpYaHENg9O7LgTCrA="; - }; - }; - crowdsec-hub = { - pname = "crowdsec-hub"; - version = "850614b9fcd4298f559b422c5ac685a69aa2e5ff"; - src = fetchFromGitHub { - owner = "crowdsecurity"; - repo = "hub"; - rev = "850614b9fcd4298f559b422c5ac685a69aa2e5ff"; - fetchSubmodules = false; - sha256 = "sha256-96MMwFN5KongQA3YJVSuk7Kanbr1gR94CCyiflmez2k="; - }; - date = "2025-05-17"; - }; -} diff --git a/pkgs/crowdsec/default.nix b/pkgs/crowdsec/default.nix deleted file mode 100644 index 66faac3..0000000 --- a/pkgs/crowdsec/default.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ pkgs }: -let - sources = pkgs.callPackage ./_sources/generated.nix { }; - callPackage = pkgs.lib.callPackageWith (pkgs // { inherit sources; }); -in -{ - hub = callPackage ./hub.nix { }; - firewall-bouncer = callPackage ./firewall-bouncer.nix { }; -} diff --git a/pkgs/crowdsec/firewall-bouncer.nix b/pkgs/crowdsec/firewall-bouncer.nix deleted file mode 100644 index 86370c4..0000000 --- a/pkgs/crowdsec/firewall-bouncer.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ - lib, - sources, - buildGoModule, - envsubst, - coreutils, -}: -let - envsubstBin = lib.getExe envsubst; -in -buildGoModule { - inherit (sources.crowdsec-firewall-bouncer) pname version src; - - vendorHash = "sha256-7Jxvg8UEjUxnIz1llvXyI2AefJ31OVdNzhWD/C8wU/Y="; - - postInstall = '' - mkdir -p $out/lib/systemd/system - - CFG=/var/lib/crowdsec/config BIN=$out/bin/cs-firewall-bouncer ${envsubstBin} \ - -i ./config/crowdsec-firewall-bouncer.service \ - -o $out/lib/systemd/system/crowdsec-firewall-bouncer.service - - substituteInPlace $out/lib/systemd/system/crowdsec-firewall-bouncer.service \ - --replace-fail /bin/sleep ${coreutils}/bin/sleep - ''; -} diff --git a/pkgs/crowdsec/hub.nix b/pkgs/crowdsec/hub.nix deleted file mode 100644 index 1b8c9b3..0000000 --- a/pkgs/crowdsec/hub.nix +++ /dev/null @@ -1 +0,0 @@ -{ sources }: sources.crowdsec-hub.src diff --git a/pkgs/crowdsec/nvfetcher.toml b/pkgs/crowdsec/nvfetcher.toml deleted file mode 100644 index 2287dba..0000000 --- a/pkgs/crowdsec/nvfetcher.toml +++ /dev/null @@ -1,7 +0,0 @@ -[crowdsec-hub] -src.git = "https://github.com/crowdsecurity/hub.git" -fetch.github = "crowdsecurity/hub" - -[crowdsec-firewall-bouncer] -src.github = "crowdsecurity/cs-firewall-bouncer" -fetch.github = "crowdsecurity/cs-firewall-bouncer" diff --git a/pkgs/default.nix b/pkgs/default.nix index 0e5de7a..3162787 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -1,5 +1,22 @@ -{ pkgs }: { - crowdsec = import ./crowdsec { inherit pkgs; }; - starbound = pkgs.callPackage ./starbound { }; -} + pkgs, + lib, +}: let + inherit (builtins) fromJSON mapAttrs readFile; + inherit (pkgs) callPackage; +in + { + starbound = callPackage ./starbound {}; + prometheus-fail2ban-exporter = callPackage ./prometheus/fail2ban-exporter.nix { + sources = pkgs.callPackage ./_sources_pkgs/generated.nix {}; + }; + afvalcalendar = callPackage ./afvalcalendar {}; + } + // ( + # Add nextcloud apps + let + mkNextcloudApp = pkgs.callPackage ./mkNextcloudApp.nix {}; + sources = fromJSON (readFile ./_sources_nextcloud/generated.json); + in + mapAttrs (_: source: mkNextcloudApp source) sources + ) diff --git a/pkgs/mkNextcloudApp.nix b/pkgs/mkNextcloudApp.nix new file mode 100644 index 0000000..9bf6b26 --- /dev/null +++ b/pkgs/mkNextcloudApp.nix @@ -0,0 +1,9 @@ +{ + fetchNextcloudApp, + lib, +}: source: +fetchNextcloudApp { + url = source.src.url; + sha256 = source.src.sha256; + license = "unlicense"; # Blatant lie +} diff --git a/pkgs/nextcloud-apps.toml b/pkgs/nextcloud-apps.toml new file mode 100644 index 0000000..36566db --- /dev/null +++ b/pkgs/nextcloud-apps.toml @@ -0,0 +1,31 @@ +[bookmarks] +# src.github = "nextcloud/bookmarks" +src.prefix = "v" +src.manual = "v13.1.3" +fetch.tarball = "https://github.com/nextcloud/bookmarks/releases/download/v$ver/bookmarks-$ver.tar.gz" + +[calendar] +# src.github = "nextcloud-releases/calendar" +src.manual = "v4.6.7" +fetch.tarball = "https://github.com/nextcloud-releases/calendar/releases/download/$ver/calendar-$ver.tar.gz" + +[contacts] +# src.github = "nextcloud-releases/contacts" +src.manual = "v5.5.3" +fetch.tarball = "https://github.com/nextcloud-releases/contacts/releases/download/$ver/contacts-$ver.tar.gz" + +[cookbook] +# src.github = "christianlupus-nextcloud/cookbook-releases" +src.prefix = "v" +src.manual = "0.10.5" +fetch.tarball = "https://github.com/christianlupus-nextcloud/cookbook-releases/releases/download/v$ver/Cookbook-$ver.tar.gz" + +[news] +# src.github = "nextcloud/news" +# Update to 25 when angular rewrite is done/the alpha when I need to switch to nextcloud 28+ +src.manual = "24.0.0" +fetch.tarball = "https://github.com/nextcloud/news/releases/download/$ver/news.tar.gz" + +[notes] +src.github = "nextcloud/notes" +fetch.tarball = "https://github.com/nextcloud/notes/releases/download/$ver/notes.tar.gz" diff --git a/pkgs/nvfetcher.toml b/pkgs/nvfetcher.toml new file mode 100644 index 0000000..d0dfbe5 --- /dev/null +++ b/pkgs/nvfetcher.toml @@ -0,0 +1,3 @@ +[prometheus-fail2ban-exporter] +src.manual = "v0.10.1" # No gitlab support in nvfetcher +fetch.git = "https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter" diff --git a/pkgs/prometheus/fail2ban-exporter.nix b/pkgs/prometheus/fail2ban-exporter.nix new file mode 100644 index 0000000..b2c6a25 --- /dev/null +++ b/pkgs/prometheus/fail2ban-exporter.nix @@ -0,0 +1,8 @@ +{ + buildGoModule, + sources, +}: +buildGoModule { + inherit (sources.prometheus-fail2ban-exporter) pname src version; + vendorHash = "sha256-5o8p5p0U/c0WAIV5dACnWA3ThzSh2tt5LIFMb59i9GY="; +} diff --git a/pkgs/starbound/default.nix b/pkgs/starbound/default.nix index 26f2184..304f0f3 100644 --- a/pkgs/starbound/default.nix +++ b/pkgs/starbound/default.nix @@ -5,33 +5,30 @@ patchelf, steamPackages, replace-secret, -}: -let +}: let # Use the directory in which starbound is installed so steamcmd # doesn't have to be reinstalled constantly (we're using DynamicUser # with StateDirectory to persist this). - steamcmd = steamPackages.steamcmd.override { steamRoot = "/var/lib/starbound/.steamcmd"; }; - wrapperPath = lib.makeBinPath [ - patchelf - steamcmd - replace-secret - ]; + steamcmd = steamPackages.steamcmd.override { + steamRoot = "/var/lib/starbound/.steamcmd"; + }; + wrapperPath = lib.makeBinPath [patchelf steamcmd replace-secret]; in -stdenv.mkDerivation { - name = "starbound-update-script"; - nativeBuildInputs = [ makeWrapper ]; - dontUnpack = true; - patchPhase = '' - interpreter="$(cat $NIX_CC/nix-support/dynamic-linker)" - substitute ${./launch-starbound.sh} launch-starbound --subst-var interpreter - ''; - installPhase = '' - mkdir -p $out/bin - cp launch-starbound $out/bin/launch-starbound - chmod +x $out/bin/launch-starbound - ''; - postFixup = '' - wrapProgram $out/bin/launch-starbound \ - --prefix PATH : "${wrapperPath}" - ''; -} + stdenv.mkDerivation { + name = "starbound-update-script"; + nativeBuildInputs = [makeWrapper]; + dontUnpack = true; + patchPhase = '' + interpreter="$(cat $NIX_CC/nix-support/dynamic-linker)" + substitute ${./launch-starbound.sh} launch-starbound --subst-var interpreter + ''; + installPhase = '' + mkdir -p $out/bin + cp launch-starbound $out/bin/launch-starbound + chmod +x $out/bin/launch-starbound + ''; + postFixup = '' + wrapProgram $out/bin/launch-starbound \ + --prefix PATH : "${wrapperPath}" + ''; + }