summaryrefslogtreecommitdiff
path: root/os/kay/modules/services/mail.nix
diff options
context:
space:
mode:
authorsinanmohd <sinan@sinanmohd.com>2025-10-17 08:31:18 +0530
committersinanmohd <sinan@sinanmohd.com>2025-10-17 08:45:14 +0530
commit84c39b405972516a9be2e8be8729097f8691050f (patch)
tree5a63186f3004e36a0f7560ee90ef358bd3662aa9 /os/kay/modules/services/mail.nix
parent5fd8a7084e907f4c1b4c2c86cfd69f622b4c294a (diff)
chore(os/kay): refactor
Diffstat (limited to 'os/kay/modules/services/mail.nix')
-rw-r--r--os/kay/modules/services/mail.nix173
1 files changed, 173 insertions, 0 deletions
diff --git a/os/kay/modules/services/mail.nix b/os/kay/modules/services/mail.nix
new file mode 100644
index 0000000..685461f
--- /dev/null
+++ b/os/kay/modules/services/mail.nix
@@ -0,0 +1,173 @@
+{ config, pkgs, ... }:
+let
+ ipv6 = "2001:470:ee65::1337";
+ domain = config.global.userdata.domain;
+ username = config.global.userdata.name;
+ email = [
+ "${username}@${domain}"
+
+ # used by github automation
+ # https://github.com/nocodb/nocodb/blob/32826d4b24e9285b898bb3547fdf550f81c930bb/nix/bumper/bumper.sh#L5
+ "auto@${domain}"
+ # used by mail.sinanmohd.com
+ "postmaster@${domain}"
+ # used by ns1.sinanmohd.com
+ "hostmaster@${domain}"
+ ];
+
+ credentials_directory = "/run/credentials/stalwart-mail.service";
+in
+{
+ security.acme.certs.${domain}.postRun = "systemctl restart stalwart-mail.service";
+ sops.secrets = {
+ "mail.${domain}/dkim_rsa" = { };
+ "mail.${domain}/dkim_ed25519" = { };
+ "mail.${domain}/password" = { };
+ };
+
+ systemd.services.stalwart-mail.serviceConfig.LoadCredential = [
+ "password:${config.sops.secrets."mail.${domain}/password".path}"
+
+ "dkim_rsa:${config.sops.secrets."mail.${domain}/dkim_rsa".path}"
+ "dkim_ed25519:${config.sops.secrets."mail.${domain}/dkim_ed25519".path}"
+
+ "cert:${config.security.acme.certs.${domain}.directory}/fullchain.pem"
+ "key:${config.security.acme.certs.${domain}.directory}/key.pem"
+ ];
+
+ services.postgresql = {
+ ensureDatabases = [ "stalwart" ];
+ ensureUsers = [
+ {
+ name = "stalwart";
+ ensureDBOwnership = true;
+ }
+ ];
+ };
+
+ services.stalwart-mail = {
+ enable = true;
+ openFirewall = true;
+
+ settings = {
+ queue.outbound = {
+ ip-strategy = "ipv6_then_ipv4";
+ source-ip.v6 = "['${ipv6}']";
+ tls.starttls = "optional";
+ };
+ http.url = "'https://stalwart.${domain}'";
+
+ server = {
+ hostname = "mail.${domain}";
+ listener = {
+ smtp = {
+ bind = [
+ "[${ipv6}]:25"
+ "0.0.0.0:25"
+ ];
+ protocol = "smtp";
+ };
+ submission = {
+ bind = "[::]:587";
+ protocol = "smtp";
+ };
+ submissions = {
+ bind = "[::]:465";
+ protocol = "smtp";
+ tls.implicit = true;
+ };
+ imaptls = {
+ bind = "[::]:993";
+ protocol = "imap";
+ tls.implicit = true;
+ };
+ http = {
+ bind = "[::]:8085";
+ protocol = "http";
+ };
+ };
+ };
+
+ signature = {
+ rsa = {
+ private-key = "%{file:${credentials_directory}/dkim_rsa}%";
+ inherit domain;
+ selector = "rsa";
+ headers = [
+ "From"
+ "To"
+ "Date"
+ "Subject"
+ "Message-ID"
+ ];
+ algorithm = "rsa-sha-256";
+ canonicalization = "simple/simple";
+
+ set-body-length = true;
+ expire = "2d";
+ report = true;
+ };
+ ed25519 = {
+ private-key = "%{file:${credentials_directory}/dkim_ed25519}%";
+ inherit domain;
+ selector = "ed25519";
+ headers = [
+ "From"
+ "To"
+ "Date"
+ "Subject"
+ "Message-ID"
+ ];
+ algorithm = "ed25519-sha256";
+ canonicalization = "simple/simple";
+
+ set-body-length = true;
+ expire = "2d";
+ report = true;
+ };
+ };
+
+ certificate."default" = {
+ cert = "%{file:${credentials_directory}/cert}%";
+ private-key = "%{file:${credentials_directory}/key}%";
+ };
+
+ storage = {
+ data = "postgresql";
+ fts = "postgresql";
+ blob = "postgresql";
+ lookup = "postgresql";
+ directory = "memory";
+ };
+ store.postgresql = {
+ type = "postgresql";
+ host = "localhost";
+ database = "stalwart";
+ user = "stalwart";
+ timeout = "15s";
+ tls.enable = false;
+ pool.max-connections = 10;
+ };
+
+ directory."memory" = {
+ type = "memory";
+
+ principals = [
+ {
+ class = "admin";
+ name = "${username}@${domain}";
+ secret = "%{file:${credentials_directory}/password}%";
+ inherit email;
+ }
+ {
+ # for mta-sts & dmarc reports
+ class = "individual";
+ name = "reports@${domain}";
+ secret = "%{file:${credentials_directory}/password}%";
+ email = [ "reports@${domain}" ];
+ }
+ ];
+ };
+ };
+ };
+}