summaryrefslogtreecommitdiff
path: root/hosts/surtr/email/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'hosts/surtr/email/default.nix')
-rw-r--r--hosts/surtr/email/default.nix108
1 files changed, 106 insertions, 2 deletions
diff --git a/hosts/surtr/email/default.nix b/hosts/surtr/email/default.nix
index 83820c65..d9e6fff9 100644
--- a/hosts/surtr/email/default.nix
+++ b/hosts/surtr/email/default.nix
@@ -52,6 +52,22 @@ let
52 mainProgram = "internal-policy-server"; 52 mainProgram = "internal-policy-server";
53 }; 53 };
54 }); 54 });
55 password-server =
56 let
57 workspace = flakeInputs.uv2nix.lib.workspace.loadWorkspace { workspaceRoot = ./password-server; };
58 pythonSet = flake.lib.pythonSet {
59 inherit pkgs;
60 python = pkgs.python3;
61 overlay = workspace.mkPyprojectOverlay {
62 sourcePreference = "wheel";
63 };
64 };
65 virtualEnv = pythonSet.mkVirtualEnv "password-server-env" workspace.deps.default;
66 in virtualEnv.overrideAttrs (oldAttrs: {
67 meta = (oldAttrs.meta or {}) // {
68 mainProgram = "password-server";
69 };
70 });
55 71
56 nftables-nologin-script = pkgs.resholve.writeScript "nftables-mail-nologin" { 72 nftables-nologin-script = pkgs.resholve.writeScript "nftables-mail-nologin" {
57 inputs = with pkgs; [inetutils nftables gnugrep findutils]; 73 inputs = with pkgs; [inetutils nftables gnugrep findutils];
@@ -776,6 +792,9 @@ in {
776 "surtr.yggdrasil.li" = { 792 "surtr.yggdrasil.li" = {
777 restartUnits = [ "postfix.service" "dovecot.service" ]; 793 restartUnits = [ "postfix.service" "dovecot.service" ];
778 }; 794 };
795 "pw.bouncy.email" = {
796 restartUnits = [ "nginx.service" ];
797 };
779 } // listToAttrs (map (domain: nameValuePair "spm.${domain}" { restartUnits = ["nginx.service"]; }) spmDomains) 798 } // listToAttrs (map (domain: nameValuePair "spm.${domain}" { restartUnits = ["nginx.service"]; }) spmDomains)
780 // listToAttrs (concatMap (domain: [ 799 // listToAttrs (concatMap (domain: [
781 (nameValuePair domain { restartUnits = ["postfix.service" "dovecot.service"]; }) 800 (nameValuePair domain { restartUnits = ["postfix.service" "dovecot.service"]; })
@@ -814,6 +833,11 @@ in {
814 "unix:/run/spm/server.sock" = {}; 833 "unix:/run/spm/server.sock" = {};
815 }; 834 };
816 }; 835 };
836 upstreams.password-server = {
837 servers = {
838 "unix:/run/email-password-server.sock" = {};
839 };
840 };
817 841
818 virtualHosts = listToAttrs (map (domain: nameValuePair "spm.${domain}" { 842 virtualHosts = listToAttrs (map (domain: nameValuePair "spm.${domain}" {
819 forceSSL = true; 843 forceSSL = true;
@@ -868,7 +892,28 @@ in {
868 ''; 892 '';
869 }; 893 };
870 }; 894 };
871 }) emailDomains); 895 }) emailDomains) // {
896 "pw.bouncy.email" = {
897 forceSSL = true;
898 kTLS = true;
899 http3 = false;
900 sslCertificate = "/run/credentials/nginx.service/pw.bouncy.email.pem";
901 sslCertificateKey = "/run/credentials/nginx.service/pw.bouncy.email.key.pem";
902 extraConfig = ''
903 ssl_stapling off;
904 ssl_verify_client optional;
905 ssl_client_certificate ${toString ./ca/ca.crt};
906 '';
907 locations."/" = {
908 proxyPass = "http://password-server";
909
910 extraConfig = ''
911 proxy_set_header SSL-CLIENT-VERIFY $ssl_client_verify;
912 proxy_set_header SSL-CLIENT-S-DN $ssl_client_s_dn;
913 '';}
914 ;
915 };
916 };
872 }; 917 };
873 918
874 systemd.services.nginx.serviceConfig.LoadCredential = concatMap (domain: [ 919 systemd.services.nginx.serviceConfig.LoadCredential = concatMap (domain: [
@@ -878,7 +923,10 @@ in {
878 "mta-sts.${domain}.key.pem:${config.security.acme.certs."mta-sts.${domain}".directory}/key.pem" 923 "mta-sts.${domain}.key.pem:${config.security.acme.certs."mta-sts.${domain}".directory}/key.pem"
879 "mta-sts.${domain}.pem:${config.security.acme.certs."mta-sts.${domain}".directory}/fullchain.pem" 924 "mta-sts.${domain}.pem:${config.security.acme.certs."mta-sts.${domain}".directory}/fullchain.pem"
880 "mta-sts.${domain}.chain.pem:${config.security.acme.certs."mta-sts.${domain}".directory}/chain.pem" 925 "mta-sts.${domain}.chain.pem:${config.security.acme.certs."mta-sts.${domain}".directory}/chain.pem"
881 ]) emailDomains; 926 ]) emailDomains ++ [
927 "pw.bouncy.email.key.pem:${config.security.acme.certs."pw.bouncy.email".directory}/key.pem"
928 "pw.bouncy.email.pem:${config.security.acme.certs."pw.bouncy.email".directory}/fullchain.pem"
929 ];
882 930
883 systemd.services.spm = { 931 systemd.services.spm = {
884 serviceConfig = { 932 serviceConfig = {
@@ -1021,6 +1069,62 @@ in {
1021 }; 1069 };
1022 users.groups."postfix-internal-policy" = {}; 1070 users.groups."postfix-internal-policy" = {};
1023 1071
1072 systemd.sockets."email-password-server" = {
1073 requiredBy = ["postfix.service"];
1074 wants = ["email-password-server.service"];
1075 socketConfig = {
1076 ListenStream = "/run/email-password-server.sock";
1077 };
1078 };
1079 systemd.services."email-password-server" = {
1080 after = [ "postgresql.service" ];
1081 bindsTo = [ "postgresql.service" ];
1082
1083 serviceConfig = {
1084 Type = "notify";
1085
1086 ExecStart = getExe' password-server "password-server";
1087
1088 Environment = [
1089 "PGDATABASE=email"
1090 ];
1091
1092 LoadCredential = [
1093 "secret:${config.sops.secrets."email-password-server-secret".path}"
1094 ];
1095
1096 DynamicUser = false;
1097 User = "email-password-server";
1098 Group = "email-password-server";
1099 ProtectSystem = "strict";
1100 SystemCallFilter = "@system-service";
1101 NoNewPrivileges = true;
1102 ProtectKernelTunables = true;
1103 ProtectKernelModules = true;
1104 ProtectKernelLogs = true;
1105 ProtectControlGroups = true;
1106 MemoryDenyWriteExecute = true;
1107 RestrictSUIDSGID = true;
1108 KeyringMode = "private";
1109 ProtectClock = true;
1110 RestrictRealtime = true;
1111 PrivateDevices = true;
1112 PrivateTmp = true;
1113 ProtectHostname = true;
1114 ReadWritePaths = ["/run/postgresql"];
1115 };
1116 };
1117 users.users."email-password-server" = {
1118 isSystemUser = true;
1119 group = "email-password-server";
1120 };
1121 users.groups."email-password-server" = {};
1122 sops.secrets."email-password-server-secret" = {
1123 format = "binary";
1124 sopsFile = ./email-password-server-secret;
1125 };
1126
1127
1024 services.postfwd = { 1128 services.postfwd = {
1025 enable = true; 1129 enable = true;
1026 cache = false; 1130 cache = false;