128 lines
4.4 KiB
Nix
128 lines
4.4 KiB
Nix
# 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"];
|
||
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";
|
||
};
|
||
};
|
||
|
||
environment.persistence.${config.impermanence.name} = {
|
||
directories = [
|
||
"/var/lib/mailman"
|
||
"/var/lib/mailman-web"
|
||
];
|
||
files = ["/root/.ssh/known_hosts"]; # for the backup server bragi
|
||
};
|
||
|
||
networking.firewall.allowedTCPPorts = [25 80];
|
||
|
||
# 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";
|
||
NoNewPrivileges = true;
|
||
# See https://www.man7.org/linux/man-pages/man5/systemd.exec.5.html
|
||
PrivateTmp = true;
|
||
ProtectHome = true;
|
||
ReadOnlyPaths = "/";
|
||
ReadWritePaths = "/tmp";
|
||
InaccessiblePaths = "-/lost+found";
|
||
PrivateDevices = true;
|
||
PrivateUsers = true;
|
||
ProtectHostname = true;
|
||
ProtectClock = true;
|
||
ProtectKernelTunables = true;
|
||
ProtectKernelModules = true;
|
||
ProtectKernelLogs = true;
|
||
ProtectControlGroups = true;
|
||
LockPersonality = true;
|
||
MemoryDenyWriteExecute = true;
|
||
RestrictRealtime = true;
|
||
RestrictSUIDSGID = 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";
|
||
};
|
||
};
|
||
}
|