diff --git a/flake.lock b/flake.lock index 7694090..12bdf25 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,28 @@ { "nodes": { + "agenix": { + "inputs": { + "darwin": "darwin", + "home-manager": "home-manager", + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems" + }, + "locked": { + "lastModified": 1736955230, + "narHash": "sha256-uenf8fv2eG5bKM8C/UvFaiJMZ4IpUFaQxk9OH5t/1gA=", + "owner": "ryantm", + "repo": "agenix", + "rev": "e600439ec4c273cf11e06fe4d9d906fb98fa097c", + "type": "github" + }, + "original": { + "owner": "ryantm", + "repo": "agenix", + "type": "github" + } + }, "auto-cpufreq": { "inputs": { "nixpkgs": [ @@ -51,6 +74,28 @@ "type": "github" } }, + "darwin": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1700795494, + "narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d", + "type": "github" + }, + "original": { + "owner": "lnl7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, "flake-compat": { "flake": false, "locked": { @@ -144,7 +189,7 @@ }, "flake-utils": { "inputs": { - "systems": "systems" + "systems": "systems_2" }, "locked": { "lastModified": 1710146030, @@ -162,7 +207,7 @@ }, "flake-utils_2": { "inputs": { - "systems": "systems_2" + "systems": "systems_3" }, "locked": { "lastModified": 1701680307, @@ -180,7 +225,7 @@ }, "flake-utils_3": { "inputs": { - "systems": "systems_3" + "systems": "systems_4" }, "locked": { "lastModified": 1710146030, @@ -298,6 +343,27 @@ } }, "home-manager": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1703113217, + "narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "home-manager_2": { "inputs": { "nixpkgs": [ "nixpkgs" @@ -645,13 +711,14 @@ }, "root": { "inputs": { + "agenix": "agenix", "auto-cpufreq": "auto-cpufreq", "commander-nvim": "commander-nvim", "flake-parts": "flake-parts", "gen-nvim": "gen-nvim", "gtrackmap": "gtrackmap", "hastebin": "hastebin", - "home-manager": "home-manager", + "home-manager": "home-manager_2", "ketchup": "ketchup", "ksoloti-pr": "ksoloti-pr", "lanzaboote": "lanzaboote", @@ -730,6 +797,21 @@ "type": "github" } }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "vimpeccable": { "flake": false, "locked": { diff --git a/flake.nix b/flake.nix index 98eb3dd..0d90054 100644 --- a/flake.nix +++ b/flake.nix @@ -52,8 +52,12 @@ inputs.nixpkgs.follows = "nixpkgs"; }; ksoloti-pr.url = "github:repomaa/nixpkgs/pkg/ksoloti"; + agenix = { + url = "github:ryantm/agenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; - outputs = { flake-parts, nixpkgs, ... }@inputs: + outputs = { flake-parts, agenix, nixpkgs, ... }@inputs: flake-parts.lib.mkFlake { inherit inputs; } ( let ssh.publicKeys.yubikey = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLIUkESu5NnBi1M0+ZjYrkp6/rIFuwc3aguspf98jmOydNce6l65cnS3GRzc9oWx4lu11ahi87ZuE+pYV+gaHm4="; @@ -74,6 +78,7 @@ (writeShellScriptBin "evaluate" '' ${nix}/bin/nix build --dry-run ".#nixosConfigurations.$1.config.system.build.toplevel" | ${nix-output-monitor}/bin/nom '') + agenix.packages.${pkgs.system}.default ]; }; }; diff --git a/hosts/freun.dev/default.nix b/hosts/freun.dev/default.nix index b8b0088..bb55317 100644 --- a/hosts/freun.dev/default.nix +++ b/hosts/freun.dev/default.nix @@ -4,5 +4,6 @@ ./hardware-configuration.nix ./configuration.nix ./services.nix + ./secrets.nix ]; } diff --git a/hosts/freun.dev/secrets.nix b/hosts/freun.dev/secrets.nix new file mode 100644 index 0000000..b307c78 --- /dev/null +++ b/hosts/freun.dev/secrets.nix @@ -0,0 +1,22 @@ +{ lib, config, ... }: +{ + age.secrets = lib.listToAttrs + ( + map (secret: { name = secret; value = { file = ../../secrets/${secret}.age; }; }) [ + "gotosocial" + "hastebin-tokens" + "immich" + "storage-box-credentials" + "vaultwarden" + ] + ) // { + smtp-password = { + file = ../../secrets/smtp-password.age; + owner = + if (config.services.grafana.enable) then + config.systemd.services.grafana.serviceConfig.User + else + "root"; + }; + }; +} diff --git a/hosts/radish/packages.nix b/hosts/radish/packages.nix index ee44ac5..44ed17b 100644 --- a/hosts/radish/packages.nix +++ b/hosts/radish/packages.nix @@ -24,6 +24,11 @@ }; services = { + openssh = { + enable = true; + openFirewall = false; + }; + tailscale = { enable = true; useRoutingFeatures = "client"; diff --git a/modules/default.nix b/modules/default.nix index 0b6b0f2..3473dc8 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -1,9 +1,10 @@ -{ ... }: +{ inputs, ... }: { imports = [ ./vlans.nix ./firewall.nix ./storage-box-mounts.nix ./services + inputs.agenix.nixosModules.default ]; } diff --git a/modules/services/gotosocial.nix b/modules/services/gotosocial.nix index 5836536..3f003a4 100644 --- a/modules/services/gotosocial.nix +++ b/modules/services/gotosocial.nix @@ -1,6 +1,7 @@ { config, lib, ... }: let cfg = config.modules.services.gotosocial; + secrets = config.age.secrets; domain = config.networking.domain; fqdn = "${cfg.subdomain}.${domain}"; port = cfg.port; @@ -24,7 +25,7 @@ in config = lib.mkIf cfg.enable { services.gotosocial = { enable = true; - environmentFile = "/var/secrets/gotosocial.env"; + environmentFile = secrets.gotosocial.path; settings = { host = fqdn; account-domain = domain; diff --git a/modules/services/grafana.nix b/modules/services/grafana.nix index 1031873..844a7e1 100644 --- a/modules/services/grafana.nix +++ b/modules/services/grafana.nix @@ -1,6 +1,7 @@ { lib, config, ... }: let cfg = config.modules.services.grafana; + secrets = config.age.secrets; fqdn = "${cfg.subdomain}.${config.networking.domain}"; in { @@ -40,7 +41,7 @@ in from_address = "noreply@freun.dev"; from_name = "Vaultwarden"; user = "noreply@freun.dev"; - password = "$__file{/var/secrets/smtp-password}"; + password = "$__file{${secrets.smtp-password.path}}"; }; }; }; diff --git a/modules/services/hastebin.nix b/modules/services/hastebin.nix index 5335773..d419152 100644 --- a/modules/services/hastebin.nix +++ b/modules/services/hastebin.nix @@ -1,6 +1,7 @@ { lib, config, inputs, ... }: let cfg = config.services.hastebin; + secrets = config.age.secrets; fqdn = "${cfg.subdomain}.${config.networking.domain}"; in { @@ -33,7 +34,7 @@ in "jsx" ]; }; - auth_tokens_file = "/var/secrets/hastebin-tokens"; + auth_tokens_file = secrets.hastebin-tokens.path; }; modules.services.webserver = { diff --git a/modules/services/immich.nix b/modules/services/immich.nix index 09322cd..9f98dd5 100644 --- a/modules/services/immich.nix +++ b/modules/services/immich.nix @@ -1,6 +1,7 @@ { pkgs, lib, config, ... }: let cfg = config.modules.services.immich; + secrets = config.age.secrets; fqdn = "${cfg.subdomain}.${config.networking.domain}"; volumeServices = names: ( @@ -52,6 +53,13 @@ let { } services ); + + environment = { + TZ = cfg.timezone; + DB_USERNAME = "postgres"; + POSTGRES_USER = environment.DB_USERNAME; + DB_DATABASE_NAME = "immich"; + }; in { options.modules.services.immich = { @@ -59,6 +67,10 @@ in subdomain = lib.mkOption { type = lib.types.str; }; + timezone = lib.mkOption { + type = lib.types.str; + default = "Europe/Helsinki"; + }; version = lib.mkOption { type = lib.types.str; default = "latest"; @@ -97,8 +109,9 @@ in virtualisation.oci-containers.containers = { "immich_machine_learning" = { image = "ghcr.io/immich-app/immich-machine-learning:${cfg.version}"; + inherit environment; environmentFiles = [ - "/var/secrets/immich.env" + secrets.immich.path ]; volumes = [ "immich_model_cache:/cache:rw" @@ -113,9 +126,9 @@ in "immich_postgres" = { image = "registry.hub.docker.com/tensorchord/pgvecto-rs:pg14-v0.2.0"; environmentFiles = [ - "/var/secrets/immich.env" + secrets.immich.path ]; - environment = { + environment = environment // { POSTGRES_INITDB_ARGS = "--data-checksums"; }; volumes = [ @@ -131,8 +144,9 @@ in "immich_redis" = { image = "registry.hub.docker.com/library/redis:6.2-alpine"; + inherit environment; environmentFiles = [ - "/var/secrets/immich.env" + secrets.immich.path ]; log-driver = "journald"; extraOptions = [ @@ -143,8 +157,9 @@ in "immich_server" = { image = "ghcr.io/immich-app/immich-server:${cfg.version}"; + inherit environment; environmentFiles = [ - "/var/secrets/immich.env" + secrets.immich.path ]; volumes = [ "/etc/localtime:/etc/localtime:ro" diff --git a/modules/services/vaultwarden.nix b/modules/services/vaultwarden.nix index f0ffa5a..6c1adcc 100644 --- a/modules/services/vaultwarden.nix +++ b/modules/services/vaultwarden.nix @@ -1,6 +1,7 @@ { lib, config, ... }: let cfg = config.modules.services.vaultwarden; + secrets = config.age.secrets; fqdn = "${cfg.subdomain}.${config.networking.domain}"; port = config.services.vaultwarden.config.ROCKET_PORT; in @@ -23,7 +24,7 @@ in services.vaultwarden = { enable = true; dbBackend = "postgresql"; - environmentFile = "/var/secrets/vaultwarden.env"; + environmentFile = secrets.vaultwarden.path; config = { DOMAIN = "https://${fqdn}"; DATABASE_URL = "postgres://%2Fvar%2Frun%2Fpostgresql/vaultwarden"; diff --git a/modules/services/webserver.nix b/modules/services/webserver.nix index 1ce0bd3..9d84096 100644 --- a/modules/services/webserver.nix +++ b/modules/services/webserver.nix @@ -38,10 +38,6 @@ in type = lib.types.str; default = "hetzner"; }; - environmentFile = lib.mkOption { - type = lib.types.str; - default = "/var/secrets/lego"; - }; }; vHosts = lib.mkOption { type = lib.types.attrsOf types.vhost; diff --git a/modules/storage-box-mounts.nix b/modules/storage-box-mounts.nix index 0f7bf2d..bd8a467 100644 --- a/modules/storage-box-mounts.nix +++ b/modules/storage-box-mounts.nix @@ -23,12 +23,14 @@ let }; cfg = config.modules.storageBoxMounts; + secrets = config.age.secrets; + mountOptions = { uid, gid, ... }: [ "x-systemd.automount" "auto" "x-systemd.device-timeout=5s" "x-systemd.mount-timeout=5s" - "credentials=/var/secrets/storage-box-credentials" + "credentials=${secrets.storage-box-credentials.path}" ] ++ ( if (uid != null) then [ "uid=${toString uid}" ] else [ ] ) ++ ( diff --git a/secrets/gotosocial.age b/secrets/gotosocial.age new file mode 100644 index 0000000..8269d37 --- /dev/null +++ b/secrets/gotosocial.age @@ -0,0 +1,10 @@ +age-encryption.org/v1 +-> ssh-ed25519 osOCZA j4E5QbHMQm/p5X87ADaDs3UXoYvK6kNOZN548Giiuxg +SGiUy4u4wZEPV5HyREfyGnmi1pZUxxTLNvpvWbvLw6A +-> ssh-ed25519 Zmk+Rw CKL/dmRt1uK8rXcL5/jvKVt8kbOMwbtD6QEszgkXjmU +t64DTcIze3o+KTYm5xtAW7l7B7EntcCN1DsOgmJLLno +-> ssh-ed25519 PT7ffg 0X40j5NfqTW0zDuJZTzJt0A96lzOMUqwiT8ePYHYRjM +22724DDGthA6cyJhB/oquTRy1VEEw6/0YBdDov61m2k +--- Somq6fnDd8OEprRrsbpy53fxyay1XL5TIgVa6KV2MJY +Lʿ'Hj­ +#Mbu%dK0L/*I /}{IVA .'j$ \ No newline at end of file diff --git a/secrets/hastebin-tokens.age b/secrets/hastebin-tokens.age new file mode 100644 index 0000000..8dc925d Binary files /dev/null and b/secrets/hastebin-tokens.age differ diff --git a/secrets/immich.age b/secrets/immich.age new file mode 100644 index 0000000..29fb9bf Binary files /dev/null and b/secrets/immich.age differ diff --git a/secrets/secrets.nix b/secrets/secrets.nix new file mode 100644 index 0000000..874f265 --- /dev/null +++ b/secrets/secrets.nix @@ -0,0 +1,19 @@ +let + moco = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDRXRJUwX98l2Vl4bUZdyHGhLjlf1RGAA5VCa4dmEJdU"; + jokke = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP0IGUXVtUChrWHMaHoGq4USQwviHR1v1CLeDztWshZ4"; + users = [ moco jokke ]; + + apu = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICAZkIuXtpP9a9bHkBl+MJI//q3ClMqzx03Rd/Xe4rjc"; + freun-dev = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEvCSjIjipog1Xf9mPc683r5VSGSjVc8v1UZg5VrbbxM"; + radish = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIQ0fy4n3yyD64+g55eZazeI5g9FurJnlC6fRiOXbbks"; + + hosts = [ apu freun-dev radish ]; +in +{ + "gotosocial.age".publicKeys = users ++ [ freun-dev ]; + "hastebin-tokens.age".publicKeys = users ++ [ freun-dev ]; + "immich.age".publicKeys = users ++ [ freun-dev ]; + "storage-box-credentials.age".publicKeys = users ++ [ freun-dev ]; + "vaultwarden.age".publicKeys = users ++ [ freun-dev ]; + "smtp-password.age".publicKeys = users ++ [ freun-dev ]; +} diff --git a/secrets/smtp-password.age b/secrets/smtp-password.age new file mode 100644 index 0000000..973eda1 Binary files /dev/null and b/secrets/smtp-password.age differ diff --git a/secrets/storage-box-credentials.age b/secrets/storage-box-credentials.age new file mode 100644 index 0000000..694f0d9 Binary files /dev/null and b/secrets/storage-box-credentials.age differ diff --git a/secrets/vaultwarden.age b/secrets/vaultwarden.age new file mode 100644 index 0000000..36a31db Binary files /dev/null and b/secrets/vaultwarden.age differ