server: add keycloak
This commit is contained in:
parent
9e70d53ee5
commit
32ea4fdd8d
|
@ -20,6 +20,7 @@ in {
|
||||||
./mumble.nix
|
./mumble.nix
|
||||||
./mailserver.nix
|
./mailserver.nix
|
||||||
./home.nix
|
./home.nix
|
||||||
|
./keycloak.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
system.stateVersion = "22.11";
|
system.stateVersion = "22.11";
|
||||||
|
|
|
@ -14,6 +14,7 @@ let
|
||||||
(lib.filterAttrs (k: v: builtins.elem k names && v.enable) config.services.prometheus.exporters));
|
(lib.filterAttrs (k: v: builtins.elem k names && v.enable) config.services.prometheus.exporters));
|
||||||
in {
|
in {
|
||||||
# a bunch of services for personal use not intended for the public
|
# a bunch of services for personal use not intended for the public
|
||||||
|
# TODO: keycloakify this
|
||||||
services.grafana = {
|
services.grafana = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
settings = {
|
||||||
|
@ -34,6 +35,10 @@ in {
|
||||||
};
|
};
|
||||||
services.nginx.upstreams.grafana.servers."unix:/${config.services.grafana.settings.server.socket}" = {};
|
services.nginx.upstreams.grafana.servers."unix:/${config.services.grafana.settings.server.socket}" = {};
|
||||||
|
|
||||||
|
# TODO:
|
||||||
|
# services.keycloak.plugins = [ pkgs.keycloak.plugins.keycloak-metrics-spi ];
|
||||||
|
services.keycloak.settings.metrics-enabled = true;
|
||||||
|
|
||||||
services.nginx.virtualHosts."home.${cfg.domainName}" = {
|
services.nginx.virtualHosts."home.${cfg.domainName}" = {
|
||||||
quic = true;
|
quic = true;
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
|
|
105
system/hosts/nixserver/keycloak.nix
Normal file
105
system/hosts/nixserver/keycloak.nix
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
{ config
|
||||||
|
, lib
|
||||||
|
, pkgs
|
||||||
|
, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.server;
|
||||||
|
in {
|
||||||
|
services.keycloak = {
|
||||||
|
enable = true;
|
||||||
|
database.passwordFile = "/secrets/keycloak_db_pass";
|
||||||
|
settings = {
|
||||||
|
hostname = "keycloak.${cfg.domainName}";
|
||||||
|
http-enabled = true;
|
||||||
|
http-host = "127.0.0.1";
|
||||||
|
http-port = 5739;
|
||||||
|
https-port = 5740;
|
||||||
|
proxy = "edge";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.nginx.virtualHosts."keycloak.${cfg.domainName}" = {
|
||||||
|
quic = true;
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/".proxyPass = "http://${lib.quoteListenAddr config.services.keycloak.settings.http-host}:${toString config.services.keycloak.settings.http-port}/";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.gitea.settings.openid = {
|
||||||
|
ENABLE_OPENID_SIGNIN = true;
|
||||||
|
ENABLE_OPENID_SIGNUP = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nextcloud.extraOptions.allow_local_remote_servers = true;
|
||||||
|
|
||||||
|
# a crude way to make some python packages available for synapse
|
||||||
|
services.matrix-synapse.plugins = with pkgs.python3.pkgs; [ authlib ];
|
||||||
|
services.matrix-synapse.settings.password_config.enabled = false;
|
||||||
|
|
||||||
|
# See also https://meta.akkoma.dev/t/390
|
||||||
|
# https://<pleroma>/oauth/keycloak?scope=openid+profile
|
||||||
|
# ...but this doesnt even work, the callback simply gets ignored
|
||||||
|
# oh well
|
||||||
|
services.akkoma.config = {
|
||||||
|
":ueberauth" = let
|
||||||
|
url = "https://keycloak.${cfg.domainName}";
|
||||||
|
realm = cfg.keycloakRealm;
|
||||||
|
format = pkgs.formats.elixirConf { };
|
||||||
|
in {
|
||||||
|
"Ueberauth.Strategy.Keycloak.OAuth" = {
|
||||||
|
client_id = "akkoma";
|
||||||
|
client_secret = format.lib.mkRaw ''System.get_env("KEYCLOAK_CLIENT_SECRET")'';
|
||||||
|
site = url;
|
||||||
|
authorize_url = "${url}/realms/${realm}/protocol/openid-connect/auth";
|
||||||
|
token_url = "${url}/realms/${realm}/protocol/openid-connect/token";
|
||||||
|
userinfo_url = "${url}/realms/${realm}/protocol/openid-connect/userinfo";
|
||||||
|
token_method = format.lib.mkRaw ":post";
|
||||||
|
};
|
||||||
|
Ueberauth.providers = {
|
||||||
|
keycloak = format.lib.mkTuple [ (format.lib.mkRaw "Ueberauth.Strategy.Keycloak") {
|
||||||
|
default_scope = "openid profile";
|
||||||
|
uid_field = format.lib.mkRaw ":preferred_username";
|
||||||
|
} ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.akkoma.package = pkgs.akkoma.overrideAttrs (old: {
|
||||||
|
buildInputs = let
|
||||||
|
inherit (pkgs.beamPackages) fetchHex buildMix;
|
||||||
|
oldDeps = old.buildInputs or [];
|
||||||
|
tesla = builtins.head (builtins.filter (x: x.packageName == "tesla") oldDeps);
|
||||||
|
ueberauth = builtins.head (builtins.filter (x: x.packageName == "ueberauth") oldDeps);
|
||||||
|
in oldDeps ++ builtins.attrValues rec {
|
||||||
|
# TODO: nothing, this is just a reminder to relock these every once in a while
|
||||||
|
oauth2 = buildMix rec {
|
||||||
|
name = "oauth2";
|
||||||
|
version = "2.1.0";
|
||||||
|
|
||||||
|
src = fetchHex {
|
||||||
|
pkg = "${name}";
|
||||||
|
version = "${version}";
|
||||||
|
sha256 = "0h9bps7gq7bac5gc3q0cgpsj46qnchpqbv5hzsnd2z9hnf2pzh4a";
|
||||||
|
};
|
||||||
|
|
||||||
|
beamDeps = [ tesla ];
|
||||||
|
};
|
||||||
|
ueberauth_keycloak_strategy = buildMix rec {
|
||||||
|
name = "ueberauth_keycloak_strategy";
|
||||||
|
version = "0.4.0";
|
||||||
|
|
||||||
|
src = fetchHex {
|
||||||
|
pkg = "${name}";
|
||||||
|
version = "${version}";
|
||||||
|
sha256 = "06r10w0azlpypjgggar1lf7h2yazn2dpyicy97zxkjyxgf9jfc60";
|
||||||
|
};
|
||||||
|
|
||||||
|
beamDeps = [ oauth2 ueberauth ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
OAUTH_CONSUMER_STRATEGIES = "keycloak:ueberauth_keycloak_strategy";
|
||||||
|
});
|
||||||
|
systemd.services.akkoma = {
|
||||||
|
environment.OAUTH_CONSUMER_STRATEGIES = "keycloak:ueberauth_keycloak_strategy";
|
||||||
|
serviceConfig.EnvironmentFile = "/secrets/akkoma/envrc";
|
||||||
|
};
|
||||||
|
}
|
|
@ -66,7 +66,7 @@ in {
|
||||||
server_name = "matrix.${cfg.domainName}";
|
server_name = "matrix.${cfg.domainName}";
|
||||||
max_upload_size = "100M";
|
max_upload_size = "100M";
|
||||||
email = {
|
email = {
|
||||||
smtp_host = "mail.pavluk.org";
|
smtp_host = "mail.${cfg.domainName}";
|
||||||
smtp_port = 587;
|
smtp_port = 587;
|
||||||
smtp_user = "noreply";
|
smtp_user = "noreply";
|
||||||
smtp_password = cfg.unhashedNoreplyPassword;
|
smtp_password = cfg.unhashedNoreplyPassword;
|
||||||
|
|
|
@ -9,6 +9,11 @@
|
||||||
default = "pavluk.org";
|
default = "pavluk.org";
|
||||||
description = "domain name";
|
description = "domain name";
|
||||||
};
|
};
|
||||||
|
keycloakRealm = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "master";
|
||||||
|
description = "keycloak realm";
|
||||||
|
};
|
||||||
lanCidrV4 = mkOption {
|
lanCidrV4 = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = "LAN mask (IPv4)";
|
description = "LAN mask (IPv4)";
|
||||||
|
|
|
@ -123,6 +123,8 @@ in {
|
||||||
{ directory = /var/lib/dovecot; user = "root"; group = "root"; mode = "0755"; }
|
{ directory = /var/lib/dovecot; user = "root"; group = "root"; mode = "0755"; }
|
||||||
] ++ lib.optionals config.security.sudo.enable [
|
] ++ lib.optionals config.security.sudo.enable [
|
||||||
{ directory = /var/db/sudo/lectured; user = "root"; group = "root"; mode = "0700"; }
|
{ directory = /var/db/sudo/lectured; user = "root"; group = "root"; mode = "0700"; }
|
||||||
|
] ++ lib.optionals config.services.openldap.enable [
|
||||||
|
{ directory = /var/lib/openldap; inherit (config.services.openldap) user group; mode = "0755"; }
|
||||||
] ++ cfg.directories);
|
] ++ cfg.directories);
|
||||||
files = map (x:
|
files = map (x:
|
||||||
if builtins.isPath x then toString x
|
if builtins.isPath x then toString x
|
||||||
|
|
Loading…
Reference in a new issue