services/{keycloak,glauth}: init

This commit is contained in:
kat witch 2021-09-04 22:57:01 +01:00
parent d0e82242d5
commit d64087e160
No known key found for this signature in database
GPG key ID: 1B477797DCA5EC72
9 changed files with 311 additions and 29 deletions

View file

@ -3,6 +3,7 @@
profiles.hardware.aarch64
profiles.hardware.oracle.ubuntu
services.nginx
services.keycloak
];
kw.oci = {
@ -27,4 +28,6 @@
networkFilter = [ "public" ];
block.locations."/" = { root = splashy; };
};
system.stateVersion = "21.11";
}

View file

@ -27,4 +27,6 @@
networkFilter = [ "public" ];
block.locations."/" = { root = splashy; };
};
system.stateVersion = "21.11";
}

View file

@ -0,0 +1,176 @@
{ config, pkgs, lib, ... }: with lib; let
cfg = options.services.glauth;
dbcfg = options.services.glauth.database;
in
{
options.services.glauth = {
enable = mkEnableOption "GLAuth";
package = mkOption {
type = types.package;
default = pkgs.glauth;
};
outTOML = {
description = "The TOML produced from cfg.settings";
type = type.str;
default = toTOML cfg.settings;
};
configFile = {
description = "The config path that GLAuth uses";
type = types.path;
default = pkgs.writeText "glauth-config" outTOML;
};
database = {
enable = mkEnableOption "use a database";
local = mkEnableOption "local database creation";
type = mkOption {
type = types.enum [
"postgres"
"mysql"
"sqlite"
];
default = "postgres";
};
host = mkOption {
type = types.str;
default = "localhost";
};
port = mkOption {
type = types.port;
default = 5432;
};
username = mkOption {
type = types.str;
default = "glauth";
};
passwordFile = mkOption {
type = types.nullOr types.path;
default = null;
};
ssl = mkEnableOption "use ssl for the database connection";
};
settings = mkOption {
type = json.types.attrs;
default = mkIf cfg.database.enable {
backend =
let
pluginHandlers = {
"mysql" = "NewMySQLHandler";
"postgres" = "NewPostgresHandler";
"sqlite" = "NewSQLiteHandler";
};
in
{
datastore = "plugin";
plugin = "bin/${cfg.database.type}.so";
pluginhandler = pluginHandlers.${dbcfg.type};
database = builtins.replaceStrings (singleton "\n") (singleton " ") ''
host=${dbcfg.host}
port=${dbcfg.port}
dbname=glauth
username=${dbcfg.username}
password=@db-password@
sslmode=${if dbcfg.ssl then "enable" else "disable"}
'';
};
};
};
};
config =
let
localCheck = dbcfg.local && dbcfg.host != "localhost";
postgresCheck = localCheck && dbcfg.type == "postgres";
mysqlCheck = localCheck && dbcfg.type == "mysql";
in
mkIf cfg.enable {
systemd.services.glauthPostgreSQLInit = lib.mkIf postgresCheck {
after = [ "postgresql.service" ];
before = [ "glauth.service" ];
bindsTo = [ "postgresql.service" ];
path = [ config.services.postgresql.package ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
User = "postgres";
Group = "postgres";
};
script = ''
set -o errexit -o pipefail -o nounset -o errtrace
shopt -s inherit_errexit
create_role="$(mktemp)"
trap 'rm -f "$create_role"' ERR EXIT
echo "CREATE ROLE glauth WITH LOGIN PASSWORD '$(<'${dbcfg.passwordFile}')' CREATEDB" > "$create_role"
psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='glauth'" | grep -q 1 || psql -tA --file="$create_role"
psql -tAc "SELECT 1 FROM pg_database WHERE datname = 'glauth'" | grep -q 1 || psql -tAc 'CREATE DATABASE "glauth" OWNER "glauth"'
'';
};
systemd.services.glauthMySQLInit = lib.mkIf mysqlCheck {
after = [ "mysql.service" ];
before = [ "glauth.service" ];
bindsTo = [ "mysql.service" ];
path = [ config.services.mysql.package ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
User = config.services.mysql.user;
Group = config.services.mysql.group;
};
script = ''
set -o errexit -o pipefail -o nounset -o errtrace
shopt -s inherit_errexit
db_password="$(<'${dbcfg.passwordFile}')"
( echo "CREATE USER IF NOT EXISTS 'glauth'@'localhost' IDENTIFIED BY '$db_password';"
echo "CREATE DATABASE glauth CHARACTER SET utf8 COLLATE utf8_unicode_ci;"
echo "GRANT ALL PRIVILEGES ON glauth.* TO 'glauth'@'localhost';"
) | mysql -N
'';
};
users.groups.glauth = { };
users.users.glauth = {
isSystemUser = true;
extraGroups = singleton "glauth";
};
systemd.services.glauth =
let
databaseServices = attrByPath [ dbcfg.type ] [ ] {
"mysql" = [ "glauthMySQLInit.service" "mysql.service" ];
"postgres" = [ "glauthPostgreSQLInit.service" "postgresql.service" ];
};
in {
after = databaseServices;
bindsTo = databaseServices;
wantedBy = singleton "multi-user.target";
path = [
cfg.package
replace-secret
];
serviceConfig = {
ExecStartPre =
let
startPreFullPrivileges = ''
set -o errexit -o pipefail -o nounset -o errtrace
shopt -s inherit_errexit
umask u=rwx,g=,o=
install -T -m 0400 -o glauth -g glauth '${dbcfg.passwordFile}' /run/glauth/secrets/db_password
'';
startPre = ''
install -T -m 0600 ${cfg.configFile} /run/glauth/config.cfg
replace-secret '@db-password@' /run/glauth/config.cfg
'';
in
[
"+${pkgs.writeShellScript "glauth-start-pre-full-privileges" startPreFullPrivileges}"
"${pkgs.writeShellScript "glauth-start-pre" startPre}"
];
ExecStart = "${cfg.package}/bin/glauth -c /run/glauth/config.cfg";
User = "glauth";
Group = "glauth";
RuntimeDirectory = "glauth";
LogsDirectory = "glauth";
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
};
};
};
}

