168 lines
5.4 KiB
Nix
168 lines
5.4 KiB
Nix
import ./make-test-python.nix (
|
|
{ pkgs, ... }:
|
|
let
|
|
certs = import ./common/acme/server/snakeoil-certs.nix;
|
|
domain = certs.domain;
|
|
in
|
|
{
|
|
name = "rspamd-trainer";
|
|
meta = with pkgs.lib.maintainers; {
|
|
maintainers = [ onny ];
|
|
};
|
|
|
|
nodes = {
|
|
machine =
|
|
{ options, config, ... }:
|
|
{
|
|
|
|
security.pki.certificateFiles = [
|
|
certs.ca.cert
|
|
];
|
|
|
|
networking.extraHosts = ''
|
|
127.0.0.1 ${domain}
|
|
'';
|
|
|
|
services.rspamd-trainer = {
|
|
enable = true;
|
|
settings = {
|
|
HOST = domain;
|
|
USERNAME = "spam@${domain}";
|
|
INBOXPREFIX = "INBOX/";
|
|
};
|
|
secrets = [
|
|
# Do not use this in production. This will make passwords
|
|
# world-readable in the Nix store
|
|
"${pkgs.writeText "secrets" ''
|
|
PASSWORD = test123
|
|
''}"
|
|
];
|
|
};
|
|
|
|
services.maddy = {
|
|
enable = true;
|
|
hostname = domain;
|
|
primaryDomain = domain;
|
|
ensureAccounts = [ "spam@${domain}" ];
|
|
ensureCredentials = {
|
|
# Do not use this in production. This will make passwords world-readable
|
|
# in the Nix store
|
|
"spam@${domain}".passwordFile = "${pkgs.writeText "postmaster" "test123"}";
|
|
};
|
|
tls = {
|
|
loader = "file";
|
|
certificates = [
|
|
{
|
|
certPath = "${certs.${domain}.cert}";
|
|
keyPath = "${certs.${domain}.key}";
|
|
}
|
|
];
|
|
};
|
|
config =
|
|
builtins.replaceStrings
|
|
[
|
|
"imap tcp://0.0.0.0:143"
|
|
"submission tcp://0.0.0.0:587"
|
|
]
|
|
[
|
|
"imap tls://0.0.0.0:993 tcp://0.0.0.0:143"
|
|
"submission tls://0.0.0.0:465 tcp://0.0.0.0:587"
|
|
]
|
|
options.services.maddy.config.default;
|
|
};
|
|
|
|
services.rspamd = {
|
|
enable = true;
|
|
locals = {
|
|
"redis.conf".text = ''
|
|
servers = "${config.services.redis.servers.rspamd.unixSocket}";
|
|
'';
|
|
"classifier-bayes.conf".text = ''
|
|
backend = "redis";
|
|
autolearn = true;
|
|
'';
|
|
};
|
|
};
|
|
|
|
services.redis.servers.rspamd = {
|
|
enable = true;
|
|
port = 0;
|
|
unixSocket = "/run/redis-rspamd/redis.sock";
|
|
user = config.services.rspamd.user;
|
|
};
|
|
|
|
environment.systemPackages = [
|
|
(pkgs.writers.writePython3Bin "send-testmail" { } ''
|
|
import smtplib
|
|
import ssl
|
|
from email.mime.text import MIMEText
|
|
context = ssl.create_default_context()
|
|
msg = MIMEText("Hello World")
|
|
msg['Subject'] = 'Test'
|
|
msg['From'] = "spam@${domain}"
|
|
msg['To'] = "spam@${domain}"
|
|
with smtplib.SMTP_SSL(host='${domain}', port=465, context=context) as smtp:
|
|
smtp.login('spam@${domain}', 'test123')
|
|
smtp.sendmail(
|
|
'spam@${domain}', 'spam@${domain}', msg.as_string()
|
|
)
|
|
'')
|
|
(pkgs.writers.writePython3Bin "create-mail-dirs" { } ''
|
|
import imaplib
|
|
with imaplib.IMAP4_SSL('${domain}') as imap:
|
|
imap.login('spam@${domain}', 'test123')
|
|
imap.create("\"INBOX/report_spam\"")
|
|
imap.create("\"INBOX/report_ham\"")
|
|
imap.create("\"INBOX/report_spam_reply\"")
|
|
imap.select("INBOX")
|
|
imap.copy("1", "\"INBOX/report_ham\"")
|
|
imap.logout()
|
|
'')
|
|
(pkgs.writers.writePython3Bin "test-imap" { } ''
|
|
import imaplib
|
|
with imaplib.IMAP4_SSL('${domain}') as imap:
|
|
imap.login('spam@${domain}', 'test123')
|
|
imap.select("INBOX/learned_ham")
|
|
status, refs = imap.search(None, 'ALL')
|
|
assert status == 'OK'
|
|
assert len(refs) == 1
|
|
status, msg = imap.fetch(refs[0], 'BODY[TEXT]')
|
|
assert status == 'OK'
|
|
assert msg[0][1].strip() == b"Hello World"
|
|
imap.logout()
|
|
'')
|
|
];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
testScript =
|
|
{ nodes }:
|
|
''
|
|
start_all()
|
|
machine.wait_for_unit("maddy.service")
|
|
machine.wait_for_open_port(143)
|
|
machine.wait_for_open_port(993)
|
|
machine.wait_for_open_port(587)
|
|
machine.wait_for_open_port(465)
|
|
|
|
# Send test mail to spam@domain
|
|
machine.succeed("send-testmail")
|
|
|
|
# Create mail directories required for rspamd-trainer and copy mail from
|
|
# INBOX into INBOX/report_ham
|
|
machine.succeed("create-mail-dirs")
|
|
|
|
# Start rspamd-trainer. It should read mail from INBOX/report_ham
|
|
machine.wait_for_unit("rspamd.service")
|
|
machine.wait_for_unit("redis-rspamd.service")
|
|
machine.wait_for_file("/run/rspamd/rspamd.sock")
|
|
machine.succeed("systemctl start rspamd-trainer.service")
|
|
|
|
# Check if mail got processed by rspamd-trainer successfully and check for
|
|
# it in INBOX/learned_ham
|
|
machine.succeed("test-imap")
|
|
'';
|
|
}
|
|
)
|