From 6ca265e97bd37b3373d5a06d839722f2b5eab18f Mon Sep 17 00:00:00 2001 From: blake Date: Sun, 19 Oct 2025 13:59:06 -0500 Subject: [PATCH] add postfix --- hosts/nixos/snowbelle/configuration.nix | 1 + modules/homelab/.default.nix.template.nix | 18 ++-- modules/homelab/default.nix | 1 + modules/homelab/postfix/default.nix | 100 ++++++++++++++++++++++ secrets/secrets.yaml | 6 +- 5 files changed, 113 insertions(+), 13 deletions(-) create mode 100644 modules/homelab/postfix/default.nix diff --git a/hosts/nixos/snowbelle/configuration.nix b/hosts/nixos/snowbelle/configuration.nix index 6623b4f..503574c 100644 --- a/hosts/nixos/snowbelle/configuration.nix +++ b/hosts/nixos/snowbelle/configuration.nix @@ -36,6 +36,7 @@ in enable = true; backups.enable = true; motd.enable = true; + postfix.enable = true; gitea.enable = true; glance.enable = true; immich.enable = true; diff --git a/modules/homelab/.default.nix.template.nix b/modules/homelab/.default.nix.template.nix index 06b355f..c8002ab 100644 --- a/modules/homelab/.default.nix.template.nix +++ b/modules/homelab/.default.nix.template.nix @@ -3,15 +3,12 @@ config, lib, ... -}: - -let +}: let service = ""; - cfg = config.modules.services.${service}; + cfg = config.homelab.${service}; sec = config.sops.secrets; homelab = config.homelab; -in -{ +in { options.modules.services.${service} = { enable = lib.mkEnableOption "enables ${service}"; @@ -44,7 +41,6 @@ in }; config = lib.mkIf cfg.enable { - # declare ${service} group users.groups.${service} = { gid = lib.mkForce cfg.ids; @@ -58,7 +54,7 @@ in home = cfg.data_dir; createHome = true; group = service; - extraGroups = [ "media" ]; + extraGroups = ["media"]; }; # enable the ${service} service @@ -85,7 +81,7 @@ in # add to caddy for reverse proxy services.caddy.virtualHosts."${cfg.url}" = { - serverAliases = [ "${service}.${homelab.public_domain}" ]; + serverAliases = ["${service}.${homelab.public_domain}"]; extraConfig = '' tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key reverse_proxy 127.0.0.1:${toString cfg.port} @@ -118,9 +114,9 @@ in # }; # add to backups - system.backups.baks = { + homelab.backups.baks = { ${service} = { - paths = [ cfg.data_dir ]; + paths = [cfg.data_dir]; }; }; }; diff --git a/modules/homelab/default.nix b/modules/homelab/default.nix index 59d6ca5..48219a4 100644 --- a/modules/homelab/default.nix +++ b/modules/homelab/default.nix @@ -44,6 +44,7 @@ in ./motd ./backups ./glance + ./postfix ./caddy ./home/zigbee2mqtt ./vaultwarden diff --git a/modules/homelab/postfix/default.nix b/modules/homelab/postfix/default.nix new file mode 100644 index 0000000..66c263b --- /dev/null +++ b/modules/homelab/postfix/default.nix @@ -0,0 +1,100 @@ +{ + pkgs, + config, + lib, + ... +}: let + service = "postfix"; + cfg = config.homelab.${service}; + sec = config.sops.secrets; + homelab = config.homelab; +in { + options.modules.services.${service} = { + enable = lib.mkEnableOption "enables ${service}"; + + # set port options + port = lib.mkOption { + type = lib.types.int; + default = 587; + description = "set port for ${service} (default: ${toString cfg.port}"; + }; + url = lib.mkOption { + type = lib.types.str; + default = "${service}.${homelab.base_domain}"; + description = "set domain for ${service}"; + }; + data_dir = lib.mkOption { + type = lib.types.str; + default = "/var/lib/${service}"; + description = "set data directory for ${service}"; + }; + ids = lib.mkOption { + type = lib.types.int; + default = cfg.port; + description = "set uid and pid of ${service} user (matches port by default)"; + }; + backup = lib.mkOption { + type = lib.types.bool; + default = true; + description = "enable backups for ${service}"; + }; + }; + + config = lib.mkIf cfg.enable { + # declare ${service} group + # users.groups.${service} = { + # gid = lib.mkForce cfg.ids; + # }; + # + # # declare ${service} user + # users.users.${service} = { + # description = "${service} server user"; + # uid = lib.mkForce cfg.ids; + # isSystemUser = true; + # home = cfg.data_dir; + # createHome = true; + # group = service; + # extraGroups = []; + # }; + + # enable the ${service} service + services.postfix = { + enable = true; + relayHost = "smtp.gmail.com"; + relayPort = cfg.port; + config = { + smtp_use_tls = "yes"; + smtp_sasl_auth_enable = "yes"; + smtp_sasl_security_options = ""; + smtp_sasl_password_maps = "texthash:${config.sops.secrets."postfix_passwd".path}"; + # optional: Forward mails to root (e.g. from cron jobs, smartd) + # to me privately and to my work email: + virtual_alias_maps = "inline:{ {root=me@blakedheld.xyz, throwedspam@gmail.com} }"; + }; + }; + + # override umask to make permissions work out + # systemd.services.${service}.serviceConfig = { + # UMask = lib.mkForce "0007"; + # User = service; + # Group = service; + #}; + + # open firewall + networking.firewall.allowedTCPPorts = [ cfg.port ]; + + sops.secrets = { + "${service}_passwd" = { + owner = config.services.postfix.user; + group = config.services.postfix.group; + }; + }; + + # add to backups + homelab.backups.baks = { + ${service} = { + paths = [cfg.data_dir]; + }; + }; + }; +} diff --git a/secrets/secrets.yaml b/secrets/secrets.yaml index 3871095..03a86c8 100644 --- a/secrets/secrets.yaml +++ b/secrets/secrets.yaml @@ -22,6 +22,8 @@ minecraft_recpro_db_passwd: ENC[AES256_GCM,data:dPAkdEX0hBigo/lND2r3ShxnS4Jc5wTI #ENC[AES256_GCM,data:nbB5Cd7i/KTMCjCzcX8o1sxREZQ/gLAG,iv:iyuO2erxdJM08WHJBjKuNIXYxVhH7rfyOLTcGCcGqNQ=,tag:UeDszimXv8kQUmDetLeFqg==,type:comment] mosquitto_hashed_passwd: ENC[AES256_GCM,data:k1Lnr8ZTDpzXMoRmRH61X41boX/D8Rm1KPh7x3/IHFo+XKIOUQns53iA+7e7Ohp8uWSthDlOk4SlRvTXdUNiEz7Zmw9LYwy7BHbwpNo2pFApAye1ORPrMrhMUkUfgBgc8oqPPyRXmmrOAFp6GBbRhg==,iv:D8wQL9iF0rqOte5X24kDTVjYUJXbZSLz0Ykbp0HqmYo=,tag:RUCgO1uKPIdumSo563cg1Q==,type:str] mosquitto_passwd.yaml: ENC[AES256_GCM,data:9xwHiUaQ6zG/4rkRemXtbRJ/KEV4yajqyYlcXRR1eAQ2XijYOzitPjt53h3FPqp5rxl6dJerXNH5CiZZK3t1l339NxNseJFGVmIHitWJxNmGJMlG3M8r8Q==,iv:C6WWZuVkYaasB2pol3uf4Mc3d/lDEgt2pKX+dHl/Cr4=,tag:jYTC6RKF2TzDSwSUh6D8zQ==,type:str] +#ENC[AES256_GCM,data:zmSByl0De3a39qLbS99oce7ORe2BBoPa+3I05/YYxL7iBeWCP3ZK,iv:6nUTBUFpNK7Mttckqu6Wk/QJ5cP4+iL+EH4ldaIuu9s=,tag:pc5UtjbNPsVOEMCdLKgGMA==,type:comment] +postfix_passwd: ENC[AES256_GCM,data:6VMANDTcvAxPMG4uEOsjhYFGV+CRr9a7VXqm/x+0UYP3Uh5bzLfvt6KVjiuIGEpjlj1rJXJhSKkb+Q==,iv:8PiRwJ+U6kRTtAsDXvdz/DtBinS2uLhWRipT8T8k7Kg=,tag:KppmdbquoEWHhWHeo6WuwA==,type:str] #ENC[AES256_GCM,data:3oMbbBSrbjrqsdiON1ENB8JeKW0=,iv:+/eL/51OA+VHbkWWSNzQId5BlxnMm+5NBA0uKw010Tk=,tag:vBJpCYmvFivBYIKatDWgHw==,type:comment] copyparty_passwd: ENC[AES256_GCM,data:I3UYy4nJ0B6RnIp661O0VVqEmxloxxcroBKmNFcgoQ==,iv:sWkPfKqomrNaYFZbn+BeQEugRMlaqi1qJhELqfsGCik=,tag:Sgz56ZW9EY49zfwFDN7whg==,type:str] #ENC[AES256_GCM,data:3ATkokBKeOp97uORzaePROrKKfG94ic=,iv:MNJRh6Vrso1heqNUJc0M4xGNcMLGwcF9IzoiQ5+SS+g=,tag:xj8Actwkirvq4GE+Ly1M9w==,type:comment] @@ -47,7 +49,7 @@ sops: U0tmdFBuZnJES3piOTZNV0VKQmQ0eVUKCWRQ/flLzmpC64WyLoipklZBmrkpYiUg PRu+itNolpPTHm96pe+P93g2iP0wgekG0cX21wkiU2xaLF3dY2FEIA== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-10-17T08:24:51Z" - mac: ENC[AES256_GCM,data:kIlrr+U7+O1Ocdi8CffmQNOQYh46crnaaQHBOkeOwG4AuAErNb1UjhZiOUELYD6bTG4GnIw0QGAS6xu+C22aA/jKsg/Z0q/LjX3FPDLLmLyEXhjIDVB+DOsxUsUWupZqGOq+HoBWuVYt11kc2ylPqqC5JlxNwQpIXGa1YgsKaNQ=,iv:L813P4Zvse38E2+K1wv0kTrPYgaKQc0rAleGGfhJRyA=,tag:k0v2ApQincLnu1Pd3WOkGw==,type:str] + lastmodified: "2025-10-19T18:56:10Z" + mac: ENC[AES256_GCM,data:PvcwcWT8Qvk7rL6Z38IiKKBtkskaI6MntkxLhvtYyaMJqCjgOUQQcv0mriKlUB4kUaiOhKgXEwaHDKNHlK4F5RI+pQJ0HUAABCfntNx325ILmL373m0kqritkrX1hvlgpz3Qg9YmNe6+Kf7qrjGcdcpNAomwVV13WEhFL5ZraFU=,iv:xafv63PT4ByltcMhE3pruuFO5iIa49AK5rWJe9uI09U=,tag:fJuQmlTN3P+U4SX9JnQzWQ==,type:str] unencrypted_suffix: _unencrypted version: 3.11.0