-
-
Notifications
You must be signed in to change notification settings - Fork 14.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nixos/nextcloud: use LoadCredential to read secrets #367433
base: master
Are you sure you want to change the base?
nixos/nextcloud: use LoadCredential to read secrets #367433
Conversation
b15113c
to
6587fd2
Compare
This should be generally well tested already so reviews are encouraged, undrafting when
|
runtimeSystemdCredentials = [] | ||
++ (lib.optional (cfg.config.dbpassFile != null) "dbpass:${cfg.config.dbpassFile}") | ||
++ (lib.optional (cfg.config.objectstore.s3.enable) "s3_secret:${cfg.config.objectstore.s3.secretFile}") | ||
++ (lib.optional (cfg.config.objectstore.s3.sseCKeyFile != null) "s3_sse_c_key:${cfg.config.objectstore.s3.sseCKeyFile}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
runtimeSystemdCredentials = [] | |
++ (lib.optional (cfg.config.dbpassFile != null) "dbpass:${cfg.config.dbpassFile}") | |
++ (lib.optional (cfg.config.objectstore.s3.enable) "s3_secret:${cfg.config.objectstore.s3.secretFile}") | |
++ (lib.optional (cfg.config.objectstore.s3.sseCKeyFile != null) "s3_sse_c_key:${cfg.config.objectstore.s3.sseCKeyFile}"); | |
runtimeSystemdCredentials = lib.optional (cfg.config.dbpassFile != null) "dbpass:${cfg.config.dbpassFile}" | |
++ lib.optional (cfg.config.objectstore.s3.enable) "s3_secret:${cfg.config.objectstore.s3.secretFile}" | |
++ lib.optional (cfg.config.objectstore.s3.sseCKeyFile != null) "s3_sse_c_key:${cfg.config.objectstore.s3.sseCKeyFile}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer consistent indentation
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; | ||
}; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will definitely not work. notify_push:setup verifies if the configuration is correct and checks if the domain and trusted proxy settings are correct. It is not similar to nextcloud-setup and must be run after the notify_push service is up. If it fails the service is none functional.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not too invested in reducing how many credentials the long running process can read. The ordering works just fine like this with after
and Type=notify
.
In general having nextcloud-notify_push_setup.service
compared to postStart
just changes which service fails in case something goes wrong
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will definitely not work. notify_push:setup verifies if the configuration is correct and checks if the domain and trusted proxy settings are correct
@SuperSandro2000 I think @networkException is right here and I fail to understand what'll break exactly either.
Please elaborate.
Thanks! |
…-and-secrets This patch adds a subtest and corresponding configuration to with-declarative-redis-and-secrets to test for nextcloud notify_push to be working, just as in with-postgresql-and-redis. As notify_push needs to connect to the database, including it in this test checks that it can read the dbpassFile properly.
This patch replaces the use of writeScriptBin for the nextcloud-occ script with writeShellApplication, enabling shell checking. This patch also updates various invocations of the script to use lib.getExe.
…closer to phpfpm config
6c60763
to
6fece8a
Compare
# On Nextcloud ≥ 26, it is not necessary to patch the database files to prevent | ||
# an automatic creation of the database user. | ||
environment.NC_setup_create_db_user = lib.mkIf (nextcloudGreaterOrEqualThan "26") "false"; | ||
}; | ||
nextcloud-cron = { | ||
after = [ "nextcloud-setup.service" ]; | ||
# FIXME: In contrast to the occ wrapper script running phpCli directly will not | ||
# set NEXTCLOUD_CONFIG_DIR correctly currently. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain why you added a fixme for that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a note is better, I added this after removing the explicit (somewhat duplicate) variable from the nextcloud-update-db
service
umask 0077 | ||
# NOTE: The phpfpm runtime directory is currently preserved | ||
# between restarts. | ||
rm -rf /run/phpfpm/nextcloud-credentials/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be nicer to use $RUNTIME_DIRECTORY/nextcloud-credentials/
here.
It's rather unlikely that you ever change serviceConfig.RuntimeDirectory
in a phpfpm unit, but with that change we'd be safe here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also... doesn't this mean that other phpfpm instances can see these values (even though only readable as root, so not from PHP code)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be nicer to use
$RUNTIME_DIRECTORY/nextcloud-credentials/
here.
I don't think this currently applies here but $RUNTIME_DIRECTORY
has the pesky detail that you can technically specify multiple directories which will end up as /run/a:/run/b
in the variable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also... doesn't this mean that other phpfpm instances can see these values (even though only readable as root, so not from PHP code)?
Yes sadly thats the case, briefly as root
and then as nextcloud
. I don't know phpfpm good enough to know what would happen if the service were rootless, but that would be much cleaner here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this currently applies here but $RUNTIME_DIRECTORY has the pesky detail that you can technically specify multiple directories which will end up as /run/a:/run/b in the variable
Meh, makes perfect sense for a variable name in signular :/
but good point, I'll retract that.
Yes sadly thats the case, briefly as root and then as nextcloud. I don't know phpfpm good enough to know what would happen if the service were rootless, but that would be much cleaner here
My main problem is that the runtime directory is used for each phpfpm service, i.e. each PHP application on the same host will have this in its runtime directory (sure, different user then, but this smells like a disaster waiting to happen).
But given that we can specify multiple runtime directories, wouldn't it be an option to add another directory to the phpfpm-nextcloud service and place the secrets into that dir?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But given that we can specify multiple runtime directories, wouldn't it be an option to add another directory to the phpfpm-nextcloud service and place the secrets into that dir?
Sure, good point. I'll work on this in a bit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a separate runtime directory to the service (https://github.com/NixOS/nixpkgs/compare/dedb0ac10499c7406ce55399db5ac7fdf3568907..4d4d3672a52c630e4a3f7970b5c3aa1bb2beda00). Note that sadly RuntimeDirectoryPreserve=true
as well as the mode also applies. I also don't know a way to avoid the lib.mkForce
here.
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; | ||
}; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will definitely not work. notify_push:setup verifies if the configuration is correct and checks if the domain and trusted proxy settings are correct
@SuperSandro2000 I think @networkException is right here and I fail to understand what'll break exactly either.
Please elaborate.
fd5180a
to
dedb0ac
Compare
# NOTE: This early returns the script when nextcloud is in maintenance mode | ||
# or needs `occ upgrade`. Using ExecCondition= is not possible here | ||
# because it doesn't work with systemd credentials. | ||
${lib.getExe occ} status -e; [ $? -ne 0 ] && exit 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, doesn't this fail the service since script
adds a set -e
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed the implementation to use status --output=json
, feels nicer compared to -e
anyways: https://github.com/NixOS/nixpkgs/compare/4d4d3672a52c630e4a3f7970b5c3aa1bb2beda00..3d64615e8a60490360283fad2ed7b8bca6f29372
script = '' | ||
# NOTE: This early returns the script when nextcloud is in maintenance mode | ||
# or needs `occ upgrade`. Using ExecCondition= is not possible here | ||
# because it doesn't work with systemd credentials. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fwiw opened systemd/systemd#35788 to discuss whether we could change this upstream.
dedb0ac
to
4d4d367
Compare
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]>
This patch changes the implementation of the subtests to check for redis' cache being non empty to only run redis-cli and jq in a shell and assert the returned length in python. This fixes jq "len" simply not compiling and makes sure regressions get noticed.
4d4d367
to
3d64615
Compare
This pull request 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 usesystemd-run
for loading credentials when being called from outside a service.See the individual commits for more details.
Depends on #365442
Continuation of #152141
Things done
nix.conf
? (See Nix manual)sandbox = relaxed
sandbox = true
nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)Add a 👍 reaction to pull requests you find important.