{ config, pkgs, ... }: let cfg = config.mailserver; certsDir = "/var/certs"; # Extracting a Certificate from Traefik`s acme.json # Source: https://www.zdyn.net/docker/2022/02/04/acme-certificate.html dumpTraefikMailCerts = pkgs.writeScript "dump-mail-certs" '' #!/bin/sh ${pkgs.jq}/bin/jq -r '.le.Certificates[] | select(.domain.main=="${cfg.fqdn}") | .certificate' /var/lib/traefik/acme.json | base64 -d > ${cfg.certificateFile} ${pkgs.jq}/bin/jq -r '.le.Certificates[] | select(.domain.main=="${cfg.fqdn}") | .key' /var/lib/traefik/acme.json | base64 -d > ${cfg.keyFile} ''; in { imports = [ ./mailserver-accounts.secret.nix ]; # See: https://nixos-mailserver.readthedocs.io/en/latest/options.html mailserver = { enable = true; fqdn = "mail.pleshevski.ru"; domains = [ "pleshevski.ru" ]; # We use traefik to generate certificates certificateScheme = 1; certificateFile = "${certsDir}/cert-${cfg.fqdn}.pem"; keyFile = "${certsDir}/key-${cfg.fqdn}.pem"; hierarchySeparator = "/"; }; services.traefik.dynamicConfigOptions.http = { routers.mailserver_acme = { rule = "Host(`${cfg.fqdn}`)"; entryPoints = [ "http" ]; tls = { certResolver = "le"; domains = [ { main = cfg.fqdn; sans = cfg.domains; } ]; }; service = "noop@internal"; }; }; systemd = { # Watch traefik`s acme.json to update certs in /var/certs # Source: https://superuser.com/questions/1171751/restart-systemd-service-automatically-whenever-a-directory-changes-any-file-ins services.dump-traefik-mail-cert = { unitConfig = { Description = "Restart mail cert service"; After = [ "network.target" ]; }; serviceConfig = { Type = "oneshot"; ExecStart = "${dumpTraefikMailCerts}"; }; wantedBy = [ "multi-user.target" ]; }; paths.dump-traefik-mail-cert = { wantedBy = [ "multi-user.target" ]; pathConfig.PathChanged = "/var/lib/traefik/acme.json"; }; }; }