View file

@ -0,0 +1,56 @@
{ config, tf, lib, ... }: with lib; {
services.glauth = {
enable = true;
configFile = config.secrets.files.glauth-config-file.path;
database = {
enable = true;
type = "postgres";
passwordFile = config.secrets.files.glauth-password-file.path;
};
settings = {
syslog = true;
ldap = {
enable = false;
listen = "0.0.0.0:3893";
};
ldaps = {
enabled = true;
listen = "0.0.0.0:3894";
cert = "/var/lib/acme/auth.kittywit.ch/fullchain.pem";
key = "/var/lib/acme/auth.kittywit.ch/key.pem";
};
backend = {
baseDN = "dc=kittywitch,dc=com";
};
users = [{
name = "kat";
passsha256 = tf.variables.glauth-password.ref;
uidnumber = 1000;
primarygroup = 1500;
}];
groups = [{
name = "admins";
gidnumber = 1500;
}];
};
};
kw.secrets.variables = mapListToAttrs (field:
nameValuePair = "glauth-${field}" {
path = "services/glauth";
inherit field;
}) ["password-hash" "postgres"];
secrets.files = {
glauth-postgres-file = {
text = "${tf.variables.glauth-postgres.ref}";
owner = "glauth";
group = "glauth";
};
glauth-config-file = {
text = services.glauth.outTOML;
owner = "glauth";
group = "glauth";
};
};
};

View file

@ -0,0 +1,42 @@
{ config, lib, tf, ... }: with lib; {
services.keycloak = {
enable = true;
bindAddress = "127.0.0.1";
httpPort = "8089";
httpsPort = "8445";
initialAdminPassword = "mewpymewlymewlies";
forceBackendUrlToFrontendUrl = true;
frontendUrl = "https://auth.${config.network.dns.domain}/auth";
database.passwordFile = config.secrets.files.keycloak-postgres-file.path;
};
users.groups.keycloak = { };
users.users.postgres.extraGroups = singleton "keycloak";
users.users.keycloak = {
isSystemUser = true;
extraGroups = singleton "keycloak";
};
kw.secrets.variables.keycloak-postgres = {
path = "services/keycloak";
field = "postgres";
};
secrets.files.keycloak-postgres-file = {
text = "${tf.variables.keycloak-postgres.ref}";
owner = "postgres";
group = "keycloak";
};
services.nginx.virtualHosts."auth.${config.network.dns.domain}" = {
enableACME = true;
forceSSL = true;
locations = { "/".proxyPass = "http://127.0.0.1:8089"; };
};
deploy.tf.dns.records.services_keycloak = {
inherit (config.network.dns) zone;
domain = "auth";
cname = { inherit (config.network.addresses.public) target; };
};
}

