summary refs log tree commit diff
path: root/host/Rory-ovh/services/email
diff options
context:
space:
mode:
Diffstat (limited to 'host/Rory-ovh/services/email')
-rw-r--r--host/Rory-ovh/services/email/autoconfig.nix18
-rw-r--r--host/Rory-ovh/services/email/maddy.conf124
-rw-r--r--host/Rory-ovh/services/email/maddy.nix71
-rw-r--r--host/Rory-ovh/services/email/nginx.nix32
-rw-r--r--host/Rory-ovh/services/email/root.nix8
5 files changed, 253 insertions, 0 deletions
diff --git a/host/Rory-ovh/services/email/autoconfig.nix b/host/Rory-ovh/services/email/autoconfig.nix
new file mode 100644

index 0000000..5f3bce2 --- /dev/null +++ b/host/Rory-ovh/services/email/autoconfig.nix
@@ -0,0 +1,18 @@ +{ config, ... }: +{ + services.go-autoconfig = { + enable = !config.virtualisation.isVmVariant; + settings = { + service_addr = ":1323"; + domain = "autoconfig.rory.gay"; + imap = { + server = "rory.gay"; + port = 993; + }; + smtp = { + server = "rory.gay"; + port = 587; + }; + }; + }; +} diff --git a/host/Rory-ovh/services/email/maddy.conf b/host/Rory-ovh/services/email/maddy.conf new file mode 100644
index 0000000..1d3eb2f --- /dev/null +++ b/host/Rory-ovh/services/email/maddy.conf
@@ -0,0 +1,124 @@ + +# Minimal configuration with TLS disabled, adapted from upstream example +# configuration here https://github.com/foxcpp/maddy/blob/master/maddy.conf +# Do not use this in production! + +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 { + optional_step regexp "(.+)\+(.+)@(.+)" "$1@$3" + optional_step static { + entry postmaster root@$(primary_domain) + } + optional_step file /etc/maddy/aliases +} + +msgpipeline local_routing { + destination postmaster $(local_domains) { + modify { + replace_rcpt &local_rewrites + } + deliver_to &local_mailboxes + } + 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 $(local_domains) { + reject 501 5.1.8 "Use Submission for outgoing SMTP" + } + default_source { + destination postmaster $(local_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 $(local_domains) { + check { + authorize_sender { + prepare_email &local_rewrites + user_to_email identity + } + } + destination postmaster $(local_domains) { + deliver_to &local_routing + } + default_destination { + modify { + dkim $(primary_domain) $(local_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 $(primary_domain) + bounce { + destination postmaster $(local_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 +} \ No newline at end of file diff --git a/host/Rory-ovh/services/email/maddy.nix b/host/Rory-ovh/services/email/maddy.nix new file mode 100644
index 0000000..3f1d427 --- /dev/null +++ b/host/Rory-ovh/services/email/maddy.nix
@@ -0,0 +1,71 @@ +{ + lib, + pkgs, + options, + config, + ... +}: +{ + config = lib.mkIf (!config.virtualisation.isVmVariant) { + services.maddy = { + enable = true; + primaryDomain = "rory.gay"; + hostname = "mail.rory.gay"; + ensureAccounts = [ + "root@rory.gay" + ]; + ensureCredentials = { + "root@rory.gay".passwordFile = "/var/lib/maddy/passwd/root"; + }; + config = builtins.readFile ./maddy.conf; + # builtins.replaceStrings + # [ + # "imap tcp://0.0.0.0:143" + # "submission tcp://0.0.0.0:587" + # "entry postmaster postmaster@$(primary_domain)" + # ] + # [ + # "imap tls://0.0.0.0:993 tcp://0.0.0.0:143" + # "submission tls://0.0.0.0:465 tcp://0.0.0.0:587" + # "entry postmaster root@$(primary_domain)" + # ] + # options.services.maddy.config.default; + + tls = { + loader = "file"; + certificates = [ + { + # certPath = "/var/lib/acme/mail.rory.gay/fullchain.pem"; + # keyPath = "/var/lib/acme/mail.rory.gay/key.pem"; + certPath = "/run/credentials/maddy.service/acme-fullchain.pem"; + keyPath = "/run/credentials/maddy.service/acme-key.pem"; + } + ]; + }; + }; + + networking.firewall.allowedTCPPorts = [ + 25 + 143 + 465 + 587 + 993 + ]; + + users.users.maddy.extraGroups = [ "nginx" ]; + + fileSystems."/var/lib/maddy" = { + depends = [ "/" ]; + device = "/data/maddy"; + fsType = "none"; + options = [ "bind" ]; + }; + + systemd.services.maddy.serviceConfig = { + LoadCredential = [ + "acme-fullchain.pem:/var/lib/acme/rory.gay/fullchain.pem" + "acme-key.pem:/var/lib/acme/rory.gay/key.pem" + ]; + }; + }; +} diff --git a/host/Rory-ovh/services/email/nginx.nix b/host/Rory-ovh/services/email/nginx.nix new file mode 100644
index 0000000..5b04612 --- /dev/null +++ b/host/Rory-ovh/services/email/nginx.nix
@@ -0,0 +1,32 @@ +{ config, ... }: +{ + services.nginx.virtualHosts = { + "mta-sts.rory.gay" = { + enableACME = !config.virtualisation.isVmVariant; + forceSSL = !config.virtualisation.isVmVariant; + locations = { + "/.well-known/mta-sts.txt" = { + # age 604800 + return = '' + 200 "version: STSv1 + mode: enforce + max_age: 120 + mx: mail.rory.gay + "''; + }; + }; + }; + "mail.rory.gay" = { + enableACME = !config.virtualisation.isVmVariant; + forceSSL = !config.virtualisation.isVmVariant; + locations = { + "/".return = "200 'OK'"; + }; + }; + "autoconfig.rory.gay" = { + enableACME = !config.virtualisation.isVmVariant; + forceSSL = !config.virtualisation.isVmVariant; + locations."/".proxyPass = "http://localhost:1323"; + }; + }; +} diff --git a/host/Rory-ovh/services/email/root.nix b/host/Rory-ovh/services/email/root.nix new file mode 100644
index 0000000..7db85d8 --- /dev/null +++ b/host/Rory-ovh/services/email/root.nix
@@ -0,0 +1,8 @@ +{ ... }: +{ + imports = [ + ./autoconfig.nix + ./maddy.nix + ./nginx.nix + ]; +}