infrastructure/services/mail/postfix.nix

220 lines
8.4 KiB
Nix

{ pkgs, lib, config, tf, ... }:
let
publicCert = "daiyousei.kittywit.ch";
ldaps = "ldaps://auth.${config.networks.internet.uqdn}:636";
virtualRegex = pkgs.writeText "virtual-regex" ''
/^kat\.[^@.]+@kittywit\.ch$/ kat@kittywit.ch
/^kat\.[^@.]+@dork\.dev$/ kat@kittywit.ch
/^arc\.[^@.]+@kittywit\.ch$/ arc@kittywit.ch
/^arc\.[^@.]+@dork\.dev$/ arc@kittywit.ch
'';
helo_access = pkgs.writeText "helo_access" ''
${if tf.state.enable then config.networks.internet.ipv4 else ""} REJECT Get lost - you're lying about who you are
${if tf.state.enable then config.networks.internet.ipv6 else ""} REJECT Get lost - you're lying about who you are
kittywit.ch REJECT Get lost - you're lying about who you are
dork.dev REJECT Get lost - you're lying about who you are
'';
in {
kw.secrets.variables."postfix-ldap-password" = {
path = "services/dovecot";
field = "password";
};
secrets.files = {
domains-ldap = {
text = ''
server_host = ${ldaps}
search_base = dc=domains,dc=mail,dc=kittywit,dc=ch
query_filter = (&(dc=%s)(objectClass=mailDomain))
result_attribute = postfixTransport
bind = yes
version = 3
bind_dn = cn=dovecot,dc=mail,dc=kittywit,dc=ch
bind_pw = ${tf.variables.postfix-ldap-password.ref}
scope = one
'';
owner = "postfix";
group = "postfix";
};
accountsmap-ldap = {
text = ''
server_host = ${ldaps}
search_base = ou=users,dc=kittywit,dc=ch
query_filter = (&(objectClass=mailAccount)(|(uid=%s)(mail=%s)))
result_attribute = mail
version = 3
bind = yes
bind_dn = cn=dovecot,dc=mail,dc=kittywit,dc=ch
bind_pw = ${tf.variables.postfix-ldap-password.ref}
'';
owner = "postfix";
group = "postfix";
};
accountsmap-services-ldap = {
text = ''
server_host = ${ldaps}
search_base = ou=services,dc=kittywit,dc=ch
query_filter = (&(objectClass=mailAccount)(|(uid=%s)(mail=%s)))
result_attribute = mail
version = 3
bind = yes
bind_dn = cn=dovecot,dc=mail,dc=kittywit,dc=ch
bind_pw = ${tf.variables.postfix-ldap-password.ref}
'';
owner = "postfix";
group = "postfix";
};
aliases-ldap = {
text = ''
server_host = ${ldaps}
search_base = dc=aliases,dc=mail,dc=kittywit,dc=ch
query_filter = (&(objectClass=mailAlias)(mail=%s))
result_attribute = maildrop
version = 3
bind = yes
bind_dn = cn=dovecot,dc=mail,dc=kittywit,dc=ch
bind_pw = ${tf.variables.postfix-ldap-password.ref}
'';
owner = "postfix";
group = "postfix";
};
};
services.postfix = {
enable = true;
enableSubmission = true;
hostname = config.networks.internet.uqdn;
domain = "kittywit.ch";
masterConfig."465" = {
type = "inet";
private = false;
command = "smtpd";
args = [
"-o smtpd_client_restrictions=permit_sasl_authenticated,reject"
"-o syslog_name=postfix/smtps"
"-o smtpd_tls_wrappermode=yes"
"-o smtpd_sasl_auth_enable=yes"
"-o smtpd_tls_security_level=none"
"-o smtpd_reject_unlisted_recipient=no"
"-o smtpd_recipient_restrictions="
"-o smtpd_relay_restrictions=permit_sasl_authenticated,reject"
"-o milter_macro_daemon_name=ORIGINATING"
];
};
mapFiles."virtual-regex" = virtualRegex;
mapFiles."helo_access" = helo_access;
extraConfig = ''
smtp_bind_address = ${if tf.state.enable then tf.resources.${config.networking.hostName}.getAttr "private_ip" else ""}
smtp_bind_address6 = ${if tf.state.enable then config.networks.internet.ipv6 else ""}
mailbox_transport = lmtp:unix:private/dovecot-lmtp
masquerade_domains = ldap:${config.secrets.files.domains-ldap.path}
virtual_mailbox_domains = ldap:${config.secrets.files.domains-ldap.path}
virtual_alias_maps = ldap:${config.secrets.files.accountsmap-ldap.path},ldap:${config.secrets.files.accountsmap-services-ldap.path},ldap:${config.secrets.files.aliases-ldap.path},regexp:/var/lib/postfix/conf/virtual-regex
virtual_transport = lmtp:unix:private/dovecot-lmtp
smtpd_milters = unix:/run/opendkim/opendkim.sock,unix:/run/rspamd/rspamd-milter.sock
non_smtpd_milters = unix:/run/opendkim/opendkim.sock
milter_protocol = 6
milter_default_action = accept
milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_type} {auth_authen} {auth_author} {mail_addr} {mail_host} {mail_mailer}
# bigger attachement size
mailbox_size_limit = 202400000
message_size_limit = 51200000
smtpd_helo_required = yes
smtpd_delay_reject = yes
strict_rfc821_envelopes = yes
# send Limit
smtpd_error_sleep_time = 1s
smtpd_soft_error_limit = 10
smtpd_hard_error_limit = 20
smtpd_use_tls = yes
smtp_tls_note_starttls_offer = yes
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = ${config.secrets.files."${config.networking.hostName}.kittywit.ch-cert".path}
smtpd_tls_key_file = ${config.secrets.files."${config.networking.hostName}.kittywit.ch-key".path}
smtpd_tls_CAfile = ${config.secrets.files."${config.networking.hostName}.kittywit.ch-cert".path}
smtpd_tls_dh512_param_file = ${config.security.dhparams.params.postfix512.path}
smtpd_tls_dh1024_param_file = ${config.security.dhparams.params.postfix2048.path}
smtpd_tls_session_cache_database = btree:''${data_directory}/smtpd_scache
smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1
smtpd_tls_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1
smtpd_tls_mandatory_ciphers = medium
tls_medium_cipherlist = AES128+EECDH:AES128+EDH
# authentication
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $mydomain
smtpd_sasl_security_options = noanonymous
smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
smtpd_sasl_type = dovecot
smtpd_sasl_path = /var/lib/postfix/queue/private/auth
smtpd_relay_restrictions = permit_mynetworks,
permit_sasl_authenticated,
defer_unauth_destination
smtpd_client_restrictions = permit_mynetworks,
permit_sasl_authenticated,
reject_invalid_hostname,
reject_unknown_client,
permit
smtpd_helo_restrictions = permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_pipelining,
reject_non_fqdn_hostname,
reject_invalid_hostname,
warn_if_reject reject_unknown_hostname,
permit
smtpd_recipient_restrictions = permit_mynetworks,
permit_sasl_authenticated,
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_non_fqdn_hostname,
reject_invalid_hostname,
reject_unknown_sender_domain,
reject_unknown_recipient_domain,
reject_unknown_client_hostname,
reject_unauth_pipelining,
reject_unknown_client,
permit
smtpd_sender_restrictions = permit_mynetworks,
permit_sasl_authenticated,
reject_non_fqdn_sender,
reject_unknown_sender_domain,
reject_unknown_client_hostname,
reject_unknown_address
smtpd_etrn_restrictions = permit_mynetworks, reject
smtpd_data_restrictions = reject_unauth_pipelining, reject_multi_recipient_bounce, permit
'';
};
systemd.services.postfix.wants = [ "openldap.service" ];
systemd.services.postfix.after = [ "openldap.service" "network.target" ];
security.dhparams = {
enable = true;
params.postfix512.bits = 512;
params.postfix2048.bits = 1024;
};
networks.internet.tcp = [
25 # smtp
465 # stmps
587 # submission
];
}