at master 5.2 kB view raw
1{ pkgs, ... }: 2let 3 certs = import ./common/acme/server/snakeoil-certs.nix; 4 domain = certs.domain; 5in 6{ 7 name = "rspamd-trainer"; 8 meta = with pkgs.lib.maintainers; { 9 maintainers = [ onny ]; 10 }; 11 12 nodes = { 13 machine = 14 { options, config, ... }: 15 { 16 17 security.pki.certificateFiles = [ 18 certs.ca.cert 19 ]; 20 21 networking.extraHosts = '' 22 127.0.0.1 ${domain} 23 ''; 24 25 services.rspamd-trainer = { 26 enable = true; 27 settings = { 28 HOST = domain; 29 USERNAME = "spam@${domain}"; 30 INBOXPREFIX = "INBOX/"; 31 }; 32 secrets = [ 33 # Do not use this in production. This will make passwords 34 # world-readable in the Nix store 35 "${pkgs.writeText "secrets" '' 36 PASSWORD = test123 37 ''}" 38 ]; 39 }; 40 41 services.maddy = { 42 enable = true; 43 hostname = domain; 44 primaryDomain = domain; 45 ensureAccounts = [ "spam@${domain}" ]; 46 ensureCredentials = { 47 # Do not use this in production. This will make passwords world-readable 48 # in the Nix store 49 "spam@${domain}".passwordFile = "${pkgs.writeText "postmaster" "test123"}"; 50 }; 51 tls = { 52 loader = "file"; 53 certificates = [ 54 { 55 certPath = "${certs.${domain}.cert}"; 56 keyPath = "${certs.${domain}.key}"; 57 } 58 ]; 59 }; 60 config = 61 builtins.replaceStrings 62 [ 63 "imap tcp://0.0.0.0:143" 64 "submission tcp://0.0.0.0:587" 65 ] 66 [ 67 "imap tls://0.0.0.0:993 tcp://0.0.0.0:143" 68 "submission tls://0.0.0.0:465 tcp://0.0.0.0:587" 69 ] 70 options.services.maddy.config.default; 71 }; 72 73 services.rspamd = { 74 enable = true; 75 locals = { 76 "redis.conf".text = '' 77 servers = "${config.services.redis.servers.rspamd.unixSocket}"; 78 ''; 79 "classifier-bayes.conf".text = '' 80 backend = "redis"; 81 autolearn = true; 82 ''; 83 }; 84 }; 85 86 services.redis.servers.rspamd = { 87 enable = true; 88 port = 0; 89 unixSocket = "/run/redis-rspamd/redis.sock"; 90 user = config.services.rspamd.user; 91 }; 92 93 environment.systemPackages = [ 94 (pkgs.writers.writePython3Bin "send-testmail" { } '' 95 import smtplib 96 import ssl 97 from email.mime.text import MIMEText 98 context = ssl.create_default_context() 99 msg = MIMEText("Hello World") 100 msg['Subject'] = 'Test' 101 msg['From'] = "spam@${domain}" 102 msg['To'] = "spam@${domain}" 103 with smtplib.SMTP_SSL(host='${domain}', port=465, context=context) as smtp: 104 smtp.login('spam@${domain}', 'test123') 105 smtp.sendmail( 106 'spam@${domain}', 'spam@${domain}', msg.as_string() 107 ) 108 '') 109 (pkgs.writers.writePython3Bin "create-mail-dirs" { } '' 110 import imaplib 111 with imaplib.IMAP4_SSL('${domain}') as imap: 112 imap.login('spam@${domain}', 'test123') 113 imap.create("\"INBOX/report_spam\"") 114 imap.create("\"INBOX/report_ham\"") 115 imap.create("\"INBOX/report_spam_reply\"") 116 imap.select("INBOX") 117 imap.copy("1", "\"INBOX/report_ham\"") 118 imap.logout() 119 '') 120 (pkgs.writers.writePython3Bin "test-imap" { } '' 121 import imaplib 122 with imaplib.IMAP4_SSL('${domain}') as imap: 123 imap.login('spam@${domain}', 'test123') 124 imap.select("INBOX/learned_ham") 125 status, refs = imap.search(None, 'ALL') 126 assert status == 'OK' 127 assert len(refs) == 1 128 status, msg = imap.fetch(refs[0], 'BODY[TEXT]') 129 assert status == 'OK' 130 assert msg[0][1].strip() == b"Hello World" 131 imap.logout() 132 '') 133 ]; 134 135 }; 136 137 }; 138 139 testScript = 140 { nodes }: 141 '' 142 start_all() 143 machine.wait_for_unit("maddy.service") 144 machine.wait_for_open_port(143) 145 machine.wait_for_open_port(993) 146 machine.wait_for_open_port(587) 147 machine.wait_for_open_port(465) 148 149 # Send test mail to spam@domain 150 machine.succeed("send-testmail") 151 152 # Create mail directories required for rspamd-trainer and copy mail from 153 # INBOX into INBOX/report_ham 154 machine.succeed("create-mail-dirs") 155 156 # Start rspamd-trainer. It should read mail from INBOX/report_ham 157 machine.wait_for_unit("rspamd.service") 158 machine.wait_for_unit("redis-rspamd.service") 159 machine.wait_for_file("/run/rspamd/rspamd.sock") 160 machine.succeed("systemctl start rspamd-trainer.service") 161 162 # Check if mail got processed by rspamd-trainer successfully and check for 163 # it in INBOX/learned_ham 164 machine.succeed("test-imap") 165 ''; 166}