at 23.11-beta 7.6 kB view raw
1# This tests parsedmarc by sending a report to its monitored email 2# address and reading the results out of Elasticsearch. 3 4{ pkgs, ... }@args: 5let 6 inherit (import ../../lib/testing-python.nix args) makeTest; 7 inherit (pkgs) lib; 8 9 dmarcTestReport = builtins.fetchurl { 10 name = "dmarc-test-report"; 11 url = "https://github.com/domainaware/parsedmarc/raw/f45ab94e0608088e0433557608d9f4e9517d3afe/samples/aggregate/estadocuenta1.infonacot.gob.mx!example.com!1536853302!1536939702!2940.xml.zip"; 12 sha256 = "0dq64cj49711kbja27pjl2hy0d3azrjxg91kqrh40x46fkn1dwkx"; 13 }; 14 15 sendEmail = address: 16 pkgs.writeScriptBin "send-email" '' 17 #!${pkgs.python3.interpreter} 18 import smtplib 19 from email import encoders 20 from email.mime.base import MIMEBase 21 from email.mime.multipart import MIMEMultipart 22 from email.mime.text import MIMEText 23 24 sender_email = "dmarc_tester@fake.domain" 25 receiver_email = "${address}" 26 27 message = MIMEMultipart() 28 message["From"] = sender_email 29 message["To"] = receiver_email 30 message["Subject"] = "DMARC test" 31 32 message.attach(MIMEText("Testing parsedmarc", "plain")) 33 34 attachment = MIMEBase("application", "zip") 35 36 with open("${dmarcTestReport}", "rb") as report: 37 attachment.set_payload(report.read()) 38 39 encoders.encode_base64(attachment) 40 41 attachment.add_header( 42 "Content-Disposition", 43 "attachment; filename= estadocuenta1.infonacot.gob.mx!example.com!1536853302!1536939702!2940.xml.zip", 44 ) 45 46 message.attach(attachment) 47 text = message.as_string() 48 49 with smtplib.SMTP('localhost') as server: 50 server.sendmail(sender_email, receiver_email, text) 51 server.quit() 52 ''; 53in 54{ 55 localMail = makeTest 56 { 57 name = "parsedmarc-local-mail"; 58 meta = with lib.maintainers; { 59 maintainers = [ talyz ]; 60 }; 61 62 nodes.parsedmarc = 63 { nodes, ... }: 64 { 65 virtualisation.memorySize = 2048; 66 67 services.postfix = { 68 enableSubmission = true; 69 enableSubmissions = true; 70 submissionsOptions = { 71 smtpd_sasl_auth_enable = "yes"; 72 smtpd_client_restrictions = "permit"; 73 }; 74 }; 75 76 services.parsedmarc = { 77 enable = true; 78 provision = { 79 geoIp = false; 80 localMail = { 81 enable = true; 82 hostname = "localhost"; 83 }; 84 }; 85 }; 86 87 environment.systemPackages = [ 88 (sendEmail "dmarc@localhost") 89 pkgs.jq 90 ]; 91 }; 92 93 testScript = { nodes }: 94 let 95 esPort = toString nodes.parsedmarc.config.services.elasticsearch.port; 96 valueObject = lib.optionalString (lib.versionAtLeast nodes.parsedmarc.config.services.elasticsearch.package.version "7") ".value"; 97 in '' 98 parsedmarc.start() 99 parsedmarc.wait_for_unit("postfix.service") 100 parsedmarc.wait_for_unit("dovecot2.service") 101 parsedmarc.wait_for_unit("parsedmarc.service") 102 parsedmarc.wait_until_succeeds( 103 "curl -sS -f http://localhost:${esPort}" 104 ) 105 106 parsedmarc.fail( 107 "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940" 108 + " | tee /dev/console" 109 + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'" 110 ) 111 parsedmarc.succeed("send-email") 112 parsedmarc.wait_until_succeeds( 113 "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940" 114 + " | tee /dev/console" 115 + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'" 116 ) 117 ''; 118 }; 119 120 externalMail = 121 let 122 certs = import ../common/acme/server/snakeoil-certs.nix; 123 mailDomain = certs.domain; 124 parsedmarcDomain = "parsedmarc.fake.domain"; 125 in 126 makeTest { 127 name = "parsedmarc-external-mail"; 128 meta = with lib.maintainers; { 129 maintainers = [ talyz ]; 130 }; 131 132 nodes = { 133 parsedmarc = 134 { nodes, ... }: 135 { 136 virtualisation.memorySize = 2048; 137 138 security.pki.certificateFiles = [ 139 certs.ca.cert 140 ]; 141 142 networking.extraHosts = '' 143 127.0.0.1 ${parsedmarcDomain} 144 ${nodes.mail.config.networking.primaryIPAddress} ${mailDomain} 145 ''; 146 147 services.parsedmarc = { 148 enable = true; 149 provision.geoIp = false; 150 settings.imap = { 151 host = mailDomain; 152 port = 993; 153 ssl = true; 154 user = "alice"; 155 password = "${pkgs.writeText "imap-password" "foobar"}"; 156 }; 157 }; 158 159 environment.systemPackages = [ 160 pkgs.jq 161 ]; 162 }; 163 164 mail = 165 { nodes, ... }: 166 { 167 imports = [ ../common/user-account.nix ]; 168 169 networking.extraHosts = '' 170 127.0.0.1 ${mailDomain} 171 ${nodes.parsedmarc.config.networking.primaryIPAddress} ${parsedmarcDomain} 172 ''; 173 174 services.dovecot2 = { 175 enable = true; 176 protocols = [ "imap" ]; 177 sslCACert = "${certs.ca.cert}"; 178 sslServerCert = "${certs.${mailDomain}.cert}"; 179 sslServerKey = "${certs.${mailDomain}.key}"; 180 }; 181 182 services.postfix = { 183 enable = true; 184 origin = mailDomain; 185 config = { 186 myhostname = mailDomain; 187 mydestination = mailDomain; 188 }; 189 enableSubmission = true; 190 enableSubmissions = true; 191 submissionsOptions = { 192 smtpd_sasl_auth_enable = "yes"; 193 smtpd_client_restrictions = "permit"; 194 }; 195 }; 196 environment.systemPackages = [ (sendEmail "alice@${mailDomain}") ]; 197 198 networking.firewall.allowedTCPPorts = [ 993 ]; 199 }; 200 }; 201 202 testScript = { nodes }: 203 let 204 esPort = toString nodes.parsedmarc.config.services.elasticsearch.port; 205 valueObject = lib.optionalString (lib.versionAtLeast nodes.parsedmarc.config.services.elasticsearch.package.version "7") ".value"; 206 in '' 207 mail.start() 208 mail.wait_for_unit("postfix.service") 209 mail.wait_for_unit("dovecot2.service") 210 211 parsedmarc.start() 212 parsedmarc.wait_for_unit("parsedmarc.service") 213 parsedmarc.wait_until_succeeds( 214 "curl -sS -f http://localhost:${esPort}" 215 ) 216 217 parsedmarc.fail( 218 "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940" 219 + " | tee /dev/console" 220 + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'" 221 ) 222 mail.succeed("send-email") 223 parsedmarc.wait_until_succeeds( 224 "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940" 225 + " | tee /dev/console" 226 + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'" 227 ) 228 ''; 229 }; 230}