snix/ops/modules/stalwart.nix
Florian Klink a52ea3675c feat(*): initialize new Snix infrastructure
Co-Authored-By: edef <edef@edef.eu>
Co-Authored-by: Ryan Lahfa <raito@lix.systems>
Change-Id: Ica1cda177a236814de900f50a8a61d288f58f519
2025-03-17 17:15:07 +00:00

83 lines
2.4 KiB
Nix

# Stalwart is an all-in-one mailserver in Rust.
# https://stalw.art/
{ config, lib, ... }:
let
inherit (lib) mkOption mkEnableOption mkIf types;
cfg = config.services.depot.stalwart;
certs = config.security.acme.certs.${cfg.mailDomain} or (throw "NixOS-level ACME was not enabled for `${cfg.mailDomain}`: mailserver cannot autoconfigure!");
mkBind = port: ip: "${ip}:${toString port}";
in
{
options.services.depot.stalwart = {
enable = mkEnableOption "Stalwart Mail server";
listenAddresses = mkOption {
type = types.listOf types.str;
default = [
"49.12.112.149"
"[2a01:4f8:c013:3e62::2]"
];
};
mailDomain = mkOption {
type = types.str;
description = "The email domain, i.e. the part after @";
example = "snix.dev";
};
};
config = mkIf cfg.enable {
# Open only from the listen addresses.
networking.firewall.allowedTCPPorts = [ 25 587 143 443 ];
services.stalwart-mail = {
enable = true;
settings = {
certificate.letsencrypt = {
cert = "file://${certs.directory}/fullchain.pem";
private-key = "file://${certs.directory}/key.pem";
};
server = {
hostname = cfg.mailDomain;
tls = {
certificate = "letsencrypt";
enable = true;
implicit = false;
};
listener = {
smtp = {
bind = map (mkBind 587) cfg.listenAddresses;
protocol = "smtp";
};
imap = {
bind = map (mkBind 143) cfg.listenAddresses;
protocol = "imap";
};
mgmt = {
bind = map (mkBind 443) cfg.listenAddresses;
protocol = "https";
};
};
};
session = {
rcpt = {
directory = "in-memory";
# Allow this server to be used as a relay for authenticated principals.
relay = [
{ "if" = "!is_empty(authenticated_as)"; "then" = true; }
{ "else" = false; }
];
};
auth = {
mechanisms = [ "PLAIN" ];
directory = "in-memory";
};
};
jmap.directory = "in-memory";
queue.outbound.next-hop = [ "local" ];
directory.in-memory = {
type = "memory";
};
};
};
};
}