About to make changes to Grafana LDAP

This commit is contained in:
niten 2022-02-07 14:08:34 -08:00
parent 2048377c3f
commit 5411c53022
6 changed files with 180 additions and 55 deletions

View File

@ -89,6 +89,7 @@ in {
host-secrets.backplane-host-auth.target-file;
FUDO_SERVICE_PASSWD_FILE =
host-secrets.backplane-service-auth.target-file;
# GUILE_AUTO_COMPILE = "0";
};
sites.${cfg.backplane-hostname} = {
@ -97,31 +98,32 @@ in {
site-config = {
auth_method = "external";
extauth_program =
# "${pkgs.guile}/bin/guile -s /run/backplane-auth.scm";
"${pkgs.guile}/bin/guile -s ${pkgs.backplane-auth}/backplane-auth.scm";
extauth_pool_size = 3;
auth_use_cache = true;
auth_use_cache = false;
modules = {
mod_adhoc = {};
mod_caps = {};
mod_carboncopy = {};
mod_client_state = {};
# mod_caps = {};
# mod_carboncopy = {};
# mod_client_state = {};
mod_configure = {};
mod_disco = {};
# mod_disco = {};
mod_fail2ban = {};
mod_last = {};
# mod_last = {};
mod_offline.access_max_user_messages = 5000;
mod_ping = {};
mod_pubsub = {
access_createnode = "pubsub_createnode";
ignore_pep_from_offline = true;
last_item_cache = false;
plugins = [
"flat"
"pep"
];
};
mod_roster = {};
# mod_pubsub = {
# access_createnode = "pubsub_createnode";
# ignore_pep_from_offline = true;
# last_item_cache = false;
# plugins = [
# "flat"
# "pep"
# ];
# };
# mod_roster = {};
mod_stream_mgmt = {};
mod_time = {};
mod_version = {};

View File

@ -9,6 +9,58 @@ let
hostname = config.instance.hostname;
domain-name = config.fudo.hosts.${hostname}.domain;
host-secrets = config.fudo.secrets.host-secrets.${hostname};
datasourceOpts = { name, ... }: {
options = with types; {
url = mkOption {
type = str;
description = "Datasource URL.";
};
type = mkOption {
type = enum [ "prometheus" "loki" ];
description = "Type of the datasource.";
};
name = mkOption {
type = str;
description = "Name of the datasource.";
default = name;
};
default = mkOption {
type = bool;
description = "Use this datasource as the default while querying.";
default = false;
};
};
};
ldapOpts = {
options = with types; {
hosts = mkOption {
type = listOf str;
description = "LDAP server hostnames.";
};
bind-dn = mkOption {
type = str;
description = "DN as which to bind with the LDAP server.";
};
bind-passwd = mkOption {
type = str;
description = "Password with which to bind to the LDAP server.";
};
base-dn = mkOption {
type = str;
description = "DN under which to search for users.";
};
};
};
in {
options.fudo.metrics.grafana = with types; {
@ -43,6 +95,12 @@ in {
description = "Address from which mail will be sent (i.e. 'from' address).";
default = "${toplevel.config.fudo.grafana.smtp.username}@${domain-name}";
};
domain = mkOption {
type = str;
description = "Domain of the SMTP server.";
default = toplevel.config.instance.local-domain;
};
};
database = {
@ -67,6 +125,12 @@ in {
};
};
ldap = mkOption {
type = nullOr (submodule ldapOpts);
description = "";
default = null;
};
admin-password-file = mkOption {
type = str;
description = "Path to a file containing the admin user's password.";
@ -77,10 +141,10 @@ in {
description = "Path to a file containing the server's secret key, used for signatures.";
};
prometheus-hosts = mkOption {
type = listOf str;
description = "A list of URLs to prometheus data sources.";
default = [];
datasources = mkOption {
type = attrsOf (submodule datasourceOpts);
description = "A list of datasources supplied to Grafana.";
default = {};
};
state-directory = mkOption {
@ -93,11 +157,26 @@ in {
};
config = mkIf cfg.enable {
systemd.tmpfiles.rules = let
grafana-user = config.systemd.services.grafana.serviceConfig.User;
in [
"d ${cfg.state-directory} 0700 ${grafana-user} - - -"
];
systemd = {
tmpfiles.rules = let
grafana-user = config.systemd.services.grafana.serviceConfig.User;
in [
"d ${cfg.state-directory} 0700 ${grafana-user} - - -"
];
services.grafana.serviceConfig = {
EnvironmentFile = host-secrets.grafana-environment-file.target-file;
};
};
fudo.secrets.host-secrets.${hostname}.grafana-environment-file = {
source-file = pkgs.writeText "grafana.env" ''
${optionalString (cfg.ldap != null)
''GRAFANA_LDAP_BIND_PASSWD="${cfg.ldap.bind-passwd}"''}
'';
target-file = "/run/metrics/grafana/auth-bind.passwd";
user = config.systemd.services.grafana.serviceConfig.User;
};
services = {
nginx = {
@ -133,12 +212,30 @@ in {
smtp = {
enable = true;
fromAddress = "metrics@fudo.org";
# TODO: create system user as necessary
fromAddress = "${cfg.smtp.username}@${cfg.smtp.domain}";
host = "${cfg.smtp.hostname}:25";
user = cfg.smtp.username;
passwordFile = cfg.smtp.password-file;
};
extraOptions = mkIf (cfg.ldap != null) (let
config-file = pkgs.writeText "grafana-ldap.toml" ''
[[servers]]
host = "${concatStringsSep " " cfg.ldap.hosts}"
port = 389
start_tls = true
bind_dn = "${cfg.ldap.bind-dn}"
bind_password = "''${GRAFANA_LDAP_BIND_PASSWD}"
search_filter = "(uid=%s)"
search_base_dns = [ "${cfg.ldap.base-dn}" ]
'';
in {
AUTH_LDAP_ENABLED = "true";
AUTH_LDAP_ALLOW_SIGN_UP = "false";
AUTH_LDAP_CONFIG_FILE = config-file;
});
database = {
host = cfg.database.hostname;
name = cfg.database.name;
@ -147,15 +244,16 @@ in {
type = "postgres";
};
provision.datasources = imap0 (i: host: {
editable = false;
isDefault = (i == 0);
name = builtins.trace "PROMETHEUS-HOST: ${host}" host;
type = "prometheus";
url = let
scheme = if private-network then "http" else "https";
in "${scheme}://${host}/";
}) cfg.prometheus-hosts;
provision = {
enable = true;
datasources = let
make-datasource = datasource: {
editable = false;
isDefault = datasource.default;
inherit (datasource) name type url;
};
in map make-datasource (attrValues cfg.datasources);
};
};
};
};

View File

@ -96,7 +96,8 @@ let
};
config-file = builtins.toJSON jabber-config;
in pkgs.writeText "ejabberd.config.yml.template" config-file;
in pkgs.lib.text.format-json-file
(pkgs.writeText "ejabberd.config.yml.template" config-file);
enter-secrets = template: secrets: target: let
secret-swappers = map
@ -170,13 +171,13 @@ in {
};
log-level = mkOption {
type = int;
type = str;
description = ''
Log level at which to run the server.
See: https://docs.ejabberd.im/admin/guide/troubleshooting/
'';
default = 3;
default = "info";
};
state-directory = mkOption {
@ -212,8 +213,6 @@ in {
in {
acme.host-domains.${hostname} = mapAttrs' (site: siteOpts:
nameValuePair siteOpts.hostname {
extra-domains =
(optional (siteOpts.hostname != host-fqdn) host-fqdn);
local-copies.ejabberd = {
user = cfg.user;
group = cfg.group;

View File

@ -127,7 +127,7 @@ let
userDatabaseAccessSql = user: database: dbOpts: ''
\c ${database}
${join-lines
(mapAttrsToList (userTableAccessSql user) dbOpts.entity-access)}
(mapAttrsToList (userTableAccessSql user) dbOpts.entity-access)}
'';
userAccessSql = user: userOpts:
join-lines (mapAttrsToList (userDatabaseAccessSql user) userOpts.databases);
@ -375,20 +375,24 @@ in {
requires = [ "postgresql.target" ];
after = [ "postgresql.target" "postgresql-password-setter.target" ];
partOf = [ cfg.systemd-target ];
script = let
allow-user-login = user: "ALTER ROLE ${user} WITH LOGIN;";
wantedBy = [ "postgresql.target" ];
serviceConfig = {
User = config.services.postgresql.superUser;
ExecStart = let
allow-user-login = user: "ALTER ROLE ${user} WITH LOGIN;";
extra-settings-sql = pkgs.writeText "settings.sql" ''
${concatStringsSep "\n"
(map allow-user-login (mapAttrsToList (key: val: key) cfg.users))}
${usersAccessSql cfg.users}
extra-settings-sql = pkgs.writeText "settings.sql" ''
${concatStringsSep "\n"
(map allow-user-login (mapAttrsToList (key: val: key) cfg.users))}
${usersAccessSql cfg.users}
'';
in pkgs.writeShellScript "postgresql-finalizer.sh" ''
${pkgs.postgresql}/bin/psql --port ${
toString config.services.postgresql.port
} -d postgres -f ${extra-settings-sql}
chgrp ${cfg.socket-group} ${cfg.socket-directory}/.s.PGSQL*
'';
in ''
${pkgs.postgresql}/bin/psql --port ${
toString config.services.postgresql.port
} -d postgres -f ${extra-settings-sql}
${pkgs.coreutils}/bin/chgrp ${cfg.socket-group} ${cfg.socket-directory}/.s.PGSQL*
'';
};
};
};
};

View File

@ -21,6 +21,13 @@ let
gpgsql-password=__PASSWORD__
gpgsql-dnssec=${if cfg.enable-dnssec then "yes" else "no"}
gpgsql-extra-connection-parameters=sslmode=require
${optionalString cfg.debug ''
log-dns-details
log-dns-queries
log-timestamp
loglevel=6
query-logging
''}
'';
pdns-config-dir = pkgs.writeTextDir "pdns.conf" ''
@ -61,6 +68,7 @@ let
networks-string = concatStringsSep " " (v4-nets ++ v6-nets);
in ''"v=spf1 mx ${networks-string} -all"''))
(mkRecord "ns1.${domain-name}" "A" host-ip)
(mkRecord domain-name "A" host-ip)
] ++
(optional (domain.gssapi-realm != null)
(mkRecord "_kerberos.${domain-name}" "TXT" ''"domain.gssapi-realm"'')) ++
@ -158,6 +166,12 @@ in {
default = true;
};
debug = mkOption {
type = bool;
description = "Enable verbose debugging.";
default = false;
};
database = {
host = mkOption {
type = str;
@ -190,7 +204,10 @@ in {
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = [ cfg.port ];
networking.firewall = {
allowedTCPPorts = [ cfg.port ];
allowedUDPPorts = [ cfg.port ];
};
users = {
users.${cfg.user} = {
@ -308,7 +325,6 @@ in {
"--chroot=${runtime-dir}"
"--daemon=no"
"--guardian=no"
"--disable-syslog"
"--write-pid=no"
"--config-dir=${pdns-config-dir}"
]);

View File

@ -37,6 +37,12 @@ in {
description = "Site name of the current local host.";
};
local-zone = mkOption {
type = nullOr str;
description = "Zone name of the current local host.";
default = null;
};
local-admins = mkOption {
type = listOf str;
description = "List of users who should have admin access to the local host.";