View file

@ -4,6 +4,7 @@ with lib;
let
domains = [ "kittywitch" "dork" ];
users = [ "gitea" "kat" "keycloak" ];
in
{
imports = [ sources.nixos-mailserver.outPath ];
@ -13,7 +14,8 @@ in
nameValuePair "mail-${field}-hash" {
path = "secrets/mail-kittywitch";
field = "${field}-hash";
}) [ "gitea" "kat" ]
})
users
++ map
(domain:
nameValuePair "mail-domainkey-${domain}" {
@ -22,7 +24,7 @@ in
})
domains);
deploy.tf.dns.records = lib.mkMerge (map
deploy.tf.dns.records = mkMerge (map
(domain:
let
zoneGet = domain: if domain == "dork" then "dork.dev." else config.network.dns.zone;
@ -55,18 +57,14 @@ in
})
domains);
secrets.files = {
mail-kat-hash = {
text = ''
${tf.variables.mail-kat-hash.ref}
'';
};
mail-gitea-hash = {
text = ''
${tf.variables.mail-gitea-hash.ref}
'';
};
};
secrets.files = listToAttrs (map
(user:
nameValuePair "mail-${user}-hash" {
text = ''
${tf.variables.mail-kat-hash.ref}
'';
})
users);
mailserver = {
enable = true;
@ -85,15 +83,19 @@ in
virusScanning = false;
# nix run nixpkgs.apacheHttpd -c htpasswd -nbB "" "super secret password" | cut -d: -f2
loginAccounts = {
"kat@kittywit.ch" = {
hashedPasswordFile = config.secrets.files.mail-kat-hash.path;
aliases = [ "postmaster@kittywit.ch" ];
catchAll = [ "kittywit.ch" "dork.dev" ];
};
"gitea@kittywit.ch" = {
hashedPasswordFile = config.secrets.files.mail-gitea-hash.path;
};
};
loginAccounts = mkMerge [
(listToAttrs (map
(user:
nameValuePair "${user}@kittywit.ch" {
hashedPasswordFile = config.secrets.files."mail-${user}-hash".path;
})
users))
{
"kat@kittywit.ch" = {
aliases = [ "postmaster@kittywit.ch" ];
catchAll = [ "kittywit.ch" "dork.dev" ];
};
}
];
};
}

View file

@ -3,7 +3,8 @@
home.file = lib.mkIf config.deploy.profile.trusted (
let
bitw = pkgs.writeShellScriptBin "bitw" ''${pkgs.rbw-bitw}/bin/bitw -p gpg://${config.kw.secrets.repo.bitw.source} "$@"'';
in {
in
{
".local/share/weechat/sec.conf".text = ''
#
# weechat -- sec.conf

View file

@ -89,10 +89,10 @@
"homepage": null,
"owner": "kittywitch",
"repo": "nixexprs",
"rev": "05050726c147903a257c03bc454250cf0cb6b997",
"sha256": "0fk4fyxvc4kivd5g6nnxrrwll51innx1dlx7wq7mvaarlm9vj5h0",
"rev": "ee427185906d11bb33b10fa9215d65f9cc8cfc37",
"sha256": "13b910rhv8fhf0ls1ajnvz2nc9dvkphxf1hyqbf13c448rvn8ds3",
"type": "tarball",
"url": "https://github.com/kittywitch/nixexprs/archive/05050726c147903a257c03bc454250cf0cb6b997.tar.gz",
"url": "https://github.com/kittywitch/nixexprs/archive/ee427185906d11bb33b10fa9215d65f9cc8cfc37.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"niv": {

@ -1 +1 @@
Subproject commit 35f5ebb5b8aa58c12d9b6d55a3c45730e15192a9
Subproject commit ee427185906d11bb33b10fa9215d65f9cc8cfc37