diff --git a/.sops.yaml b/.sops.yaml index fc66233..4fdecd4 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -34,8 +34,4 @@ creation_rules: key_groups: - age: - *admin_christine - - *server_build_machine - - path_regex: nix-system-configs/secrets/mail/[^/]+\.(yaml|json|env|ini)$ - key_groups: - - age: - - *admin_christine \ No newline at end of file + - *server_build_machine \ No newline at end of file diff --git a/dry_run.zsh b/dry_run.zsh index f350dab..9920b80 100755 --- a/dry_run.zsh +++ b/dry_run.zsh @@ -16,7 +16,6 @@ configs=( "nixos-traefik" "nixos-build-machine" "nixos-logs" - "nixos-mail" ) if [[ -n "$1" ]]; then diff --git a/flake.nix b/flake.nix index be591ff..c43d220 100644 --- a/flake.nix +++ b/flake.nix @@ -57,11 +57,6 @@ inherit system; modules = [./nix-system-configs/modules/system/gramethus.nix]; }; - - "nixos-mail" = nixpkgs.lib.nixosSystem { - inherit system; - modules = [./nix-system-configs/modules/system/mail-server.nix]; - }; }; }; } diff --git a/nix-system-configs/modules/secrets-config/sops-mail.nix b/nix-system-configs/modules/secrets-config/sops-mail.nix deleted file mode 100644 index 499d620..0000000 --- a/nix-system-configs/modules/secrets-config/sops-mail.nix +++ /dev/null @@ -1,58 +0,0 @@ -{ - config, - pkgs, - lib, - ... -}: { - imports = let - # replace this with an actual commit id or tag - commit = "17eea6f3816ba6568b8c81db8a4e6ca438b30b7c"; - in [ - "${builtins.fetchTarball { - url = "https://github.com/Mic92/sops-nix/archive/${commit}.tar.gz"; - # replace this with an actual hash - sha256 = "ktjWTq+D5MTXQcL9N6cDZXUf9kX8JBLLBLT0ZyOTSYY="; - }}/modules/sops" - ]; - - # This will add secrets.yml to the nix store - # You can avoid this by adding a string to the full path instead, i.e. - # sops.defaultSopsFile = "/root/.sops/secrets/example.yaml"; - sops.defaultSopsFile = ../../secrets/mail/secrets.yaml; - # This will automatically import SSH keys as age keys - #sops.age.sshKeyPaths = ["/home/nixosdd/.ssh/id_ed25519"]; - # This is using an age key that is expected to already be in the filesystem - sops.age.keyFile = "/var/lib/sops-nix/key.txt"; - # This will generate a new key if the key specified above does not exist - sops.age.generateKey = true; - - # Export individual WireGuard keys from the SOPS YAML as text secrets so they - # are available both as strings and as files (.path) - sops.secrets."admin-password" = { - format = "yaml"; - sopsFile = ../../secrets/mail/secrets.yaml; - owner = "root"; - mode = "0400"; - }; - - sops.secrets."board-member-password" = { - format = "yaml"; - sopsFile = ../../secrets/mail/secrets.yaml; - owner = "root"; - mode = "0400"; - }; - - sops.secrets."cloudflare-dns-token" = { - format = "yaml"; - sopsFile = ../../secrets/mail/secrets.yaml; - owner = "root"; - mode = "0444"; - }; - - sops.secrets."cloudflare-username" = { - format = "yaml"; - sopsFile = ../../secrets/mail/secrets.yaml; - owner = "root"; - mode = "0444"; - }; -} diff --git a/nix-system-configs/modules/system/blank_system_USE_THIS_AS_COPY.nix b/nix-system-configs/modules/system/blank_system_USE_THIS_AS_COPY.nix index 6311c3d..dc2d50c 100644 --- a/nix-system-configs/modules/system/blank_system_USE_THIS_AS_COPY.nix +++ b/nix-system-configs/modules/system/blank_system_USE_THIS_AS_COPY.nix @@ -35,7 +35,6 @@ in { (choose [./modules/bootloader/seabios-assigned-iso-at-birth.nix ../bootloader/seabios-assigned-iso-at-birth.nix]) (choose [./modules/lix-default.nix ../lix-default.nix]) (choose [./modules/secrets-config/sops-the-blank-system.nix ../secrets-config/sops-the-blank-system.nix]) - (choose [./modules/toolsets/grafana_metric.nix ../toolsets/grafana_metric.nix]) ]; config = { diff --git a/nix-system-configs/modules/system/forgejo.nix b/nix-system-configs/modules/system/forgejo.nix index d58b5c6..e836c3b 100644 --- a/nix-system-configs/modules/system/forgejo.nix +++ b/nix-system-configs/modules/system/forgejo.nix @@ -109,7 +109,7 @@ in { server = { DOMAIN = "git.prg-radio.org"; ROOT_URL = "https://git.prg-radio.org/"; - HTTP_PORT = 30000; + HTTP_PORT = 3000; # SSH integration SSH_PORT = lib.head config.services.openssh.ports; }; @@ -197,7 +197,7 @@ in { }; # Open ports in the firewall. - networking.firewall.allowedTCPPorts = [30000]; + networking.firewall.allowedTCPPorts = [3000]; system.stateVersion = "25.11"; }; diff --git a/nix-system-configs/modules/system/mail-server.nix b/nix-system-configs/modules/system/mail-server.nix deleted file mode 100644 index 257f6a7..0000000 --- a/nix-system-configs/modules/system/mail-server.nix +++ /dev/null @@ -1,135 +0,0 @@ -{ - config, - pkgs, - lib, - ... -}: let - choose = paths: lib.findFirst builtins.pathExists null paths; -in { - options.local = { - hostname = lib.mkOption { - type = lib.types.str; - default = "nixos-default"; - description = "System hostname"; - }; - username = lib.mkOption { - type = lib.types.str; - default = "user"; - description = "Primary user username"; - }; - userDescription = lib.mkOption { - type = lib.types.str; - default = "NixOS User"; - description = "Primary user description"; - }; - address = lib.mkOption { - type = lib.types.str; - default = "10.1.1.100"; - description = "Static IP address"; - }; - }; - - imports = lib.filter (x: x != null) [ - (choose [./modules/desktop-manager/sway_greetd_homemanager.nix ../desktop-manager/sway_greetd_homemanager.nix]) - (choose [./modules/local/hostname_username.nix ../local/hostname_username.nix]) - (choose [./modules/local/networking_local.nix ../local/networking_local.nix]) - (choose [./modules/bootloader/seabios-assigned-proxmox-at-birth.nix ../bootloader/seabios-assigned-proxmox-at-birth.nix]) - (choose [./modules/lix-default.nix ../lix-default.nix]) - (choose [./modules/secrets-config/sops-the-blank-system.nix ../secrets-config/sops-the-blank-system.nix]) - (choose [./modules/toolsets/grafana_metric.nix ../toolsets/grafana_metric.nix]) - (choose [./modules/secrets-config/sops-mail.nix ../secrets-config/sops-mail.nix]) - ]; - - config = { - local.hostname = "nixos-mailserver"; - local.username = "mailprg"; - local.userDescription = "NixOS PRG Mailing Service"; - local.address = "10.1.1.15"; - system.stateVersion = "25.11"; - - services.stalwart-mail = { - enable = true; - openFirewall = true; - settings = { - server = { - hostname = "mail.prg-radio.org"; - tls = { - enable = true; - implicit = true; - }; - listener = { - smtp = { - protocol = "smtp"; - bind = "[::]:25"; - proxy.trusted-networks = [ - "10.1.1.250/32" - ]; - }; - submissions = { - bind = "[::]:465"; - protocol = "smtp"; - tls.implicit = true; - # Also trust proxy for SMTPS - proxy.trusted-networks = ["10.1.1.250/32"]; - }; - imaps = { - bind = "[::]:993"; - protocol = "imap"; - tls.implicit = true; - proxy.trusted-networks = ["10.1.1.250/32"]; - }; - jmap = { - bind = "[::]:8080"; - url = "https://mail.prg-radio.org"; - protocol = "http"; - }; - management = { - bind = ["127.0.0.1:8080"]; - protocol = "http"; - }; - }; - }; - lookup.default = { - hostname = "mail.prg-radio.org"; - domain = "prg-radio.org"; - }; - acme."letsencrypt" = { - directory = "https://acme-v02.api.letsencrypt.org/directory"; - challenge = "dns-01"; - contact = config.sops.secrets."cloudflare-username".path; - domains = ["prg-radio.org" "mail.prg-radio.org"]; - provider = "cloudflare"; - secret = config.sops.secrets."cloudflare-dns-token".path; - }; - session.auth = { - mechanisms = "[plain]"; - directory = "'in-memory'"; - }; - storage.directory = "in-memory"; - session.rcpt.directory = "'in-memory'"; - directory."imap".lookup.domains = ["prg-radio.org"]; - directory."in-memory" = { - type = "memory"; - principals = [ - { - class = "individual"; - name = "Polyteknisk Radiogruppe Board Member"; - secret = config.sops.secrets."board-member-password".path; - email = ["board@prg-radio.org"]; - } - { - class = "individual"; - name = "postmaster"; - secret = config.sops.secrets."board-member-password".path; - email = ["postmaster@prg-radio.org"]; - } - ]; - }; - authentication.fallback-admin = { - user = "admin"; - secret = config.sops.secrets."admin-password".path; - }; - }; - }; - }; -} diff --git a/nix-system-configs/modules/system/traefik.nix b/nix-system-configs/modules/system/traefik.nix index 7275a45..a458f3a 100644 --- a/nix-system-configs/modules/system/traefik.nix +++ b/nix-system-configs/modules/system/traefik.nix @@ -265,20 +265,6 @@ in { teamspeak-data = { address = "[::]:30033/tcp"; }; - - # Mail entrypoints: plain SMTP, implicit SMTPS (465) and IMAPS (993) - #smtp = { - # # plain SMTP (port 25) - TCP passthrough to backend - # address = "[::]:25"; - # }; - smtps = { - # implicit TLS SMTP (port 465) - passthrough to backend - address = "[::]:465"; - }; - imaps = { - # implicit TLS IMAP (port 993) - passthrough to backend - address = "[::]:993"; - }; }; log = { level = "INFO"; @@ -364,14 +350,6 @@ in { tls = {}; middlewares = ["anubisForwardAuth"]; }; - - # Mail HTTP (JMAP / web) - terminate TLS at Traefik and forward to Stalwart JMAP HTTP listener - mail = { - rule = "Host(`mail.prg-radio.org`)"; - service = "mail-jmap"; - entryPoints = ["websecure"]; - tls = {certresolver = "acme";}; - }; }; http.services = { @@ -384,7 +362,7 @@ in { forgejo.loadBalancer = { servers = [ - {url = "http://10.1.1.4:30000";} + {url = "http://10.1.1.4:3000";} ]; }; matrix.loadBalancer = { @@ -409,11 +387,6 @@ in { {url = "http://10.1.1.10:3000";} ]; }; - - # Mail JMAP HTTP backend - mail-jmap.loadBalancer = { - servers = [{url = "http://10.1.1.15:8080";}]; - }; }; # TCP routing for TeamSpeak @@ -451,30 +424,6 @@ in { passthrough = true; }; }; - - # Mail TCP routers: SMTP (25), SMTPS (465 implicit TLS), IMAPS (993 implicit TLS) - #mail-smtp = { - # # catch-all TCP router for port 25 - # rule = "HostSNI(`*`)"; - # service = "mail-smtp"; - # entryPoints = ["smtp"]; - # }; - - mail-smtps = { - # SMTPS implicit TLS - passthrough to backend - rule = "HostSNI(`*`)"; - service = "mail-smtps"; - entryPoints = ["smtps"]; - tls = {passthrough = true;}; - }; - - mail-imaps = { - # IMAPS implicit TLS - passthrough to backend - rule = "HostSNI(`*`)"; - service = "mail-imaps"; - entryPoints = ["imaps"]; - tls = {passthrough = true;}; - }; }; tcp.services = { @@ -493,19 +442,6 @@ in { {address = "10.1.1.248:12244";} ]; }; - - # Mail TCP services - # mail-smtp.loadBalancer = { - # servers = [ { address = "10.1.1.15:25"; } ]; - # }; - - mail-smtps.loadBalancer = { - servers = [{address = "10.1.1.15:465";}]; - }; - - mail-imaps.loadBalancer = { - servers = [{address = "10.1.1.15:993";}]; - }; }; # UDP routing for TeamSpeak voice diff --git a/nix-system-configs/secrets/mail/secrets.yaml b/nix-system-configs/secrets/mail/secrets.yaml deleted file mode 100644 index a085774..0000000 --- a/nix-system-configs/secrets/mail/secrets.yaml +++ /dev/null @@ -1,19 +0,0 @@ -admin-password: ENC[AES256_GCM,data:o8nD9CDNzufxVjfH7TqUY4QO6Xkz1xbpFu74jMVRR57NDKpKsg3ijRmBvvq1/QuJ2TM=,iv:xVGjzrRFpCyjriW6yB/UjuGiNhK4oeBiDA+Pk/BTOWc=,tag:H/ZuqffTDGsGTWTTKplvvA==,type:str] -board-member-password: ENC[AES256_GCM,data:8KLyqyGFi/ehvbNU6HsWilMO42UnXYL6puc/OOPgMDiU2fuDM2o7TibUCn1BXi9UyiE=,iv:UyLOFSARK/5p/zin7vqQic9C5qlryd/O/mjcw3eZ3ao=,tag:N2RJC6nZC+V3XoAw/eWYfA==,type:str] -cloudflare-dns-token: ENC[AES256_GCM,data:W0S9WWmhQMwjKbKI60vBjYlSb0chZUYcVs3A4DsVRfJwErcIqDWoJg==,iv:nRH8hLvCavydVC16M93N+r/t9WwNY4339CE4zGSINsk=,tag:yIUKs/XB3arhApGeik6p1A==,type:str] -cloudflare-username: ENC[AES256_GCM,data:5QCWOZcv6RKlk1/5LWjjCW0m,iv:9VzhRDlLq36pMfv0tu7POxheLFKdXP8tLLiKlTOr/30=,tag:MiijON1+mKJj6VMdnaJTkA==,type:str] -sops: - age: - - recipient: age1746rvsvsc3snxfl7cndm222wd5kck4aqj3x7nednlegq0gdjhfcqx0qv7m - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBseTM3bTJtamFBVzRkOVpp - bEZNQlJoNUVjTFd0NGl3VktmUUdHWi9wMTM0CnE3bTh5QmM1KzVqTnI3RHdmbXhN - a0NWRkthbG9OZ3pZMEZkU3hjWUNyd1UKLS0tIE5KdXgzQmRRWTVBbDFTSEkzQW9o - ZWE0ci9wSmhpWmc1OHZwb09aTjk1TUUKitmILkhief6sapPh3gZAEDsaHqcv3se0 - +6w+hs05ChkXHQ+JlXOTznd5ZNS4hwOAk5KOconNbauBaKWDplnHhA== - -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-02-15T14:13:19Z" - mac: ENC[AES256_GCM,data:7hFjuvictSbcXLqXwG0VgWErKJpFsy1PfDyepQQXpszpMT4Z/BwvXlk4ppKo8C0PaCLv2qi86yBmFm/O6xUBhsMEFWYHQ+mJpYtqLX0GDvj1cn4LwDEnRa+2SiHkkZeHSwrtOHCBw8vE2R2sXBaNMkUoSXkcQ4lPS6YjulpO1vw=,iv:5aZxEnPymcvNpsUyGvvRI3o7hnfExSFWlBrzoIhQkFQ=,tag:6JJGvBL9XeiPw+TdN2qEgA==,type:str] - unencrypted_suffix: _unencrypted - version: 3.11.0