grafana: mint the admin password into the store and apply it on every start
Grafana's built-in admin kept the nixpkgs default password `admin`, and Grafana's API takes basic auth whatever `auth.disable_login_form` says, so the public vhost gave server-admin to `admin:admin`. `swarm-bao-grafana-admin` creates a random password in the store under Grafana's existing leaf when none is stored (`create` without `update`, so the first one is kept), then copies it into the container. `security.admin_password` reads it for a new database, and a `grafana cli admin reset-admin-password` in `grafana.service`'s `preStart` applies it to an existing one on every start. Closes #5138
This commit is contained in:
parent
cf4c4cde87
commit
993f5fd99d
7 changed files with 251 additions and 48 deletions
|
|
@ -123,9 +123,8 @@ let
|
|||
{
|
||||
# This fixture enables grafana and NOT authelia, so the login-form toggle
|
||||
# has to follow "grafana requires SSO" rather than "both services are on
|
||||
# this host". Grafana ships an
|
||||
# `admin`/`admin` account and its vhost is on the public gateway, so a
|
||||
# password box there is a way in whatever the topology.
|
||||
# this host". Its vhost is on the public gateway, so a password box there
|
||||
# is a way in whatever the topology.
|
||||
name = "grafana disables its local login form even where authelia is not on this host";
|
||||
ok =
|
||||
grafanaOldPath.containers.swarm-grafana.config.services.grafana.settings.auth.disable_login_form;
|
||||
|
|
@ -196,6 +195,36 @@ let
|
|||
&& !(grafanaRefusedFor grafanaRemoteAuthelia "services.hyperhive.swarm.authelia.url")
|
||||
&& !(grafanaRefusedFor grafanaRemoteAuthelia "deploy.bao.grafanaOidcClientCertFile");
|
||||
}
|
||||
{
|
||||
# Grafana's API takes basic auth whatever the login form says, so the
|
||||
# built-in admin's password is the only thing between the public vhost
|
||||
# and server-admin. Upstream sets it only when it creates the database,
|
||||
# so both halves are pinned: the setting a new database reads, and the
|
||||
# reset every start applies to whichever database exists. Without the
|
||||
# reset, a database created before the setting keeps `admin`.
|
||||
#
|
||||
# The reset's `--config` must be the file the server reads, or it resets
|
||||
# a different database: compared by store path against the server's own
|
||||
# command line.
|
||||
name = "grafana's admin password is minted into the store and applied to new and existing databases";
|
||||
ok =
|
||||
let
|
||||
unit = grafanaRemoteAuthelia.systemd.services.swarm-bao-grafana-admin;
|
||||
grafana = grafanaRemoteAuthelia.containers.swarm-grafana.config.services.grafana;
|
||||
service = grafanaRemoteAuthelia.containers.swarm-grafana.config.systemd.services.grafana;
|
||||
resetConfig = lib.head (
|
||||
lib.head (lib.filter lib.isList (builtins.split "--config ([^ ]+)" service.preStart))
|
||||
);
|
||||
in
|
||||
lib.hasInfix "bao kv put -cas=0 secret/swarm/services/swarm-grafana/admin/password value=-" unit.script
|
||||
&& lib.hasInfix "openssl rand -hex 32" unit.script
|
||||
&& lib.hasInfix "atomic_write_secret 0400 196:0 /var/lib/nixos-containers/swarm-grafana/var/lib/grafana-admin/password" unit.script
|
||||
&& lib.elem "container@swarm-grafana.service" unit.before
|
||||
&& unit.environment.BAO_CLIENT_CERT == "/etc/pki/bao-grafana-oidc.pem"
|
||||
&& grafana.settings.security.admin_password == "$__file{/var/lib/grafana-admin/password}"
|
||||
&& lib.hasInfix "admin reset-admin-password --password-from-stdin < /var/lib/grafana-admin/password" service.preStart
|
||||
&& lib.hasInfix "-config ${resetConfig}" service.script;
|
||||
}
|
||||
{
|
||||
# Same 403-not-a-miss reason as the matrix and queue arms below: the
|
||||
# reader's grant covers the `services` prefix, so a path outside it is
|
||||
|
|
|
|||
Loading…
Reference in a new issue