From 2025eb74a47c9bd50b50c2234fb095cfdaa2e76a Mon Sep 17 00:00:00 2001 From: nullishamy Date: Wed, 18 Jun 2025 21:41:53 +0100 Subject: [PATCH] feat: moar nix --- .gitignore | 2 + README.md | 24 +++ config/nix01.nix | 140 +++++++++++++ config/nix02.nix | 90 +++++++++ config/nixos.nix | 32 +++ config/services/kener-pkg.nix | 45 +++++ config/services/kener.nix | 44 ++++ config/services/sharkey-pkg.nix | 141 +++++++++++++ config/services/sharkey.nix | 246 ++++++++++++++++++++++ config/services/upsnap.nix | 43 ++++ config/tf.nix | 94 +++++++++ flake.lock | 348 +++++++++++++++++++++++++++++++- flake.nix | 88 +++++++- justfile | 15 ++ secrets/atticd.env.age | Bin 4688 -> 4908 bytes secrets/authentik.env.age | 11 + secrets/blog.dbpass.age | 12 ++ secrets/default.nix | 2 + secrets/forgejo.dbpass.age | 11 + secrets/pgadmin.password.age | 11 + secrets/secrets.nix | 13 +- secrets/sharkey.dbpass.age | Bin 0 -> 550 bytes secrets/sharkey.redispass.age | 11 + 23 files changed, 1408 insertions(+), 15 deletions(-) create mode 100644 config/nix01.nix create mode 100644 config/nix02.nix create mode 100644 config/services/kener-pkg.nix create mode 100644 config/services/kener.nix create mode 100644 config/services/sharkey-pkg.nix create mode 100644 config/services/sharkey.nix create mode 100644 config/services/upsnap.nix create mode 100644 config/tf.nix create mode 100644 justfile create mode 100644 secrets/authentik.env.age create mode 100644 secrets/blog.dbpass.age create mode 100644 secrets/forgejo.dbpass.age create mode 100644 secrets/pgadmin.password.age create mode 100644 secrets/sharkey.dbpass.age create mode 100644 secrets/sharkey.redispass.age diff --git a/.gitignore b/.gitignore index 9b42106..e532ccd 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .direnv/ +.terraform* +tf/ diff --git a/README.md b/README.md index 8ffff02..175ea1b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,27 @@ # nixlab The Nix part of my homelab, just messing around + +## boostrap +TODO: Figure out if addNetworking is required still +- Set `addNetworking` to `false` in `config/tf.nix` +- `just deploy` +- Wait for the infra to build +- Start the containers and log in to them +- Redeploy infra with `addNetworking` +- Put the `host-key.pub` into `~/.ssh/authorized_keys` on each host +- (This wil fail) `just deploy` +- Fetch the SSH keys of the hosts and put them in `secrets/secrets.nix` +- Remember to add it to `systems`! +- Rekey the secrets with `just rekey` +- `just deploy` +- Wait for the deploy +- Set the IPs properly in `flake.nix` (using the TF config as a ref) +- Reboot the nodes + +## ref +- https://nixos.wiki/wiki/Proxmox_Linux_Container +- https://github.com/ryantm/agenix +- https://registry.terraform.io/providers/Telmate/proxmox/latest/docs/resources/lxc +- https://terranix.org/documentation/flakes.html +- https://discourse.nixos.org/t/qbittorrent-headless-service-module/32397 diff --git a/config/nix01.nix b/config/nix01.nix new file mode 100644 index 0000000..3291f85 --- /dev/null +++ b/config/nix01.nix @@ -0,0 +1,140 @@ +{ modulesPath, pkgs, config, lib, ... }: + +{ + imports = [ + # Include the default lxd configuration. + "${modulesPath}/virtualisation/proxmox-lxc.nix" + # Include the container-specific autogenerated configuration. + ./lxd.nix + ./services/sharkey.nix + ]; + + networking = { + dhcpcd.enable = false; + useDHCP = false; + useHostResolvConf = false; + firewall.enable = false; + nameservers = ["192.168.1.155" "1.1.1.1"]; + }; + + environment.systemPackages = with pkgs; [ + git + curl + vim + ]; + + services.postgresql = { + enable = true; + enableTCPIP = true; + ensureDatabases = [ "authentik" "blog" "forgejo" "infisical" "sharkey" ]; + ensureUsers = [ + { + name = "authentik"; + ensureDBOwnership = true; + } + { + name = "blog"; + ensureDBOwnership = true; + } + { + name = "forgejo"; + ensureDBOwnership = true; + } + { + name = "infisical"; + ensureDBOwnership = true; + } + { + name = "sharkey"; + ensureDBOwnership = true; + } + ]; + + authentication = pkgs.lib.mkOverride 10 '' + # type database DBuser auth-method + local all all trust + # ipv4 + host all all 127.0.0.1/32 trust + # ipv6 + host all all ::1/128 trust + # LAN + host all all 192.168.0.0/16 trust + ''; + }; + + services.calibre-server = { + enable = true; + auth = { + enable = true; + userDb = "/var/lib/calibre-server/.config/calibre/server-users.sqlite"; + }; + libraries = [ + "/var/lib/calibre-server" + ]; + }; + + services.pgadmin = { + enable = true; + initialEmail = "hello@amyerskine.me"; + initialPasswordFile = config.age.secrets."pgadmin.password".path; + }; + + services.nginx.enable = true; + services.nginx.virtualHosts."pg.nix01.cluster" = { + locations."/" = { + proxyPass = "http://127.0.0.1:5050"; + proxyWebsockets = true; + }; + }; + + services.nginx.virtualHosts."sharkey.nix01.cluster" = { + locations."/" = { + proxyPass = "http://127.0.0.1:3001"; + proxyWebsockets = true; + }; + }; + + services.nginx.virtualHosts."calibre.nix01.cluster" = { + locations."/" = { + proxyPass = "http://127.0.0.1:8080"; + proxyWebsockets = true; + }; + }; + + services.sharkey = { + enable = true; + domain = "fedi.amy.mov"; + package = (pkgs.callPackage ./services/sharkey-pkg.nix {}); + + database = { + passwordFile = config.age.secrets."sharkey.dbpass".path; + }; + + redis = { + passwordFile = config.age.secrets."sharkey.redispass".path; + }; + + meilisearch = { + createLocally = false; + }; + + settings = { + id = "aidx"; + port = 3001; + + maxNoteLength = 8192; + maxFileSize = 1024 * 1024 * 1024; + proxyRemoteFiles = true; + + # at the suggestion of Sharkey maintainers, + # this allows the server to run multiple workers + # and without this (and postgres tuning), the instance runs slowly + clusterLimit = 3; + + signToActivityPubGet = true; + CheckActivityPubGetSigned = false; + }; + }; + + system.stateVersion = "24.11"; # Did you read the comment? +} diff --git a/config/nix02.nix b/config/nix02.nix new file mode 100644 index 0000000..cb033d1 --- /dev/null +++ b/config/nix02.nix @@ -0,0 +1,90 @@ +{ modulesPath, pkgs, unstable, config, ... }: + +{ + imports = [ + # Include the default lxd configuration. + "${modulesPath}/virtualisation/proxmox-lxc.nix" + # Include the container-specific autogenerated configuration. + ./lxd.nix + ]; + + networking = { + dhcpcd.enable = false; + useDHCP = false; + useHostResolvConf = false; + firewall.enable = false; + nameservers = ["192.168.1.155" "1.1.1.1"]; + }; + + environment.systemPackages = with pkgs; [ + git + curl + vim + ]; + + services.nginx = { + enable = true; + }; + + services.nginx.virtualHosts."forgejo.nix02.cluster" = { + locations."/" = { + proxyPass = "http://127.0.0.1:8312"; + proxyWebsockets = true; + }; + }; + + services.nginx.virtualHosts."forge.amy.mov" = { + locations."/" = { + proxyPass = "http://127.0.0.1:8312"; + proxyWebsockets = true; + }; + }; + + services.forgejo = { + enable = true; + package = unstable.forgejo; + settings = { + server = { + HTTP_PORT = 8312; + ROOT_URL = "https://forge.amy.mov"; + }; + }; + + database = { + createDatabase = false; + + type = "postgres"; + host = "nix01.cluster"; + name = "forgejo"; + user = "forgejo"; + passwordFile = config.age.secrets."forgejo.dbpass".path; + }; + }; + + services.authentik = { + enable = true; + environmentFile = config.age.secrets."authentik.env".path; + + nginx = { + enable = true; + enableACME = false; + host = "auth.nix02.cluster"; + }; + + createDatabase = false; + + settings = { + postgresql = { + host = "nix01.cluster"; + user = "authentik"; + password = "authentik"; + name = "authentik"; + }; + + disable_startup_analytics = true; + avatars = "initials"; + }; + }; + + system.stateVersion = "24.11"; # Did you read the comment? +} diff --git a/config/nixos.nix b/config/nixos.nix index 25997a4..dbf3562 100644 --- a/config/nixos.nix +++ b/config/nixos.nix @@ -7,6 +7,8 @@ # Include the container-specific autogenerated configuration. ./lxd.nix ./services/opengist.nix + ./services/kener.nix + #./services/upsnap.nix ]; networking = { @@ -22,6 +24,36 @@ vim ]; + # services.upsnap = { + # enable = true; + # }; + + services.kener = { + enable = true; + }; + + # Would like to use my PG DB for this but the service just doesn't + # support DBs that are hosted outside of the Nix box + services.writefreely = { + enable = true; + host = "write.amy.mov"; + + database = { + type = "sqlite3"; + }; + + admin = { + name = "amy"; + }; + + settings = { + server = { + bind = "0.0.0.0"; + port = 8123; + }; + }; + }; + services.opengist = { enable = true; config = ./opengist.yml; diff --git a/config/services/kener-pkg.nix b/config/services/kener-pkg.nix new file mode 100644 index 0000000..58c1ec8 --- /dev/null +++ b/config/services/kener-pkg.nix @@ -0,0 +1,45 @@ +{ lib, buildNpmPackage, fetchFromGitHub }: + +let + pname = "kener"; + version = "3.2.12"; +in +buildNpmPackage rec { + inherit pname version; + + src = fetchFromGitHub { + owner = "rajnandan1"; + repo = pname; + rev = "e6b5600a4726f719c2228d7d2da5a919e4bc15a3"; + hash = "sha256-UBmt7SYZ2WukJvT1TOcwVr/L8RZVpVkLamCNV/xC8L4="; + }; + + npmDepsHash = "sha256-csB6qMJt3wBQyyWrK31F0FaRck3rt0JiH/lv77f+570="; + + npmBuild = "npm run build"; + # Copy src because the main runner (hosts the API etc) calls some stuff from it + installPhase = '' + mkdir $out + + cp -R src/ $out + cp -R node_modules/ $out + cp -R build/ $out + cp -R migrations/ $out + cp -R seeds/ $out + cp -R static/ $out + + cp -R knexfile.js $out + sed -i "s@./migrations@$out/migrations@g" $out/knexfile.js + sed -i "s@./seeds@$out/seeds@g" $out/knexfile.js + + cp main.js $out + ''; + + meta = with lib; { + description = "Stunning status pages, batteries included!"; + homepage = "https://kener.ing"; + license = licenses.mit; + maintainers = with maintainers; [ nullishamy ]; + mainProgram = ""; + }; +} diff --git a/config/services/kener.nix b/config/services/kener.nix new file mode 100644 index 0000000..04ff0d0 --- /dev/null +++ b/config/services/kener.nix @@ -0,0 +1,44 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.kener; + src = builtins.fetchTarball { + url = "https://github.com/rajnandan1/kener/archive/refs/tags/3.2.12.tar.gz"; + sha256 = "sha256:0a301jz8vqi2bd93k4lyabinshvadz084jfnkzrmxqrfr7w9gqbl"; + }; +in { + options = { + services.kener = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable Kener. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.kener = + let + kener = (pkgs.callPackage ./kener-pkg.nix {}); + in { + path = [ + pkgs.nodejs + pkgs.unixtools.ping + ]; + environment = { + "DATABASE_URL" = "sqlite:///opt/kener/kener.db"; + "ORIGIN" = "https://amy.mov"; + "KENER_SECRET_KEY" = "my-super-strong-key"; + }; + name = "kener.service"; + enable = true; + script = "node ${kener}/main.js"; + description = "Kener"; + }; + }; +} diff --git a/config/services/sharkey-pkg.nix b/config/services/sharkey-pkg.nix new file mode 100644 index 0000000..0b580d3 --- /dev/null +++ b/config/services/sharkey-pkg.nix @@ -0,0 +1,141 @@ +{ + lib, + stdenv, + fetchFromGitLab, + bash, + makeWrapper, + jemalloc, + ffmpeg-headless, + python3, + pkg-config, + glib, + vips, + pnpm_9, + nodejs, + pixman, + pango, + cairo, +}: +stdenv.mkDerivation (finalAttrs: { + pname = "sharkey"; + version = "2025.4.2"; + + src = fetchFromGitLab { + domain = "activitypub.software"; + owner = "TransFem-org"; + repo = "Sharkey"; + rev = finalAttrs.version; + fetchSubmodules = true; + hash = "sha256-gCZY9d/YLNQRGVFqsK7//UDiS19Jtqa7adGliIdE+4c="; + }; + + pnpmDeps = pnpm_9.fetchDeps { + inherit (finalAttrs) src pname; + hash = "sha256-2bt/sHKGNIjKfOvZ6DCXvdJcKoOJX/ueWdLULlYK3YU="; + }; + + nativeBuildInputs = [ + pnpm_9.configHook + nodejs + makeWrapper + python3 + pkg-config + ]; + + buildInputs = [ + glib + vips + + pixman + pango + cairo + ]; + + # This environment variable is required for `node-gyp`, which is used by some native dependencies we build below. + # Without it, `node-gyp` won't know where the source code for node.js is, and will fail to download it instead. + npm_config_nodedir = nodejs; + + # Sharkey depends on some packages with native code that needs to be built. + # These aren't built by default, so we need to run their build scripts manually. + # + # The tricky thing is that not all of them required for Sharkey to "successfully" build. + # They will trick you, make you think that Sharkey works, and successfully run your databse migrations. + # And then, when your instance tries to run, it will crash with an error like: + # + # Error [ERR_INTERNAL_ASSERTION]: This is caused by either a bug in Node.js or incorrect usage of Node.js internals. + # Please open an issue with this stack trace at https://github.com/nodejs/node/issues + # + # If you see that error, IT IS LYING TO YOU. It means Sharkey added a new dependency that required native code to be built. + # Figure out what is the new dependency. You can ask in their discord, and they'll probably tell you. + # And then, build it in the `buildPhase` below. + + buildPhase = '' + runHook preBuild + + ( + cd node_modules/.pnpm/node_modules/v-code-diff + pnpm run postinstall + ) + ( + cd node_modules/.pnpm/node_modules/re2 + pnpm run rebuild + ) + ( + cd node_modules/.pnpm/node_modules/sharp + pnpm run install + ) + ( + cd node_modules/.pnpm/node_modules/canvas + pnpm run install + ) + + pnpm build + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out/Sharkey + + ln -s /var/lib/sharkey $out/Sharkey/files + ln -s /run/sharkey $out/Sharkey/.config + cp -r * $out/Sharkey + + makeWrapper ${lib.getExe pnpm_9} $out/bin/sharkey \ + --chdir $out/Sharkey \ + --prefix PATH : ${ + lib.makeBinPath [ + bash + pnpm_9 + nodejs + ] + } \ + --prefix LD_LIBRARY_PATH : ${ + lib.makeLibraryPath [ + jemalloc + ffmpeg-headless + stdenv.cc.cc.lib + ] + } + + runHook postInstall + ''; + + passthru = { + inherit (finalAttrs) pnpmDeps; + }; + + meta = { + description = "🌎 A Sharkish microblogging platform 🚀"; + homepage = "https://joinsharkey.org"; + license = lib.licenses.gpl3Only; + maintainers = with lib.maintainers; [ sodiboo ]; + platforms = [ + "x86_64-linux" + "aarch64-linux" + ]; + mainProgram = "sharkey"; + }; +}) diff --git a/config/services/sharkey.nix b/config/services/sharkey.nix new file mode 100644 index 0000000..af3bec0 --- /dev/null +++ b/config/services/sharkey.nix @@ -0,0 +1,246 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.services.sharkey; + + createDB = cfg.database.host == "127.0.0.1" && cfg.database.createLocally; + createRedis = cfg.redis.host == "127.0.0.1" && cfg.redis.createLocally; + createMeili = cfg.meilisearch.host == "127.0.0.1" && cfg.meilisearch.createLocally; + + createMeiliKey = cfg.meilisearch.key == lib.fakeSha256; + + settingsFormat = pkgs.formats.yaml { }; + configFile = settingsFormat.generate "sharkey-config.yml" cfg.settings; +in +{ + options = { + services.sharkey = with lib; { + enable = mkEnableOption "sharkey"; + + domain = mkOption { + type = lib.types.str; + example = "fedi.amy.mov"; + }; + + package = lib.mkOption { + type = lib.types.package; + defaultText = lib.literalExpression "pkgs.sharkey"; + description = "Sharkey package to use."; + }; + + database = { + createLocally = mkOption { + type = lib.types.bool; + default = true; + }; + + host = mkOption { + type = lib.types.str; + default = "127.0.0.1"; + }; + + port = mkOption { + type = lib.types.port; + default = 5432; + }; + + name = mkOption { + type = lib.types.str; + default = "sharkey"; + }; + + passwordFile = mkOption { + description = '' + Path to a file containing the password for the database user. + + This file must be readable by the `sharkey` user. + + If creating a database locally, it must also be readable by the `postgres` user. + ''; + type = lib.types.path; + example = "/run/secrets/sharkey-db-password"; + }; + }; + + redis = { + createLocally = mkOption { + type = lib.types.bool; + default = true; + }; + + host = mkOption { + type = lib.types.str; + default = "127.0.0.1"; + }; + + port = mkOption { + type = lib.types.port; + default = 6379; + }; + + passwordFile = mkOption { + description = '' + Path to a file containing the password for the redis server. + + This file must be readable by the `sharkey` user. + ''; + type = lib.types.path; + example = "/run/secrets/sharkey-redis-password"; + }; + }; + + meilisearch = { + createLocally = mkOption { + type = lib.types.bool; + default = true; + }; + + host = mkOption { + type = lib.types.str; + default = "127.0.0.1"; + }; + + port = mkOption { + type = lib.types.port; + default = 7700; + }; + + index = mkOption { + type = lib.types.str; + default = replaceStrings [ "." ] [ "_" ] cfg.domain; + }; + + key = mkOption { + type = lib.types.str; + default = "$MEILI_MASTER_KEY"; + }; + }; + + settings = mkOption { + type = settingsFormat.type; + default = { }; + description = '' + Configuration for Sharkey, see + + for supported settings. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + documentation.enable = false; + + assertions = [ + { + assertion = createMeiliKey -> createMeili; + message = "services.sharkey.meilisearch.key is required to be set when connecting to a remote meilisearch instance"; + } + ]; + + services.sharkey.settings = { + url = "https://${cfg.domain}/"; + db.host = cfg.database.host; + db.port = cfg.database.port; + db.db = cfg.database.name; + db.user = cfg.database.name; + db.pass = "$SHARKEY_DB_PASSWORD"; + redis.host = cfg.redis.host; + redis.port = cfg.redis.port; + redis.pass = "$SHARKEY_REDIS_PASSWORD"; + meilisearch.host = cfg.meilisearch.host; + meilisearch.port = cfg.meilisearch.port; + meilisearch.apiKey = cfg.meilisearch.key; + meilisearch.index = cfg.meilisearch.index; + meilisearch.ssl = !createMeili; + meilisearch.scope = "global"; + }; + + environment.etc."sharkey.yml".source = configFile; + + systemd.services.sharkey = { + after = + [ "network-online.target" ] + ++ lib.optionals createDB [ "postgresql.service" ] + ++ lib.optionals createRedis [ "redis-sharkey.service" ] + ++ lib.optionals createMeili [ "meilisearch.service" ]; + wantedBy = [ "multi-user.target" ]; + + preStart = '' + SHARKEY_DB_PASSWORD="$(cat ${lib.escapeShellArg cfg.database.passwordFile})" \ + SHARKEY_REDIS_PASSWORD="$(cat ${lib.escapeShellArg cfg.redis.passwordFile})" \ + ${pkgs.envsubst}/bin/envsubst -i "${configFile}" > $MISSKEY_CONFIG_YML + ''; + + environment.MISSKEY_CONFIG_YML = "/run/sharkey/config.yml"; + environment.NODE_ENV = "production"; + + serviceConfig = { + EnvironmentFile = lib.mkIf ( + config.services.meilisearch.masterKeyEnvironmentFile != null + ) config.services.meilisearch.masterKeyEnvironmentFile; + Type = "simple"; + User = "sharkey"; + + StateDirectory = "sharkey"; + StateDirectoryMode = "0700"; + RuntimeDirectory = "sharkey"; + RuntimeDirectoryMode = "0700"; + ExecStart = "${cfg.package}/bin/sharkey migrateandstart"; + TimeoutSec = 60; + Restart = "always"; + + StandardOutput = "journal"; + StandardError = "journal"; + SyslogIdentifier = "sharkey"; + }; + }; + + services.postgresql = lib.mkIf createDB { + enable = true; + settings.port = cfg.database.port; + ensureUsers = [ + { + name = cfg.database.name; + ensureDBOwnership = true; + } + ]; + ensureDatabases = [ cfg.database.name ]; + }; + + services.redis = lib.mkIf createRedis { + servers.sharkey = { + enable = true; + user = "sharkey"; + bind = "127.0.0.1"; + port = cfg.redis.port; + requirePassFile = cfg.redis.passwordFile; + }; + }; + + systemd.services.postgresql.postStart = lib.mkIf createDB '' + $PSQL -tAc "ALTER ROLE ${cfg.database.name} WITH ENCRYPTED PASSWORD '$(printf "%s" $(cat ${cfg.database.passwordFile} | tr -d "\n"))';" + ''; + + services.meilisearch = lib.mkIf createMeili { + enable = true; + listenAddress = "127.0.0.1"; + listenPort = cfg.meilisearch.port; + environment = "production"; + }; + + users.users.sharkey = { + group = "sharkey"; + isSystemUser = true; + home = "/run/sharkey"; + packages = [ cfg.package ]; + }; + + users.groups.sharkey = { }; + }; + meta.maintainers = with lib.maintainers; [ sodiboo ]; +} diff --git a/config/services/upsnap.nix b/config/services/upsnap.nix new file mode 100644 index 0000000..95ac0fe --- /dev/null +++ b/config/services/upsnap.nix @@ -0,0 +1,43 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.upsnap; + src = pkgs.fetchzip { + url = "https://github.com/seriousm4x/UpSnap/releases/download/5.0.4/UpSnap_5.0.4_linux_amd64.zip"; + sha256 = "sha256:1qlav9if6f2c50rzakyilxgzmq2c5bzcs6lx1w7sffxhl440nxhs"; + }; +in { + options = { + services.upsnap = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable UpSnap. + ''; + }; + + bind = mkOption { + type = types.str; + default = "0.0.0.0:8090"; + description = '' + The bind address/port + ''; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.upsnap = { + environment = { + "HOME" = "/opt/upsnap"; + }; + name = "upsnap.service"; + enable = true; + script = "${src} serve --http ${cfg.bind}"; + description = "UpSnap"; + }; + }; +} diff --git a/config/tf.nix b/config/tf.nix new file mode 100644 index 0000000..207c24b --- /dev/null +++ b/config/tf.nix @@ -0,0 +1,94 @@ +{ lib, ... }: +let + # Set to false to boostrap the containers + addNetworking = true; + + pmHost = "https://192.168.1.100"; + + creds = { + ctPassword = "password"; + }; + + sshKeys = '' + ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDTbclOyOwIAPgVE/v5lIuf0P+Tq/Qkw3+GFa4YuRaCC amy@nixon + ''; + + templates = { + nixos = "nas-main:vztmpl/nixos-system-x86_64-linux.tar.xz"; + }; +in { + terraform = { + required_providers = { + proxmox = { + source = "telmate/proxmox"; + version = "3.0.2-rc01"; + }; + }; + }; + + provider.proxmox = { + pm_api_url = "${pmHost}:8006/api2/json"; + pm_tls_insecure = true; + + pm_user = "root@pam"; + pm_password = ""; + }; + + resource.proxmox_lxc = { + nix01 = { + target_node = "strawberry"; + hostname = "nix01"; + ostemplate = templates.nixos; + password = creds.ctPassword; + unprivileged = true; + swap = 1024; + ostype = "nixos"; + cmode = "console"; + + rootfs = { + storage = "local-lvm"; + size = "16G"; + }; + + network = lib.mkIf addNetworking { + name = "eth0"; + bridge = "vmbr0"; + ip = "192.168.1.220/32"; + gw = "192.168.1.1"; + firewall = false; + }; + + features = { + nesting = true; + }; + }; + + nix02 = { + target_node = "strawberry"; + hostname = "nix02"; + ostemplate = templates.nixos; + password = creds.ctPassword; + unprivileged = true; + swap = 1024; + ostype = "nixos"; + cmode = "console"; + + rootfs = { + storage = "local-lvm"; + size = "16G"; + }; + + network = lib.mkIf addNetworking { + name = "eth0"; + bridge = "vmbr0"; + ip = "192.168.1.221/32"; + gw = "192.168.1.1"; + firewall = false; + }; + + features = { + nesting = true; + }; + }; + }; +} diff --git a/flake.lock b/flake.lock index 9fdbea0..ee29d07 100644 --- a/flake.lock +++ b/flake.lock @@ -21,6 +21,50 @@ "type": "github" } }, + "authentik-nix": { + "inputs": { + "authentik-src": "authentik-src", + "flake-compat": "flake-compat", + "flake-parts": "flake-parts", + "flake-utils": "flake-utils", + "napalm": "napalm", + "nixpkgs": "nixpkgs_2", + "pyproject-build-systems": "pyproject-build-systems", + "pyproject-nix": "pyproject-nix", + "systems": "systems_2", + "uv2nix": "uv2nix" + }, + "locked": { + "lastModified": 1749129962, + "narHash": "sha256-gc1l5z5dWw9a9DWsrp0ZiD+SSMsNpEwMEiRi8K5sh5c=", + "owner": "nix-community", + "repo": "authentik-nix", + "rev": "271a38f7c4e2551f0674b894e2adf7cd1ddb8168", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "authentik-nix", + "type": "github" + } + }, + "authentik-src": { + "flake": false, + "locked": { + "lastModified": 1749043670, + "narHash": "sha256-gwHngqb23U8By7jhxFWQZOXy+vPQApJSkvr4gHI5ifQ=", + "owner": "goauthentik", + "repo": "authentik", + "rev": "bda30c5ad5838fea36dc0a06f8580cca437f0fc0", + "type": "github" + }, + "original": { + "owner": "goauthentik", + "ref": "version/2025.4.2", + "repo": "authentik", + "type": "github" + } + }, "darwin": { "inputs": { "nixpkgs": [ @@ -45,8 +89,8 @@ }, "deploy-rs": { "inputs": { - "flake-compat": "flake-compat", - "nixpkgs": "nixpkgs_2", + "flake-compat": "flake-compat_2", + "nixpkgs": "nixpkgs_3", "utils": "utils" }, "locked": { @@ -64,6 +108,22 @@ } }, "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1747046372, + "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { "flake": false, "locked": { "lastModified": 1696426674, @@ -83,6 +143,24 @@ "inputs": { "nixpkgs-lib": "nixpkgs-lib" }, + "locked": { + "lastModified": 1748821116, + "narHash": "sha256-F82+gS044J1APL0n4hH50GYdPRv/5JWm34oCJYmVKdE=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "49f0870db23e8c1ca0b5259734a02cd9e1e371a1", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_2" + }, "locked": { "lastModified": 1743550720, "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", @@ -97,6 +175,48 @@ "type": "github" } }, + "flake-parts_3": { + "inputs": { + "nixpkgs-lib": [ + "terranix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1736143030, + "narHash": "sha256-+hu54pAoLDEZT9pjHlqL9DNzWz0NbUn8NEAHP7PQPzU=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "b905f6fc23a9051a6e1b741e1438dbfc0634c6de", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": [ + "authentik-nix", + "systems" + ] + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "home-manager": { "inputs": { "nixpkgs": [ @@ -118,6 +238,32 @@ "type": "github" } }, + "napalm": { + "inputs": { + "flake-utils": [ + "authentik-nix", + "flake-utils" + ], + "nixpkgs": [ + "authentik-nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1725806412, + "narHash": "sha256-lGZjkjds0p924QEhm/r0BhAxbHBJE1xMOldB/HmQH04=", + "owner": "willibutz", + "repo": "napalm", + "rev": "b492440d9e64ae20736d3bec5c7715ffcbde83f5", + "type": "github" + }, + "original": { + "owner": "willibutz", + "ref": "avoid-foldl-stack-overflow", + "repo": "napalm", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1703013332, @@ -135,6 +281,21 @@ } }, "nixpkgs-lib": { + "locked": { + "lastModified": 1748740939, + "narHash": "sha256-rQaysilft1aVMwF14xIdGS3sj1yHlI6oKQNBRTF40cc=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "656a64127e9d791a334452c6b6606d17539476e2", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs-lib_2": { "locked": { "lastModified": 1743296961, "narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", @@ -149,7 +310,39 @@ "type": "github" } }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1749794982, + "narHash": "sha256-Kh9K4taXbVuaLC0IL+9HcfvxsSUx8dPB5s5weJcc9pc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ee930f9755f58096ac6e8ca94a1887e0534e2d81", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs_2": { + "locked": { + "lastModified": 1748929857, + "narHash": "sha256-lcZQ8RhsmhsK8u7LIFsJhsLh/pzR9yZ8yqpTzyGdj+Q=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c2a03962b8e24e669fb37b7df10e7c79531ff1a4", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { "locked": { "lastModified": 1702272962, "narHash": "sha256-D+zHwkwPc6oYQ4G3A1HuadopqRwUY/JkMwHz1YF7j4Q=", @@ -165,7 +358,7 @@ "type": "github" } }, - "nixpkgs_3": { + "nixpkgs_4": { "locked": { "lastModified": 1743583204, "narHash": "sha256-F7n4+KOIfWrwoQjXrL2wD9RhFYLs2/GGe/MQY1sSdlE=", @@ -181,12 +374,80 @@ "type": "github" } }, + "nixpkgs_5": { + "locked": { + "lastModified": 1728956102, + "narHash": "sha256-J8zo+UYNjHATsxn2/ROl8iaji2RgLm+sG7b3VcD36YM=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "3d85bae2431f20ab1ac5cf14d03d314dffe629af", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "type": "github" + } + }, + "pyproject-build-systems": { + "inputs": { + "nixpkgs": [ + "authentik-nix", + "nixpkgs" + ], + "pyproject-nix": [ + "authentik-nix", + "pyproject-nix" + ], + "uv2nix": [ + "authentik-nix", + "uv2nix" + ] + }, + "locked": { + "lastModified": 1748562898, + "narHash": "sha256-STk4QklrGpM3gliPKNJdBLSQvIrqRuwHI/rnYb/5rh8=", + "owner": "pyproject-nix", + "repo": "build-system-pkgs", + "rev": "33bd58351957bb52dd1700ea7eeefe34de06a892", + "type": "github" + }, + "original": { + "owner": "pyproject-nix", + "repo": "build-system-pkgs", + "type": "github" + } + }, + "pyproject-nix": { + "inputs": { + "nixpkgs": [ + "authentik-nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1746540146, + "narHash": "sha256-QxdHGNpbicIrw5t6U3x+ZxeY/7IEJ6lYbvsjXmcxFIM=", + "owner": "pyproject-nix", + "repo": "pyproject.nix", + "rev": "e09c10c24ebb955125fda449939bfba664c467fd", + "type": "github" + }, + "original": { + "owner": "pyproject-nix", + "repo": "pyproject.nix", + "type": "github" + } + }, "root": { "inputs": { "agenix": "agenix", + "authentik-nix": "authentik-nix", "deploy-rs": "deploy-rs", - "flake-parts": "flake-parts", - "nixpkgs": "nixpkgs_3" + "flake-parts": "flake-parts_2", + "nixpkgs": "nixpkgs_4", + "nixpkgs-unstable": "nixpkgs-unstable", + "terranix": "terranix" } }, "systems": { @@ -205,6 +466,21 @@ } }, "systems_2": { + "locked": { + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "owner": "nix-systems", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-linux", + "type": "github" + } + }, + "systems_3": { "locked": { "lastModified": 1681028828, "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", @@ -219,9 +495,44 @@ "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" + } + }, + "terranix": { + "inputs": { + "flake-parts": "flake-parts_3", + "nixpkgs": "nixpkgs_5", + "systems": "systems_4" + }, + "locked": { + "lastModified": 1749381683, + "narHash": "sha256-16z7tXZch12SAd3d8tbAiEOamyq3zFbw1oUq/ipmTkM=", + "owner": "terranix", + "repo": "terranix", + "rev": "9d2370279d595be9e728b68d29ff0b546d88e619", + "type": "github" + }, + "original": { + "owner": "terranix", + "repo": "terranix", + "type": "github" + } + }, "utils": { "inputs": { - "systems": "systems_2" + "systems": "systems_3" }, "locked": { "lastModified": 1701680307, @@ -236,6 +547,31 @@ "repo": "flake-utils", "type": "github" } + }, + "uv2nix": { + "inputs": { + "nixpkgs": [ + "authentik-nix", + "nixpkgs" + ], + "pyproject-nix": [ + "authentik-nix", + "pyproject-nix" + ] + }, + "locked": { + "lastModified": 1748916602, + "narHash": "sha256-GiwjjmPIISDFD0uQ1DqQ+/38hZ+2z1lTKVj/TkKaWwQ=", + "owner": "pyproject-nix", + "repo": "uv2nix", + "rev": "a4dd471de62b27928191908f57bfcd702ec2bfc9", + "type": "github" + }, + "original": { + "owner": "pyproject-nix", + "repo": "uv2nix", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 379d4d4..073f2c1 100644 --- a/flake.nix +++ b/flake.nix @@ -4,38 +4,110 @@ inputs = { flake-parts.url = "github:hercules-ci/flake-parts"; + authentik-nix.url = "github:nix-community/authentik-nix"; + terranix.url = "github:terranix/terranix"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + # Later version of nixpkgs for forgejo + nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; + deploy-rs.url = "github:serokell/deploy-rs"; agenix.url = "github:ryantm/agenix"; }; outputs = inputs@{ flake-parts, self, ... }: + let + sshUser = "root"; + activateConfig = inputs.deploy-rs.lib.x86_64-linux.activate.nixos; + + baseModules = [ + ./secrets + inputs.agenix.nixosModules.default + { + _module.args.unstable = import inputs.nixpkgs-unstable { + system = "x86_64-linux"; + config.allowUnfree = true; + }; + } + ]; + + hosts = { + nix01 = { + location = "nix01.cluster"; + }; + + nix02 = { + location = "nix02.cluster"; + }; + }; + in flake-parts.lib.mkFlake { inherit inputs; } { - systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin" ]; + systems = [ "x86_64-linux" ]; perSystem = { config, self', inputs', pkgs, system, ... }: { + _module.args.pkgs = import inputs.nixpkgs { + inherit system; + config.allowUnfree = true; + }; + devShells.default = pkgs.mkShell { packages = with pkgs; [ + terraform deploy-rs + just inputs'.agenix.packages.default ]; }; + + packages.default = inputs.terranix.lib.terranixConfiguration { + inherit system; + modules = [ ./config/tf.nix ]; + }; }; flake = { nixosConfigurations.nixos = inputs.nixpkgs.lib.nixosSystem { system = "x86_64-linux"; - modules = [ + modules = baseModules ++ [ ./config/nixos.nix - ./secrets - inputs.agenix.nixosModules.default ]; }; - deploy.nodes.nixos = { - hostname = "nixos.cluster"; + # deploy.nodes.nixos = { + # hostname = "nixos.cluster"; + # profiles.system = { + # sshUser = "root"; + # path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.nixos; + # }; + # }; + + nixosConfigurations.nix01 = inputs.nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = baseModules ++ [ + ./config/nix01.nix + ]; + }; + + deploy.nodes.nix01 = { + hostname = hosts.nix01.location; profiles.system = { - sshUser = "root"; - path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.nixos; + inherit sshUser; + path = activateConfig self.nixosConfigurations.nix01; + }; + }; + + nixosConfigurations.nix02 = inputs.nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = baseModules ++ [ + ./config/nix02.nix + inputs.authentik-nix.nixosModules.default + ]; + }; + + deploy.nodes.nix02 = { + hostname = hosts.nix02.location; + profiles.system = { + inherit sshUser; + path = activateConfig self.nixosConfigurations.nix02; }; }; diff --git a/justfile b/justfile new file mode 100644 index 0000000..131c956 --- /dev/null +++ b/justfile @@ -0,0 +1,15 @@ +[private] +default: + @just --list + +# Deploy the infrastructure through Terraform +infra: + nix build -o tf/homelab.tf.json && cd tf && terraform apply + +# Deploy the systems through deploy-rs +deploy: + ssh-add host-key; deploy --auto-rollback false --magic-rollback false + +# Rekey all of the secrets +rekey: + cd secrets && agenix -r -i ../host-key diff --git a/secrets/atticd.env.age b/secrets/atticd.env.age index bdf798f24bf51db92a4f606b05919def92dc6824..dd857c24122cba3a5864a9d650a44336a92b89a9 100644 GIT binary patch literal 4908 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 T*C(rWcUO3Zs+=^}I4unTd09L^ literal 4688 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 igz8>AuUEKk|J>$9? ssh-ed25519 IYaO9g m8IFAIsugPKr+aH/NKMEuEaUKxgsOEkglfVU+LeCkHE +UmtFqaY5jLy0Vw/mrfGVADj1RFCCdLHE4g1t8SXjiR4 +-> ssh-ed25519 Xqrm3g ZemtqeCHXBipTzFF8Wi6bYMQhOtUPa7cmFDea9RFB2Q +5/ZkLwrYpRyGMb/iQ3rOzZgCfod01lk5s+QgSajESq8 +-> ssh-ed25519 FkAUOA BdMn4hxvWNOvSM5wRhsDtKEFrOOJoqHEF659cC6pO1c +9Txf5IOCDLIVR6aaR29EXfXF505GBzYJv79c2aSad6w +-> ssh-ed25519 G48T3w uV889WAiFjGtIrdqqf05C7Coy+0ZaaeGd0PMCCzfa1U +K32JwPfl2pTNhHZpWbbwD0ESdQhy4VuVG2R+2uy48Qs +--- L4+z0lU8ww3YDkHUpR7zCMLfQMLzpW8VLl22u2yHtTE +KC7D%sAQhDZצ]p]7ks]Fg@Za+?}`fN6;by'ؽ0and[o3W4kPз_Lu 2,#{Y;G7H͑48`Heg;!/Ng` ItY=pQvT~ ", $  j6݆e_}=ۂ@kjխ#|-l1qB \ No newline at end of file diff --git a/secrets/blog.dbpass.age b/secrets/blog.dbpass.age new file mode 100644 index 0000000..e13b168 --- /dev/null +++ b/secrets/blog.dbpass.age @@ -0,0 +1,12 @@ +age-encryption.org/v1 +-> ssh-ed25519 IYaO9g ddDuW7b6yGdgv2TWdNWtn/9cA7Onw7NhnmAqk217jWk +kEZ6a9fr2ujIjFrUmpcrPkOSHiD76r8XoqQ+STYCZxg +-> ssh-ed25519 Xqrm3g 8IHpKy90zF1jGTJ8GpN5pzJvJ53sGWO94ze3sI5wDVw +wNlEOKy4z8f9Fj+/dyfe/gw4csMokoCIGmGGhvZTTXc +-> ssh-ed25519 FkAUOA QRc7iYIMYP/wFDOeswkIoVY9ybFO21GJTX5f0ddAZR0 +W/ZCrz/Ce17zZRqKcych5fxJQDB+ShLCYGFAWBHgrJs +-> ssh-ed25519 G48T3w 1EUU7Vjhf/i8b9oxfg9IhQcu6Wolto74yK/6TvbLZ3g +LQsvfwD1Urxo/wdUkt0QktWEEh0X9E5htHLusqdZRUg +--- HEFxRiVTg2950mW0Gjf8wuzpMo7sa72gn3w92fhbBv4 +qE;'Q +GAVi"pbV͵ \ No newline at end of file diff --git a/secrets/default.nix b/secrets/default.nix index c716f07..e091acc 100644 --- a/secrets/default.nix +++ b/secrets/default.nix @@ -4,6 +4,8 @@ fileName: _: lib.nameValuePair (lib.removeSuffix ".age" fileName) { file = ./. + "/${fileName}"; + # FIXME: Don't do this bruh + mode = "0644"; } ) (import ./secrets.nix); } diff --git a/secrets/forgejo.dbpass.age b/secrets/forgejo.dbpass.age new file mode 100644 index 0000000..f92e244 --- /dev/null +++ b/secrets/forgejo.dbpass.age @@ -0,0 +1,11 @@ +age-encryption.org/v1 +-> ssh-ed25519 IYaO9g VGA0gLwtQGiFgmgEf3tjwTgHLgGEi1RUDmDRLTnIFHY +p74Eblp5zp+6PQNxEPeAdfEYjIWCJptatCJjiqGzXTw +-> ssh-ed25519 Xqrm3g tCFqDPviklsnX5sM1k6aZTTEYXsMRCGE/fPR9Pvy0D0 +EN3zvXgiR2I2gsoJHrf4Ws0e0APrIL4abJpTxmCU0QY +-> ssh-ed25519 FkAUOA v78yauukg/kqKxwyV7OSjrK6cTYsR/WMfrmqX2To50Q +JBBrbiE1OcrU1ccc2dcR075/smE4S34fmEMed8dxhRw +-> ssh-ed25519 G48T3w MJ/fDTqSKaiQayZMYxaIOaQimPMEzsjxHXEYUKB5VBE +x7/Tc8vC5s14t5AAsZBI74h9ylqZWgARDof8tBwkxfE +--- X2s9FwwDdkcRWFMNLiv1JX/BE8RcPZGP86vh+PdpdtE + S=ݡxU]:FÐhD!/7 \ No newline at end of file diff --git a/secrets/pgadmin.password.age b/secrets/pgadmin.password.age new file mode 100644 index 0000000..5d5055d --- /dev/null +++ b/secrets/pgadmin.password.age @@ -0,0 +1,11 @@ +age-encryption.org/v1 +-> ssh-ed25519 IYaO9g MOUCzOR71o8NIie8OHb738/OQ63ztsQm+sJktwTRHUY +lFIByNCGmCE2PWOp2PZE/hxFw4xkn9yUM50gwc2ut68 +-> ssh-ed25519 Xqrm3g IwwSBGM8ua3DqaQN+Wbnf3OmysOfLGJ7TOuNJZYNT3g +kxZmpD/qBlRvJocKxJdwmS5xDTcqDh4n8OuioR+hKtc +-> ssh-ed25519 FkAUOA Uu9awt3H4XnIKzJQZvgJDdqrY6KrCMWJ5QPc25N5gQw +bdXLLhlC6I3QtDcRPXY1gKUhHKePpeQaSWqO2I5CTzg +-> ssh-ed25519 G48T3w ScMxEKkuhSvubQpJCnhr3UdMBl+aF20Bejx3tiBB+lg +DZaY3phejHvYxGrZdE6VnLWrQG/h9Vxm9587SuoEZcE +--- 8B25N9XV5c5T0lLQhUYLs7VV0Zi9Jn1VE8cEGAYyKPs +pxMݬ呹m}Omm5 \ No newline at end of file diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 8dc8c74..03b4a11 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -1,10 +1,21 @@ +# Used by the agenix cli and our module to generate all of the secret entries into the agenix module (see ./default.nix) let + # host-key.pub amy = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDTbclOyOwIAPgVE/v5lIuf0P+Tq/Qkw3+GFa4YuRaCC amy@nixon"; users = [ amy ]; + # /etc/ssh/ssh_host_ed25519_key.pub on each host nixos = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILMAy1iKOrL2yBCWljLnuwo29G5plDblI41jJ4Woy1el root@nixos"; - systems = [ nixos ]; + nix01 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBQfwok81BymeM9zW8D/LPZxRX6HGLkeTi1hS7GjPoZF root@nix01"; + nix02 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGFJBDr16y8BAhtLfbc2WYJLwtgrxEyrpJx0zJpHPn/Z root@nix02"; + systems = [ nixos nix01 nix02 ]; in { "atticd.env.age".publicKeys = users ++ systems; + "blog.dbpass.age".publicKeys = users ++ systems; + "pgadmin.password.age".publicKeys = users ++ systems; + "sharkey.dbpass.age".publicKeys = users ++ systems; + "sharkey.redispass.age".publicKeys = users ++ systems; + "authentik.env.age".publicKeys = users ++ systems; + "forgejo.dbpass.age".publicKeys = users ++ systems; } diff --git a/secrets/sharkey.dbpass.age b/secrets/sharkey.dbpass.age new file mode 100644 index 0000000000000000000000000000000000000000..6ecf913ae3854a6e3fcf685114df0b766d81f9c4 GIT binary patch literal 550 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCUlj7;>mOjoD~ax%F5r$jtOli7YYkDJcsnb8-#JkF<2Gvfwg|3QY@j3rH-F3`_M2 z4)={R4h;+_PjarvC`>kVFLw?$2+2zfFe&l!PDZyaqOd5}I9;K#%+fU3%_T3<$fMH9 zG%C#`)6_qxG~dLnFexm}+`BBwH8m?U&(N>J-GnRBN#D~TC_OAQ(J!LP!!;yO+c8T& z#VEulDlb37Khw}GC(Jv@SUae~q8Qyaw`|8ye@BHpkEHa(v@nmdL=RI#!%#PmFvl#{ zWN#BQ6Mer5*R+ZZeK#NH5@%;$qhhY~tbig%*Cdy~Dw7bW3U|w@Qti;vbjS1}*RTk` z^qiv5kSLR?@;q-J({yy(+)XS(jLQ`YliVttT#HjHy|e=?jhu|~^Q*iHLn;its>*_b zjI+JVk|GLyg9}~D!;`tZ{L(6OEDZ9JqudHIeS9mzJu5xJyj`*qo!z5+LwvFgjLKZh zQmQPAT@1K%b#)cY!W_+f^0Qr>!d*)$%Yq{divukp&CPwZ4U>b)3{3p8gzer=BL-Otd_`VJ-k?l(qi= literal 0 HcmV?d00001 diff --git a/secrets/sharkey.redispass.age b/secrets/sharkey.redispass.age new file mode 100644 index 0000000..61cfac7 --- /dev/null +++ b/secrets/sharkey.redispass.age @@ -0,0 +1,11 @@ +age-encryption.org/v1 +-> ssh-ed25519 IYaO9g DItojUGo0JgjIqrK08qOAHEPQJyi1O1nxrPlgy/AP1E +mCBsazT0fmMkZS0IPAwED+T9HKTe3tKyQ1Za/aJIgH8 +-> ssh-ed25519 Xqrm3g SElTQ//ZPGb3WcAl8eAlJ15GBFWNdcsb3YQIb70OxlU +sZ2t9r5/D31qnAsrB/L5wktCpqioX2wXqbVxXfhSKWQ +-> ssh-ed25519 FkAUOA pt/3qcltuba+E+z82uhY7jvV28wmrKv49kiTIVYcn3o +B2PoSaa8WTGFNk6R0tq6JXXRQQa3MthhRZtWDfS1MYs +-> ssh-ed25519 G48T3w Zn7f2iF40UtqNyIp+mR/uzK3Gie0ei7EnYqlk83P/08 +eefHjO7mEHG6XmX0iN+vVtMHUe1F25p4Revh6Ii8SUY +--- fU40EtRSgZ9IrSbs8CytvsbTaTWh30xoKsMHmMkUWsE +K=mv>+e1n&@cqI!#9Tq; \ No newline at end of file