{ config, lib, ... }: with lib; let cfg = config.fudo.mail-server; container-maildir = "/var/lib/mail"; container-statedir = "/var/lib/mail-state"; container-shared = "container/mail-server"; container-postfix-cert = "${container-shared}/postfix/cert.pem"; container-postfix-key = "${container-shared}/postfix/key.pem"; container-dovecot-cert = "${container-shared}/dovecot/cert.pem"; container-dovecot-key = "${container-shared}/dovecot/key.pem"; container-fudo-ca-cert = "${container-shared}/fudo-ca.pem"; # Don't bother with group-id, nixos doesn't seem to use it anyway container-mail-user = "mailer"; container-mail-user-id = 542; container-mail-group = "mailer"; fudo-cfg = config.fudo.common; in rec { options.fudo.mail-server.container = { ldap-url = mkOption { type = types.str; description = "URL of the LDAP server to use for authentication."; example = "ldaps://auth.fudo.org/"; }; }; config = mkIf (cfg.enableContainer && !cfg.enable) { # Disable postfix on thi host--it'll be run in the container instead services.postfix.enable = false; # Copy data intended for the container to a path in /etc which can be # bind-mounted. environment.etc = { "${container-postfix-cert}" = { mode = "0444"; source = cfg.postfix.ssl-certificate; }; "${container-postfix-key}" = { mode = "0400"; source = cfg.postfix.ssl-private-key; }; "${container-dovecot-cert}" = { mode = "0444"; source = cfg.dovecot.ssl-certificate; }; "${container-dovecot-key}" = { mode = "0400"; source = cfg.dovecot.ssl-private-key; }; "${container-fudo-ca-cert}" = { mode = "0444"; source = "/etc/nixos/static/fudo_ca.pem"; }; }; security.acme.certs.${cfg.hostname}.email = fudo-cfg.admin-email; services.nginx = mkIf cfg.monitoring { enable = true; virtualHosts = let proxy-headers = '' proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; ''; trusted-network-string = optionalString ((length fudo-cfg.local-networks) > 0) (concatStringsSep "\n" (map (network: "allow ${network};") fudo-cfg.local-networks)) + "\ndeny all;"; in { "${cfg.hostname}" = { enableACME = true; forceSSL = true; locations."/metrics/postfix" = { proxyPass = "http://127.0.0.1:9154/metrics"; extraConfig = '' ${proxy-headers} ${trusted-network-string} ''; }; locations."/metrics/dovecot" = { proxyPass = "http://127.0.0.1:9166/metrics"; extraConfig = '' ${proxy-headers} ${trusted-network-string} ''; }; locations."/metrics/rspamd" = { proxyPass = "http://127.0.0.1:7980/metrics"; extraConfig = '' ${proxy-headers} ${trusted-network-string} ''; }; }; }; }; containers.mail-server = { autoStart = true; bindMounts = { "${container-maildir}" = { hostPath = cfg.mail-directory; isReadOnly = false; }; "${container-statedir}" = { hostPath = cfg.state-directory; isReadOnly = false; }; "/etc/${container-shared}" = { hostPath = "/etc/${container-shared}"; isReadOnly = true; }; }; config = { config, pkgs, ... }: { environment.systemPackages = with pkgs; [ nmap ]; imports = [ ../local.nix ]; environment = { etc = { "postfix-certs/key.pem" = { source = "/etc/${container-postfix-key}"; user = config.services.postfix.user; mode = "0400"; }; "dovecot-certs/key.pem" = { source = "/etc/${container-dovecot-key}"; user = config.services.dovecot2.user; mode = "0400"; }; }; }; fudo.mail-server = { enable = true; hostname = cfg.hostname; domain = cfg.domain; debug = cfg.debug; monitoring = cfg.monitoring; state-directory = container-statedir; mail-directory = container-maildir; postfix.ssl-certificate = "/etc/${container-postfix-cert}"; postfix.ssl-private-key = "/etc/postfix-certs/key.pem"; dovecot = { ssl-certificate = "/etc/${container-dovecot-cert}"; ssl-private-key = "/etc/dovecot-certs/key.pem"; ldap = { # ca = "/etc/${container-fudo-ca-cert}"; server-urls = cfg.dovecot.ldap.server-urls; reader-dn = cfg.dovecot.ldap.reader-dn; reader-passwd = cfg.dovecot.ldap.reader-passwd; }; }; local-domains = cfg.local-domains; alias-users = cfg.alias-users; user-aliases = cfg.user-aliases; sender-blacklist = cfg.sender-blacklist; recipient-blacklist = cfg.recipient-blacklist; trusted-networks = cfg.trusted-networks; mail-user = container-mail-user; mail-user-id = container-mail-user-id; mail-group = container-mail-group; clamav.enable = cfg.clamav.enable; dkim.signing = cfg.dkim.signing; }; }; }; }; }