From e665bb0b1488bfa2d5e75f11354d0c7b02d76d36 Mon Sep 17 00:00:00 2001 From: andromeda Date: Fri, 2 Jan 2026 18:05:01 +0100 Subject: [PATCH 1/7] attempt mailserver? --- flake.lock | 106 +++++++++++++++++++++- flake.nix | 6 ++ machines/109-199-104-83/configuration.nix | 78 ++++++++++++++++ pub-keys.nix | 1 + secrets/secret3.age | 9 ++ secrets/secrets.nix | 1 + 6 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 secrets/secret3.age diff --git a/flake.lock b/flake.lock index 7a57004..2927be9 100644 --- a/flake.lock +++ b/flake.lock @@ -91,6 +91,22 @@ "type": "github" } }, + "blobs": { + "flake": false, + "locked": { + "lastModified": 1604995301, + "narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=", + "owner": "simple-nixos-mailserver", + "repo": "blobs", + "rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265", + "type": "gitlab" + }, + "original": { + "owner": "simple-nixos-mailserver", + "repo": "blobs", + "type": "gitlab" + } + }, "darwin": { "inputs": { "nixpkgs": [ @@ -130,6 +146,22 @@ } }, "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1761588595, + "narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { "flake": false, "locked": { "lastModified": 1751685974, @@ -224,6 +256,54 @@ "type": "github" } }, + "git-hooks": { + "inputs": { + "flake-compat": [ + "nixos-mailserver", + "flake-compat" + ], + "gitignore": "gitignore", + "nixpkgs": [ + "nixos-mailserver", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1763988335, + "narHash": "sha256-QlcnByMc8KBjpU37rbq5iP7Cp97HvjRP0ucfdh+M4Qc=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "50b9238891e388c9fdc6a5c49e49c42533a1b5ce", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "nixos-mailserver", + "git-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, "gnome-shell": { "flake": false, "locked": { @@ -332,6 +412,29 @@ "type": "github" } }, + "nixos-mailserver": { + "inputs": { + "blobs": "blobs", + "flake-compat": "flake-compat", + "git-hooks": "git-hooks", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1766321686, + "narHash": "sha256-icOWbnD977HXhveirqA10zoqvErczVs3NKx8Bj+ikHY=", + "owner": "simple-nixos-mailserver", + "repo": "nixos-mailserver", + "rev": "7d433bf89882f61621f95082e90a4ab91eb0bdd3", + "type": "gitlab" + }, + "original": { + "owner": "simple-nixos-mailserver", + "repo": "nixos-mailserver", + "type": "gitlab" + } + }, "nixpkgs": { "locked": { "lastModified": 1766651565, @@ -432,7 +535,7 @@ }, "nvf": { "inputs": { - "flake-compat": "flake-compat", + "flake-compat": "flake-compat_2", "flake-parts": "flake-parts_2", "mnw": "mnw", "ndg": "ndg", @@ -480,6 +583,7 @@ "agenix": "agenix", "home-manager": "home-manager_2", "impermanence": "impermanence", + "nixos-mailserver": "nixos-mailserver", "nixpkgs": "nixpkgs", "noshell": "noshell", "nur": "nur", diff --git a/flake.nix b/flake.nix index d123880..8e53f66 100644 --- a/flake.nix +++ b/flake.nix @@ -9,6 +9,10 @@ inputs.nixpkgs.follows = "nixpkgs"; }; impermanence.url = "github:nix-community/impermanence"; + nixos-mailserver = { + url = "gitlab:simple-nixos-mailserver/nixos-mailserver"; + inputs.nixpkgs.follows = "nixpkgs"; + }; nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; noshell = { url = "github:viperML/noshell"; @@ -35,6 +39,7 @@ agenix, home-manager, impermanence, + nixos-mailserver, nixpkgs, noshell, nur, @@ -56,6 +61,7 @@ ./secrets.nix impermanence.nixosModules.impermanence agenix.nixosModules.default + nixos-mailserver.nixosModule phoenix.nixosModules.default ]; }; diff --git a/machines/109-199-104-83/configuration.nix b/machines/109-199-104-83/configuration.nix index 32f9ffa..f5ff048 100644 --- a/machines/109-199-104-83/configuration.nix +++ b/machines/109-199-104-83/configuration.nix @@ -2,8 +2,86 @@ config, modulesPath, machine, + pkgs, ... }: { + # mailserver config + mailserver = { + enable = true; + stateVersion = 3; + fqdn = "mail.galaxious.de"; + domains = ["galaxious.de"]; + x509.useACMEHost = config.mailserver.fqdn; + loginAccounts = { + "test@galaxious.de" = { + hashedPasswordFile = builtins.toString config.age.secrets.secret3.path; + }; + }; + }; + + # wildcard cert config + # systemctl start galaxious.de.service & journalctl -fu acme-galaxious.de.service + security.acme = { + acceptTerms = true; + defaults.email = "security@example.com"; + certs."mail.galaxious.de" = { + domain = "mail.galaxious.de"; + dnsProvider = "rfc2136"; + environmentFile = "/var/lib/secrets/certs.secret"; + dnsPropagationCheck = false; + }; + }; + services.bind = { + enable = true; + extraConfig = '' + include "/var/lib/secrets/dnskeys.conf"; + ''; + zones = [ + rec { + name = "galaxious.de"; + file = "/var/db/bind/${name}"; + master = true; + extraConfig = "allow-update { key rfc2136key.galaxious.de; };"; + } + ]; + }; + systemd.services.dns-rfc2136-conf = { + requiredBy = [ + "acme-galaxious.de.service" + "bind.service" + ]; + before = [ + "acme-galaxious.de.service" + "bind.service" + ]; + unitConfig = { + ConditionPathExists = "!/var/lib/secrets/dnskeys.conf"; + }; + serviceConfig = { + Type = "oneshot"; + UMask = 77; + }; + path = [pkgs.bind]; + script = '' + mkdir -p /var/lib/secrets + chmod 755 /var/lib/secrets + tsig-keygen rfc2136key.galaxious.de > /var/lib/secrets/dnskeys.conf + chown named:root /var/lib/secrets/dnskeys.conf + chmod 400 /var/lib/secrets/dnskeys.conf + + # extract secret value from the dnskeys.conf + while read x y; do if [ "$x" = "secret" ]; then secret="''${y:1:''${#y}-3}"; fi; done < /var/lib/secrets/dnskeys.conf + + cat > /var/lib/secrets/certs.secret << EOF + RFC2136_NAMESERVER='127.0.0.1:53' + RFC2136_TSIG_ALGORITHM='hmac-sha256.' + RFC2136_TSIG_KEY='rfc2136key.galaxious.de' + RFC2136_TSIG_SECRET='$secret' + EOF + chmod 400 /var/lib/secrets/certs.secret + ''; + }; + system.stateVersion = "25.11"; nix.settings.experimental-features = ["flakes" "nix-command"]; imports = [(modulesPath + "/profiles/qemu-guest.nix")]; diff --git a/pub-keys.nix b/pub-keys.nix index 389786b..8bf4995 100644 --- a/pub-keys.nix +++ b/pub-keys.nix @@ -3,6 +3,7 @@ secret0.file = ./secrets/secret0.age; secret1.file = ./secrets/secret1.age; secret2.file = ./secrets/secret2.age; + secret3.file = ./secrets/secret3.age; }; pub-keys = { ssh = { diff --git a/secrets/secret3.age b/secrets/secret3.age new file mode 100644 index 0000000..290793d --- /dev/null +++ b/secrets/secret3.age @@ -0,0 +1,9 @@ +age-encryption.org/v1 +-> ssh-ed25519 mT2fyg cUa93hQI9YjBLTG0L6NsQlvKWdzcH430HKa2GdTrR1Q +8TSbI0gZyhEIAAuCyRHRLsLVHuQj1EsKXV5MHGsmkc8 +-> ssh-ed25519 UHxfvA UuD65gpfUz/1TgFdwuidcaHgsU/SeSDl33JnkJw2Z00 +F6/s0vRDzs0yEHjd5q/N+IaOJ6XS5x0o6yCbZkhLg2w +-> ssh-ed25519 Xoin5w AcTxV1ov0tYiFr8vctKAEbdyIhCHADw+8bqXlK7WWH4 +ezCrCyfZNkTPHLXusMNbahN4nomFONyQyaBY3eb6vJw +--- Jt5iP2xl8dHdS2l4upIvNaImL192xfrmYQ7VMwkdEVI +xr"N/ُ,ݱ[A^=Ni~p0W Sb5BԽ*n +Eph`h!%ZM\y}Mwe:; \ No newline at end of file diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 309c6ac..285a1ab 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -7,4 +7,5 @@ in { "secret0.age".publicKeys = [andromeda lenovo]; "secret1.age".publicKeys = [andromeda lenovo]; "secret2.age".publicKeys = [andromeda lenovo _109-199-104-83]; + "secret3.age".publicKeys = [andromeda lenovo _109-199-104-83]; } From 52a906919ddca7f55f9181691739b1c2b671e538 Mon Sep 17 00:00:00 2001 From: andromeda Date: Fri, 2 Jan 2026 18:24:00 +0100 Subject: [PATCH 2/7] change cert email to a real email :'( --- machines/109-199-104-83/configuration.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/machines/109-199-104-83/configuration.nix b/machines/109-199-104-83/configuration.nix index f5ff048..f8484f5 100644 --- a/machines/109-199-104-83/configuration.nix +++ b/machines/109-199-104-83/configuration.nix @@ -19,11 +19,11 @@ }; }; - # wildcard cert config + # cert config # systemctl start galaxious.de.service & journalctl -fu acme-galaxious.de.service security.acme = { acceptTerms = true; - defaults.email = "security@example.com"; + defaults.email = "mtgmonket@gmail.com"; certs."mail.galaxious.de" = { domain = "mail.galaxious.de"; dnsProvider = "rfc2136"; From 6db05df6a78dcfc9e82113fdc217ac176ba295df Mon Sep 17 00:00:00 2001 From: andromeda Date: Fri, 2 Jan 2026 18:37:27 +0100 Subject: [PATCH 3/7] add firewall xD --- machines/109-199-104-83/configuration.nix | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/machines/109-199-104-83/configuration.nix b/machines/109-199-104-83/configuration.nix index f8484f5..7e170ee 100644 --- a/machines/109-199-104-83/configuration.nix +++ b/machines/109-199-104-83/configuration.nix @@ -100,6 +100,11 @@ usePredictableInterfaceNames = true; hostName = machine.hostname; domain = "galaxious.de"; + firewall = { + enable = true; + allowedTCPPorts = [80 443]; + allowedUDPPorts = [80 443]; + }; }; systemd.network = { enable = true; From 5366c48991c9059883dae4adcd4e6ed6a399f3ca Mon Sep 17 00:00:00 2001 From: andromeda Date: Fri, 2 Jan 2026 20:21:46 +0100 Subject: [PATCH 4/7] use nginx for acme --- machines/109-199-104-83/configuration.nix | 68 +++-------------------- 1 file changed, 9 insertions(+), 59 deletions(-) diff --git a/machines/109-199-104-83/configuration.nix b/machines/109-199-104-83/configuration.nix index 7e170ee..1ec2aa7 100644 --- a/machines/109-199-104-83/configuration.nix +++ b/machines/109-199-104-83/configuration.nix @@ -2,86 +2,36 @@ config, modulesPath, machine, - pkgs, ... -}: { +}: rec { # mailserver config mailserver = { enable = true; stateVersion = 3; - fqdn = "mail.galaxious.de"; - domains = ["galaxious.de"]; + fqdn = "mail.${networking.domain}"; + domains = ["${networking.domain}"]; x509.useACMEHost = config.mailserver.fqdn; loginAccounts = { - "test@galaxious.de" = { + "test@${networking.domain}" = { hashedPasswordFile = builtins.toString config.age.secrets.secret3.path; }; }; }; # cert config - # systemctl start galaxious.de.service & journalctl -fu acme-galaxious.de.service security.acme = { acceptTerms = true; defaults.email = "mtgmonket@gmail.com"; - certs."mail.galaxious.de" = { - domain = "mail.galaxious.de"; - dnsProvider = "rfc2136"; - environmentFile = "/var/lib/secrets/certs.secret"; - dnsPropagationCheck = false; - }; }; - services.bind = { + services.nginx = { enable = true; - extraConfig = '' - include "/var/lib/secrets/dnskeys.conf"; - ''; - zones = [ - rec { - name = "galaxious.de"; - file = "/var/db/bind/${name}"; - master = true; - extraConfig = "allow-update { key rfc2136key.galaxious.de; };"; - } - ]; - }; - systemd.services.dns-rfc2136-conf = { - requiredBy = [ - "acme-galaxious.de.service" - "bind.service" - ]; - before = [ - "acme-galaxious.de.service" - "bind.service" - ]; - unitConfig = { - ConditionPathExists = "!/var/lib/secrets/dnskeys.conf"; + virtualHosts."mail.${networking.domain}" = { + forceSSL = true; + enableACME = true; }; - serviceConfig = { - Type = "oneshot"; - UMask = 77; - }; - path = [pkgs.bind]; - script = '' - mkdir -p /var/lib/secrets - chmod 755 /var/lib/secrets - tsig-keygen rfc2136key.galaxious.de > /var/lib/secrets/dnskeys.conf - chown named:root /var/lib/secrets/dnskeys.conf - chmod 400 /var/lib/secrets/dnskeys.conf - - # extract secret value from the dnskeys.conf - while read x y; do if [ "$x" = "secret" ]; then secret="''${y:1:''${#y}-3}"; fi; done < /var/lib/secrets/dnskeys.conf - - cat > /var/lib/secrets/certs.secret << EOF - RFC2136_NAMESERVER='127.0.0.1:53' - RFC2136_TSIG_ALGORITHM='hmac-sha256.' - RFC2136_TSIG_KEY='rfc2136key.galaxious.de' - RFC2136_TSIG_SECRET='$secret' - EOF - chmod 400 /var/lib/secrets/certs.secret - ''; }; + # system config system.stateVersion = "25.11"; nix.settings.experimental-features = ["flakes" "nix-command"]; imports = [(modulesPath + "/profiles/qemu-guest.nix")]; From c632cd20c62d3fc4de58a1b9efc4c89fad52a9d5 Mon Sep 17 00:00:00 2001 From: andromeda Date: Fri, 2 Jan 2026 20:33:21 +0100 Subject: [PATCH 5/7] roundcube? --- machines/109-199-104-83/configuration.nix | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/machines/109-199-104-83/configuration.nix b/machines/109-199-104-83/configuration.nix index 1ec2aa7..2699370 100644 --- a/machines/109-199-104-83/configuration.nix +++ b/machines/109-199-104-83/configuration.nix @@ -3,16 +3,28 @@ modulesPath, machine, ... -}: rec { +}: { + # roundcube config + services.roundcube = { + enable = true; + hostName = "webmail.${config.networking.domain}"; + extraConfig = '' + $config['imap_host'] = "ssl://${config.mailserver.fqdn}"; + $config['smtp_host'] = "ssl://${config.mailserver.fqdn}"; + $config['smtp_user'] = "%u"; + $config['smtp_pass'] = "%p"; + ''; + }; + # mailserver config mailserver = { enable = true; stateVersion = 3; - fqdn = "mail.${networking.domain}"; - domains = ["${networking.domain}"]; + fqdn = "mail.${config.networking.domain}"; + domains = ["${config.networking.domain}"]; x509.useACMEHost = config.mailserver.fqdn; loginAccounts = { - "test@${networking.domain}" = { + "test@${config.networking.domain}" = { hashedPasswordFile = builtins.toString config.age.secrets.secret3.path; }; }; @@ -25,7 +37,7 @@ }; services.nginx = { enable = true; - virtualHosts."mail.${networking.domain}" = { + virtualHosts."mail.${config.networking.domain}" = { forceSSL = true; enableACME = true; }; From 1d17664e7aad482cdaf73cc593955d573422d132 Mon Sep 17 00:00:00 2001 From: andromeda Date: Fri, 2 Jan 2026 20:48:50 +0100 Subject: [PATCH 6/7] reset mail password --- secrets/secret3.age | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/secrets/secret3.age b/secrets/secret3.age index 290793d..2662112 100644 --- a/secrets/secret3.age +++ b/secrets/secret3.age @@ -1,9 +1,9 @@ age-encryption.org/v1 --> ssh-ed25519 mT2fyg cUa93hQI9YjBLTG0L6NsQlvKWdzcH430HKa2GdTrR1Q -8TSbI0gZyhEIAAuCyRHRLsLVHuQj1EsKXV5MHGsmkc8 --> ssh-ed25519 UHxfvA UuD65gpfUz/1TgFdwuidcaHgsU/SeSDl33JnkJw2Z00 -F6/s0vRDzs0yEHjd5q/N+IaOJ6XS5x0o6yCbZkhLg2w --> ssh-ed25519 Xoin5w AcTxV1ov0tYiFr8vctKAEbdyIhCHADw+8bqXlK7WWH4 -ezCrCyfZNkTPHLXusMNbahN4nomFONyQyaBY3eb6vJw ---- Jt5iP2xl8dHdS2l4upIvNaImL192xfrmYQ7VMwkdEVI -xr"N/ُ,ݱ[A^=Ni~p0W Sb5BԽ*n +Eph`h!%ZM\y}Mwe:; \ No newline at end of file +-> ssh-ed25519 mT2fyg I7JjyF+Iyr09EWnBTFGcxC/Wclx8EgRiAjOXD8vR334 +pbA1bnwW0h0UIS/EGPztXN72ge07gjkWXGvVezwzWNQ +-> ssh-ed25519 UHxfvA XnpdsHrU8rWONBEWypeZzgDMXK1+9YWb5jmL4idlhnI +tennpCG/vrXbOGl07qzMI1nV+rlXIouP+OopIArlEWA +-> ssh-ed25519 Xoin5w uspIqtQXmqzaSb5cs+vIKSV9AtS95C4WKZlakdyHlBk +RFSf6zArm32oIhz3sq7KpZEABw563Bl134A89WA0wZk +--- KUNVSY1AD3PbVt2PyKyENjcUe7qpcMAxO69RD0b0OdQ +#XVѝRL^ǺfjcBfGv2m-]{UY"Æe8Bh~ѯݕ:vZؒwRyM8Tqq Á~4 \ No newline at end of file From 2ed0cade4d29308581639ca0377dd0df72204e9a Mon Sep 17 00:00:00 2001 From: andromeda Date: Fri, 2 Jan 2026 21:06:04 +0100 Subject: [PATCH 7/7] use mkpasswd -s rather than mkpasswd? --- secrets/secret3.age | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/secrets/secret3.age b/secrets/secret3.age index 2662112..c38cb97 100644 --- a/secrets/secret3.age +++ b/secrets/secret3.age @@ -1,9 +1,9 @@ age-encryption.org/v1 --> ssh-ed25519 mT2fyg I7JjyF+Iyr09EWnBTFGcxC/Wclx8EgRiAjOXD8vR334 -pbA1bnwW0h0UIS/EGPztXN72ge07gjkWXGvVezwzWNQ --> ssh-ed25519 UHxfvA XnpdsHrU8rWONBEWypeZzgDMXK1+9YWb5jmL4idlhnI -tennpCG/vrXbOGl07qzMI1nV+rlXIouP+OopIArlEWA --> ssh-ed25519 Xoin5w uspIqtQXmqzaSb5cs+vIKSV9AtS95C4WKZlakdyHlBk -RFSf6zArm32oIhz3sq7KpZEABw563Bl134A89WA0wZk ---- KUNVSY1AD3PbVt2PyKyENjcUe7qpcMAxO69RD0b0OdQ -#XVѝRL^ǺfjcBfGv2m-]{UY"Æe8Bh~ѯݕ:vZؒwRyM8Tqq Á~4 \ No newline at end of file +-> ssh-ed25519 mT2fyg slLOkD/9TAYOuZ/g5U4NvPWUlmYZeie12xzggioviw0 +E0uAj4RMgv7DTJpvtEO54G9XHNLFOgFflR54Cl6/X8g +-> ssh-ed25519 UHxfvA xHFujOdegur0PLNHZP+h5RxHhVD2K906NZx7nprMkUs +PdDxzD5QBdE/yWPMnF+CDGROEpE4nYvg12v1G3QK9XI +-> ssh-ed25519 Xoin5w YWsO9HtEFB79+aKr6eWi5Sg5geKfzT+IrDy2L5qEmx4 +sXLRmcRDyAv64nSGs8QXcHmKYO+F11Pzea1EVGmpEys +--- Sjg8SqkkEEL4X0G1GOUoHO702ZtrM0hMniIdS7yIsDA +'B(7Dϓ=hh fɮxT!K.~س,ߓD|+p"tGyQRcPQQ Ս=qiא