at 17.09-beta 6.7 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 rspamdCfg = config.services.rspamd; 8 postfixCfg = config.services.postfix; 9 cfg = config.services.rmilter; 10 11 inetSocket = addr: port: "inet:[${toString port}@${addr}]"; 12 unixSocket = sock: "unix:${sock}"; 13 14 systemdSocket = if cfg.bindSocket.type == "unix" then cfg.bindSocket.path 15 else "${cfg.bindSocket.address}:${toString cfg.bindSocket.port}"; 16 rmilterSocket = if cfg.bindSocket.type == "unix" then unixSocket cfg.bindSocket.path 17 else inetSocket cfg.bindSocket.address cfg.bindSocket.port; 18 19 rmilterConf = '' 20 pidfile = /run/rmilter/rmilter.pid; 21 bind_socket = ${if cfg.socketActivation then "fd:3" else rmilterSocket}; 22 tempdir = /tmp; 23 '' + (with cfg.rspamd; if enable then '' 24 spamd { 25 servers = ${concatStringsSep ", " servers}; 26 connect_timeout = 1s; 27 results_timeout = 20s; 28 error_time = 10; 29 dead_time = 300; 30 maxerrors = 10; 31 reject_message = "${rejectMessage}"; 32 ${optionalString (length whitelist != 0) "whitelist = ${concatStringsSep ", " whitelist};"} 33 34 # rspamd_metric - metric for using with rspamd 35 # Default: "default" 36 rspamd_metric = "default"; 37 ${extraConfig} 38 }; 39 '' else "") + cfg.extraConfig; 40 41 rmilterConfigFile = pkgs.writeText "rmilter.conf" rmilterConf; 42 43in 44 45{ 46 47 ###### interface 48 49 options = { 50 51 services.rmilter = { 52 53 enable = mkOption { 54 type = types.bool; 55 default = cfg.rspamd.enable; 56 description = "Whether to run the rmilter daemon."; 57 }; 58 59 debug = mkOption { 60 type = types.bool; 61 default = false; 62 description = "Whether to run the rmilter daemon in debug mode."; 63 }; 64 65 user = mkOption { 66 type = types.string; 67 default = "rmilter"; 68 description = '' 69 User to use when no root privileges are required. 70 ''; 71 }; 72 73 group = mkOption { 74 type = types.string; 75 default = "rmilter"; 76 description = '' 77 Group to use when no root privileges are required. 78 ''; 79 }; 80 81 bindSocket.type = mkOption { 82 type = types.enum [ "unix" "inet" ]; 83 default = "unix"; 84 description = '' 85 What kind of socket rmilter should listen on. Either "unix" 86 for an Unix domain socket or "inet" for a TCP socket. 87 ''; 88 }; 89 90 bindSocket.path = mkOption { 91 type = types.str; 92 default = "/run/rmilter/rmilter.sock"; 93 description = '' 94 Path to Unix domain socket to listen on. 95 ''; 96 }; 97 98 bindSocket.address = mkOption { 99 type = types.str; 100 default = "::1"; 101 example = "0.0.0.0"; 102 description = '' 103 Inet address to listen on. 104 ''; 105 }; 106 107 bindSocket.port = mkOption { 108 type = types.int; 109 default = 11990; 110 description = '' 111 Inet port to listen on. 112 ''; 113 }; 114 115 socketActivation = mkOption { 116 type = types.bool; 117 default = true; 118 description = '' 119 Enable systemd socket activation for rmilter. 120 121 Disabling socket activation is not recommended when a Unix 122 domain socket is used and could lead to incorrect 123 permissions. 124 ''; 125 }; 126 127 rspamd = { 128 enable = mkOption { 129 type = types.bool; 130 default = rspamdCfg.enable; 131 description = "Whether to use rspamd to filter mails"; 132 }; 133 134 servers = mkOption { 135 type = types.listOf types.str; 136 default = ["r:/run/rspamd/rspamd.sock"]; 137 description = '' 138 Spamd socket definitions. 139 Is server name is prefixed with r: it is rspamd server. 140 ''; 141 }; 142 143 whitelist = mkOption { 144 type = types.listOf types.str; 145 default = [ ]; 146 description = "list of ips or nets that should be not checked with spamd"; 147 }; 148 149 rejectMessage = mkOption { 150 type = types.str; 151 default = "Spam message rejected; If this is not spam contact abuse"; 152 description = "reject message for spam"; 153 }; 154 155 extraConfig = mkOption { 156 type = types.lines; 157 default = ""; 158 description = "Custom snippet to append to end of `spamd' section"; 159 }; 160 }; 161 162 extraConfig = mkOption { 163 type = types.lines; 164 default = ""; 165 description = "Custom snippet to append to rmilter config"; 166 }; 167 168 postfix = { 169 enable = mkOption { 170 type = types.bool; 171 default = false; 172 description = "Add rmilter to postfix main.conf"; 173 }; 174 175 configFragment = mkOption { 176 type = types.str; 177 description = "Addon to postfix configuration"; 178 default = '' 179 smtpd_milters = ${rmilterSocket} 180 milter_protocol = 6 181 milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen} 182 ''; 183 }; 184 }; 185 186 }; 187 188 }; 189 190 191 ###### implementation 192 193 config = mkMerge [ 194 195 (mkIf cfg.enable { 196 197 users.extraUsers = singleton { 198 name = cfg.user; 199 description = "rmilter daemon"; 200 uid = config.ids.uids.rmilter; 201 group = cfg.group; 202 }; 203 204 users.extraGroups = singleton { 205 name = cfg.group; 206 gid = config.ids.gids.rmilter; 207 }; 208 209 systemd.services.rmilter = { 210 description = "Rmilter Service"; 211 212 wantedBy = [ "multi-user.target" ]; 213 after = [ "network.target" ]; 214 215 serviceConfig = { 216 ExecStart = "${pkgs.rmilter}/bin/rmilter ${optionalString cfg.debug "-d"} -n -c ${rmilterConfigFile}"; 217 ExecReload = "${pkgs.coreutils}/bin/kill -USR1 $MAINPID"; 218 User = cfg.user; 219 Group = cfg.group; 220 PermissionsStartOnly = true; 221 Restart = "always"; 222 RuntimeDirectory = "rmilter"; 223 RuntimeDirectoryMode = "0750"; 224 }; 225 226 }; 227 228 systemd.sockets.rmilter = mkIf cfg.socketActivation { 229 description = "Rmilter service socket"; 230 wantedBy = [ "sockets.target" ]; 231 socketConfig = { 232 ListenStream = systemdSocket; 233 SocketUser = cfg.user; 234 SocketGroup = cfg.group; 235 SocketMode = "0660"; 236 }; 237 }; 238 }) 239 240 (mkIf (cfg.enable && cfg.rspamd.enable && rspamdCfg.enable) { 241 users.extraUsers.${cfg.user}.extraGroups = [ rspamdCfg.group ]; 242 }) 243 244 (mkIf (cfg.enable && cfg.postfix.enable) { 245 services.postfix.extraConfig = cfg.postfix.configFragment; 246 users.extraUsers.${postfixCfg.user}.extraGroups = [ cfg.group ]; 247 }) 248 ]; 249}