Skip to content

Commit

Permalink
nixos/nextcloud: use LoadCredential to read secrets
Browse files Browse the repository at this point in the history
This patch adds support for using systemd's LoadCredential
feature to read various secret files used by nextcloud service
units.

Previously credentials had to be readable by the nextcloud user,
this is now no longer required.

The nextcloud-occ wrapper script has been adjusted to use
systemd-run for loading credentials when being called from
outside a service.

In detail this change touches various details of the module:

- The nix_read_secret() php function now takes the name of a
  file relative to the path specified in the CREDENTIALS_DIRECTORY
  environment variable.
- The nix_read_secret() now exits with error code 1 instead of
  throwing a RuntimeException as this will properly error out
  the nextcloud-occ script
- Only the nextcloud-setup service unit has the adminpass credential
  added in addition to the other credentials
- Uses of ExecCondition= in nextcloud-cron and nextcloud-update-db
  have been replaced by a shell conditional as ExecCondition currently
  doesn't support credentials
- The phpfpm-nextcloud service now runs a preStart script to make
  the credentials it gets readable by the nextcloud user as the
  unit runs as root but the php process itself as nextcloud.
- To invoke occ notify_push:setup when using nextcloud notify_push
  a new service has been added that replaces the preStart script
  in nextcloud-notify_push.service. This has been done as the
  main executable only needs the database password credential.

Co-authored-by: lassulus <[email protected]>
  • Loading branch information
networkException and Lassulus committed Jan 1, 2025
1 parent 30a23e1 commit 55b37e4
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 100 deletions.
119 changes: 66 additions & 53 deletions nixos/modules/services/web-apps/nextcloud-notify_push.nix
Original file line number Diff line number Diff line change
Expand Up @@ -78,60 +78,73 @@ in
);

config = lib.mkIf cfg.enable {
systemd.services.nextcloud-notify_push = {
description = "Push daemon for Nextcloud clients";
documentation = [ "https://github.com/nextcloud/notify_push" ];
after = [
"phpfpm-nextcloud.service"
"redis-nextcloud.service"
];
wantedBy = [ "multi-user.target" ];
environment = {
NEXTCLOUD_URL = cfg.nextcloudUrl;
SOCKET_PATH = cfg.socketPath;
DATABASE_PREFIX = cfg.dbtableprefix;
LOG = cfg.logLevel;
systemd.services = {
nextcloud-notify_push = {
description = "Push daemon for Nextcloud clients";
documentation = [ "https://github.com/nextcloud/notify_push" ];
after = [
"phpfpm-nextcloud.service"
"redis-nextcloud.service"
];
wantedBy = [ "multi-user.target" ];
environment = {
NEXTCLOUD_URL = cfg.nextcloudUrl;
SOCKET_PATH = cfg.socketPath;
DATABASE_PREFIX = cfg.dbtableprefix;
LOG = cfg.logLevel;
};
script =
let
dbType = if cfg.dbtype == "pgsql" then "postgresql" else cfg.dbtype;
dbUser = lib.optionalString (cfg.dbuser != null) cfg.dbuser;
dbPass = lib.optionalString (cfg.dbpassFile != null) ":$DATABASE_PASSWORD";
dbHostHasPrefix = prefix: lib.hasPrefix prefix (toString cfg.dbhost);
isPostgresql = dbType == "postgresql";
isMysql = dbType == "mysql";
isSocket = (isPostgresql && dbHostHasPrefix "/") || (isMysql && dbHostHasPrefix "localhost:/");
dbHost = lib.optionalString (cfg.dbhost != null) (
if isSocket then lib.optionalString isMysql "@localhost" else "@${cfg.dbhost}"
);
dbOpts = lib.optionalString (cfg.dbhost != null && isSocket) (
if isPostgresql then
"?host=${cfg.dbhost}"
else if isMysql then
"?socket=${lib.removePrefix "localhost:" cfg.dbhost}"
else
throw "unsupported dbtype"
);
dbName = lib.optionalString (cfg.dbname != null) "/${cfg.dbname}";
dbUrl = "${dbType}://${dbUser}${dbPass}${dbHost}${dbName}${dbOpts}";
in
lib.optionalString (cfg.dbpassFile != null) ''
export DATABASE_PASSWORD="$(<"$CREDENTIALS_DIRECTORY/dbpass")"
''
+ ''
export DATABASE_URL="${dbUrl}"
exec ${cfg.package}/bin/notify_push '${cfgN.datadir}/config/config.php'
'';
serviceConfig = {
User = "nextcloud";
Group = "nextcloud";
RuntimeDirectory = [ "nextcloud-notify_push" ];
Restart = "on-failure";
RestartSec = "5s";
Type = "notify";
LoadCredential = lib.optional (cfg.dbpassFile != null) "dbpass:${cfg.dbpassFile}";
};
};
postStart = ''
${cfgN.occ}/bin/nextcloud-occ notify_push:setup ${cfg.nextcloudUrl}/push
'';
script =
let
dbType = if cfg.dbtype == "pgsql" then "postgresql" else cfg.dbtype;
dbUser = lib.optionalString (cfg.dbuser != null) cfg.dbuser;
dbPass = lib.optionalString (cfg.dbpassFile != null) ":$DATABASE_PASSWORD";
dbHostHasPrefix = prefix: lib.hasPrefix prefix (toString cfg.dbhost);
isPostgresql = dbType == "postgresql";
isMysql = dbType == "mysql";
isSocket = (isPostgresql && dbHostHasPrefix "/") || (isMysql && dbHostHasPrefix "localhost:/");
dbHost = lib.optionalString (cfg.dbhost != null) (
if isSocket then lib.optionalString isMysql "@localhost" else "@${cfg.dbhost}"
);
dbOpts = lib.optionalString (cfg.dbhost != null && isSocket) (
if isPostgresql then
"?host=${cfg.dbhost}"
else if isMysql then
"?socket=${lib.removePrefix "localhost:" cfg.dbhost}"
else
throw "unsupported dbtype"
);
dbName = lib.optionalString (cfg.dbname != null) "/${cfg.dbname}";
dbUrl = "${dbType}://${dbUser}${dbPass}${dbHost}${dbName}${dbOpts}";
in
lib.optionalString (dbPass != "") ''
export DATABASE_PASSWORD="$(<"${cfg.dbpassFile}")"
''
+ ''
export DATABASE_URL="${dbUrl}"
exec ${cfg.package}/bin/notify_push '${cfgN.datadir}/config/config.php'
'';
serviceConfig = {
User = "nextcloud";
Group = "nextcloud";
RuntimeDirectory = [ "nextcloud-notify_push" ];
Restart = "on-failure";
RestartSec = "5s";
Type = "notify";

nextcloud-notify_push_setup = {
wantedBy = [ "multi-user.target" ];
requiredBy = [ "nextcloud-notify_push.service" ];
after = [ "nextcloud-notify_push.service" ];
serviceConfig = {
Type = "oneshot";
User = "nextcloud";
Group = "nextcloud";
ExecStart = "${lib.getExe cfgN.occ} notify_push:setup ${cfg.nextcloudUrl}/push";
LoadCredential = config.systemd.services.nextcloud-cron.serviceConfig.LoadCredential;
};
};
};

Expand Down
Loading

0 comments on commit 55b37e4

Please sign in to comment.