mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-07-22 08:30:57 +00:00
[Backport release-26.05] nixos/flarum: add initialAdminPasswordFile and databasePasswordFile options (#544362)
This commit is contained in:
@@ -10,16 +10,23 @@ with lib;
|
||||
let
|
||||
cfg = config.services.flarum;
|
||||
|
||||
# Only placeholders reach the world-readable Nix store; the install
|
||||
# script substitutes the real secrets at runtime.
|
||||
flarumInstallConfig = pkgs.writeText "config.json" (
|
||||
builtins.toJSON {
|
||||
debug = false;
|
||||
offline = false;
|
||||
|
||||
baseUrl = cfg.baseUrl;
|
||||
databaseConfiguration = cfg.database;
|
||||
databaseConfiguration =
|
||||
cfg.database
|
||||
// optionalAttrs (cfg.databasePasswordFile != null) {
|
||||
password = "@databasePassword@";
|
||||
};
|
||||
adminUser = {
|
||||
username = cfg.adminUser;
|
||||
password = cfg.initialAdminPassword;
|
||||
password =
|
||||
if cfg.initialAdminPasswordFile != null then "@adminPassword@" else cfg.initialAdminPassword;
|
||||
email = cfg.adminEmail;
|
||||
};
|
||||
settings = {
|
||||
@@ -69,7 +76,26 @@ in
|
||||
initialAdminPassword = mkOption {
|
||||
type = types.str;
|
||||
default = "flarum";
|
||||
description = "Initial password for the adminUser";
|
||||
description = ''
|
||||
Initial password for the adminUser.
|
||||
|
||||
WARNING: This is stored world-readable in the Nix store.
|
||||
Use {option}`initialAdminPasswordFile` instead.
|
||||
'';
|
||||
};
|
||||
|
||||
initialAdminPasswordFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = "/run/secrets/flarum-admin-password";
|
||||
description = ''
|
||||
File containing the initial password for adminUser.
|
||||
Must be readable by the flarum user.
|
||||
Takes precedence over {option}`initialAdminPassword`.
|
||||
|
||||
The password must not contain `"` or `\` characters, as it is
|
||||
substituted into a JSON installation config verbatim.
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
@@ -98,7 +124,12 @@ in
|
||||
bool
|
||||
int
|
||||
]);
|
||||
description = "MySQL database parameters";
|
||||
description = ''
|
||||
MySQL database parameters.
|
||||
|
||||
WARNING: A `password` set here is stored world-readable in the
|
||||
Nix store. Use {option}`databasePasswordFile` instead.
|
||||
'';
|
||||
default = {
|
||||
# the database driver; i.e. MySQL; MariaDB...
|
||||
driver = "mysql";
|
||||
@@ -118,6 +149,20 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
databasePasswordFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = "/run/secrets/flarum-db-password";
|
||||
description = ''
|
||||
File containing the database password.
|
||||
Must be readable by the flarum user.
|
||||
Takes precedence over `database.password`.
|
||||
|
||||
The password must not contain `"` or `\` characters, as it is
|
||||
substituted into a JSON installation config verbatim.
|
||||
'';
|
||||
};
|
||||
|
||||
createDatabaseLocally = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
@@ -210,6 +255,8 @@ in
|
||||
Type = "oneshot";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
# The secret-filled install config is staged in /tmp
|
||||
PrivateTmp = true;
|
||||
};
|
||||
path = [ config.services.phpfpm.phpPackage ];
|
||||
script = ''
|
||||
@@ -222,7 +269,18 @@ in
|
||||
''
|
||||
+ optionalString (cfg.createDatabaseLocally && cfg.database.driver == "mysql") ''
|
||||
if [ ! -f config.php ]; then
|
||||
php flarum install --file=${flarumInstallConfig}
|
||||
install -m 0600 ${flarumInstallConfig} /tmp/flarum-install.json
|
||||
${optionalString (cfg.initialAdminPasswordFile != null) ''
|
||||
${pkgs.replace-secret}/bin/replace-secret '@adminPassword@' \
|
||||
${escapeShellArg cfg.initialAdminPasswordFile} /tmp/flarum-install.json
|
||||
''}
|
||||
${optionalString (cfg.databasePasswordFile != null) ''
|
||||
${pkgs.replace-secret}/bin/replace-secret '@databasePassword@' \
|
||||
${escapeShellArg cfg.databasePasswordFile} /tmp/flarum-install.json
|
||||
''}
|
||||
php flarum install --file=/tmp/flarum-install.json
|
||||
# config.php contains the database password; stateDir is world-readable
|
||||
chmod 600 config.php
|
||||
fi
|
||||
''
|
||||
+ ''
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
};
|
||||
|
||||
nodes.machine =
|
||||
{ ... }:
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
# Flarum installs and migrates the database on first boot and runs a
|
||||
# MariaDB server alongside PHP-FPM and nginx, so give the VM some headroom.
|
||||
@@ -28,8 +28,11 @@
|
||||
|
||||
adminUser = "admin";
|
||||
adminEmail = "admin@example.com";
|
||||
# Flarum rejects admin passwords shorter than 8 characters.
|
||||
initialAdminPassword = "flarum-admin-password";
|
||||
# The trailing newline matches how secret managers typically write files.
|
||||
initialAdminPasswordFile = "${pkgs.writeText "admin-pass" "flarum-admin-password\n"}";
|
||||
# MariaDB authenticates via unix socket and never checks this password;
|
||||
# setting it still exercises the substitution path.
|
||||
databasePasswordFile = "${pkgs.writeText "db-pass" "flarum-db-password\n"}";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -48,5 +51,23 @@
|
||||
|
||||
# The admin API endpoint should respond, confirming the app booted cleanly.
|
||||
machine.succeed("curl -sf http://localhost/api -o /dev/null")
|
||||
|
||||
# Only the placeholders may appear in the install config in the Nix store.
|
||||
machine.succeed("grep -q '@adminPassword@' /nix/store/*-config.json")
|
||||
machine.succeed("grep -q '@databasePassword@' /nix/store/*-config.json")
|
||||
machine.fail("grep -qe 'flarum-admin-password' -e 'flarum-db-password' /nix/store/*-config.json")
|
||||
|
||||
# A successful login proves the admin password was substituted intact.
|
||||
machine.succeed(
|
||||
"curl -sf http://localhost/api/token "
|
||||
+ "-H 'Content-Type: application/json' "
|
||||
+ "-d '{\"identification\": \"admin\", \"password\": \"flarum-admin-password\"}' "
|
||||
+ "| grep -F token"
|
||||
)
|
||||
|
||||
# The database password must arrive intact in config.php, which must
|
||||
# not be world-readable.
|
||||
machine.succeed("grep -q 'flarum-db-password' /var/lib/flarum/config.php")
|
||||
machine.succeed("[ $(stat -c %a /var/lib/flarum/config.php) = 600 ]")
|
||||
'';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user