diff --git a/.agent/rules/bos55-nix-style.md b/.agent/rules/bos55-nix-style.md deleted file mode 100644 index 9ea05b3..0000000 --- a/.agent/rules/bos55-nix-style.md +++ /dev/null @@ -1,39 +0,0 @@ -# Bos55 NixOS Configuration Style Guide - -Follow these rules when modifying or extending the Bos55 NixOS configuration. - -## 1. Network & IP Management -- **Local Ownership**: Define host IP addresses only within their respective host configuration files (e.g., `hosts/BinaryCache/default.nix`). -- **Dynamic Discovery**: Do NOT use global IP mapping modules. Instead, use inter-host evaluation to resolve IPs and ports at build time: - ```nix - # In another host's config - let - bcConfig = inputs.self.nixosConfigurations.BinaryCache.config; - bcIp = (pkgs.lib.head bcConfig.networking.interfaces.ens18.ipv4.addresses).address; - in "http://${bcIp}:8080" - ``` - -## 2. Modular Service Design -- **Encapsulation**: Services must be self-contained. Options like `openFirewall`, `port`, and `enableRemoteBuilder` should live in the service module (`modules/services//default.nix`). -- **Firewall Responsibility**: The service module is responsible for opening firewall ports (e.g., TCP 8080, SSH 22) based on its own options. Do not open ports manually in host files if the service provides an option. -- **Remote Builders**: If a service like Attic supports remote building, include the `builder` user, trusted-users, and SSH configuration within that module's options. - -## 3. Container Networking -- **Discovery by Name**: Host services should connect to their companion containers (e.g., PostgreSQL) using the container name rather than `localhost` or bridge IPs. -- **Host Resolution**: Use `networking.extraHosts` in the service module to map the container name to `127.0.0.1` on the host for seamless traffic routing. - -## 4. Secrets Management (sops-nix) -- **Centralized Config**: Fleet-wide `sops-nix` settings (like `defaultSopsFile` and `age.keyFile`) must live in `modules/common/default.nix`. -- **No Hardcoded Paths**: Always use `config.sops.secrets."path/to/secret".path` to reference credentials. - -## 5. DNS & DNS Zone Files -- **Serial Increment**: Every change to a Bind9 zone file (e.g., `db.depeuter.dev`) MUST increment the `Serial` number in the SOA record. -- **Specific Domains**: Prefer a single, well-defined domain (e.g., `nix-cache.depeuter.dev`) over multiple aliases or magic values. - -## 6. CI/CD Robustness -- **IP-Based Login**: When CI runners (Gitea Actions) need to interact with internal services, use direct IP addresses (e.g., `192.168.0.25`) for login/auth to bypass potential DNS resolution issues in the runner environment. - -## 8. Git Workflow & Commits -- **Atomic Commits**: Each commit should represent a single logical change and be easily revertible. Split docs, metadata, and core code changes into separate commits. -- **Conventional Commits**: Use conventional commit messages (e.g., `feat:`, `fix:`, `docs:`, `refactor:`, `ci:`, `meta:`). -- **Branching**: Always work in feature branches and push to origin to create pull requests. diff --git a/.agent/skills/bos55-nix-config/SKILL.md b/.agent/skills/bos55-nix-config/SKILL.md deleted file mode 100644 index cf364dd..0000000 --- a/.agent/skills/bos55-nix-config/SKILL.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -name: bos55-nix-config -description: Best practices and codestyle for the Bos55 NixOS configuration project. ---- - -# Bos55 NixOS Configuration Skill - -This skill provides the core principles and implementation patterns for the Bos55 NixOS project. Use this skill when adding new hosts, services, or networking rules. - -## Core Principles - -### 1. Minimal Hardcoding -- **Host IPs**: Always define IPv4/IPv6 addresses within the host configuration (`hosts/`). -- **Options**: Prefer `lib.mkOption` over hardcoded strings for ports, domain names, and database credentials. -- **Unified Variables**: If a value is shared (e.g., between a PG container and a host service), define a local variable (e.g., `let databaseName = "attic"; in ...`) to ensure consistency. - -### 2. Service-Driven Configuration -- **Encapsulation**: Service modules should manage their own firewall rules, users/groups, and SSH settings. -- **Trusted Access**: Use the service module to define `nix.settings.trusted-users` for things like remote builders. - -### 3. Build-Time Discovery -- **Inter-Host Evaluation**: To avoid magic values, resolve a host's IP or port by evaluating its configuration in the flake's output: - ```nix - bcConfig = inputs.self.nixosConfigurations.BinaryCache.config; - ``` -- **Domain Deferral**: Client modules should defer their default domain settings from the server module's domain option. - -## Implementation Patterns - -### Container-Host Connectivity -- **Pattern**: `Service` on host -> `Container` via bridge mapping. -- **Rule**: Map the container name to `127.0.0.1` using `networking.extraHosts` to allow the host service to resolve the container by name without needing the bridge IP. - -### Secrets Management -- **Rule**: Standardize all secrets via `sops-nix`. -- **Common Module**: Ensure `modules/common/default.nix` handles the default `sopsFile` and `age` key configuration. - -### Bind9 Management -- **Rule**: **ALWAYS** increment the serial when editing zone records. - -### CI/CD Networking -- **Rule**: Use direct IPs for machine-to-machine login steps in Actions workflows to ensure reliability across different runner environments. - -## 4. Security & Documentation -- **Supply Chain Protection**: Always verify and lock Nix flake inputs. Use fixed-output derivations for external resource downloads. -- **Assumptions Documentation**: Clearly document environment assumptions (e.g., Proxmox virtualization, Tailscale networking, and specific IP ranges) in host or service READMEs. -- **Project Structure**: Maintain the separation of `hosts`, `modules`, `users`, and `secrets` to ensure clear ownership and security boundaries. - -### 5. Git Standards -- **Rule**: Follow **Conventional Commits** (e.g., `feat:`, `refactor:`, `docs:`, `meta:`). -- **Rule**: Keep commits **atomic** and **revertible**. Never mix documentation, infrastructure, and style guide changes in a single commit. diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 74d6457..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: "Build" -on: - pull_request: - push: - -jobs: - determine-hosts: - name: "Determining hosts to build" - runs-on: ubuntu-latest - container: catthehacker/ubuntu:act-24.04 - outputs: - hosts: ${{ steps.hosts.outputs.hostnames }} - steps: - - uses: actions/checkout@v5 - - uses: https://github.com/cachix/install-nix-action@v31 - with: - nix_path: nixpkgs=channel:nixos-unstable - - name: "Determine hosts" - id: hosts - run: | - hostnames="$(nix eval .#nixosConfigurations --apply builtins.attrNames --json)" - printf "hostnames=%s\n" "${hostnames}" >> "${GITHUB_OUTPUT}" - - build: - runs-on: ubuntu-latest - container: catthehacker/ubuntu:act-24.04 - needs: determine-hosts - strategy: - matrix: - hostname: [ - Development, - Testing - ] - - steps: - - uses: actions/checkout@v5 - - uses: https://github.com/cachix/install-nix-action@v31 - with: - nix_path: nixpkgs=channel:nixos-unstable - - name: "Build host" - run: | - nix build ".#nixosConfigurations.${{ matrix.hostname }}.config.system.build.toplevel" --verbose - diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 8cb0f4b..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: "Test" -on: - pull_request: - push: -jobs: - tests: - if: false - runs-on: ubuntu-latest - container: - image: catthehacker/ubuntu:act-latest - steps: - - uses: actions/checkout@v5 - - uses: https://github.com/cachix/install-nix-action@v31 - with: - nix_path: nixpkgs=channel:nixos-unstable - - name: "My custom step" - run: nix run nixpkgs#hello diff --git a/.gitignore b/.gitignore index 8daf605..485dee6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ .idea -result diff --git a/flake.lock b/flake.lock index da5c167..67df8c4 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1772624091, - "narHash": "sha256-QKyJ0QGWBn6r0invrMAK8dmJoBYWoOWy7lN+UHzW1jc=", + "lastModified": 1760524057, + "narHash": "sha256-EVAqOteLBFmd7pKkb0+FIUyzTF61VKi7YmvP1tw4nEw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "80bdc1e5ce51f56b19791b52b2901187931f5353", + "rev": "544961dfcce86422ba200ed9a0b00dd4b1486ec5", "type": "github" }, "original": { @@ -48,11 +48,11 @@ ] }, "locked": { - "lastModified": 1772495394, - "narHash": "sha256-hmIvE/slLKEFKNEJz27IZ8BKlAaZDcjIHmkZ7GCEjfw=", + "lastModified": 1760393368, + "narHash": "sha256-8mN3kqyqa2PKY0wwZ2UmMEYMcxvNTwLaOrrDsw6Qi4E=", "owner": "Mic92", "repo": "sops-nix", - "rev": "1d9b98a29a45abe9c4d3174bd36de9f28755e3ff", + "rev": "ab8d56e85b8be14cff9d93735951e30c3e86a437", "type": "github" }, "original": { diff --git a/hosts/Development/default.nix b/hosts/Development/default.nix index 68c5fea..77f6758 100644 --- a/hosts/Development/default.nix +++ b/hosts/Development/default.nix @@ -3,7 +3,6 @@ { config = { homelab = { - networking.hostIp = "192.168.0.91"; apps = { bind9.enable = true; homepage = { @@ -12,9 +11,9 @@ }; traefik.enable = true; plex.enable = true; + solidtime.enable = true; }; virtualisation.guest.enable = true; - users.deploy.enable = true; }; networking = { @@ -38,7 +37,7 @@ interfaces.ens18 = { ipv4.addresses = [ { - address = config.homelab.networking.hostIp; + address = "192.168.0.91"; prefixLength = 24; } ]; @@ -61,8 +60,7 @@ environment = { # NOTE Required # The email address used when setting up the initial administrator account to login to pgAdmin. - # TODO Hugo: Populate 'pgadmin_email' in sops. - PGADMIN_DEFAULT_EMAIL = config.sops.placeholder.pgadmin_email or "pgadmin-admin@example.com"; + PGADMIN_DEFAULT_EMAIL = "kmtl.hugo+pgadmin@gmail.com"; # NOTE Required # The password used when setting up the initial administrator account to login to pgAdmin. PGADMIN_DEFAULT_PASSWORD = "ChangeMe"; diff --git a/hosts/Isabel/default.nix b/hosts/Isabel/default.nix index f275b0e..0a1f50f 100644 --- a/hosts/Isabel/default.nix +++ b/hosts/Isabel/default.nix @@ -165,7 +165,7 @@ providers: # Certificates "--certificatesresolvers.letsencrypt.acme.dnschallenge=true" "--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare" - "--certificatesresolvers.letsencrypt.acme.email=${config.sops.placeholder.acme_email or "acme-email@example.com"}" + "--certificatesresolvers.letsencrypt.acme.email=tibo.depeuter@telenet.be" "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" # Additional routes @@ -176,8 +176,8 @@ providers: # "8080:8080/tcp" # The Web UI (enabled by --api.insecure=true) ]; environment = { - # TODO Hugo: Populate 'cloudflare_dns_token' in sops. - "CLOUDFLARE_DNS_API_TOKEN" = config.sops.placeholder.cloudflare_dns_token or "CLOUDFLARE_TOKEN_PLACEHOLDER"; + # TODO Hide this! + "CLOUDFLARE_DNS_API_TOKEN" = "6Vz64Op_a6Ls1ljGeBxFoOVfQ-yB-svRbf6OyPv2"; }; environmentFiles = [ ]; diff --git a/modules/apps/default.nix b/modules/apps/default.nix index f62dca7..385f915 100644 --- a/modules/apps/default.nix +++ b/modules/apps/default.nix @@ -9,6 +9,7 @@ ./homepage ./jellyfin ./plex + ./solidtime ./speedtest ./technitium-dns ./traefik diff --git a/modules/apps/gitea/default.nix b/modules/apps/gitea/default.nix index 34d52e4..0361bd5 100644 --- a/modules/apps/gitea/default.nix +++ b/modules/apps/gitea/default.nix @@ -496,8 +496,7 @@ in { #FORGEJO__mailer__CLIENT_KEY_FILE = "custom/mailer/key.pem"; # Mail from address, RFC 5322. This can be just an email address, or the # `"Name" ` format. - # TODO Hugo: Populate 'gitea_mailer_from' in sops. - FORGEJO__mailer__FROM = config.sops.placeholder.gitea_mailer_from or "git@example.com"; + FORGEJO__mailer__FROM = ''"${title}" ''; # Sometimes it is helpful to use a different address on the envelope. Set this to use # ENVELOPE_FROM as the from on the envelope. Set to `<>` to send an empty address. #FORGEJO__mailer__ENVELOPE_FROM = ""; diff --git a/modules/apps/solidtime/default.nix b/modules/apps/solidtime/default.nix new file mode 100644 index 0000000..725d32d --- /dev/null +++ b/modules/apps/solidtime/default.nix @@ -0,0 +1,278 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.homelab.apps.solidtime; + + networkName = "solidtime"; + internalNetworkName = "solidtime-internal"; + proxyNet = config.homelab.apps.traefiik.sharedNetworkName; + + user = "1000:1000"; + + # dbExternalPort = ...; + dbInternalPort = 5432; + + gotenbergPort = 3000; + + inherit (config.virtualisation.oci-containers) containers; + + solidtimeImageName = "solidtime/solidtime"; + version = "0.10.0"; + solidtimeImage = "${solidtimeImageName}:${version}"; + solidtimeImageFile = pkgs.dockerTools.pullImage { + imageName = solidtimeImageName; + finalImageTag = version; + imageDigest = "sha256:817d3a366ecc39f0473d7154372afa82dd4e6e50c66d70be45804892c8421cbb"; + sha256 = "sha256-h5aCKaquUF/EVsOHaLOHrn1HAoXZYPhAbJ+e4cmjSA8="; + }; + + volumes = [ + "solidtime-storage:/var/www/html/storage" + "solidtime-logs:/var/www/html/storage/logs" + "solidtime-app:/var/www/html/storage/app" + ]; + + # laravel.env + laravelEnv = { + APP_NAME = "Solidtime"; + VITE_APP_NAME = laravelEnv.APP_NAME; + APP_ENV = "production"; + APP_DEBUG = "false"; + APP_URL = "http://localhost:${toString cfg.port}"; + APP_FORCE_HTTPS = "false"; + APP_ENABLE_REGISTRATION = "false"; + TRUSTED_PROXIES = "0.0.0.0/0,2000:0:0:0:0:0:0:0/3"; + + # Logging + LOG_CHANNEL = "stderr_daily"; + LOG_LEVEL = "debug"; + + # Database + DB_CONNECTION = "pgsql"; + DB_HOST = containers.solidtimeDb.hostname; + DB_PORT = toString dbInternalPort; + DB_SSL_MODE = "require"; + DB_DATABASE = "solidtime"; + DB_USERNAME = "solidtime"; + DB_PASSWORD = "ChangeMe"; + + # Mail + #MAIL_MAILER = "smtp"; + #MAIL_HOST = "smtp.gmail.com"; + #MAIL_PORT = "465"; + #MAIL_ENCRYPTION = "tls"; + #MAIL_FROM_ADDRESS = "no-reply@time.depeuter.dev"; + MAIL_FROM_NAME = laravelEnv.APP_NAME; + #MAIL_USERNAME = "kmtl.hugo@gmail.com"; + #MAIL_PASSWORD = "fhfxoequhhqidrhd"; + + # Queue + QUEUE_CONNECTION = "database"; + + # File storage + FILESYSTEM_DISK = "local"; + PUBLIC_FILESYSTEM_DISK = "public"; + + # Services + GOTENBERG_URL = "http://${containers.solidtimeGotenberg.hostname}:${toString gotenbergPort}"; + }; + +in { + options.homelab.apps.solidtime = { + enable = lib.mkEnableOption "Solidtime time tracker using Docker"; + port = lib.mkOption { + type = lib.types.int; + default = 8000; + description = "Solidtime WebUI port"; + }; + exposePort = lib.mkEnableOption "Expose Soldtime port"; + }; + + config = lib.mkIf cfg.enable { + homelab.virtualisation.containers.enable = true; + + # Make sure the Docker network exists. + systemd.services = { + "docker-${networkName}-create-network" = { + description = "Create Docker network for ${networkName}"; + requiredBy = [ + "${containers.solidtime.serviceName}.service" + ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + if ! ${pkgs.docker}/bin/docker network ls | grep -q ${networkName}; then + ${pkgs.docker}/bin/docker network create ${networkName} + fi + ''; + }; + "docker-${internalNetworkName}-create-network" = { + description = "Create Docker network for ${internalNetworkName}"; + requiredBy = [ + "${containers.solidtime.serviceName}.service" + "${containers.solidtimeScheduler.serviceName}.service" + "${containers.solidtimeQueue.serviceName}.service" + "${containers.solidtimeDb.serviceName}.service" + "${containers.solidtimeGotenberg.serviceName}.service" + ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + if ! ${pkgs.docker}/bin/docker network ls | grep -q ${internalNetworkName}; then + ${pkgs.docker}/bin/docker network create ${internalNetworkName} + fi + ''; + }; + }; + + virtualisation.oci-containers.containers = { + solidtime = { + hostname = "solidtime"; + image = solidtimeImage; + imageFile = solidtimeImageFile; + inherit user; + autoStart = true; + dependsOn = [ + "solidtimeDb" + ]; + ports = [ + # Open ports if you don't use Traefik + "${toString cfg.port}:8000" + ]; + networks = [ + networkName + internalNetworkName + ]; + extraOptions = [ + # Healthecks + # test: [ "CMD", "curl", "--fail", "http://localhost:8000/health-check/up" ] + ''--health-cmd=curl --fail http://localhost:8000/health-check/up'' + ]; + inherit volumes; + labels = { + "traefik.enable" = "true"; + "traefik.http.routers.solidtime.rule" = "Host(`time.${config.networking.hostName}.depeuter.dev`)"; + "traefik.http.services.solidtime.loadbalancer.server.port" = toString cfg.port; + }; + environmentFiles = [ + "/home/admin/.solidtime.env" + ]; + environment = laravelEnv // { + CONTAINER_MODE = "http"; + }; + }; + solidtimeScheduler = { + hostname = "scheduler"; + image = solidtimeImage; + imageFile = solidtimeImageFile; + inherit user; + autoStart = true; + dependsOn = [ + "solidtimeDb" + ]; + networks = [ + internalNetworkName + ]; + extraOptions = [ + # Healthchecks + # test: [ "CMD", "healthcheck" ] + ''--health-cmd="healthcheck"'' + ]; + inherit volumes; + environmentFiles = [ + "/home/admin/.solidtime.env" + ]; + environment = laravelEnv // { + CONTAINER_MODE = "scheduler"; + }; + }; + solidtimeQueue = { + hostname = "queue"; + image = solidtimeImage; + imageFile = solidtimeImageFile; + inherit user; + autoStart = true; + networks = [ + internalNetworkName + ]; + extraOptions = [ + # Healthchecks + # test: [ "CMD", "healthcheck" ] + ''--health-cmd="healthcheck"'' + ]; + inherit volumes; + dependsOn = [ + "solidtimeDb" + ]; + environmentFiles = [ + "/home/admin/.solidtime.env" + ]; + environment = laravelEnv // { + CONTAINER_MODE = "worker"; + WORKER_COMMAND = "php /var/www/html/artisan queue:work"; + }; + }; + solidtimeDb = let + imageName = "postgres"; + finalImageTag = "15"; + in { + hostname = "database"; + image = "${imageName}:${finalImageTag}"; + imageFile = pkgs.dockerTools.pullImage { + inherit imageName finalImageTag; + imageDigest = "sha256:98fe06b500b5eb29e45bf8c073eb0ca399790ce17b1d586448edc4203627d342"; + sha256 = "sha256-AZ4VkOlROX+nR/MjDjsA4xdHzmtKjiBAtsp2Q6IdOvg="; + }; + autoStart = true; + ports = [ + # "${toString dbExternalPort}:${toString dbInternalPort}" + ]; + networks = [ + internalNetworkName + ]; + extraOptions = [ + # Healthchecks + # test: - CMD - pg_isready - '-q' - '-d' - '${DB_DATABASE}' - '-U' - '${DB_USERNAME}' retries: 3 timeout: 5s + ''--health-cmd="pg_isready -q -d ${laravelEnv.DB_DATABASE} -U ${laravelEnv.DB_USERNAME}"'' + "--health-retries=3" + "--health-timeout=5s" + ]; + volumes = [ + "solidtime-db:/var/lib/postgresql/data" + ]; + environment = { + PGPASSWORD = laravelEnv.DB_PASSWORD; + POSTGRES_DB = laravelEnv.DB_DATABASE; + POSTGRES_USER = laravelEnv.DB_USERNAME; + POSTGRES_PASSWORD = laravelEnv.DB_PASSWORD; + }; + }; + solidtimeGotenberg = let + imageName = "gotenberg/gotenberg"; + finalImageTag = "8.26.0"; + in { + hostname = "gotenberg"; + image = "${imageName}:${finalImageTag}"; + imageFile = pkgs.dockerTools.pullImage { + inherit imageName finalImageTag; + imageDigest = "sha256:328551506b3dec3ff6381dd47e5cd72a44def97506908269e201a8fbfa1c12c0"; + sha256 = "sha256-1zz4xDAgXxHUnkCVIfjHTgXb82EFEx+5am6Cu9+eZj4="; + }; + autoStart = true; + networks = [ + internalNetworkName + ]; + extraOptions = [ + # Healthchecks + # test: [ "CMD", "curl", "--silent", "--fail", "http://localhost:3000/health" ] + ''--health-cmd="curl --silent --fail http://localhost:${toString gotenbergPort}/health"'' + ]; + }; + }; + }; +} + diff --git a/modules/apps/traefik/default.nix b/modules/apps/traefik/default.nix index 54588c1..7f6ce38 100644 --- a/modules/apps/traefik/default.nix +++ b/modules/apps/traefik/default.nix @@ -72,7 +72,7 @@ in { # Certificates "--certificatesresolvers.letsencrypt.acme.dnschallenge=true" "--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare" - "--certificatesresolvers.letsencrypt.acme.email=${config.sops.placeholder.acme_email or "acme-email@example.com"}" + "--certificatesresolvers.letsencrypt.acme.email=tibo.depeuter@telenet.be" "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" ]; volumes = [ diff --git a/modules/apps/vaultwarden/default.nix b/modules/apps/vaultwarden/default.nix index 6c55d0a..4510299 100644 --- a/modules/apps/vaultwarden/default.nix +++ b/modules/apps/vaultwarden/default.nix @@ -13,12 +13,12 @@ in { description = "Vaultwarden WebUI port"; }; domain = lib.mkOption { - type = lib.types.str; + type = lib.types.string; example = "https://vault.depeuter.dev"; description = "Domain to configure Vaultwarden on"; }; name = lib.mkOption { - type = lib.types.str; + type = lib.types.string; example = "Hugo's Vault"; description = "Service name to use for invitations and mail"; }; @@ -77,7 +77,7 @@ in { dataDir = "/data"; in { hostname = "vaultwarden"; - image = "vaultwarden/server:1.35.4-alpine"; + image = "vaultwarden/server:1.34.3-alpine"; autoStart = true; ports = [ "${toString cfg.port}:80/tcp" @@ -344,7 +344,6 @@ in { # ORG_CREATION_USERS=none ## A comma-separated list means only those users can create orgs: # ORG_CREATION_USERS=admin1@example.com,admin2@example.com - # TODO Hugo: Redact org creation users if needed. ## Invitations org admins to invite users, even when signups are disabled # INVITATIONS_ALLOWED=true @@ -591,7 +590,7 @@ in { ## To make sure the email links are pointing to the correct host, set the DOMAIN variable. ## Note: if SMTP_USERNAME is specified, SMTP_PASSWORD is mandatory SMTP_HOST = "smtp.gmail.com"; - SMTP_FROM = config.sops.placeholder.vaultwarden_smtp_from or "vaultwarden@example.com"; + SMTP_FROM = "vault@depeuter.dev"; SMTP_FROM_NAME = cfg.name; # SMTP_USERNAME=username # SMTP_PASSWORD=password diff --git a/modules/common/default.nix b/modules/common/default.nix index 746d1c1..44309f5 100644 --- a/modules/common/default.nix +++ b/modules/common/default.nix @@ -1,8 +1,4 @@ { - imports = [ - ./secrets.nix - ]; - config = { homelab = { services.openssh.enable = true; @@ -16,10 +12,5 @@ # Set your time zone. time.timeZone = "Europe/Brussels"; - - sops = { - defaultSopsFile = ../../secrets/secrets.yaml; - age.keyFile = "/var/lib/sops-nix/key.txt"; - }; }; } diff --git a/modules/common/secrets.nix b/modules/common/secrets.nix deleted file mode 100644 index 10b6473..0000000 --- a/modules/common/secrets.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ config, lib, ... }: - -{ - sops.secrets = { - # -- User Public Keys (Anti-Fingerprinting) -- - "user_keys_admin" = { neededForUsers = true; }; - "user_keys_deploy" = { neededForUsers = true; }; - "user_keys_backup" = { neededForUsers = true; }; - - # -- Infrastructure Metadata -- - # Hugo TODO: Populate these in your .sops.yaml / secrets file - "acme_email" = {}; - "cloudflare_dns_token" = {}; - "pgadmin_email" = {}; - "gitea_mailer_from" = {}; - "vaultwarden_smtp_from" = {}; - }; -} diff --git a/users/admin/default.nix b/users/admin/default.nix index 14766da..dc01c81 100644 --- a/users/admin/default.nix +++ b/users/admin/default.nix @@ -26,9 +26,7 @@ in { config.users.groups.wheel.name # Enable 'sudo' for the user. ]; initialPassword = "ChangeMe"; - openssh.authorizedKeys.keyFiles = [ - config.sops.secrets.user_keys_admin.path - ]; + openssh.authorizedKeys.keys = cfg.authorizedKeys; packages = with pkgs; [ curl git diff --git a/users/backup/default.nix b/users/backup/default.nix index 8c20374..acae033 100644 --- a/users/backup/default.nix +++ b/users/backup/default.nix @@ -12,8 +12,9 @@ in { extraGroups = [ "docker" # Allow access to the docker socket. ]; - openssh.authorizedKeys.keyFiles = [ - config.sops.secrets.user_keys_backup.path + openssh.authorizedKeys.keys = [ + # Hugo + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICms6vjhE9kOlqV5GBPGInwUHAfCSVHLI2Gtzee0VXPh" ]; }; }; diff --git a/users/deploy/default.nix b/users/deploy/default.nix index 93505fc..0509d1e 100644 --- a/users/deploy/default.nix +++ b/users/deploy/default.nix @@ -15,8 +15,8 @@ in { isSystemUser = true; home = "/var/empty"; shell = pkgs.bashInteractive; - openssh.authorizedKeys.keyFiles = [ - config.sops.secrets.user_keys_deploy.path + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPrG+ldRBdCeHEXrsy/qHXIJYg8xQXVuiUR0DxhFjYNg" ]; }; };