nixConfig/nixos/modules/mailman.nix
2024-08-19 13:23:47 +02:00

120 lines
4.2 KiB
Nix
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Adapted and simplified from https://nixos.wiki/wiki/Mailman
{
config,
lib,
pkgs,
...
}: let
inherit
(lib)
mkIf
mkEnableOption
mkOption
;
inherit (lib.types) nonEmptyStr;
cfg = config.services.mathebau-mailman;
in {
options.services.mathebau-mailman = {
enable = mkEnableOption "mathebau mailman service";
hostName = mkOption {
type = nonEmptyStr;
};
siteOwner = mkOption {
type = nonEmptyStr;
};
};
config = mkIf cfg.enable {
services = {
postfix = {
enable = true;
relayDomains = ["hash:/var/lib/mailman/data/postfix_domains"];
sslCert = config.security.acme.certs.${cfg.hostName}.directory + "/full.pem";
sslKey = config.security.acme.certs.${cfg.hostName}.directory + "/key.pem";
config = {
transport_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
local_recipient_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
proxy_interfaces = "130.83.2.184";
smtputf8_enable = "no"; # HRZ does not know SMTPUTF8
};
relayHost = "192.168.0.24"; # Relay to eihort which relays to HRZ (see https://www.hrz.tu-darmstadt.de/services/it_services/email_infrastruktur/index.de.jsp)
};
mailman = {
enable = true;
inherit (cfg) siteOwner;
hyperkitty.enable = true;
webHosts = [cfg.hostName];
serve.enable = true; #
# Don't include confirmation tokens in reply addresses, because we would need to send them to HRZ otherwise.
settings.mta.verp_confirmations = "no";
};
nginx.virtualHosts.${cfg.hostName} = {
enableACME = true; # Get certificates (primarily for postfix)
forceSSL = false; # Don't use HTTPS behind the proxy
};
};
environment.persistence.${config.impermanence.name} = {
directories = [
"/var/lib/acme" # Persist TLS keys and account
"/var/lib/mailman"
"/var/lib/mailman-web"
];
files = ["/root/.ssh/known_hosts"]; # for the backup server bragi
};
security.acme.defaults.email = cfg.siteOwner;
security.acme.acceptTerms = true;
networking.firewall.allowedTCPPorts = [25 80 443];
# Update HRZ allowlist
# For account details see https://www-cgi.hrz.tu-darmstadt.de/mail/
# will stop working if no valid TUIDs are associated to our domain.
systemd.timers."mailAllowlist" = {
wantedBy = ["timers.target"];
timerConfig = {
OnBootSec = "5m"; # Run every 5 minutes
OnUnitActiveSec = "5m";
RandomizedDelaySec = "2m"; # prevent overload on regular intervals
Unit = "mailAllowlist.service";
};
};
systemd.services."mailAllowlist" = {
description = "Allowlist update: Post the mail addresses used by mailman to the HRZ allowllist";
script = ''
# Get the mail addresses' local-part
cut -d '@' -f 1 /var/lib/mailman/data/postfix_lmtp | grep -v '#' | grep "\S" > /tmp/addresses
# Post local-parts to HRZ
${pkgs.curl}/bin/curl https://www-cgi.hrz.tu-darmstadt.de/mail/whitelist-update.php -F emaildomain=${cfg.hostName} -F password=$(cat /run/secrets/allowlistPass) -F emailliste=@/tmp/addresses -F meldungen=voll
# Cleanup
rm /tmp/addresses
'';
serviceConfig = {
Type = "oneshot";
User = "mailman";
PrivateTmp = true;
};
};
# Backups
services.borgbackup.jobs.mailman = {
paths = [
"/var/lib/mailman/data"
"/var/lib/mailman-web"
];
encryption.mode = "none"; # Otherwise the key is next to the backup or we have human interaction.
environment = {
BORG_RSH = "ssh -i /run/secrets/backupKey";
# “Borg ensures that backups are not created on random drives that just happen to contain a Borg repository.”
# https://borgbackup.readthedocs.io/en/stable/deployment/automated-local.html
# We don't want this in order to not need to persist borg cache and simplify new deployments.
BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK = "yes";
};
repo = "borg@192.168.1.11:lobon"; # TODO for https://gitea.mathebau.de/Fachschaft/nixConfig/issues/33
startAt = "daily";
user = "root";
group = "root";
};
};
}