diff --git a/default.nix b/default.nix
index 60dbceb..88e1829 100644
--- a/default.nix
+++ b/default.nix
@@ -41,7 +41,15 @@ in
type = types.listOf types.str;
example = [ "example.com" ];
default = [];
- description = "The domains that this mail server serves.";
+ description = "The domains that this mail server serves and provides a mailbox for.";
+ };
+
+ relayDomains = mkOption {
+ type = types.listOf types.str;
+ example = [ "lists.example.com" ];
+ default = [];
+ defaultText = lib.literalExpression "config.mailserver.domains";
+ description = "The domains that this mail server relays, in addition to those in {option}`domains`.";
};
certificateDomains = mkOption {
@@ -1319,4 +1327,8 @@ in
./mail-server/nginx.nix
./mail-server/kresd.nix
];
+
+ config = {
+ mailserver.relayDomains = cfg.domains;
+ };
}
diff --git a/flake.nix b/flake.nix
index 6fb5637..2b9a497 100644
--- a/flake.nix
+++ b/flake.nix
@@ -34,12 +34,13 @@
"clamav"
"multiple"
"ldap"
+ "relay"
];
genTest = testName: release: {
"name"= "${testName}-${builtins.replaceStrings ["."] ["_"] release.name}";
"value"= import (./tests/. + "/${testName}.nix") {
pkgs = release.pkgs;
- inherit blobs;
+ inherit blobs lib;
};
};
# Generate an attribute set such as
diff --git a/mail-server/opendkim.nix b/mail-server/opendkim.nix
index cdb283c..5fd096d 100644
--- a/mail-server/opendkim.nix
+++ b/mail-server/opendkim.nix
@@ -41,13 +41,13 @@ let
echo "Generated key for domain ${dom} selector ${cfg.dkimSelector}"
fi
'';
- createAllCerts = lib.concatStringsSep "\n" (map createDomainDkimCert cfg.domains);
+ createAllCerts = lib.concatStringsSep "\n" (map createDomainDkimCert cfg.relayDomains);
keyTable = pkgs.writeText "opendkim-KeyTable"
- (lib.concatStringsSep "\n" (lib.flip map cfg.domains
+ (lib.concatStringsSep "\n" (lib.flip map cfg.relayDomains
(dom: "${dom} ${dom}:${cfg.dkimSelector}:${cfg.dkimKeyDirectory}/${dom}.${cfg.dkimSelector}.key")));
signingTable = pkgs.writeText "opendkim-SigningTable"
- (lib.concatStringsSep "\n" (lib.flip map cfg.domains (dom: "${dom} ${dom}")));
+ (lib.concatStringsSep "\n" (lib.flip map cfg.relayDomains (dom: "${dom} ${dom}")));
dkim = config.services.opendkim;
args = [ "-f" "-l" ] ++ lib.optionals (dkim.configFile != null) [ "-x" dkim.configFile ];
@@ -58,7 +58,7 @@ in
enable = true;
selector = cfg.dkimSelector;
keyPath = cfg.dkimKeyDirectory;
- domains = "csl:${builtins.concatStringsSep "," cfg.domains}";
+ domains = "csl:${builtins.concatStringsSep "," cfg.relayDomains}";
configFile = pkgs.writeText "opendkim.conf" (''
Canonicalization ${cfg.dkimHeaderCanonicalization}/${cfg.dkimBodyCanonicalization}
UMask 0002
diff --git a/mail-server/postfix.nix b/mail-server/postfix.nix
index 6ba6ec6..964ba71 100644
--- a/mail-server/postfix.nix
+++ b/mail-server/postfix.nix
@@ -157,6 +157,7 @@ let
tls_ca_cert_file = ${cfg.ldap.tlsCAFile}
tls_require_cert = yes
+ domain = ${lib.concatStringsSep ", " cfg.domains}
search_base = ${cfg.ldap.searchBase}
scope = ${cfg.ldap.searchScope}
diff --git a/mail-server/rspamd.nix b/mail-server/rspamd.nix
index 8fb9b00..42e4d43 100644
--- a/mail-server/rspamd.nix
+++ b/mail-server/rspamd.nix
@@ -73,7 +73,7 @@ in
domain = "${cfg.dmarcReporting.domain}";
org_name = "${cfg.dmarcReporting.organizationName}";
from_name = "${cfg.dmarcReporting.fromName}";
- msgid_from = "dmarc-rua";
+ msgid_from = "${cfg.dmarcReporting.domain}";
}''}
''; };
};
diff --git a/tests/clamav.nix b/tests/clamav.nix
index ae186df..3828a72 100644
--- a/tests/clamav.nix
+++ b/tests/clamav.nix
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
-{ pkgs ? import {}, blobs}:
+{ pkgs ? import {}, blobs, ...}:
pkgs.nixosTest {
name = "clamav";
diff --git a/tests/relay.nix b/tests/relay.nix
new file mode 100644
index 0000000..3088cc3
--- /dev/null
+++ b/tests/relay.nix
@@ -0,0 +1,78 @@
+# This tests is used to test features requiring several mail domains.
+
+{ lib, pkgs ? import { }, ... }:
+
+let
+ hashPassword = password: pkgs.runCommand
+ "password-${password}-hashed"
+ { buildInputs = [ pkgs.mkpasswd ]; inherit password; }
+ ''
+ mkpasswd -sm bcrypt <<<"$password" > $out
+ '';
+
+ password = pkgs.writeText "password" "password";
+
+ domainGenerator = domain: {
+ imports = [ ../default.nix ];
+ virtualisation.memorySize = 1024;
+ mailserver = {
+ enable = true;
+ fqdn = "mail.${domain}";
+ domains = [ domain ];
+ localDnsResolver = false;
+ loginAccounts = {
+ "user@${domain}" = {
+ hashedPasswordFile = hashPassword "password";
+ };
+ };
+ enableImap = true;
+ enableImapSsl = true;
+ };
+ services = {
+ dnsmasq = {
+ enable = true;
+ settings.mx-host = [ "domain1.com,domain1,10" "domain2.com,domain2,10" ];
+ };
+ # disable rspamd because of graylisting
+ postfix.config.smtpd_milters = lib.mkForce [ ];
+ rspamd.enable = lib.mkForce false;
+ redis.servers.rspamd.enable = false;
+ };
+ systemd.services.postfix.requires = lib.mkForce [ "postfix-setup.service" ];
+ };
+
+in
+
+pkgs.nixosTest {
+ name = "relay";
+ nodes = {
+ domain1 = {
+ imports = [
+ ../default.nix
+ (domainGenerator "domain1.com")
+ ];
+ mailserver.relayDomains = [ "replay.domain1.com" ];
+ # ip of itself
+ services.postfix.networks = [ "[2001:db8:1::1]/128" ];
+ };
+ domain2 = domainGenerator "domain2.com";
+ client = { pkgs, ... }: {
+ environment.systemPackages = [
+ (pkgs.writeScriptBin "mail-check" ''
+ ${pkgs.python3}/bin/python ${../scripts/mail-check.py} $@
+ '')
+ ];
+ };
+ };
+ testScript = ''
+ start_all()
+
+ domain1.wait_for_unit("multi-user.target")
+ domain2.wait_for_unit("multi-user.target")
+
+ # user@domain1.com sends a mail to user@domain2.com
+ client.succeed(
+ "mail-check send-and-read --smtp-port 25 --smtp-starttls --smtp-host domain1 --from-addr user@relay.domain1.com --imap-host domain2 --to-addr user@domain2.com --dst-password-file ${password} --ignore-dkim-spf"
+ )
+ '';
+}