Skip to content

Commit

Permalink
ntfy-sh: add runtime secret file support
Browse files Browse the repository at this point in the history
ADDED: smtpSenderPassFile and webPushPrivateKeyFile options
ADDED: systemd LoadCredential for secure runtime secret handling
ADDED: security hardening options for notification service
CHANGED: state directory handling
  • Loading branch information
JacobMetz committed Nov 22, 2024
1 parent bc44ad6 commit 79f59b0
Showing 1 changed file with 57 additions and 5 deletions.
62 changes: 57 additions & 5 deletions nixos/modules/services/misc/ntfy-sh.nix
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{ config, lib, pkgs, ... }:

let
cfg = config.services.ntfy-sh;

settingsFormat = pkgs.formats.yaml { };
in

{
options.services.ntfy-sh = {
enable = lib.mkEnableOption "[ntfy-sh](https://ntfy.sh), a push notification service";
enable = lib.mkEnableOption "ntfy-sh, a push notification service";

package = lib.mkPackageOption pkgs "ntfy-sh" { };

Expand All @@ -23,13 +23,54 @@ in
description = "Primary group of ntfy-sh user.";
};

smtpSenderPass = lib.mkOption {
type = lib.types.str;
default = "";
description = ''
The password for the SMTP sender.
For improved security, consider using 'smtpSenderPassFile' instead
which keeps credentials out of the Nix store.
'';
};

smtpSenderPassFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = ''
Path to a file containing the password for the SMTP sender.
Uses systemd's LoadCredential feature for secure runtime secret handling,
preventing the secret from being written to the Nix store.
'';
};

webPushPrivateKey = lib.mkOption {
type = lib.types.str;
default = "";
description = ''
The private key for web push notifications.
For improved security, consider using 'webPushPrivateKeyFile' instead
which keeps credentials out of the Nix store.
'';
};

webPushPrivateKeyFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = ''
Path to a file containing the private key for web push notifications.
Uses systemd's LoadCredential feature for secure runtime secret handling,
preventing the secret from being written to the Nix store.
'';
};

settings = lib.mkOption {
type = lib.types.submodule {
freeformType = settingsFormat.type;
options = {
base-url = lib.mkOption {
type = lib.types.str;
example = "https://ntfy.example";
# CHANGED: Detailed documentation
description = ''
Public facing base URL of the service
Expand All @@ -53,7 +94,8 @@ in
'';

description = ''
Configuration for ntfy.sh, supported values are [here](https://ntfy.sh/docs/config/#config-options).
Configuration for ntfy.sh, supported values are documented at
https://ntfy.sh/docs/config/#config-options
'';
};
};
Expand All @@ -63,7 +105,6 @@ in
configuration = settingsFormat.generate "server.yml" cfg.settings;
in
lib.mkIf cfg.enable {
# to configure access control via the cli
environment = {
etc."ntfy/server.yml".source = configuration;
systemPackages = [ cfg.package ];
Expand All @@ -82,11 +123,23 @@ in
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];

environment = lib.mkIf (cfg.smtpSenderPassFile != null || cfg.webPushPrivateKeyFile != null) {
CREDENTIALS_DIRECTORY = "%d/credentials";
SMTP_SENDER_PASS = lib.mkIf (cfg.smtpSenderPassFile != null)
"$(cat $CREDENTIALS_DIRECTORY/smtp_pass)";
WEB_PUSH_PRIVATE_KEY = lib.mkIf (cfg.webPushPrivateKeyFile != null)
"$(cat $CREDENTIALS_DIRECTORY/webpush_key)";
};

serviceConfig = {
ExecStart = "${cfg.package}/bin/ntfy serve -c ${configuration}";
User = cfg.user;
StateDirectory = "ntfy-sh";

LoadCredential = lib.mkIf (cfg.smtpSenderPassFile != null || cfg.webPushPrivateKeyFile != null)
(lib.optional (cfg.smtpSenderPassFile != null) "smtp_pass:${cfg.smtpSenderPassFile}" ++
lib.optional (cfg.webPushPrivateKeyFile != null) "webpush_key:${cfg.webPushPrivateKeyFile}");

DynamicUser = true;
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
PrivateTmp = true;
Expand All @@ -102,7 +155,6 @@ in
RestrictNamespaces = true;
RestrictRealtime = true;
MemoryDenyWriteExecute = true;
# Upstream Recommandation
LimitNOFILE = 20500;
};
};
Expand Down

0 comments on commit 79f59b0

Please sign in to comment.