nixpkgs/nixos/tests/parsedmarc/default.nix
Kim Lindberger ebaa226853
elk7: 7.11.1 -> 7.16.1, 6.8.3 -> 6.8.21 + add filebeat module and tests (#150879)
* elk7: 7.11.1 -> 7.16.1

* nixosTests.elk: Improve reliability and compatibility with ELK 7.x

- Use comparisons in jq instead of grepping
- Match for `.hits.total.value` if version >= 7, otherwise it always
  passes
- Make curl fail if requests fails

* nixos/filebeat: Add initial module and test

Filebeat is an open source file harvester, mostly used to fetch logs
files and feed them into logstash.

This module can be used instead of journalbeat if used with
`filebeat7` and configured with the `journald` input.

* python3Packages.parsedmarc.tests: Fix breakage

- Don't use the deprecated elasticsearch7-oss package
- Improve jq query robustness and add tracing

* rl-2205: Note the addition of the filebeat service

* elk6: 6.8.3 -> 6.8.21

The latest version includes a fix for CVE-2021-44228.

* nixos/journalbeat: Add a loose dependency on elasticsearch

Avoid unnecssary back-off when elasticsearch is running on the same
host.
2021-12-17 00:20:52 +09:00

236 lines
7.6 KiB
Nix

# This tests parsedmarc by sending a report to its monitored email
# address and reading the results out of Elasticsearch.
{ pkgs, ... }@args:
let
inherit (import ../../lib/testing-python.nix args) makeTest;
inherit (pkgs) lib;
dmarcTestReport = builtins.fetchurl {
name = "dmarc-test-report";
url = "https://github.com/domainaware/parsedmarc/raw/f45ab94e0608088e0433557608d9f4e9517d3afe/samples/aggregate/estadocuenta1.infonacot.gob.mx!example.com!1536853302!1536939702!2940.xml.zip";
sha256 = "0dq64cj49711kbja27pjl2hy0d3azrjxg91kqrh40x46fkn1dwkx";
};
sendEmail = address:
pkgs.writeScriptBin "send-email" ''
#!${pkgs.python3.interpreter}
import smtplib
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
sender_email = "dmarc_tester@fake.domain"
receiver_email = "${address}"
message = MIMEMultipart()
message["From"] = sender_email
message["To"] = receiver_email
message["Subject"] = "DMARC test"
message.attach(MIMEText("Testing parsedmarc", "plain"))
attachment = MIMEBase("application", "zip")
with open("${dmarcTestReport}", "rb") as report:
attachment.set_payload(report.read())
encoders.encode_base64(attachment)
attachment.add_header(
"Content-Disposition",
"attachment; filename= estadocuenta1.infonacot.gob.mx!example.com!1536853302!1536939702!2940.xml.zip",
)
message.attach(attachment)
text = message.as_string()
with smtplib.SMTP('localhost') as server:
server.sendmail(sender_email, receiver_email, text)
server.quit()
'';
in
{
localMail = makeTest
{
name = "parsedmarc-local-mail";
meta = with lib.maintainers; {
maintainers = [ talyz ];
};
nodes.parsedmarc =
{ nodes, ... }:
{
virtualisation.memorySize = 2048;
services.postfix = {
enableSubmission = true;
enableSubmissions = true;
submissionsOptions = {
smtpd_sasl_auth_enable = "yes";
smtpd_client_restrictions = "permit";
};
};
services.parsedmarc = {
enable = true;
provision = {
geoIp = false;
localMail = {
enable = true;
hostname = "localhost";
};
};
};
services.elasticsearch.package = pkgs.elasticsearch-oss;
environment.systemPackages = [
(sendEmail "dmarc@localhost")
pkgs.jq
];
};
testScript = { nodes }:
let
esPort = toString nodes.parsedmarc.config.services.elasticsearch.port;
valueObject = lib.optionalString (lib.versionAtLeast nodes.parsedmarc.config.services.elasticsearch.package.version "7") ".value";
in ''
parsedmarc.start()
parsedmarc.wait_for_unit("postfix.service")
parsedmarc.wait_for_unit("dovecot2.service")
parsedmarc.wait_for_unit("parsedmarc.service")
parsedmarc.wait_until_succeeds(
"curl -sS -f http://localhost:${esPort}"
)
parsedmarc.fail(
"curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940"
+ " | tee /dev/console"
+ " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'"
)
parsedmarc.succeed("send-email")
parsedmarc.wait_until_succeeds(
"curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940"
+ " | tee /dev/console"
+ " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'"
)
'';
};
externalMail =
let
certs = import ../common/acme/server/snakeoil-certs.nix;
mailDomain = certs.domain;
parsedmarcDomain = "parsedmarc.fake.domain";
in
makeTest {
name = "parsedmarc-external-mail";
meta = with lib.maintainers; {
maintainers = [ talyz ];
};
nodes = {
parsedmarc =
{ nodes, ... }:
{
virtualisation.memorySize = 2048;
security.pki.certificateFiles = [
certs.ca.cert
];
networking.extraHosts = ''
127.0.0.1 ${parsedmarcDomain}
${nodes.mail.config.networking.primaryIPAddress} ${mailDomain}
'';
services.parsedmarc = {
enable = true;
provision.geoIp = false;
settings.imap = {
host = mailDomain;
port = 993;
ssl = true;
user = "alice";
password = "${pkgs.writeText "imap-password" "foobar"}";
watch = true;
};
};
services.elasticsearch.package = pkgs.elasticsearch-oss;
environment.systemPackages = [
pkgs.jq
];
};
mail =
{ nodes, ... }:
{
imports = [ ../common/user-account.nix ];
networking.extraHosts = ''
127.0.0.1 ${mailDomain}
${nodes.parsedmarc.config.networking.primaryIPAddress} ${parsedmarcDomain}
'';
services.dovecot2 = {
enable = true;
protocols = [ "imap" ];
sslCACert = "${certs.ca.cert}";
sslServerCert = "${certs.${mailDomain}.cert}";
sslServerKey = "${certs.${mailDomain}.key}";
};
services.postfix = {
enable = true;
origin = mailDomain;
config = {
myhostname = mailDomain;
mydestination = mailDomain;
};
enableSubmission = true;
enableSubmissions = true;
submissionsOptions = {
smtpd_sasl_auth_enable = "yes";
smtpd_client_restrictions = "permit";
};
};
environment.systemPackages = [ (sendEmail "alice@${mailDomain}") ];
networking.firewall.allowedTCPPorts = [ 993 ];
};
};
testScript = { nodes }:
let
esPort = toString nodes.parsedmarc.config.services.elasticsearch.port;
valueObject = lib.optionalString (lib.versionAtLeast nodes.parsedmarc.config.services.elasticsearch.package.version "7") ".value";
in ''
mail.start()
mail.wait_for_unit("postfix.service")
mail.wait_for_unit("dovecot2.service")
parsedmarc.start()
parsedmarc.wait_for_unit("parsedmarc.service")
parsedmarc.wait_until_succeeds(
"curl -sS -f http://localhost:${esPort}"
)
parsedmarc.fail(
"curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940"
+ " | tee /dev/console"
+ " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'"
)
mail.succeed("send-email")
parsedmarc.wait_until_succeeds(
"curl -sS -f http://localhost:${esPort}/_search?q=report_id:2940"
+ " | tee /dev/console"
+ " | jq -es 'if . == [] then null else .[] | .hits.total${valueObject} > 0 end'"
)
'';
};
}