{ config, lib, pkgs, ... }: with lib; let cfg = config.services.smtprd-ng; smtprd-ng = pkgs.callPackage ./. { }; cfgText = generators.toINI { } { server = { hostname = cfg.server.hostname; port = cfg.server.port; }; client = { hostname = cfg.client.hostname; port = cfg.client.port; username = cfg.client.username; password_file = cfg.client.password_file; sender = cfg.client.sender; use_tls = cfg.client.use_tls; start_tls = cfg.client.start_tls; smime_cert = cfg.client.smime_cert; smime_cert_private = cfg.client.smime_cert_private; }; emails = cfg.emails; }; confFile = pkgs.writeText "config.ini" cfgText; in { options.services.smtprd-ng = { enable = mkEnableOption "smtprd-ng"; package = mkOption { type = types.package; default = smtprd-ng; description = mdDoc '' The smtprd-ng package to use. ''; }; server = { hostname = mkOption { type = types.str; default = "localhost"; description = mdDoc '' The hostname the local SMTP server should listen on. ''; }; port = mkOption { type = types.port; default = 8025; description = mdDoc '' The port the local SMTP server should listen on. ''; }; }; client = { hostname = mkOption { type = types.str; default = ""; description = mdDoc '' The hostname of the remote SMTP server. ''; }; port = mkOption { type = types.port; default = 587; description = mdDoc '' The port of the remote SMTP server. ''; }; username = mkOption { type = types.nullOr types.str; default = null; description = mdDoc '' The username to login to the remote SMTP server. ''; }; password_file = mkOption { type = types.nullOr types.path; default = null; description = mdDoc '' The path to the file containing the password to login to the remote SMTP server. Should not be in /nix/store! ''; }; sender = mkOption { type = types.nullOr types.str; default = null; description = mdDoc '' The email of the sender. Some SMTP servers require this to be the real FROM email address of the user. ''; }; use_tls = mkOption { type = types.bool; default = false; description = mdDoc '' Use TLS to connect. Mutually exclusive with `start_tls` ''; }; start_tls = mkOption { type = types.bool; default = false; description = mdDoc '' Use STARTLS to connect. Mutually exclusive with `use_tls` ''; }; smime_cert = mkOption { type = types.nullOr types.path; default = null; example = "''\${./mycert.pem}"; description = mdDoc '' The path to the S/MIME certificate used to sign messages. If empty, will neither encrypt, nor sign relayed messages. ''; }; smime_cert_private = mkOption { type = types.nullOr types.path; default = null; description = mdDoc '' The path to the S/MIME private key for the certificate used to sign messages. Should not be in /nix/store! ''; }; }; emails = mkOption { type = types.nullOr (types.attrsOf (types.nullOr types.str)); default = null; description = '' A required set of recipients. A certificate is optional, but required if messages should be signed and encrypted. ''; example = { "monitoring.foo@example.com" = "`/path/to/certificate`"; "unencrypted@example.com" = "`null`"; }; }; }; config = mkIf cfg.enable { assertions = [ { assertion = !cfg.client.use_tls || !cfg.client.start_tls; message = "Use either TLS or STARTTLS, not both."; } { assertion = cfg.client.smime_cert == null || (cfg.client.smime_cert != null && cfg.client.smime_cert_private != null); message = "If a S/MIME certificate should be used to sign messages, the private key to this certificate must be supplied."; } { assertion = cfg.emails != null; message = "At least one recipient must be configured."; } ]; systemd.services = { smtprd-ng = { description = "Run local SMTP relay"; wantedBy = [ "multi-user.target" ]; requires = [ "network.target" ]; serviceConfig = { DynamicUser = true; User = "smtprd-ng"; Group = "smtprd-ng"; Restart = "on-failure"; ExecStart = "${cfg.package}/bin/smtprd-ng --config ${confFile}"; }; }; }; }; }