diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..86a63dc --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/default.nix b/default.nix index 6a07f7e..9b7f6fe 100644 --- a/default.nix +++ b/default.nix @@ -26,19 +26,17 @@ in options.mailserver = { enable = mkEnableOption "nixos-mailserver"; - domain = mkOption { + fqdn = mkOption { type = types.str; - example = "example.com"; - description = "The domain that this mail server serves. So far only one domain is supported"; + example = "[ example.com ]"; + description = "The fully qualified domain name of the mail server."; }; - hostPrefix = mkOption { - type = types.str; - default = "mail"; - description = '' - The prefix of the FQDN of the server. In this example the FQDN of the server - is given by 'mail.example.com' - ''; + domains = mkOption { + type = types.listOf types.str; + example = "[ example.com ]"; + default = []; + description = "The domains that this mail server serves."; }; loginAccounts = mkOption { diff --git a/mail-server/common.nix b/mail-server/common.nix index 12d7b96..910b5c2 100644 --- a/mail-server/common.nix +++ b/mail-server/common.nix @@ -24,17 +24,17 @@ in certificatePath = if cfg.certificateScheme == 1 then cfg.certificateFile else if cfg.certificateScheme == 2 - then "${cfg.certificateDirectory}/cert-${cfg.domain}.pem" + then "${cfg.certificateDirectory}/cert-${cfg.fqdn}.pem" else if cfg.certificateScheme == 3 - then "/var/lib/acme/${cfg.hostPrefix}.${cfg.domain}/fullchain.pem" + then "/var/lib/acme/${cfg.fqdn}/fullchain.pem" else throw "Error: Certificate Scheme must be in { 1, 2, 3 }"; # key :: PATH keyPath = if cfg.certificateScheme == 1 then cfg.keyFile else if cfg.certificateScheme == 2 - then "${cfg.certificateDirectory}/key-${cfg.domain}.pem" + then "${cfg.certificateDirectory}/key-${cfg.fqdn}.pem" else if cfg.certificateScheme == 3 - then "/var/lib/acme/${cfg.hostPrefix}.${cfg.domain}/key.pem" + then "/var/lib/acme/${cfg.fqdn}/key.pem" else throw "Error: Certificate Scheme must be in { 1, 2, 3 }"; } diff --git a/mail-server/nginx.nix b/mail-server/nginx.nix index 15bb596..0ba4a54 100644 --- a/mail-server/nginx.nix +++ b/mail-server/nginx.nix @@ -21,23 +21,28 @@ with (import ./common.nix { inherit config; }); let cfg = config.mailserver; + acmeRoot = "/var/lib/acme/acme-challenge"; in { - config = with cfg; lib.mkIf (certificateScheme == 3) { - + config = lib.mkIf (cfg.certificateScheme == 3) { services.nginx = { enable = true; - virtualHosts = { - domain = { - serverName = "${hostPrefix}.${domain}"; - forceSSL = true; - enableACME = true; - locations."/" = { - root = "/var/www"; - }; - acmeRoot = "/var/lib/acme/acme-challenge"; - }; + virtualHosts."${cfg.fqdn}" = { + serverName = cfg.fqdn; + forceSSL = true; + enableACME = true; + acmeRoot = acmeRoot; }; }; + security.acme.certs."${cfg.fqdn}".postRun = #{ + # domain = "${cfg.fqdn}"; +# webroot = acmeRoot; +# postRun = + '' + systemctl reload nginx + systemctl reload postfix + systemctl reload dovecot2 + ''; +# }; }; } diff --git a/mail-server/postfix.nix b/mail-server/postfix.nix index fedb53c..a57e63d 100644 --- a/mail-server/postfix.nix +++ b/mail-server/postfix.nix @@ -19,17 +19,18 @@ with (import ./common.nix { inherit config; }); let + inherit (lib.strings) concatStringsSep; cfg = config.mailserver; # valiases_postfix :: [ String ] valiases_postfix = map (from: let to = cfg.virtualAliases.${from}; - in "${from}@${cfg.domain} ${to}@${cfg.domain}") + in "${from} ${to}") (builtins.attrNames cfg.virtualAliases); # accountToIdentity :: User -> String - accountToIdentity = account: "${account.name}@${cfg.domain} ${account.name}@${cfg.domain}"; + accountToIdentity = account: "${account.name} ${account.name}"; # vaccounts_identity :: [ String ] vaccounts_identity = map accountToIdentity (lib.attrValues cfg.loginAccounts); @@ -38,7 +39,7 @@ let valiases_file = builtins.toFile "valias" (lib.concatStringsSep "\n" valiases_postfix); # vhosts_file :: Path - vhosts_file = builtins.toFile "vhosts" cfg.domain; + vhosts_file = builtins.toFile "vhosts" (concatStringsSep "\n" cfg.domains); # vaccounts_file :: Path # see @@ -47,7 +48,7 @@ let # every alias is owned (uniquely) by its user. We have to add the users own # address though vaccounts_file = builtins.toFile "vaccounts" (lib.concatStringsSep "\n" (vaccounts_identity ++ valiases_postfix)); - + submissionHeaderCleanupRules = pkgs.writeText "submission_header_cleanup_rules" '' # Removes sensitive headers from mails handed in via the submission port. # See https://thomas-leister.de/mailserver-debian-stretch/ @@ -67,12 +68,12 @@ in enable = true; networksStyle = "host"; mapFiles."valias" = valiases_file; - mapFiles."vaccounts" = vaccounts_file; + mapFiles."vaccounts" = vaccounts_file; sslCert = certificatePath; sslKey = keyPath; enableSubmission = true; - extraConfig = + extraConfig = '' # Extra Config @@ -116,7 +117,7 @@ in ''; submissionOptions = - { + { smtpd_tls_security_level = "encrypt"; smtpd_sasl_auth_enable = "yes"; smtpd_sasl_type = "dovecot"; diff --git a/mail-server/services.nix b/mail-server/services.nix index 2cebdaf..41d2bb3 100644 --- a/mail-server/services.nix +++ b/mail-server/services.nix @@ -24,14 +24,14 @@ let cert = if cfg.certificateScheme == 1 then cfg.certificateFile else if cfg.certificateScheme == 2 - then "${cfg.certificateDirectory}/cert-${cfg.domain}.pem" + then "${cfg.certificateDirectory}/cert-${cfg.fqdn.pem" else ""; # key :: PATH key = if cfg.certificateScheme == 1 then cfg.keyFile else if cfg.certificateScheme == 2 - then "${cfg.certificateDirectory}/key-${cfg.domain}.pem" + then "${cfg.certificateDirectory}/key-${cfg.fqdn}.pem" else ""; in { diff --git a/mail-server/systemd.nix b/mail-server/systemd.nix index 48f5a5e..ecfbbde 100644 --- a/mail-server/systemd.nix +++ b/mail-server/systemd.nix @@ -23,10 +23,10 @@ let '' # Create certificates if they do not exist yet dir="${cfg.certificateDirectory}" - fqdn="${cfg.hostPrefix}.${cfg.domain}" + fqdn="${cfg.fqdn}" case $fqdn in /*) fqdn=$(cat "$fqdn");; esac - key="''${dir}/key-${cfg.domain}.pem"; - cert="''${dir}/cert-${cfg.domain}.pem"; + key="''${dir}/key-${cfg.fqdn}.pem"; + cert="''${dir}/cert-${cfg.fqdn}.pem"; if [ ! -f "''${key}" ] || [ ! -f "''${cert}" ] then @@ -50,7 +50,7 @@ let then ${pkgs.opendkim}/bin/opendkim-genkey -s "${cfg.dkimSelector}" \ - -d ${cfg.domain} \ + -d ${cfg.fqdn} \ --directory="${cfg.dkimKeyDirectory}" chown rmilter:rmilter "${dkim_key}" fi @@ -64,7 +64,7 @@ in # Create certificates and maildir folder systemd.services.postfix = { after = (if (certificateScheme == 3) then [ "nginx.service" ] else []); - preStart = + preStart = '' # Create mail directory and set permissions. See # . diff --git a/mail-server/users.nix b/mail-server/users.nix index c55375c..f49be1f 100644 --- a/mail-server/users.nix +++ b/mail-server/users.nix @@ -30,7 +30,7 @@ let # accountsToUser :: String -> UserRecord accountsToUser = account: { - name = account.name + "@" + domain; + name = account.name; isNormalUser = false; group = vmailGroupName; inherit (account) hashedPassword; diff --git a/nixops/single-server.nix b/nixops/single-server.nix index 15e9e5e..1976809 100644 --- a/nixops/single-server.nix +++ b/nixops/single-server.nix @@ -10,18 +10,21 @@ mailserver = { enable = true; - domain = "example.com"; - - hostPrefix = "mail"; + fqdn = "mail.example.com"; + domains = [ "example.com" "example2.com" ]; loginAccounts = { - user1 = { + "user1@example.com" = { hashedPassword = "$6$/z4n8AQl6K$kiOkBTWlZfBd7PvF5GsJ8PmPgdZsFGN1jPGZufxxr60PoR0oUsrvzm2oQiflyz5ir9fFJ.d/zKm/NgLXNUsNX/"; }; }; virtualAliases = { - info = "user1"; - postmaster = "user1"; - abuse = "user1"; + "info@example.com" = "user1@example.com"; + "postmaster@example.com" = "user1@example.com"; + "abuse@example.com" = "user1@example.com"; + "user1@example2.com" = "user1@example.com"; + "info@example2.com" = "user1@example.com"; + "postmaster@example2.com" = "user1@example.com"; + "abuse@example2.com" = "user1@example.com"; }; }; }; diff --git a/tests/extern.nix b/tests/extern.nix index f98f10e..03c53c6 100644 --- a/tests/extern.nix +++ b/tests/extern.nix @@ -25,14 +25,14 @@ import { mailserver = { enable = true; - domain = "example.com"; + fqdn = "mail.example.com"; + domains = [ "example.com" ]; - hostPrefix = "mail"; loginAccounts = { - user1 = { + "user1@example.com" = { hashedPassword = "$6$/z4n8AQl6K$kiOkBTWlZfBd7PvF5GsJ8PmPgdZsFGN1jPGZufxxr60PoR0oUsrvzm2oQiflyz5ir9fFJ.d/zKm/NgLXNUsNX/"; }; - user2 = { + "user2@example.com" = { hashedPassword = "$6$u61JrAtuI0a$nGEEfTP5.eefxoScUGVG/Tl0alqla2aGax4oTd85v3j3xSmhv/02gNfSemv/aaMinlv9j/ZABosVKBrRvN5Qv0"; }; }; diff --git a/tests/intern.nix b/tests/intern.nix index 58c4b75..bcfce2a 100644 --- a/tests/intern.nix +++ b/tests/intern.nix @@ -25,11 +25,11 @@ import { mailserver = { enable = true; - domain = "example.com"; + fqdn = "mail.example.com"; + domains = [ "example.com" ]; - hostPrefix = "mail"; loginAccounts = { - user1 = { + "user1@example.com" = { hashedPassword = "$6$/z4n8AQl6K$kiOkBTWlZfBd7PvF5GsJ8PmPgdZsFGN1jPGZufxxr60PoR0oUsrvzm2oQiflyz5ir9fFJ.d/zKm/NgLXNUsNX/"; }; };