From 9a2d4965af5cfaa7ed556d5913fb8597349a5644 Mon Sep 17 00:00:00 2001 From: Dmitriy Kholkin Date: Sun, 13 Jul 2025 17:42:19 +0300 Subject: [PATCH] feat: add ntfy-sh service (with firebase) --- hosts/orion/default.nix | 1 + modules/nixos/services/ntfy-sh.nix | 87 ++++++++++++++++++++++++++++++ secrets/orion/ntfy.yaml | 25 +++++++++ 3 files changed, 113 insertions(+) create mode 100644 modules/nixos/services/ntfy-sh.nix create mode 100644 secrets/orion/ntfy.yaml diff --git a/hosts/orion/default.nix b/hosts/orion/default.nix index 15f838c..86d150d 100644 --- a/hosts/orion/default.nix +++ b/hosts/orion/default.nix @@ -117,6 +117,7 @@ in ataraxia.security.acme.enable = true; ataraxia.services.authentik.enable = true; ataraxia.services.gitea.enable = true; + ataraxia.services.ntfy-sh.enable = true; ataraxia.services.syncyomi.enable = true; ataraxia.services.vaultwarden.enable = true; ataraxia.services.headscale.enable = true; diff --git a/modules/nixos/services/ntfy-sh.nix b/modules/nixos/services/ntfy-sh.nix new file mode 100644 index 0000000..598c655 --- /dev/null +++ b/modules/nixos/services/ntfy-sh.nix @@ -0,0 +1,87 @@ +{ + config, + lib, + secretsDir, + ... +}: +let + inherit (lib) + mkEnableOption + mkForce + mkIf + mkOption + recursiveUpdate + ; + inherit (lib.types) bool str; + + cfg = config.ataraxia.services.ntfy-sh; + nginx = config.ataraxia.services.nginx; + domain = "ntfy.ataraxiadev.com"; + port = "2586"; +in +{ + options.ataraxia.services.ntfy-sh = { + enable = mkEnableOption "Enable ntfy-sh service"; + sopsDir = mkOption { + type = str; + default = config.networking.hostName; + description = '' + Name for sops secrets directory. Defaults to hostname. + ''; + }; + nginxHost = mkOption { + type = bool; + default = config.ataraxia.services.nginx.enable; + description = "Enable nginx vHost integration"; + }; + }; + + config = mkIf cfg.enable { + sops.secrets.ntfy-firebase = { + sopsFile = secretsDir + /${cfg.sopsDir}/ntfy.yaml; + owner = config.services.ntfy-sh.user; + restartUnits = [ "ntfy-sh.service" ]; + }; + + services.ntfy-sh = { + enable = true; + settings = { + base-url = "https://${domain}"; + listen-http = "127.0.0.1:${port}"; + behind-proxy = cfg.nginxHost; + + attachment-cache-dir = "/var/lib/ntfy-sh/attachments"; + auth-default-access = "deny-all"; + auth-file = "/var/lib/ntfy-sh/user.db"; + cache-file = "/var/lib/ntfy-sh/cache.db"; + firebase-key-file = config.sops.secrets.ntfy-firebase.path; + }; + }; + + systemd.services.ntfy-sh = { + serviceConfig = { + User = mkForce config.services.ntfy-sh.user; + Group = mkForce config.services.ntfy-sh.group; + DynamicUser = mkForce false; + }; + }; + + services.nginx.virtualHosts = mkIf cfg.nginxHost { + ${domain} = recursiveUpdate nginx.defaultSettings { + locations."/" = { + proxyPass = "http://127.0.0.1:${port}"; + proxyWebsockets = true; + extraConfig = '' + proxy_connect_timeout 3m; + proxy_send_timeout 3m; + proxy_read_timeout 3m; + + client_max_body_size 0; # Stream request body to backend + ''; + }; + }; + }; + + persist.state.directories = [ "/var/lib/ntfy-sh" ]; + }; +} diff --git a/secrets/orion/ntfy.yaml b/secrets/orion/ntfy.yaml new file mode 100644 index 0000000..ddc96f6 --- /dev/null +++ b/secrets/orion/ntfy.yaml @@ -0,0 +1,25 @@ +ntfy-firebase: ENC[AES256_GCM,data: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,iv:sU2q6+2kdDiT2smhdViPQPGfPVehQTQ4ZEnH7fpB3+E=,tag:ebfGqDB5o0vU5AsuBcW/6Q==,type:str] +sops: + age: + - recipient: age13phpsegg6vu7a34ydtfa9s904dfpgzqhzru7epnky7glezk0xvkst9qh6h + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvVlNzSUM4WnlnTEsxWWVP + b3diZERKamtKQ0xDU0NFY3F5Qkc3NWNYd1M0Ci82djQ2SERWcXprWC84cUNFQm4w + aU0zUDZJZG90T3BQQVJ5RU1oMkxsSVUKLS0tIGVzbGFxbkNwU3VSck0vWGdERXJS + c3ovY3g3cG1oM21kdm1DV1duSm5rclEKTT7Yes1uTUlhP62fvpZBAiBG1J0RLhL5 + 3Zm8oLSFZw+Lnqo0rnF62XePrhEh/iZrl7j8/2iPlnPfZ40nTqXbPA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1m5msm7rgqye2q9zesgedg0emga4ntehlr629786lrxs3rhk0squq0ly9je + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMMGkzMXZvdVIwT2hlbEND + M1RFNHpWc3ZjbWpIV0V1djA1Q0V0NzFVeWpFCmtzalMzcGVDdklNbVRrbE11Ujlm + dXpyM003MkdqdGsxRWZweXdjMXZJVUUKLS0tIDRiV0VEYk1FMndpNmoyOHV0ZXFh + MWpEOC9WY09LbWxHWmhzVngxb2dWcUEK0zNbb+LYx7eOdpQ+UgES5Vni0NXTza1m + AKtj//egVBh6d6iBLu8u8vgtQ/i6Ap4WkidFw2VOTwYFwwnClDcoYA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-07-12T14:32:43Z" + mac: ENC[AES256_GCM,data:DXHzgci1+/ZLyK47oiiQvNTnCRxXv+9TdSFU6tM133ebZkMEid48r9any32SHW6HmjUyU9pY0HL2GxI02Fek9hIGr4AnJllNXPBFl4mPPpOFHPHTjiYOLEiHx/BK1nq/BhUBN2m5/DZP0Jy4QLE2Kx1uaeWk8pH5cTu9s1QrOBc=,iv:6vZ1XwynmbvT0RWhScTZz/kr3Rx7uMZo3Xl6ZT1Edrk=,tag:E0TmLhtJsWKBfoM7G/rWIA==,type:str] + unencrypted_suffix: _unencrypted + version: 3.10.2