forked from Fachschaft/nixConfig
178 lines
5.5 KiB
Nix
178 lines
5.5 KiB
Nix
|
{
|
|||
|
config,
|
|||
|
lib,
|
|||
|
# pkgs,
|
|||
|
...
|
|||
|
}: let
|
|||
|
inherit
|
|||
|
(lib)
|
|||
|
mkIf
|
|||
|
mkEnableOption
|
|||
|
mkOption
|
|||
|
;
|
|||
|
inherit (lib.types) str;
|
|||
|
cfg = config.services.mathebau-mail;
|
|||
|
in {
|
|||
|
options.services.mathebau-mail = {
|
|||
|
enable = mkEnableOption "mathebau mail service";
|
|||
|
fqdn = mkOption {
|
|||
|
type = str;
|
|||
|
};
|
|||
|
domain = mkOption {
|
|||
|
type = str;
|
|||
|
};
|
|||
|
siteOwner = mkOption {
|
|||
|
type = str;
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
config = mkIf cfg.enable {
|
|||
|
services = {
|
|||
|
stalwart-mail = {
|
|||
|
enable = true;
|
|||
|
openFirewall = true;
|
|||
|
settings = {
|
|||
|
# TODO TLS
|
|||
|
server = {
|
|||
|
hostname = cfg.fqdn;
|
|||
|
listener = {
|
|||
|
"smtp" = {
|
|||
|
bind = ["[::]:25"];
|
|||
|
protocol = "smtp";
|
|||
|
tls.implicit = false;
|
|||
|
};
|
|||
|
"submissions" = {
|
|||
|
bind = ["[::]:465"];
|
|||
|
protocol = "smtp";
|
|||
|
tls.implicit = true;
|
|||
|
};
|
|||
|
"imaptls" = {
|
|||
|
bind = ["[::]:993"];
|
|||
|
protocol = "imap";
|
|||
|
tls.implicit = true;
|
|||
|
};
|
|||
|
"management" = {
|
|||
|
bind = ["127.0.0.1:8080"];
|
|||
|
protocol = "http";
|
|||
|
};
|
|||
|
};
|
|||
|
tls = {
|
|||
|
certificate = cfg.fqdn;
|
|||
|
enable = true;
|
|||
|
implicit = false;
|
|||
|
};
|
|||
|
};
|
|||
|
#TODO session.rcpt.relay = [ { if = "!is_empty(authenticated_as)", then = true }, { else = false } ];
|
|||
|
queue.outbound = {
|
|||
|
# see https://stalw.art/docs/smtp/outbound/routing/ relay host example
|
|||
|
next-hop = ["relay"];
|
|||
|
tls.mta-sts = "disable";
|
|||
|
tls.dane = "disable";
|
|||
|
};
|
|||
|
queue."relay" = {
|
|||
|
address = "192.168.0.24"; #TODO mailout.hrz…
|
|||
|
port = 25;
|
|||
|
protocol = "smtp";
|
|||
|
tls.implicit = false;
|
|||
|
tls.allow-invalid-certs = false;
|
|||
|
};
|
|||
|
sieve.trusted.scripts = {
|
|||
|
redirects = ''
|
|||
|
require ["envelope", "include"];
|
|||
|
include :global "track-replies";
|
|||
|
if envelope :is "to" "gonne@koma89.tu-darmstadt.de"
|
|||
|
{
|
|||
|
redirect "gonne@mathebau.de";
|
|||
|
}
|
|||
|
'';
|
|||
|
};
|
|||
|
session.data.script = ["redirects"];
|
|||
|
authentication.fallback-admin = {
|
|||
|
user = "admin";
|
|||
|
secret = "$argon2i$v=19$m=4096,t=3,p=1$d0hYOTkzclpzSmFTZUplWnhVeWE$I7q9uB19RWL0oZKaPlMPSlGfFp6FQ/vrx80FFKCsalg";
|
|||
|
};
|
|||
|
};
|
|||
|
};
|
|||
|
};
|
|||
|
environment.persistence.${config.impermanence.name} = {
|
|||
|
directories = [
|
|||
|
"/var/lib/acme" # Persist TLS keys and account
|
|||
|
"/var/lib/stalwart-mail"
|
|||
|
];
|
|||
|
files = ["/root/.ssh/known_hosts"]; # for the backup server bragi
|
|||
|
};
|
|||
|
|
|||
|
security.acme.defaults.email = cfg.siteOwner;
|
|||
|
security.acme.acceptTerms = true;
|
|||
|
|
|||
|
# 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 to the HRZ allowllist";
|
|||
|
script = ''
|
|||
|
# Get the mail addresses' local-part
|
|||
|
#TODO
|
|||
|
# Post local-parts to HRZ
|
|||
|
${pkgs.curl}/bin/curl https://www-cgi.hrz.tu-darmstadt.de/mail/whitelist-update.php -F emaildomain=${cfg.domain} -F password=$(cat /run/secrets/allowlistPass) -F emailliste=@/tmp/addresses -F meldungen=voll
|
|||
|
# Cleanup
|
|||
|
rm /tmp/addresses
|
|||
|
'';
|
|||
|
serviceConfig = {
|
|||
|
Type = "oneshot";
|
|||
|
User = "stalwart-mail";
|
|||
|
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.mail = {
|
|||
|
paths = [
|
|||
|
"/var/lib/stalwart-mail"
|
|||
|
];
|
|||
|
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:kaluut"; # TODO for https://gitea.mathebau.de/Fachschaft/nixConfig/issues/33
|
|||
|
startAt = "daily";
|
|||
|
user = "root";
|
|||
|
group = "root";
|
|||
|
};
|
|||
|
*/
|
|||
|
};
|
|||
|
}
|