mailsystem: Add option to use selfsigned certificates in preparation for testing

This commit is contained in:
Thomas Preisner 2024-12-05 16:04:01 +01:00
parent 6d6b856bee
commit a592881b8b
5 changed files with 84 additions and 18 deletions

View file

@ -1,9 +1,21 @@
{config, ...}: let {config, ...}: let
cfg = config.mailsystem; cfg = config.mailsystem;
in rec { in rec {
sslCertPath = "${config.security.acme.certs.${cfg.fqdn}.directory}/fullchain.pem"; certificateDirectory = "/var/certs";
sslKeyPath = "${config.security.acme.certs.${cfg.fqdn}.directory}/key.pem"; sslCertPath =
sslCertService = ["acme-finished-${cfg.fqdn}.target"]; if cfg.certificateScheme == "acme"
then "${config.security.acme.certs.${cfg.fqdn}.directory}/fullchain.pem"
else "${certificateDirectory}/cert-${cfg.fqdn}.pem";
sslKeyPath =
if cfg.certificateScheme == "acme"
then "${config.security.acme.certs.${cfg.fqdn}.directory}/key.pem"
else "${certificateDirectory}/key-${cfg.fqdn}.pem";
sslCertService =
if cfg.certificateScheme == "acme"
then ["acme-finished-${cfg.fqdn}.target"]
else ["mailsystem-selfsigned-certificate.service"];
dovecotDynamicStateDir = "/var/lib/dovecot"; dovecotDynamicStateDir = "/var/lib/dovecot";
dovecotDynamicPasswdFile = "${dovecotDynamicStateDir}/passwd"; dovecotDynamicPasswdFile = "${dovecotDynamicStateDir}/passwd";

View file

@ -154,6 +154,19 @@ in {
''; '';
default = {}; default = {};
}; };
certificateScheme = lib.mkOption {
type = lib.types.enum ["acme" "selfsigned"];
default = "acme";
description = ''
The scheme to use for managing TLS certificates:
1. `acme`: The server retrieves letsencrypt certificates via NixOS's acme module using nginx.
2. `selfsigned`: The server creates self-signed certificates on the fly (intended for testing).
'';
internal = true;
visible = false;
};
}; };
imports = [ imports = [
@ -164,6 +177,7 @@ in {
./redis.nix ./redis.nix
./roundcube.nix ./roundcube.nix
./rspamd.nix ./rspamd.nix
./selfsigned.nix
./user.nix ./user.nix
]; ];
} }

View file

@ -3,20 +3,25 @@
pkgs, pkgs,
lib, lib,
... ...
}: let }:
with (import ./common.nix {inherit config;}); let
cfg = config.mailsystem; cfg = config.mailsystem;
in { in {
config = lib.mkIf cfg.enable { config =
lib.mkIf cfg.enable {
services.nginx = { services.nginx = {
enable = true; enable = true;
virtualHosts."${cfg.fqdn}" = { virtualHosts."${cfg.fqdn}" = {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = cfg.certificateScheme == "acme";
sslCertificate = lib.mkIf (cfg.certificateScheme == "selfsigned") sslCertPath;
sslCertificateKey = lib.mkIf (cfg.certificateScheme == "selfsigned") sslKeyPath;
}; };
}; };
networking.firewall.allowedTCPPorts = lib.optionals cfg.openFirewall [80 443]; networking.firewall.allowedTCPPorts = lib.optionals cfg.openFirewall [80 443];
}
// lib.mkIf (cfg.enable && cfg.certificateScheme == "acme") {
security.acme.certs."${cfg.fqdn}".reloadServices = [ security.acme.certs."${cfg.fqdn}".reloadServices = [
"postfix.service" "postfix.service"
"dovecot2.service" "dovecot2.service"

View file

@ -121,6 +121,8 @@ in {
proxyPass = "http://unix:${rspamdControllerSocket}:/"; proxyPass = "http://unix:${rspamdControllerSocket}:/";
basicAuthFile = cfg.rspamd.webUi.basicAuthFile; basicAuthFile = cfg.rspamd.webUi.basicAuthFile;
}; };
sslCertificate = lib.mkIf (cfg.certificateScheme == "selfsigned") sslCertPath;
sslCertificateKey = lib.mkIf (cfg.certificateScheme == "selfsigned") sslKeyPath;
}; };
}; };
}; };

33
mailsystem/selfsigned.nix Normal file
View file

@ -0,0 +1,33 @@
{
config,
pkgs,
lib,
...
}:
with (import ./common.nix {inherit config;}); let
cfg = config.mailsystem;
in {
config = lib.mkIf (cfg.enable && cfg.certificateScheme == "selfsigned") {
systemd.services.mailsystem-selfsigned-certificate = {
after = ["local-fs.target"];
script = ''
# Create certificates if they do not exist yet
dir="${certificateDirectory}"
fqdn="${cfg.fqdn}"
[[ $fqdn == /* ]] && fqdn=$(< "$fqdn")
key="${sslKeyPath}"
cert="${sslCertPath}"
if [[ ! -f $key || ! -f $cert ]]; then
mkdir -p "$dir"
(umask 077; "${pkgs.openssl}/bin/openssl" genrsa -out "$key" 4096) &&
"${pkgs.openssl}/bin/openssl" req -new -key "$key" -x509 -subj "/CN=$fqdn" -days 3650 -out "$cert"
fi
'';
serviceConfig = {
Type = "oneshot";
PrivateTmp = true;
};
};
};
}