Self-host your own digital island
1# nixos-mailserver: a simple mail server 2# Copyright (C) 2016-2018 Robin Raymond 3# 4# This program is free software: you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation, either version 3 of the License, or 7# (at your option) any later version. 8# 9# This program is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program. If not, see <http://www.gnu.org/licenses/> 16 17{ config, pkgs, lib, ... }: 18 19let 20 cfg = config.mailserver; 21 22 postfixCfg = config.services.postfix; 23 rspamdCfg = config.services.rspamd; 24 rspamdSocket = "rspamd.service"; 25in 26{ 27 config = with cfg; lib.mkIf enable { 28 services.rspamd = { 29 enable = true; 30 inherit debug; 31 locals = { 32 "milter_headers.conf" = { text = '' 33 extended_spam_headers = yes; 34 ''; }; 35 "redis.conf" = { text = '' 36 servers = "${cfg.redis.address}:${toString cfg.redis.port}"; 37 '' + (lib.optionalString (cfg.redis.password != null) '' 38 password = "${cfg.redis.password}"; 39 ''); }; 40 "classifier-bayes.conf" = { text = '' 41 cache { 42 backend = "redis"; 43 } 44 ''; }; 45 "antivirus.conf" = lib.mkIf cfg.virusScanning { text = '' 46 clamav { 47 action = "reject"; 48 symbol = "CLAM_VIRUS"; 49 type = "clamav"; 50 log_clean = true; 51 servers = "/run/clamav/clamd.ctl"; 52 scan_mime_parts = false; # scan mail as a whole unit, not parts. seems to be needed to work at all 53 } 54 ''; }; 55 "dkim_signing.conf" = { text = '' 56 # Disable outbound email signing, we use opendkim for this 57 enabled = false; 58 ''; }; 59 }; 60 61 overrides = { 62 "milter_headers.conf" = { 63 text = '' 64 extended_spam_headers = true; 65 ''; 66 }; 67 }; 68 69 workers.rspamd_proxy = { 70 type = "rspamd_proxy"; 71 bindSockets = [{ 72 socket = "/run/rspamd/rspamd-milter.sock"; 73 mode = "0664"; 74 }]; 75 count = 1; # Do not spawn too many processes of this type 76 extraConfig = '' 77 milter = yes; # Enable milter mode 78 timeout = 120s; # Needed for Milter usually 79 80 upstream "local" { 81 default = yes; # Self-scan upstreams are always default 82 self_scan = yes; # Enable self-scan 83 } 84 ''; 85 }; 86 workers.controller = { 87 type = "controller"; 88 count = 1; 89 bindSockets = [{ 90 socket = "/run/rspamd/worker-controller.sock"; 91 mode = "0666"; 92 }]; 93 includes = []; 94 extraConfig = '' 95 static_dir = "''${WWWDIR}"; # Serve the web UI static assets 96 ''; 97 }; 98 99 }; 100 101 services.redis.servers.rspamd = { 102 enable = lib.mkDefault true; 103 port = lib.mkDefault 6380; 104 }; 105 106 systemd.services.rspamd = { 107 requires = [ "redis-rspamd.service" ] ++ (lib.optional cfg.virusScanning "clamav-daemon.service"); 108 after = [ "redis-rspamd.service" ] ++ (lib.optional cfg.virusScanning "clamav-daemon.service"); 109 }; 110 111 systemd.services.postfix = { 112 after = [ rspamdSocket ]; 113 requires = [ rspamdSocket ]; 114 }; 115 116 users.extraUsers.${postfixCfg.user}.extraGroups = [ rspamdCfg.group ]; 117 }; 118} 119