diff options
author | Eric Wolf <robo-eric@gmx.de> | 2023-07-04 23:49:12 +0200 |
---|---|---|
committer | Yt <happysalada@tuta.io> | 2023-07-28 07:49:27 +0000 |
commit | 318d8cc4c5f9d176bc4795459b854d2bd4cf13d3 (patch) | |
tree | cdfc2e05f39f54396b82af5e988d5116ff8389ee /nixos/modules/services/web-apps/lemmy.nix | |
parent | e6f2df779870ee0c368e0a90a3266dfac41dc3b9 (diff) | |
download | nixlib-318d8cc4c5f9d176bc4795459b854d2bd4cf13d3.tar nixlib-318d8cc4c5f9d176bc4795459b854d2bd4cf13d3.tar.gz nixlib-318d8cc4c5f9d176bc4795459b854d2bd4cf13d3.tar.bz2 nixlib-318d8cc4c5f9d176bc4795459b854d2bd4cf13d3.tar.lz nixlib-318d8cc4c5f9d176bc4795459b854d2bd4cf13d3.tar.xz nixlib-318d8cc4c5f9d176bc4795459b854d2bd4cf13d3.tar.zst nixlib-318d8cc4c5f9d176bc4795459b854d2bd4cf13d3.zip |
nixos/lemmy: limit impurity by secrets
Split `services.lemmy.secretFile` into multiple options to allow only secrets.
Diffstat (limited to 'nixos/modules/services/web-apps/lemmy.nix')
-rw-r--r-- | nixos/modules/services/web-apps/lemmy.nix | 82 |
1 files changed, 56 insertions, 26 deletions
diff --git a/nixos/modules/services/web-apps/lemmy.nix b/nixos/modules/services/web-apps/lemmy.nix index a8ad4c50f2f0..6dfba907fb5d 100644 --- a/nixos/modules/services/web-apps/lemmy.nix +++ b/nixos/modules/services/web-apps/lemmy.nix @@ -1,4 +1,4 @@ -{ lib, pkgs, config, ... }: +{ lib, pkgs, config, utils, ... }: with lib; let cfg = config.services.lemmy; @@ -41,6 +41,30 @@ in default = null; description = lib.mdDoc "The connection URI to use. Takes priority over the configuration file if set."; }; + + uriFile = mkOption { + type = with types; nullOr path; + default = null; + description = lib.mdDoc "File which contains the database uri."; + }; + }; + + pictrsApiKeyFile = mkOption { + type = with types; nullOr path; + default = null; + description = lib.mdDoc "File which contains the value of `pictrs.api_key`."; + }; + + smtpPasswordFile = mkOption { + type = with types; nullOr path; + default = null; + description = lib.mdDoc "File which contains the value of `email.smtp_password`."; + }; + + adminPasswordFile = mkOption { + type = with types; nullOr path; + default = null; + description = lib.mdDoc "File which contains the value of `setup.admin_password`."; }; settings = mkOption { @@ -76,17 +100,20 @@ in }; }; }; - - secretFile = mkOption { - type = with types; nullOr path; - default = null; - description = lib.mdDoc "Path to a secret JSON configuration file which is merged at runtime with the one generated from {option}`services.lemmy.settings`."; - }; }; config = + let + secretOptions = { + pictrsApiKeyFile = { setting = [ "pictrs" "api_key" ]; path = cfg.pictrsApiKeyFile; }; + smtpPasswordFile = { setting = [ "email" "smtp_password" ]; path = cfg.smtpPasswordFile; }; + adminPasswordFile = { setting = [ "setup" "admin_password" ]; path = cfg.adminPasswordFile; }; + uriFile = { setting = [ "database" "uri" ]; path = cfg.database.uriFile; }; + }; + secrets = lib.filterAttrs (option: data: data.path != null) secretOptions; + in lib.mkIf cfg.enable { - services.lemmy.settings = (mapAttrs (name: mkDefault) + services.lemmy.settings = lib.attrsets.recursiveUpdate (mapAttrs (name: mkDefault) { bind = "127.0.0.1"; tls_enabled = true; @@ -104,14 +131,15 @@ in rate_limit.image = 6; rate_limit.image_per_second = 3600; } // { - database = mapAttrs (name: mkDefault) { - user = "lemmy"; - host = "/run/postgresql"; - port = 5432; - database = "lemmy"; - pool_size = 5; - }; - }); + database = mapAttrs (name: mkDefault) { + user = "lemmy"; + host = "/run/postgresql"; + port = 5432; + database = "lemmy"; + pool_size = 5; + }; + }) (lib.foldlAttrs (acc: option: data: acc // lib.setAttrByPath data.setting { _secret = option; }) {} secrets); + # the option name is the id of the credential loaded by LoadCredential services.postgresql = mkIf cfg.database.createLocally { enable = true; @@ -202,16 +230,19 @@ in assertion = (!(hasAttrByPath ["federation"] cfg.settings)) && (!(hasAttrByPath ["federation" "enabled"] cfg.settings)); message = "`services.lemmy.settings.federation` was removed in 0.17.0 and no longer has any effect"; } + { + assertion = cfg.database.uriFile != null -> cfg.database.uri == null && !cfg.database.createLocally; + message = "specifying a database uri while also specifying a database uri file is not allowed"; + } ]; systemd.services.lemmy = let - configFile = settingsFormat.generate "config.hjson" cfg.settings; - mergedConfig = "/run/lemmy/config.hjson"; + substitutedConfig = "/run/lemmy/config.hjson"; in { description = "Lemmy server"; environment = { - LEMMY_CONFIG_LOCATION = if cfg.secretFile == null then configFile else mergedConfig; + LEMMY_CONFIG_LOCATION = if secrets == {} then settingsFormat.generate "config.hjson" cfg.settings else substitutedConfig; LEMMY_DATABASE_URL = if cfg.database.uri != null then cfg.database.uri else (mkIf (cfg.database.createLocally) "postgres:///lemmy?host=/run/postgresql&user=lemmy"); }; @@ -226,21 +257,20 @@ in requires = lib.optionals cfg.database.createLocally [ "postgresql.service" ]; - path = mkIf (cfg.secretFile != null) [ pkgs.jq ]; - - # merge the two configs and prevent others from reading the result + # substitute secrets and prevent others from reading the result # if somehow $CREDENTIALS_DIRECTORY is not set we fail - preStart = mkIf (cfg.secretFile != null) '' + preStart = mkIf (secrets != {}) '' set -u - umask 177 - jq --slurp '.[0] * .[1]' ${lib.escapeShellArg configFile} "$CREDENTIALS_DIRECTORY/secretFile" > ${lib.escapeShellArg mergedConfig} + umask u=rw,g=,o= + cd "$CREDENTIALS_DIRECTORY" + ${utils.genJqSecretsReplacementSnippet cfg.settings substitutedConfig} ''; serviceConfig = { DynamicUser = true; RuntimeDirectory = "lemmy"; ExecStart = "${cfg.server.package}/bin/lemmy_server"; - LoadCredential = mkIf (cfg.secretFile != null) "secretFile:${toString cfg.secretFile}"; + LoadCredential = lib.foldlAttrs (acc: option: data: acc ++ [ "${option}:${toString data.path}" ]) [] secrets; PrivateTmp = true; MemoryDenyWriteExecute = true; NoNewPrivileges = true; |