mirror of
https://gitlab.com/simple-nixos-mailserver/nixos-mailserver.git
synced 2025-05-25 20:10:49 +05:00
Merge branch 'dkim-path' into 'master'
feat: add support for DKIM private key files See merge request simple-nixos-mailserver/nixos-mailserver!344
This commit is contained in:
commit
7825f53317
@ -22,7 +22,7 @@ SNM branch corresponding to your NixOS version.
|
||||
|
||||
## Features
|
||||
|
||||
* [x] Continous Integration Testing
|
||||
* [x] Continuous Integration Testing
|
||||
* [x] Multiple Domains
|
||||
* Postfix
|
||||
* [x] SMTP on port 25
|
||||
@ -44,6 +44,7 @@ SNM branch corresponding to your NixOS version.
|
||||
* [x] Via ClamAV
|
||||
* DKIM Signing
|
||||
* [x] Via Rspamd
|
||||
* [x] Allow passing DKIM signing keys
|
||||
* User Management
|
||||
* [x] Declarative user management
|
||||
* [x] Declarative password management
|
||||
@ -64,7 +65,6 @@ SNM branch corresponding to your NixOS version.
|
||||
* [ ] [Mobileconfig](https://support.apple.com/guide/profile-manager/distribute-profiles-manually-pmdbd71ebc9/mac)
|
||||
* DKIM Signing
|
||||
* [ ] Allow per domain selectors
|
||||
* [ ] Allow passing DKIM signing keys
|
||||
* Improve the Forwarding Experience
|
||||
* [ ] Support [ARC](https://en.wikipedia.org/wiki/Authenticated_Received_Chain) signing with [Rspamd](https://rspamd.com/doc/modules/arc.html)
|
||||
* [ ] Support [SRS](https://en.wikipedia.org/wiki/Sender_Rewriting_Scheme) with [postsrsd](https://github.com/roehling/postsrsd)
|
||||
|
29
default.nix
29
default.nix
@ -826,6 +826,21 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
dkimDomainPrivateKeyFiles = mkOption {
|
||||
type = types.nullOr (types.attrsOf types.path);
|
||||
default = null;
|
||||
example = {
|
||||
"mail.example.com" = "/run/secrets/dkim/mail.example.com.mail.key";
|
||||
};
|
||||
description = ''
|
||||
Paths to opendkim private keys generated with `opendkim-genkey`,
|
||||
indexed by domain name.
|
||||
If `null`, then the keys are auto generated.
|
||||
If set, then there must be an entry for every domain in
|
||||
{option}`config.mailserver.domains`.
|
||||
'';
|
||||
};
|
||||
|
||||
dkimKeyDirectory = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/dkim";
|
||||
@ -848,15 +863,15 @@ in
|
||||
};
|
||||
|
||||
dkimKeyBits = mkOption {
|
||||
type = types.int;
|
||||
default = 1024;
|
||||
type = types.nullOr types.int;
|
||||
default = if cfg.dkimDomainPrivateKeyFiles == null then 1024 else null;
|
||||
description = ''
|
||||
How many bits in generated DKIM keys. RFC6376 advises minimum 1024-bit keys.
|
||||
How many bits in generated DKIM keys. RFC6376 advises minimum 1024-bit keys.
|
||||
|
||||
If you have already deployed a key with a different number of bits than specified
|
||||
here, then you should use a different selector ({option}`mailserver.dkimSelector`). In order to get
|
||||
this package to generate a key with the new number of bits, you will either have to
|
||||
change the selector or delete the old key file.
|
||||
If you have already deployed a key with a different number of bits than specified
|
||||
here, then you should use a different selector ({option}`mailserver.dkimSelector`). In order to get
|
||||
this package to generate a key with the new number of bits, you will either have to
|
||||
change the selector or delete the old key file.
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -14,5 +14,28 @@
|
||||
assertion = config.mailserver.acmeCertificateName == config.mailserver.fqdn;
|
||||
message = "When the certificate scheme is not 'acme' (mailserver.certificateScheme != \"acme\"), it is not possible to define mailserver.acmeCertificateName";
|
||||
}
|
||||
] ++ (
|
||||
let
|
||||
sortedDomains = builtins.sort (a: b: a < b) config.mailserver.domains;
|
||||
sortedDkimDomains = builtins.attrNames config.mailserver.dkimDomainPrivateKeyFiles;
|
||||
prettyDomains = builtins.concatStringsSep ", " sortedDomains;
|
||||
prettyDkimDomains = builtins.concatStringsSep ", " sortedDkimDomains;
|
||||
in
|
||||
lib.optionals (config.mailserver.enable && config.mailserver.dkimDomainPrivateKeyFiles != null && sortedDomains != sortedDkimDomains) [
|
||||
{
|
||||
assertion = config.mailserver.dkimKeyBits != null;
|
||||
message = "When you bring your own DKIM private keys (mailserver.dkimDomainPrivateKeyFiles != null), the DKIM domains (${prettyDkimDomains}) must be identical to the mailserver.domains (${prettyDomains}).";
|
||||
}
|
||||
]
|
||||
) ++ lib.optionals (config.mailserver.enable && config.mailserver.dkimDomainPrivateKeyFiles != null) [
|
||||
{
|
||||
assertion = config.mailserver.dkimKeyBits == null;
|
||||
message = "When you bring your own DKIM private keys (mailserver.dkimDomainPrivateKeyFiles != null), you must not specify key generation options (mailserver.dkimKeyBits)";
|
||||
}
|
||||
] ++ lib.optionals (config.mailserver.enable && config.mailserver.dkimDomainPrivateKeyFiles == null) [
|
||||
{
|
||||
assertion = config.mailserver.dkimKeyBits != null;
|
||||
message = "When generating DKIM private keys (mailserver.dkimDomainPrivateKeyFiles = null), you must specify key generation options (mailserver.dkimKeyBits)";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@ -26,22 +26,37 @@ let
|
||||
rspamdUser = config.services.rspamd.user;
|
||||
rspamdGroup = config.services.rspamd.group;
|
||||
|
||||
createDkimKeypair = domain: let
|
||||
createOrLinkDkimCerts = domain: let
|
||||
privateKey = "${cfg.dkimKeyDirectory}/${domain}.${cfg.dkimSelector}.key";
|
||||
publicKey = "${cfg.dkimKeyDirectory}/${domain}.${cfg.dkimSelector}.txt";
|
||||
in pkgs.writeShellScript "dkim-keygen-${domain}" ''
|
||||
if [ ! -f "${privateKey}" ]
|
||||
then
|
||||
${lib.getExe' pkgs.rspamd "rspamadm"} dkim_keygen \
|
||||
--domain "${domain}" \
|
||||
--selector "${cfg.dkimSelector}" \
|
||||
--type "${cfg.dkimKeyType}" \
|
||||
--bits ${toString cfg.dkimKeyBits} \
|
||||
--privkey "${privateKey}" > "${publicKey}"
|
||||
chmod 0644 "${publicKey}"
|
||||
echo "Generated key for domain ${domain} and selector ${cfg.dkimSelector}"
|
||||
fi
|
||||
'';
|
||||
in pkgs.writeShellScript "dkim-keygen-${domain}" (
|
||||
if cfg.dkimDomainPrivateKeyFiles != null then
|
||||
let
|
||||
dkimPrivateKeyFile = cfg.dkimDomainPrivateKeyFiles.${domain};
|
||||
in
|
||||
''
|
||||
if [ ! -e "${dkimPrivateKeyFile}" ]; then
|
||||
echo "DKIM keyfile does not exist: ${dkimPrivateKeyFile}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ln -sf "${dkimPrivateKeyFile}" "${privateKey}"
|
||||
''
|
||||
else
|
||||
''
|
||||
if [ ! -f "${privateKey}" ]
|
||||
then
|
||||
${lib.getExe' pkgs.rspamd "rspamadm"} dkim_keygen \
|
||||
--domain "${domain}" \
|
||||
--selector "${cfg.dkimSelector}" \
|
||||
--type "${cfg.dkimKeyType}" \
|
||||
--bits ${toString cfg.dkimKeyBits} \
|
||||
--privkey "${privateKey}" > "${publicKey}"
|
||||
chmod 0644 "${publicKey}"
|
||||
echo "Generated key for domain ${domain} and selector ${cfg.dkimSelector}"
|
||||
fi
|
||||
''
|
||||
);
|
||||
in
|
||||
{
|
||||
config = with cfg; lib.mkIf enable {
|
||||
@ -165,7 +180,7 @@ in
|
||||
SupplementaryGroups = [ config.services.redis.servers.rspamd.group ];
|
||||
}
|
||||
(lib.optionalAttrs cfg.dkimSigning {
|
||||
ExecStartPre = map createDkimKeypair cfg.domains;
|
||||
ExecStartPre = map createOrLinkDkimCerts cfg.domains;
|
||||
ReadWritePaths = [ cfg.dkimKeyDirectory ];
|
||||
})
|
||||
];
|
||||
|
Loading…
x
Reference in New Issue
Block a user