diff options
Diffstat (limited to 'hosts/surtr/email/default.nix')
| -rw-r--r-- | hosts/surtr/email/default.nix | 88 |
1 files changed, 81 insertions, 7 deletions
diff --git a/hosts/surtr/email/default.nix b/hosts/surtr/email/default.nix index 83bf02f5..9cfba1f1 100644 --- a/hosts/surtr/email/default.nix +++ b/hosts/surtr/email/default.nix | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | { config, pkgs, lib, ... }: | 1 | { config, pkgs, lib, flakeInputs, ... }: |
| 2 | 2 | ||
| 3 | with lib; | 3 | with lib; |
| 4 | 4 | ||
| @@ -20,6 +20,27 @@ let | |||
| 20 | ''; | 20 | ''; |
| 21 | }; | 21 | }; |
| 22 | 22 | ||
| 23 | ccert-policy-server = flakeInputs.mach-nix.lib.${config.nixpkgs.system}.buildPythonPackage { | ||
| 24 | src = ./ccert-policy-server; | ||
| 25 | pname = "ccert-policy-server"; | ||
| 26 | version = "0.0.0"; | ||
| 27 | |||
| 28 | python = "python39"; | ||
| 29 | ignoreDataOutdated = true; | ||
| 30 | |||
| 31 | requirements = '' | ||
| 32 | sdnotify | ||
| 33 | systemd-socketserver | ||
| 34 | psycopg >=3.0.0 | ||
| 35 | psycopg-pool >=3.0.0 | ||
| 36 | psycopg-binary >=3.0.0 | ||
| 37 | ''; | ||
| 38 | |||
| 39 | overridesPre = [ | ||
| 40 | (self: super: { systemd-python = super.systemd.overrideAttrs (oldAttrs: { pname = "systemd-python"; }); }) | ||
| 41 | ]; | ||
| 42 | }; | ||
| 43 | |||
| 23 | spmDomains = ["bouncy.email"]; | 44 | spmDomains = ["bouncy.email"]; |
| 24 | in { | 45 | in { |
| 25 | config = { | 46 | config = { |
| @@ -35,7 +56,7 @@ in { | |||
| 35 | }; | 56 | }; |
| 36 | }) | 57 | }) |
| 37 | ]; | 58 | ]; |
| 38 | 59 | ||
| 39 | services.postfix = { | 60 | services.postfix = { |
| 40 | enable = true; | 61 | enable = true; |
| 41 | hostname = "surtr.yggdrasil.li"; | 62 | hostname = "surtr.yggdrasil.li"; |
| @@ -187,8 +208,9 @@ in { | |||
| 187 | "-o" "smtpd_tls_ask_ccert=yes" | 208 | "-o" "smtpd_tls_ask_ccert=yes" |
| 188 | "-o" "smtpd_tls_req_ccert=yes" | 209 | "-o" "smtpd_tls_req_ccert=yes" |
| 189 | "-o" "smtpd_client_restrictions=permit_tls_all_clientcerts,reject" | 210 | "-o" "smtpd_client_restrictions=permit_tls_all_clientcerts,reject" |
| 211 | "-o" "{smtpd_data_restrictions = check_policy_service unix:/run/postfwd3/postfwd3.sock}" | ||
| 190 | "-o" "smtpd_relay_restrictions=permit_tls_all_clientcerts,reject" | 212 | "-o" "smtpd_relay_restrictions=permit_tls_all_clientcerts,reject" |
| 191 | "-o" "smtpd_sender_restrictions=reject_unknown_sender_domain,reject_unverified_sender" | 213 | "-o" "{smtpd_sender_restrictions = reject_unknown_sender_domain,reject_unverified_sender,check_policy_service unix:/run/postfix-ccert-sender-policy.sock}" |
| 192 | "-o" "unverified_sender_reject_code=550" | 214 | "-o" "unverified_sender_reject_code=550" |
| 193 | "-o" "unverified_sender_reject_reason={Sender address rejected: undeliverable address}" | 215 | "-o" "unverified_sender_reject_reason={Sender address rejected: undeliverable address}" |
| 194 | "-o" "smtpd_recipient_restrictions=reject_unauth_pipelining,reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_tls_all_clientcerts,reject" | 216 | "-o" "smtpd_recipient_restrictions=reject_unauth_pipelining,reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_tls_all_clientcerts,reject" |
| @@ -415,7 +437,7 @@ in { | |||
| 415 | mail_plugins = $mail_plugins quota | 437 | mail_plugins = $mail_plugins quota |
| 416 | mailbox_list_index = yes | 438 | mailbox_list_index = yes |
| 417 | postmaster_address = postmaster@yggdrasil.li | 439 | postmaster_address = postmaster@yggdrasil.li |
| 418 | recipient_delimiter = | 440 | recipient_delimiter = |
| 419 | auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-+_@ | 441 | auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-+_@ |
| 420 | 442 | ||
| 421 | service lmtp { | 443 | service lmtp { |
| @@ -431,7 +453,7 @@ in { | |||
| 431 | namespace inbox { | 453 | namespace inbox { |
| 432 | separator = / | 454 | separator = / |
| 433 | inbox = yes | 455 | inbox = yes |
| 434 | prefix = | 456 | prefix = |
| 435 | 457 | ||
| 436 | mailbox Trash { | 458 | mailbox Trash { |
| 437 | auto = no | 459 | auto = no |
| @@ -602,7 +624,7 @@ in { | |||
| 602 | ${pkgs.dovecot_pigeonhole}/bin/sievec $f | 624 | ${pkgs.dovecot_pigeonhole}/bin/sievec $f |
| 603 | done | 625 | done |
| 604 | ''; | 626 | ''; |
| 605 | 627 | ||
| 606 | serviceConfig = { | 628 | serviceConfig = { |
| 607 | LoadCredential = [ | 629 | LoadCredential = [ |
| 608 | "surtr.yggdrasil.li.key.pem:${config.security.acme.certs."surtr.yggdrasil.li".directory}/key.pem" | 630 | "surtr.yggdrasil.li.key.pem:${config.security.acme.certs."surtr.yggdrasil.li".directory}/key.pem" |
| @@ -703,7 +725,7 @@ in { | |||
| 703 | }; | 725 | }; |
| 704 | systemd.sockets.spm = { | 726 | systemd.sockets.spm = { |
| 705 | wantedBy = [ "nginx.service" ]; | 727 | wantedBy = [ "nginx.service" ]; |
| 706 | 728 | ||
| 707 | socketConfig = { | 729 | socketConfig = { |
| 708 | ListenStream = "/run/spm/server.sock"; | 730 | ListenStream = "/run/spm/server.sock"; |
| 709 | SocketUser = "spm"; | 731 | SocketUser = "spm"; |
| @@ -730,5 +752,57 @@ in { | |||
| 730 | enable = true; | 752 | enable = true; |
| 731 | loglevel = "debug"; | 753 | loglevel = "debug"; |
| 732 | }; | 754 | }; |
| 755 | |||
| 756 | systemd.sockets."postfix-ccert-sender-policy" = { | ||
| 757 | requiredBy = ["postfix.service"]; | ||
| 758 | wants = ["postfix-ccert-sender-policy.service"]; | ||
| 759 | socketConfig = { | ||
| 760 | ListenStream = "/run/postfix-ccert-sender-policy.sock"; | ||
| 761 | }; | ||
| 762 | }; | ||
| 763 | systemd.services."postfix-ccert-sender-policy" = { | ||
| 764 | serviceConfig = { | ||
| 765 | Type = "notify"; | ||
| 766 | |||
| 767 | ExecStart = "${ccert-policy-server}/bin/ccert-policy-server"; | ||
| 768 | |||
| 769 | Environment = [ | ||
| 770 | "PGDATABASE=email" | ||
| 771 | ]; | ||
| 772 | |||
| 773 | DynamicUser = false; | ||
| 774 | User = "postfix-ccert-sender-policy"; | ||
| 775 | Group = "postfix-ccert-sender-policy"; | ||
| 776 | ProtectSystem = "strict"; | ||
| 777 | SystemCallFilter = "@system-service"; | ||
| 778 | NoNewPrivileges = true; | ||
| 779 | ProtectKernelTunables = true; | ||
| 780 | ProtectKernelModules = true; | ||
| 781 | ProtectKernelLogs = true; | ||
| 782 | ProtectControlGroups = true; | ||
| 783 | MemoryDenyWriteExecute = true; | ||
| 784 | RestrictSUIDSGID = true; | ||
| 785 | KeyringMode = "private"; | ||
| 786 | ProtectClock = true; | ||
| 787 | RestrictRealtime = true; | ||
| 788 | PrivateDevices = true; | ||
| 789 | PrivateTmp = true; | ||
| 790 | ProtectHostname = true; | ||
| 791 | ReadWritePaths = ["/run/postgresql"]; | ||
| 792 | }; | ||
| 793 | }; | ||
| 794 | users.users."postfix-ccert-sender-policy" = { | ||
| 795 | isSystemUser = true; | ||
| 796 | group = "postfix-ccert-sender-policy"; | ||
| 797 | }; | ||
| 798 | users.groups."postfix-ccert-sender-policy" = {}; | ||
| 799 | |||
| 800 | services.postfwd = { | ||
| 801 | enable = true; | ||
| 802 | rules = '' | ||
| 803 | id=RCPT01; protocol_state=DATA; protocol_state=END-OF-MESSAGE; action=rcpt(ccert_subject/100/3600/450 4.7.1 Exceeding maximum of 100 recipients per hour [$$ratecount]) | ||
| 804 | id=RCPT02; protocol_state=DATA; protocol_state=END-OF-MESSAGE; action=rcpt(ccert_subject/1000/86400/450 4.7.1 Exceeding maximum of 1000 recipients per day [$$ratecount]) | ||
| 805 | ''; | ||
| 806 | }; | ||
| 733 | }; | 807 | }; |
| 734 | } | 808 | } |
