diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..750baeb --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +result +result-* diff --git a/.sops.yaml b/.sops.yaml index 4931118..6c3ae99 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -1,14 +1,14 @@ keys: - - &admin_key age1e8p35795htf7twrejyugpzw0qja2v33awcw76y4gp6acnxnkzq0s935t4t + - &steffen_key age1e8p35795htf7twrejyugpzw0qja2v33awcw76y4gp6acnxnkzq0s935t4t # steffen (local) - &cryodev-main_key age1y6hushuapy0k04mrvvpev0t8lq44w904r596jus44nhkflky0yhqgq2xx6 creation_rules: - path_regex: hosts/cryodev-main/secrets.yaml$ key_groups: - age: - - *admin_key + - *steffen_key - *cryodev-main_key - path_regex: hosts/cryodev-pi/secrets.yaml$ key_groups: - age: - - *admin_key - # - *pi_key # Add pi key here once obtained + - *steffen_key + # - *cryodev-pi_key # Add after Pi installation diff --git a/docs/deployment/dns.md b/docs/deployment/dns.md index 0e00b35..8d0f99b 100644 --- a/docs/deployment/dns.md +++ b/docs/deployment/dns.md @@ -10,6 +10,8 @@ Required DNS records for the cryodev infrastructure. |----------|------|-------|---------| | `@` | A | `` | Main server | | `@` | AAAA | `` | Main server (IPv6) | +| `www` | A | `` | www redirect | +| `www` | AAAA | `` | www redirect (IPv6) | | `mail` | A | `` | Mail server | | `mail` | AAAA | `` | Mail server (IPv6) | @@ -29,7 +31,32 @@ Required DNS records for the cryodev infrastructure. | `@` | MX | `10 mail.cryodev.xyz.` | Mail delivery | | `@` | TXT | `"v=spf1 mx ~all"` | SPF | | `_dmarc` | TXT | `"v=DMARC1; p=none"` | DMARC | -| `mail._domainkey` | TXT | `"v=DKIM1; k=rsa; p=..."` | DKIM | +| `mail._domainkey` | TXT | *(siehe unten)* | DKIM | + +### Reverse DNS (PTR) + +Fuer zuverlaessige Mail-Zustellung muss ein **PTR Record** beim Hosting-Provider +konfiguriert werden (nicht im DNS-Panel der Domain): + +| IP | PTR Value | +|----|-----------| +| `` | `mail.cryodev.xyz` | +| `` | `mail.cryodev.xyz` | + +#### Hetzner Robot (Dedicated Server) + +1. [robot.hetzner.com](https://robot.hetzner.com) > **Server** > Server auswaehlen +2. **IPs** Tab +3. Bei der IPv4-Adresse auf das **Stift-Symbol** klicken +4. `mail.cryodev.xyz` eintragen und speichern +5. Fuer IPv6: Unter **Subnets** dasselbe fuer die primaere IPv6-Adresse + +#### Hetzner Cloud + +1. [cloud.hetzner.com](https://cloud.hetzner.com) > Server auswaehlen +2. **Networking** Tab +3. Bei "Primary IP" auf die IP klicken > **Reverse DNS** +4. `mail.cryodev.xyz` eintragen (fuer IPv4 und IPv6) ## Getting the DKIM Key @@ -41,6 +68,18 @@ sudo cat /var/dkim/cryodev.xyz.mail.txt Add this as a TXT record for `mail._domainkey.cryodev.xyz`. +## Complete Checklist + +- [ ] A/AAAA fuer `@` (Root-Domain) +- [ ] A/AAAA fuer `www` +- [ ] A/AAAA fuer `mail` +- [ ] CNAME fuer `git`, `headscale`, `headplane`, `netdata` +- [ ] MX Record +- [ ] TXT fuer SPF (`v=spf1 mx ~all`) +- [ ] TXT fuer DMARC (`v=DMARC1; p=none`) +- [ ] TXT fuer DKIM (`mail._domainkey` -- nach erstem Deploy) +- [ ] PTR Record beim Hosting-Provider (Reverse DNS) + ## Verification ### Check DNS Propagation @@ -60,6 +99,9 @@ dig TXT mail._domainkey.cryodev.xyz # DMARC dig TXT _dmarc.cryodev.xyz + +# Reverse DNS +dig -x ``` ### Online Tools @@ -74,7 +116,7 @@ For initial setup, use low TTLs (300 seconds) to allow quick changes. After verification, increase to: - A/AAAA records: 3600 (1 hour) -- CNAME records: 3600 (1 hour) +- CNAME records: 3600 (1 hour) - MX records: 3600 (1 hour) - TXT records: 3600 (1 hour) @@ -84,7 +126,7 @@ Ensure these ports are open on `cryodev-main`: | Port | Protocol | Service | |------|----------|---------| -| 22 | TCP | SSH | +| 2299 | TCP | SSH | | 80 | TCP | HTTP (ACME/redirect) | | 443 | TCP | HTTPS | | 25 | TCP | SMTP | diff --git a/docs/getting-started/first-install.md b/docs/getting-started/first-install.md index 1d489b3..f50c51a 100644 --- a/docs/getting-started/first-install.md +++ b/docs/getting-started/first-install.md @@ -166,14 +166,14 @@ Auf dem **Entwicklungsrechner** den neuen Host-Key in `.sops.yaml` eintragen: ```yaml keys: - - &admin_key age1e8p... # Dein lokaler Admin-Key - - &hostname_key age1abc... # Key von Schritt 3.1 + - &steffen_key age1e8p... # steffen (lokal) + - &hostname_key age1abc... # Key von Schritt 3.1 creation_rules: - path_regex: hosts//secrets.yaml$ key_groups: - age: - - *admin_key + - *steffen_key - *hostname_key ``` @@ -204,8 +204,8 @@ Diese Secrets koennen erst nach Schritt 4 erstellt werden. **Jetzt noch nicht ei | Secret | Befehl | Voraussetzung | |--------|--------|---------------| -| `tailscale/auth-key` | `sudo headscale preauthkeys create --expiration 99y --reusable --user default` | Headscale laeuft | -| `headplane/agent_pre_authkey` | `sudo headscale users create headplane-agent && sudo headscale preauthkeys create --expiration 99y --user headplane-agent` | Headscale laeuft | +| `tailscale/auth-key` | Siehe Schritt 4.1-4.2 | Headscale laeuft | +| `headplane/agent_pre_authkey` | Siehe Schritt 4.1-4.2 | Headscale laeuft | | `forgejo-runner/token` | Forgejo Admin Panel > Actions > Runners > Create Runner | Forgejo laeuft | #### Beispiel secrets.yaml (Klartext vor Verschluesselung) @@ -243,30 +243,13 @@ Services **ohne externe Abhaengigkeiten** aktivieren: ./sops.nix # Stufe 2: Erst nach Schritt 4 aktivieren - # ./headplane.nix # braucht: headplane/agent_pre_authkey (Headscale) - # ./tailscale.nix # braucht: tailscale/auth-key (Headscale) + # ./forgejo-runner.nix # braucht: forgejo-runner/token (Forgejo) + # ./headplane.nix # braucht: headplane/agent_pre_authkey (Headscale) + # ./tailscale.nix # braucht: tailscale/auth-key (Headscale) ]; } ``` -Ebenso in `hosts//services/sops.nix` die Secrets-Definitionen wieder -einkommentieren, **aber nur die fuer Stufe-1-Services**: - -```nix -sops = { - defaultSopsFile = ../secrets.yaml; - secrets = { - # "forgejo-runner/token" = { }; # Stufe 2 - "tailscale/auth-key" = { }; - }; -}; -``` - -> **Hinweis:** `tailscale/auth-key` muss in `sops.nix` definiert bleiben, da das -> Tailscale-Modul es referenziert. Es wird aber erst in Schritt 4 mit einem -> echten Wert befuellt. Solange Tailscale nicht importiert ist, hat das keinen -> Effekt. - ### 3.5 Deployen (Stufe 1) ```bash @@ -282,6 +265,26 @@ NIX_SSHOPTS="-p 2299" nixos-rebuild switch --flake .# \ Nach diesem Deploy laufen Headscale, Forgejo, Mailserver und Nginx. +### 3.6 Forgejo Admin-Account erstellen + +Beim ersten Start hat Forgejo noch keine Benutzer. Admin-Account per CLI anlegen +(auf dem **Server**): + +```bash +forgejo admin user create \ + --username \ + --email @ \ + --password \ + --admin +``` + +> **Hinweis:** Das `forgejo` Shell-Alias wird vom Modul bereitgestellt und fuehrt +> automatisch den Befehl als `forgejo`-User mit der richtigen Config aus. +> Falls der Alias nicht verfuegbar ist, neue Shell starten (`bash` oder `zsh`). +> +> Da `DISABLE_REGISTRATION = true` gesetzt ist, koennen neue Accounts +> nur per CLI erstellt werden. + ## Schritt 4: Restliche Secrets generieren und alle Services aktivieren Nachdem der Server mit Headscale und Forgejo laeuft: @@ -293,20 +296,28 @@ Nachdem der Server mit Headscale und Forgejo laeuft: sudo headscale users create headplane-agent ``` -2. **Preauth-Keys generieren**: +2. **User-IDs ermitteln** (wird fuer die Preauth-Keys benoetigt): ```bash - # Fuer Tailscale - sudo headscale preauthkeys create --expiration 99y --reusable --user default - - # Fuer Headplane Agent - sudo headscale preauthkeys create --expiration 99y --user headplane-agent + sudo headscale users list ``` -3. **Forgejo-Runner-Token** ueber das Forgejo Admin Panel erstellen: + Die Ausgabe zeigt die numerischen IDs (z.B. `1` fuer default, `2` fuer headplane-agent). + +3. **Preauth-Keys generieren** (mit den IDs aus Schritt 2): + + ```bash + # Fuer Tailscale (User-ID von "default" einsetzen) + sudo headscale preauthkeys create --expiration 99y --reusable --user + + # Fuer Headplane Agent (User-ID von "headplane-agent" einsetzen) + sudo headscale preauthkeys create --expiration 99y --user + ``` + +4. **Forgejo-Runner-Token** ueber das Forgejo Admin Panel erstellen: Administration > Actions > Runners > Create new Runner -4. **Secrets ergaenzen**: +5. **Secrets ergaenzen**: ```bash sops hosts//secrets.yaml @@ -323,12 +334,13 @@ Nachdem der Server mit Headscale und Forgejo laeuft: agent_pre_authkey: "..." ``` -5. **Stufe-2-Services aktivieren** in `hosts//services/default.nix`: +6. **Stufe-2-Services aktivieren** in `hosts//services/default.nix`: ```nix { imports = [ ./forgejo.nix + ./forgejo-runner.nix ./headplane.nix ./headscale.nix ./mailserver.nix @@ -341,8 +353,6 @@ Nachdem der Server mit Headscale und Forgejo laeuft: } ``` - Und in `sops.nix` auch `forgejo-runner/token` einkommentieren. - 6. **Erneut deployen**: ```bash diff --git a/docs/getting-started/new-client.md b/docs/getting-started/new-client.md index 93b1d0a..8cb29a8 100644 --- a/docs/getting-started/new-client.md +++ b/docs/getting-started/new-client.md @@ -36,7 +36,10 @@ Diese Anleitung beschreibt das Hinzufügen eines **neuen Raspberry Pi Clients** **Auf cryodev-main** (per SSH): ```bash -sudo headscale preauthkeys create --expiration 99y --reusable --user default +# User-ID ermitteln +sudo headscale users list +# Preauth-Key erstellen (User-ID von "default" einsetzen) +sudo headscale preauthkeys create --expiration 99y --reusable --user ``` **Ausgabe notieren!** (z.B. `tskey-preauth-abc123...`) @@ -195,17 +198,17 @@ Auf dem Entwicklungsrechner: ```yaml keys: - - &admin_key age1e8p35795htf7twrejyugpzw0qja2v33awcw76y4gp6acnxnkzq0s935t4t + - &steffen_key age1e8p35795htf7twrejyugpzw0qja2v33awcw76y4gp6acnxnkzq0s935t4t # steffen (local) - &neuer_pi_key age1xyz... # Der neue Key creation_rules: # ... bestehende Regeln ... - + - path_regex: hosts/neuer-pi/secrets.yaml$ key_groups: - age: - - *admin_key - - *neuer_pi_key + - *steffen_key + - *neuer_pi_key ``` ### 6.5 Secrets erstellen diff --git a/docs/services/headplane.md b/docs/services/headplane.md index e6c807f..458d3fc 100644 --- a/docs/services/headplane.md +++ b/docs/services/headplane.md @@ -25,9 +25,10 @@ nix-shell -p openssl --run 'openssl rand -hex 16' ```bash # First, create a dedicated user sudo headscale users create headplane-agent - -# Then create a reusable pre-auth key -sudo headscale preauthkeys create --expiration 99y --reusable --user headplane-agent +# Find the user ID +sudo headscale users list +# Then create a reusable pre-auth key (use the ID of headplane-agent) +sudo headscale preauthkeys create --expiration 99y --reusable --user ``` ### Add to Secrets @@ -101,7 +102,7 @@ sudo journalctl -u headplane -f Verify the agent pre-auth key is valid: ```bash -sudo headscale preauthkeys list --user headplane-agent +sudo headscale preauthkeys list --user ``` If expired, create a new one and update the secrets file. diff --git a/docs/services/sops.md b/docs/services/sops.md index cf1a044..6a2def2 100644 --- a/docs/services/sops.md +++ b/docs/services/sops.md @@ -31,7 +31,7 @@ Add the host key to `.sops.yaml`: ```yaml keys: - - &admin_key age1e8p35795htf7twrejyugpzw0qja2v33awcw76y4gp6acnxnkzq0s935t4t + - &steffen_key age1e8p35795htf7twrejyugpzw0qja2v33awcw76y4gp6acnxnkzq0s935t4t # steffen (local) - &main_key age1... # cryodev-main - &pi_key age1... # cryodev-pi @@ -39,14 +39,14 @@ creation_rules: - path_regex: hosts/cryodev-main/secrets.yaml$ key_groups: - age: - - *admin_key - - *main_key - + - *steffen_key + - *main_key + - path_regex: hosts/cryodev-pi/secrets.yaml$ key_groups: - age: - - *admin_key - - *pi_key + - *steffen_key + - *pi_key ``` ### 3. Create Secrets File @@ -153,7 +153,7 @@ netdata: | Mailserver password | `nix-shell -p mkpasswd --run 'mkpasswd -sm bcrypt'` | | Random hex token | `nix-shell -p openssl --run 'openssl rand -hex 16'` | | UUID | `uuidgen` | -| Tailscale preauth | `sudo headscale preauthkeys create --expiration 99y --reusable --user default` | +| Tailscale preauth | `sudo headscale preauthkeys create --expiration 99y --reusable --user ` | ## Updating Keys diff --git a/docs/services/tailscale.md b/docs/services/tailscale.md index 8b0b54c..768a21c 100644 --- a/docs/services/tailscale.md +++ b/docs/services/tailscale.md @@ -14,7 +14,10 @@ Tailscale clients connect to the self-hosted Headscale server to join the mesh V On the Headscale server (cryodev-main): ```bash -sudo headscale preauthkeys create --expiration 99y --reusable --user default +# User-ID ermitteln +sudo headscale users list +# Preauth-Key erstellen (User-ID von "default" einsetzen) +sudo headscale preauthkeys create --expiration 99y --reusable --user ``` ### Add to Secrets @@ -111,7 +114,7 @@ Check the auth key is valid: ```bash # On Headscale server -sudo headscale preauthkeys list --user default +sudo headscale preauthkeys list --user ``` Verify the login server URL is correct in the client configuration. diff --git a/hosts/cryodev-main/secrets.yaml b/hosts/cryodev-main/secrets.yaml index a36dda7..4e2dda6 100644 --- a/hosts/cryodev-main/secrets.yaml +++ b/hosts/cryodev-main/secrets.yaml @@ -1,10 +1,10 @@ tailscale: - auth-key: ENC[AES256_GCM,data:APMZrLYEqywYTmc=,iv:KiFwgR3UXLXCdl9DlR5tJOr8XUyQEeDomPx9hOREhnw=,tag:32quLtu74EIxAgmjH3hvIw==,type:str] + auth-key: ENC[AES256_GCM,data:v5C3DqYJsDKq6oUa/3G6WKxyKeIK4EJLNxWMbKjSbwe5MPtS4sZjFszMviKcEVGW,iv:4G8irABGuVhOYnK15EjbpNQ4B9VY/NdwCrfz+YAMzvA=,tag:0Vhq/TJgx+48frRy30yKFg==,type:str] forgejo-runner: - token: ENC[AES256_GCM,data:/i9KVMeEXYwQnn0=,iv:pILMNbhDviifDUFRINi6n9dtGSAeqxKMdBgjYwtXXEM=,tag:JCj5v5BZdZteo0MdTVKREw==,type:str] + token: ENC[AES256_GCM,data:sdnJcyRiTLxXoZDNbEzJAjpiK+iSUH0gV0XwbEQf94IE/6IZz5/zHw==,iv:py+qqp3VAwBGEpYiQwft3jnQS943JaBlrcckColv4f8=,tag:rtmRwW8rpXB6Pv+LSkp+Fw==,type:str] headplane: cookie_secret: ENC[AES256_GCM,data:HICF31i6yCLZGNeOFYTR3Bp0a7i0UKOvGAvx/pD3NB4=,iv:ZtK8r1YUWnf5Af0Ls341k0w1mZm+D5Rb0E1uS5z/Gdo=,tag:vwM9+4dpcmnjn/wR6Ty/MQ==,type:str] - agent_pre_authkey: ENC[AES256_GCM,data:aYkPZTR4fwArcKQ=,iv:+OhbIpwsyCJ4i4k8eyCKYAHE25F4iUHfdM+CG0+BQd8=,tag:BkT73WPjOv5Lu6dCFBXxWg==,type:str] + agent_pre_authkey: ENC[AES256_GCM,data:QvhPi2lhyP7w6HTeOSS8660NzIY9Q6AOhlOGQXnvz+qYu9vOAMQPOFMZfie5+e8g,iv:X60wVOEUIsTiMHrrd4lId0VpR7VfFDr74p8RGka3+18=,tag:kIvaHrOWIM+VQ+Qz1GiheQ==,type:str] mailserver: accounts: admin: ENC[AES256_GCM,data:gY2k3x3sA98yGNLcSWUr9aC0566MJM2UXhwLtWPUL3PRvxQt0XOzjeiC7ddgbqTAol4dBNeaV0zbFInD,iv:rxp0M9kHMgD73K+RDC562sUpXaJ067eU1CeciAke+LM=,tag:VKobduo/ZULAk17M9LD3bw==,type:str] @@ -31,7 +31,7 @@ sops: MEpGbGlQbVRsM1NxN1JxY2J1MVNTTE0KuIvuM2c1VIXKv0LGLb0NwqtSyBYcRcb1 uiIjNV0UzEt/WvnCeUTMPgIXBHk6jWcaKe13v6MHeha+/CVZ9Su/Lw== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-03-14T10:28:25Z" - mac: ENC[AES256_GCM,data:oeT8I9gMIAPnm8wlNUFjn/0UT6qfTA//fLp3USO33FMsNIOWmqt3kB4NsozS+n6ZeMxBVWQZPss8t819DYqv0xQarzfOqQe1idCGCB+7NBFcFP2VLFzkIH+9Wei9AJSlR3BRnzyVaQDi797P6pEXFn/IoQWPWZ8sX8ZKugOfY0w=,iv:RjsKhPcVZBHHLs1W3PDhcseGLV4eawafg0is6KrzhtE=,tag:ifkobUteslEZ78OvkZw8JQ==,type:str] + lastmodified: "2026-03-14T11:38:57Z" + mac: ENC[AES256_GCM,data:gmxyp3XaHeU/CT2lgo14wIbJsKs/JrZmUPhgHwo1XRN5Sf/Su6lHOpVlQS1M6R3+ZlBnS/oEur+y0gydCCqhJK1C3Y5YuUfPlOWOeQWMVxQBqxWkyemvz5KgGseDc9nG09FpoGEYa4sSeuD1J6vRsGcZiOStaA6s8NICWivdWcQ=,iv:cYILLrScr7cFiLx5INbc9z3BT7LaCjLnCH0wdn3lZ1k=,tag:IIRb/Tu8YqWNiHXH7CSOfQ==,type:str] unencrypted_suffix: _unencrypted version: 3.11.0 diff --git a/hosts/cryodev-main/services/default.nix b/hosts/cryodev-main/services/default.nix index 0bd3c67..4b447cd 100644 --- a/hosts/cryodev-main/services/default.nix +++ b/hosts/cryodev-main/services/default.nix @@ -1,13 +1,17 @@ { imports = [ + # Stufe 1: Services ohne externe Abhaengigkeiten ./forgejo.nix - ./headplane.nix ./headscale.nix ./mailserver.nix ./netdata.nix ./nginx.nix ./openssh.nix ./sops.nix - ./tailscale.nix + + # Stufe 2: Erst aktivieren wenn Headscale/Forgejo laufen und echte Secrets existieren + ./forgejo-runner.nix # braucht: forgejo-runner/token (Forgejo) + ./headplane.nix # braucht: headplane/agent_pre_authkey (Headscale) + ./tailscale.nix # braucht: tailscale/auth-key (Headscale) ]; } diff --git a/hosts/cryodev-main/services/forgejo-runner.nix b/hosts/cryodev-main/services/forgejo-runner.nix new file mode 100644 index 0000000..e2a5c1c --- /dev/null +++ b/hosts/cryodev-main/services/forgejo-runner.nix @@ -0,0 +1,28 @@ +{ + config, + outputs, + constants, + ... +}: + +{ + imports = [ + outputs.nixosModules.forgejo-runner + ]; + + services.forgejo-runner = { + enable = true; + url = "http://127.0.0.1:${toString constants.services.forgejo.port}"; + tokenFile = config.sops.templates."forgejo-runner-token".path; + }; + + sops.secrets."forgejo-runner/token" = { + mode = "0400"; + }; + + sops.templates."forgejo-runner-token" = { + content = '' + TOKEN=${config.sops.placeholder."forgejo-runner/token"} + ''; + }; +} diff --git a/hosts/cryodev-main/services/forgejo.nix b/hosts/cryodev-main/services/forgejo.nix index b911241..5d54830 100644 --- a/hosts/cryodev-main/services/forgejo.nix +++ b/hosts/cryodev-main/services/forgejo.nix @@ -8,7 +8,6 @@ { imports = [ outputs.nixosModules.forgejo - outputs.nixosModules.forgejo-runner ]; services.forgejo = { @@ -32,17 +31,6 @@ }; }; - services.forgejo-runner = { - enable = true; - url = "https://${constants.services.forgejo.fqdn}"; - tokenFile = config.sops.secrets."forgejo-runner/token".path; - }; - - sops.secrets."forgejo-runner/token" = { - # gitea-runner user is created by gitea-actions-runner service - mode = "0400"; - }; - services.nginx.virtualHosts."${constants.services.forgejo.fqdn}" = { forceSSL = true; enableACME = true; diff --git a/hosts/cryodev-main/services/headplane.nix b/hosts/cryodev-main/services/headplane.nix index fbc21bb..fc39494 100644 --- a/hosts/cryodev-main/services/headplane.nix +++ b/hosts/cryodev-main/services/headplane.nix @@ -16,6 +16,7 @@ headscale = { url = "http://127.0.0.1:${toString constants.services.headscale.port}"; public_url = "https://${constants.services.headscale.fqdn}"; + config_strict = false; }; }; }; diff --git a/hosts/cryodev-main/services/sops.nix b/hosts/cryodev-main/services/sops.nix index 8df48e1..ca01a72 100644 --- a/hosts/cryodev-main/services/sops.nix +++ b/hosts/cryodev-main/services/sops.nix @@ -13,9 +13,9 @@ sops = { defaultSopsFile = ../secrets.yaml; # age.keyFile is not set, sops-nix defaults to using /etc/ssh/ssh_host_ed25519_key - secrets = { - "forgejo-runner/token" = { }; - "tailscale/auth-key" = { }; - }; + + # Secrets fuer Stufe-2-Services werden in deren eigenen Dateien definiert: + # forgejo-runner/token -> forgejo-runner.nix + # tailscale/auth-key -> tailscale.nix (via Modul) }; } diff --git a/modules/nixos/nginx/default.nix b/modules/nixos/nginx/default.nix index d28d7a9..3b2bef1 100644 --- a/modules/nixos/nginx/default.nix +++ b/modules/nixos/nginx/default.nix @@ -62,6 +62,7 @@ in acceptTerms = true; defaults.email = mkDefault "postmaster@${config.networking.domain}"; defaults.webroot = mkDefault "/var/lib/acme/acme-challenge"; + defaults.group = mkDefault "nginx"; }; security.dhparams = mkIf cfg.forceSSL { diff --git a/result b/result deleted file mode 120000 index e931342..0000000 --- a/result +++ /dev/null @@ -1 +0,0 @@ -/nix/store/xmcpz8rawfcbzr528rlnm5v0fmnrd8dj-nixos-system-cryodev-main-25.11.20260309.44bae27 \ No newline at end of file