at 23.05-pre 7.7 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 services.elasticsearch.package = pkgs.elasticsearch-oss; 88 89 environment.systemPackages = [ 90 (sendEmail "dmarc@localhost") 91 pkgs.jq 92 ]; 93 }; 94 95 testScript = { nodes }: 96 let 97 esPort = toString nodes.parsedmarc.config.services.elasticsearch.port; 98 valueObject = lib.optionalString (lib.versionAtLeast nodes.parsedmarc.config.services.elasticsearch.package.version "7") ".value"; 99 in '' 100 parsedmarc.start() 101 parsedmarc.wait_for_unit("postfix.service") 102 parsedmarc.wait_for_unit("dovecot2.service") 103 parsedmarc.wait_for_unit("parsedmarc.service") 104 parsedmarc.wait_until_succeeds( 105 "curl -sS -f http://localhost:${esPort}" 106 ) 107 108 parsedmarc.fail( 109 "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940" 110 + " | tee /dev/console" 111 + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'" 112 ) 113 parsedmarc.succeed("send-email") 114 parsedmarc.wait_until_succeeds( 115 "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940" 116 + " | tee /dev/console" 117 + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'" 118 ) 119 ''; 120 }; 121 122 externalMail = 123 let 124 certs = import ../common/acme/server/snakeoil-certs.nix; 125 mailDomain = certs.domain; 126 parsedmarcDomain = "parsedmarc.fake.domain"; 127 in 128 makeTest { 129 name = "parsedmarc-external-mail"; 130 meta = with lib.maintainers; { 131 maintainers = [ talyz ]; 132 }; 133 134 nodes = { 135 parsedmarc = 136 { nodes, ... }: 137 { 138 virtualisation.memorySize = 2048; 139 140 security.pki.certificateFiles = [ 141 certs.ca.cert 142 ]; 143 144 networking.extraHosts = '' 145 127.0.0.1 ${parsedmarcDomain} 146 ${nodes.mail.config.networking.primaryIPAddress} ${mailDomain} 147 ''; 148 149 services.parsedmarc = { 150 enable = true; 151 provision.geoIp = false; 152 settings.imap = { 153 host = mailDomain; 154 port = 993; 155 ssl = true; 156 user = "alice"; 157 password = "${pkgs.writeText "imap-password" "foobar"}"; 158 watch = true; 159 }; 160 }; 161 162 services.elasticsearch.package = pkgs.elasticsearch-oss; 163 164 environment.systemPackages = [ 165 pkgs.jq 166 ]; 167 }; 168 169 mail = 170 { nodes, ... }: 171 { 172 imports = [ ../common/user-account.nix ]; 173 174 networking.extraHosts = '' 175 127.0.0.1 ${mailDomain} 176 ${nodes.parsedmarc.config.networking.primaryIPAddress} ${parsedmarcDomain} 177 ''; 178 179 services.dovecot2 = { 180 enable = true; 181 protocols = [ "imap" ]; 182 sslCACert = "${certs.ca.cert}"; 183 sslServerCert = "${certs.${mailDomain}.cert}"; 184 sslServerKey = "${certs.${mailDomain}.key}"; 185 }; 186 187 services.postfix = { 188 enable = true; 189 origin = mailDomain; 190 config = { 191 myhostname = mailDomain; 192 mydestination = mailDomain; 193 }; 194 enableSubmission = true; 195 enableSubmissions = true; 196 submissionsOptions = { 197 smtpd_sasl_auth_enable = "yes"; 198 smtpd_client_restrictions = "permit"; 199 }; 200 }; 201 environment.systemPackages = [ (sendEmail "alice@${mailDomain}") ]; 202 203 networking.firewall.allowedTCPPorts = [ 993 ]; 204 }; 205 }; 206 207 testScript = { nodes }: 208 let 209 esPort = toString nodes.parsedmarc.config.services.elasticsearch.port; 210 valueObject = lib.optionalString (lib.versionAtLeast nodes.parsedmarc.config.services.elasticsearch.package.version "7") ".value"; 211 in '' 212 mail.start() 213 mail.wait_for_unit("postfix.service") 214 mail.wait_for_unit("dovecot2.service") 215 216 parsedmarc.start() 217 parsedmarc.wait_for_unit("parsedmarc.service") 218 parsedmarc.wait_until_succeeds( 219 "curl -sS -f http://localhost:${esPort}" 220 ) 221 222 parsedmarc.fail( 223 "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940" 224 + " | tee /dev/console" 225 + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'" 226 ) 227 mail.succeed("send-email") 228 parsedmarc.wait_until_succeeds( 229 "curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940" 230 + " | tee /dev/console" 231 + " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'" 232 ) 233 ''; 234 }; 235}