{ config, pkgs, ... }@all: with all; let users = [ "nxcaldav" "nextcloud" "lennart" "daniel" "diane" "georg" "tessa" ]; in { sops.secrets = { "nx2site/maddy/nxcaldav_password" = { owner = "maddy"; group = "maddy"; mode = "600"; }; "nx2site/maddy/nextcloud_password" = { owner = "maddy"; group = "maddy"; mode = "600"; }; "nx2site/maddy/lennart_password" = { owner = "maddy"; group = "maddy"; mode = "600"; }; "nx2site/maddy/daniel_password" = { owner = "maddy"; group = "maddy"; mode = "600"; }; "nx2site/maddy/diane_password" = { owner = "maddy"; group = "maddy"; mode = "600"; }; "nx2site/maddy/georg_password" = { owner = "maddy"; group = "maddy"; mode = "600"; }; "nx2site/maddy/tessa_password" = { owner = "maddy"; group = "maddy"; mode = "600"; }; }; users.users."maddy" = { extraGroups = [ "acme" "nginx" ]; }; services.maddy = { enable = true; primaryDomain = hyper.domain; user = "maddy"; group = "maddy"; hostname = "ssh.${hyper.domain}"; ensureAccounts = [ "nxcaldav@${hyper.domain}" "nextcloud@${hyper.domain}" "lennart@${hyper.domain}" "daniel@${hyper.domain}" "diane@${hyper.domain}" "georg@${hyper.domain}" "tessa@${hyper.domain}" ]; ensureCredentials = { "nxcaldav@${hyper.domain}".passwordFile = config.sops.secrets."nx2site/maddy/nxcaldav_password".path; "nextcloud@${hyper.domain}".passwordFile = config.sops.secrets."nx2site/maddy/nextcloud_password".path; "lennart@${hyper.domain}".passwordFile = config.sops.secrets."nx2site/maddy/lennart_password".path; "daniel@${hyper.domain}".passwordFile = config.sops.secrets."nx2site/maddy/daniel_password".path; "diane@${hyper.domain}".passwordFile = config.sops.secrets."nx2site/maddy/diane_password".path; "georg@${hyper.domain}".passwordFile = config.sops.secrets."nx2site/maddy/georg_password".path; "tessa@${hyper.domain}".passwordFile = config.sops.secrets."nx2site/maddy/tessa_password".path; }; openFirewall = true; tls = { loader = "file"; certificates = [{ keyPath = "/var/lib/acme/nx2.site/key.pem"; certPath = "/var/lib/acme/nx2.site/cert.pem"; }]; }; # Enable TLS listeners. Configuring this via the module is not yet # implemented, see https://github.com/NixOS/nixpkgs/pull/153372 config = let admin = "lennart@${hyper.domain}"; domains = hyper.domain; # could be more inherit (hyper) domain; # nix adds 3 variables, hostname, and tls info before the file (see /etc/maddy/maddy.conf) in /* ini */'' auth.pass_table local_authdb { table sql_table { driver sqlite3 dsn credentials.db table_name passwords } } storage.imapsql local_mailboxes { driver sqlite3 dsn imapsql.db } table.chain local_rewrites { # tagging with - or + # alice-something@${domain} or alice+something@${domain} lands in inbox alice@${domain} optional_step regexp "(.+)[\+-](.+)@(.+)" "$1@$3" optional_step static { entry postmaster ${admin} entry admin ${admin} } } msgpipeline local_routing { destination ${domains} { modify { replace_rcpt &local_rewrites } reroute { destination_in &local_mailboxes { deliver_to &local_mailboxes } default_destination { modify { replace_rcpt regexp ".*" "${admin}" } deliver_to &local_mailboxes } } } # should never happen default_destination { reject 550 5.1.1 "User doesn't exist" } } smtp tcp://0.0.0.0:25 { limits { all rate 20 1s all concurrency 10 } dmarc yes check { require_mx_record dkim spf } source ${domains} { reject 501 5.1.8 "Use Submission for outgoing SMTP" } default_source { destination postmaster ${domains} { deliver_to &local_routing } default_destination { reject 550 5.1.1 "User doesn't exist" } } } submission tls://0.0.0.0:465 tcp://0.0.0.0:587 { limits { all rate 50 1s } auth &local_authdb source ${domains} { check { authorize_sender { prepare_email &local_rewrites user_to_email identity } } destination postmaster ${domains} { deliver_to &local_routing } default_destination { modify { dkim ${domain} ${domains} default } deliver_to &remote_queue } } default_source { reject 501 5.1.8 "Non-local sender domain" } } target.remote outbound_delivery { limits { destination rate 20 1s destination concurrency 10 } mx_auth { dane mtasts { cache fs fs_dir mtasts_cache/ } local_policy { min_tls_level encrypted min_mx_level none } } } target.queue remote_queue { target &outbound_delivery autogenerated_msg_domain ${domain} bounce { destination postmaster ${domains} { deliver_to &local_routing } default_destination { reject 550 5.0.0 "Refusing to send DSNs to non-local addresses" } } } imap tls://0.0.0.0:993 tcp://0.0.0.0:143 { auth &local_authdb storage &local_mailboxes } # localhost only - test purposes only (->spam!) smtp tcp://127.0.0.1:2525 { tls off destination postmaster ${domains} { deliver_to &local_routing } default_destination { modify { dkim ${domain} ${domains} default } deliver_to &remote_queue } } # nx2s-email-relay backdor smtp tcp://0.0.0.0:25025 { # 1. Allow incoming mail from the VM for your domains destination postmaster ${domains} { deliver_to &local_routing } # 2. Prevent the world from using you as an open relay default_destination { reject 521 5.0.0 "User not local" } } ''; }; } # --- Receive # 1. mx to mail.nx2.site # 2. mail.nx2.site to nx2s-email-relay (google e2-micro) # 3. nx2s-email-relay uses emaul-relay.service to socat 25 to 25025 home # 4. home gets 25025 and handles it # -- Send # 1. Via Smtp2go (mail-eu.smtp2go.com) # SPF is coverd by CNAME (return) (somehow)