diff --git a/mail-config.nix b/mail-config.nix
index e812519..e968fb5 100644
--- a/mail-config.nix
+++ b/mail-config.nix
@@ -82,15 +82,18 @@ let
# implies that the FQDN must be set as an `A` record to point to the IP of
# the server. TODO: Explain more details
#
- # TODO: Only certificate scheme 1) works as of yet.
- certificate_scheme = 1;
+ # TODO: Only certificate scheme 1) and 2) work as of yet.
+ certificate_scheme = 2;
# Sceme 1)
cert_file = "/root/mail-server.crt";
key_file = "/root/mail-server.key";
# Sceme 2)
- cert_folder = "/root/certs";
+ # This is the folder where the certificate will be created. The name is
+ # hardcoded to "cert-${domain}.pem" and "key-${domain}.pem" and the
+ # certificate is valid for 10 years.
+ cert_dir = "/root/certs";
#
# Whether to enable imap / pop3. Both variants are only supported in the
@@ -123,11 +126,11 @@ in
services = import ./mail-server/services.nix {
inherit mail_dir vmail_user_name vmail_group_name valiases domain
enable_imap enable_pop3 virus_scanning dkim_signing
- certificate_scheme cert_file key_file;
- };
+ certificate_scheme cert_file key_file cert_dir;
+ };
environment = import ./mail-server/environment.nix {
- inherit pkgs;
+ inherit pkgs certificate_scheme;
};
networking = import ./mail-server/networking.nix {
@@ -135,7 +138,8 @@ in
};
systemd = import ./mail-server/systemd.nix {
- inherit mail_dir vmail_group_name;
+ inherit mail_dir vmail_group_name certificate_scheme cert_dir host_prefix
+ domain pkgs;
};
users = import ./mail-server/users.nix {
diff --git a/mail-server/dovecot.nix b/mail-server/dovecot.nix
index 4b83d55..b294ac1 100644
--- a/mail-server/dovecot.nix
+++ b/mail-server/dovecot.nix
@@ -14,23 +14,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
-{ vmail_group_name, vmail_user_name, mail_dir, enable_imap, enable_pop3,
-certificate_scheme, cert_file, key_file }:
+{ vmail_group_name, vmail_user_name, mail_dir, enable_imap, enable_pop3, cert,
+key }:
+
let
# maildir in format "/${domain}/${user}/"
dovecot_maildir = "maildir:${mail_dir}/%d/%n/";
- # cert :: PATH
- cert = if certificate_scheme == 1
- then cert_file
- else "";
-
- # key :: PATH
- key = if certificate_scheme == 1
- then key_file
- else "";
-
-
in
{
enable = true;
diff --git a/mail-server/environment.nix b/mail-server/environment.nix
index 7f4d5d7..3b61430 100644
--- a/mail-server/environment.nix
+++ b/mail-server/environment.nix
@@ -14,10 +14,10 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
-{ pkgs, ... }:
+{ pkgs, certificate_scheme }:
{
systemPackages = with pkgs; [
dovecot opendkim openssh postfix clamav rspamd rmilter
- ];
+ ] ++ (if certificate_scheme == 2 then [ openssl ] else []);
}
diff --git a/mail-server/postfix.nix b/mail-server/postfix.nix
index d132b24..bc34593 100644
--- a/mail-server/postfix.nix
+++ b/mail-server/postfix.nix
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
-{ mail_dir, domain, valiases, certificate_scheme, cert_file, key_file }:
+{ mail_dir, domain, valiases, cert, key }:
let
# valiasToString :: { from = "..."; to = "..." } -> String
@@ -34,16 +34,6 @@ let
# vhosts_file :: Path
vhosts_file = builtins.toFile "vhosts" domain;
- # cert :: PATH
- cert = if certificate_scheme == 1
- then cert_file
- else "";
-
- # key :: PATH
- key = if certificate_scheme == 1
- then key_file
- else "";
-
in
{
enable = true;
diff --git a/mail-server/services.nix b/mail-server/services.nix
index b872586..6cea1c4 100644
--- a/mail-server/services.nix
+++ b/mail-server/services.nix
@@ -16,8 +16,23 @@
{ mail_dir, vmail_user_name, vmail_group_name, valiases, domain, enable_imap,
enable_pop3, virus_scanning, dkim_signing, certificate_scheme, cert_file,
-key_file }:
+key_file, cert_dir }:
+let
+ # cert :: PATH
+ cert = if certificate_scheme == 1
+ then cert_file
+ else if certificate_scheme == 2
+ then "${cert_dir}/cert-${domain}.pem"
+ else "";
+
+ # key :: PATH
+ key = if certificate_scheme == 1
+ then key_file
+ else if certificate_scheme == 2
+ then "${cert_dir}/key-${domain}.pem"
+ else "";
+in
{
# rspamd
rspamd = {
@@ -29,11 +44,11 @@ key_file }:
};
postfix = import ./postfix.nix {
- inherit mail_dir domain valiases certificate_scheme cert_file key_file;
+ inherit mail_dir domain valiases cert key;
};
dovecot2 = import ./dovecot.nix {
inherit vmail_group_name vmail_user_name mail_dir enable_imap
- enable_pop3 certificate_scheme cert_file key_file;
+ enable_pop3 cert key;
};
}
diff --git a/mail-server/systemd.nix b/mail-server/systemd.nix
index 0d2fe23..d6dcefb 100644
--- a/mail-server/systemd.nix
+++ b/mail-server/systemd.nix
@@ -14,8 +14,29 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
-{ mail_dir, vmail_group_name }:
+{ pkgs, mail_dir, vmail_group_name, certificate_scheme, cert_dir, host_prefix,
+domain }:
+let
+ create_certificate = if certificate_scheme == 2 then
+ ''
+ # Create certificates if they do not exist yet
+ dir="${cert_dir}"
+ fqdn="${host_prefix}.${domain}"
+ case $fqdn in /*) fqdn=$(cat "$fqdn");; esac
+ key="''${dir}/key-${domain}.pem";
+ cert="''${dir}/cert-${domain}.pem";
+
+ if [ ! -f "''${key}" ] || [ ! -f "''${cert}" ]
+ then
+ mkdir -p "${cert_dir}"
+ (umask 077; "${pkgs.openssl}/bin/openssl" genrsa -out "''${key}" 2048) &&
+ "${pkgs.openssl}/bin/openssl" req -new -key "''${key}" -x509 -subj "/CN=''${fqdn}" \
+ -days 3650 -out "''${cert}"
+ fi
+ ''
+ else "";
+in
{
# Set the correct permissions for dovecot vmail folder. See
# . We choose
@@ -23,8 +44,18 @@
# dovecot gets started.
services.dovecot2.preStart =
''
- mkdir -p ${mail_dir}
- chgrp ${vmail_group_name} ${mail_dir}
- chmod 02770 ${mail_dir}
+ # Create mail directory and set permissions
+ mkdir -p "${mail_dir}"
+ chgrp "${vmail_group_name}" "${mail_dir}"
+ chmod 02770 "${mail_dir}"
+
+ ${create_certificate}
+ '';
+
+ # Check for certificate before both postfix and dovecot to make sure it
+ # exists.
+ services.postfix.preStart =
+ ''
+ ${create_certificate}
'';
}