at master 6.7 kB view raw
1{ 2 config, 3 pkgs, 4 lib, 5 ... 6}: 7let 8 cfg = config.services.schleuder; 9 settingsFormat = pkgs.formats.yaml { }; 10 postfixMap = 11 entries: lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value: "${name} ${value}") entries); 12 writePostfixMap = name: entries: pkgs.writeText name (postfixMap entries); 13 configScript = pkgs.writeScript "schleuder-cfg" '' 14 #!${pkgs.runtimeShell} 15 set -exuo pipefail 16 umask 0077 17 ${pkgs.yq}/bin/yq \ 18 --slurpfile overrides <(${pkgs.yq}/bin/yq . <${lib.escapeShellArg cfg.extraSettingsFile}) \ 19 < ${settingsFormat.generate "schleuder.yml" cfg.settings} \ 20 '. * $overrides[0]' \ 21 > /etc/schleuder/schleuder.yml 22 chown schleuder: /etc/schleuder/schleuder.yml 23 ''; 24in 25{ 26 options.services.schleuder = { 27 enable = lib.mkEnableOption "Schleuder secure remailer"; 28 enablePostfix = lib.mkEnableOption "automatic postfix integration" // { 29 default = true; 30 }; 31 lists = lib.mkOption { 32 description = '' 33 List of list addresses that should be handled by Schleuder. 34 35 Note that this is only handled by the postfix integration, and 36 the setup of the lists, their members and their keys has to be 37 performed separately via schleuder's API, using a tool such as 38 schleuder-cli. 39 ''; 40 type = lib.types.listOf lib.types.str; 41 default = [ ]; 42 example = [ 43 "widget-team@example.com" 44 "security@example.com" 45 ]; 46 }; 47 /* 48 maybe one day.... 49 domains = lib.mkOption { 50 description = "Domains for which all mail should be handled by Schleuder."; 51 type = lib.types.listOf lib.types.str; 52 default = []; 53 example = ["securelists.example.com"]; 54 }; 55 */ 56 settings = lib.mkOption { 57 description = '' 58 Settings for schleuder.yml. 59 60 Check the [example configuration](https://0xacab.org/schleuder/schleuder/blob/master/etc/schleuder.yml) for possible values. 61 ''; 62 type = lib.types.submodule { 63 freeformType = settingsFormat.type; 64 options.keyserver = lib.mkOption { 65 type = lib.types.str; 66 description = '' 67 Key server from which to fetch and update keys. 68 69 Note that NixOS uses a different default from upstream, since the upstream default sks-keyservers.net is deprecated. 70 ''; 71 default = "keys.openpgp.org"; 72 }; 73 }; 74 default = { }; 75 }; 76 extraSettingsFile = lib.mkOption { 77 description = "YAML file to merge into the schleuder config at runtime. This can be used for secrets such as API keys."; 78 type = lib.types.nullOr lib.types.path; 79 default = null; 80 }; 81 listDefaults = lib.mkOption { 82 description = '' 83 Default settings for lists (list-defaults.yml). 84 85 Check the [example configuration](https://0xacab.org/schleuder/schleuder/-/blob/master/etc/list-defaults.yml) for possible values. 86 ''; 87 type = settingsFormat.type; 88 default = { }; 89 }; 90 }; 91 config = lib.mkIf cfg.enable { 92 assertions = [ 93 { 94 assertion = !(cfg.settings.api ? valid_api_keys); 95 message = '' 96 services.schleuder.settings.api.valid_api_keys is set. Defining API keys via NixOS config results in them being copied to the world-readable Nix store. Please use the extraSettingsFile option to store API keys in a non-public location. 97 ''; 98 } 99 { 100 assertion = !(lib.any (db: db ? password) (lib.attrValues cfg.settings.database or { })); 101 message = '' 102 A password is defined for at least one database in services.schleuder.settings.database. Defining passwords via NixOS config results in them being copied to the world-readable Nix store. Please use the extraSettingsFile option to store database passwords in a non-public location. 103 ''; 104 } 105 ]; 106 users.users.schleuder.isSystemUser = true; 107 users.users.schleuder.group = "schleuder"; 108 users.groups.schleuder = { }; 109 environment.systemPackages = [ 110 pkgs.schleuder-cli 111 ]; 112 services.postfix = lib.mkIf cfg.enablePostfix { 113 extraMasterConf = '' 114 schleuder unix - n n - - pipe 115 flags=DRhu user=schleuder argv=/${pkgs.schleuder}/bin/schleuder work ''${recipient} 116 ''; 117 transport = lib.mkIf (cfg.lists != [ ]) (postfixMap (lib.genAttrs cfg.lists (_: "schleuder:"))); 118 settings.main.schleuder_destination_recipient_limit = 1; 119 # review: does this make sense? 120 localRecipients = lib.mkIf (cfg.lists != [ ]) cfg.lists; 121 }; 122 systemd.services = 123 let 124 commonServiceConfig = { 125 # We would have liked to use DynamicUser, but since the default 126 # database is SQLite and lives in StateDirectory, and that same 127 # database needs to be readable from the postfix service, this 128 # isn't trivial to do. 129 User = "schleuder"; 130 StateDirectory = "schleuder"; 131 StateDirectoryMode = "0700"; 132 }; 133 in 134 { 135 schleuder-init = { 136 serviceConfig = commonServiceConfig // { 137 ExecStartPre = lib.mkIf (cfg.extraSettingsFile != null) [ 138 "+${configScript}" 139 ]; 140 ExecStart = [ "${pkgs.schleuder}/bin/schleuder install" ]; 141 Type = "oneshot"; 142 }; 143 }; 144 schleuder-api-daemon = { 145 after = [ 146 "local-fs.target" 147 "network.target" 148 "schleuder-init.service" 149 ]; 150 wantedBy = [ "multi-user.target" ]; 151 requires = [ "schleuder-init.service" ]; 152 serviceConfig = commonServiceConfig // { 153 ExecStart = [ "${pkgs.schleuder}/bin/schleuder-api-daemon" ]; 154 }; 155 }; 156 schleuder-weekly-key-maintenance = { 157 after = [ 158 "local-fs.target" 159 "network.target" 160 ]; 161 startAt = "weekly"; 162 serviceConfig = commonServiceConfig // { 163 ExecStart = [ 164 "${pkgs.schleuder}/bin/schleuder refresh_keys" 165 "${pkgs.schleuder}/bin/schleuder check_keys" 166 ]; 167 }; 168 }; 169 }; 170 171 environment.etc."schleuder/schleuder.yml" = lib.mkIf (cfg.extraSettingsFile == null) { 172 source = settingsFormat.generate "schleuder.yml" cfg.settings; 173 }; 174 environment.etc."schleuder/list-defaults.yml".source = 175 settingsFormat.generate "list-defaults.yml" cfg.listDefaults; 176 177 services.schleuder = { 178 #lists_dir = "/var/lib/schleuder.lists"; 179 settings.filters_dir = lib.mkDefault "/var/lib/schleuder/filters"; 180 settings.keyword_handlers_dir = lib.mkDefault "/var/lib/schleuder/keyword_handlers"; 181 }; 182 }; 183}