diff --git a/all-packages.nix b/all-packages.nix index cadc39b..345551a 100644 --- a/all-packages.nix +++ b/all-packages.nix @@ -34,10 +34,7 @@ let PHPFPMSiteConfig = callPackage ./php-fpm/siteconfig.nix {inherit utils;}; mkPHPFPMSiteConfig = callPackage ./php-fpm/mksiteconfig.nix {inherit PHPFPMSiteConfig;}; - KeycloakConfig = callPackage ./keycloak/config.nix {inherit utils;}; - mkKeycloakConfig = callPackage ./keycloak/mkconfig.nix {inherit KeycloakConfig;}; - KeycloakService = callPackage ./keycloak/unit.nix {inherit utils;}; - mkKeycloakService = callPackage ./keycloak/mkunit.nix {inherit KeycloakService;}; + mkKeycloakService = callPackage ./keycloak/unit.nix {inherit utils;}; mkKeycloakHaproxyService = callPackage ./keycloak-haproxy/unit.nix {inherit utils;}; diff --git a/keycloak-cli-config/unit.nix b/keycloak-cli-config/unit.nix index a65d8e2..12932f3 100644 --- a/keycloak-cli-config/unit.nix +++ b/keycloak-cli-config/unit.nix @@ -14,7 +14,8 @@ , keys , debug ? false }: -{...}: +{ ... +}: # https://github.com/adorsys/keycloak-config-cli diff --git a/keycloak/config.nix b/keycloak/config.nix deleted file mode 100644 index f510485..0000000 --- a/keycloak/config.nix +++ /dev/null @@ -1,62 +0,0 @@ -{ stdenv -, pkgs -, lib -, utils -}: -{ configDir ? "/etc/keycloak" -, configFile ? "keycloak.conf" -, logLevel ? "INFO" -, metricsEnabled ? false -, hostname - -, dbType ? "postgres" -, dbUsername ? "keycloak" -, dbHost ? x: "localhost" -, dbPort ? "5432" -, dbDatabase ? "keycloak" -}: -{ KeycloakPostgresDB -}: - -assert lib.assertOneOf "dbType" dbType ["postgres"]; - -utils.mkConfigFile { - name = configFile; - dir = configDir; - content = '' - # The password of the database user is given by an environment variable. - db=${dbType} - db-username=${dbUsername} - db-url-host=${dbHost {inherit KeycloakPostgresDB;}} - db-url-port=${dbPort} - db-url-database=${dbDatabase} - # db-url-properties= # Would be used for ssl, see https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/web-apps/keycloak.nix#L491 - - # Observability - - # If the server should expose metrics and healthcheck endpoints. - metrics-enabled=${if metricsEnabled then "true" else "false"} - - # HTTP - - # The file path to a server certificate or certificate chain in PEM format. - #https-certificate-file=''${kc.home.dir}conf/server.crt.pem - - # The file path to a private key in PEM format. - #https-certificate-key-file=''${kc.home.dir}conf/server.key.pem - - # The proxy address forwarding mode if the server is behind a reverse proxy. - # https://www.keycloak.org/server/reverseproxy - proxy=edge - - # Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy - #spi-sticky-session-encoder-infinispan-should-attach-route=false - - # Hostname for the Keycloak server. - hostname=${hostname} - - spi-x509cert-lookup-provider=haproxy - - log-level=${logLevel} - ''; -} diff --git a/keycloak/mkconfig.nix b/keycloak/mkconfig.nix deleted file mode 100644 index 8456f24..0000000 --- a/keycloak/mkconfig.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ KeycloakConfig -}: -{ name -, configDir ? "/etc/keycloak" -, configFile ? "keycloak.conf" -, logLevel ? "INFO" -, metricsEnabled ? false -, hostname ? "keycloak.hostname.com" - -, dbType ? "postgres" -, dbUsername ? "keycloak" -, dbHost ? x: "localhost" -, dbPort ? "5432" -, dbDatabase ? "keycloak" - -, dependsOn ? {} -}: - -{ - inherit name configDir configFile; - - inherit hostname; - - pkg = KeycloakConfig { - inherit configDir configFile hostname; - inherit logLevel metricsEnabled; - inherit dbType dbUsername dbHost dbPort dbDatabase; - }; - - inherit dependsOn; - type = "fileset"; -} diff --git a/keycloak/mkunit.nix b/keycloak/mkunit.nix deleted file mode 100644 index 73c546a..0000000 --- a/keycloak/mkunit.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ KeycloakService -}: -{ name -, configDir -, configFile -, user -, group -, postgresServiceName -, initialAdminUsername ? "admin" -, keys - -, dependsOn ? {} -}: -{ - inherit name configDir configFile; - - inherit initialAdminUsername; - - pkg = KeycloakService { - inherit configDir configFile; - inherit user group; - inherit keys initialAdminUsername; - inherit postgresServiceName; - }; - - systemdUnitFile = "${name}.service"; - - inherit dependsOn; - type = "systemd-unit"; -} diff --git a/keycloak/unit.nix b/keycloak/unit.nix index e91c192..af95bb9 100644 --- a/keycloak/unit.nix +++ b/keycloak/unit.nix @@ -3,16 +3,25 @@ , lib , utils }: -{ configDir ? "/etc/keycloak" -, configFile ? "keycloak.conf" +{ name , user ? "keycloak" , group ? "keycloak" , dbType ? "postgres" , postgresServiceName , initialAdminUsername ? null , keys + +, logLevel ? "INFO" +, metricsEnabled ? false +, hostname + +, dbUsername ? "keycloak" +, dbHost ? x: "localhost" +, dbPort ? "5432" +, dbDatabase ? "keycloak" + +, KeycloakPostgresDB }: -{ ... }: assert lib.assertOneOf "dbType" dbType ["postgres"]; @@ -25,74 +34,125 @@ let }; in -with lib.attrsets; -utils.systemd.mkService rec { - name = "keycloak"; +{ + inherit name; - content = '' - [Unit] - Description=Keycloak server - After=network-online.target - Wants=network-online.target systemd-networkd-wait-online.service ${postgresServiceName} - After=${utils.keyServiceDependencies keys} - Wants=${utils.keyServiceDependencies keys} - - [Service] - User=${user} - Group=${group} - - ${utils.keyEnvironmentFile keys.dbPassword} - ${if initialAdminUsername != null then "Environment=KEYCLOAK_ADMIN="+initialAdminUsername else ""} - ${if hasAttr "initialAdminPassword" keys then utils.keyEnvironmentFile keys.initialAdminPassword else ""} - Environment=PATH=${pkgs.coreutils}/bin - Environment=KC_HOME_DIR="/run/keycloak" + inherit initialAdminUsername; - # running the ExecStartPre as root is not ideal, but at the moment - # the only solution for Quarkus modifying the serialized - # data under /lib/quarkus - # Raised upstream as https://github.com/keycloak/keycloak/discussions/10323 - # ExecStartPre=!${keycloak}/bin/kc.sh -cf ${configDir}/${configFile} build - ExecStart=${keycloak}/bin/kc.sh -cf ${configDir}/${configFile} start + systemdUnitFile = "${name}.service"; - # ReadWritePaths=/var/lib/keycloak - # ReadWritePaths=/var/log/keycloak - # ReadWritePaths=/usr/share/java/keycloak/lib/quarkus - # ReadOnlyPaths=${configDir} - RuntimeDirectory=keycloak - DynamicUser=true - - # Disable timeout logic and wait until process is stopped - TimeoutStopSec=0 - TimeoutStartSec=10min - - # SIGTERM signal is used to stop the Java process - KillSignal=SIGTERM - - # Send the signal only to the JVM rather than its control group - KillMode=process - - # Java process is never killed - SendSIGKILL=no - - # When a JVM receives a SIGTERM signal it exits with code 143 - SuccessExitStatus=143 - - # Hardening options - # CapabilityBoundingSet= - # AmbientCapabilities=CAP_NET_BIND_SERVICES - # NoNewPrivileges=true - # Fails with: - # Failed to set up mount namespacing: /run/systemd/unit-root/var/lib/keycloak: No such file or directory - # ProtectHome=true - # ProtectSystem=strict - # ProtectKernelTunables=true - # ProtectKernelModules=true - # ProtectControlGroups=true - # PrivateTmp=true - # PrivateDevices=true - # LockPersonality=true - - [Install] - WantedBy=multi-user.target - ''; + pkg = { KeycloakPostgresDB }: + let + configFile = pkgs.writeText "keycloak.conf" '' + # The password of the database user is given by an environment variable. + db=${dbType} + db-username=${dbUsername} + db-url-host=${dbHost {inherit KeycloakPostgresDB;}} + db-url-port=${dbPort} + db-url-database=${dbDatabase} + # db-url-properties= # Would be used for ssl, see https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/web-apps/keycloak.nix#L491 + + # Observability + + # If the server should expose metrics and healthcheck endpoints. + metrics-enabled=${if metricsEnabled then "true" else "false"} + + # HTTP + + # The file path to a server certificate or certificate chain in PEM format. + #https-certificate-file=''${kc.home.dir}conf/server.crt.pem + + # The file path to a private key in PEM format. + #https-certificate-key-file=''${kc.home.dir}conf/server.key.pem + + # The proxy address forwarding mode if the server is behind a reverse proxy. + # https://www.keycloak.org/server/reverseproxy + proxy=edge + + # Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy + #spi-sticky-session-encoder-infinispan-should-attach-route=false + + # Hostname for the Keycloak server. + hostname=${hostname} + + spi-x509cert-lookup-provider=haproxy + + log-level=${logLevel} + ''; + in + with lib.attrsets; + utils.systemd.mkService rec { + name = "keycloak"; + + content = '' + [Unit] + Description=Keycloak server + After=network-online.target + Wants=network-online.target systemd-networkd-wait-online.service ${postgresServiceName} + After=${utils.keyServiceDependencies keys} + Wants=${utils.keyServiceDependencies keys} + + [Service] + User=${user} + Group=${group} + + ${utils.keyEnvironmentFile keys.dbPassword} + ${if initialAdminUsername != null then "Environment=KEYCLOAK_ADMIN="+initialAdminUsername else ""} + ${if hasAttr "initialAdminPassword" keys then utils.keyEnvironmentFile keys.initialAdminPassword else ""} + Environment=PATH=${pkgs.coreutils}/bin + Environment=KC_HOME_DIR="/run/keycloak" + + # running the ExecStartPre as root is not ideal, but at the moment + # the only solution for Quarkus modifying the serialized + # data under /lib/quarkus + # Raised upstream as https://github.com/keycloak/keycloak/discussions/10323 + # ExecStartPre=!${keycloak}/bin/kc.sh -cf ${configFile} build + ExecStart=${keycloak}/bin/kc.sh -cf ${configFile} start + + # ReadWritePaths=/var/lib/keycloak + # ReadWritePaths=/var/log/keycloak + # ReadWritePaths=/usr/share/java/keycloak/lib/quarkus + RuntimeDirectory=keycloak + DynamicUser=true + + # Disable timeout logic and wait until process is stopped + TimeoutStopSec=0 + TimeoutStartSec=10min + + # SIGTERM signal is used to stop the Java process + KillSignal=SIGTERM + + # Send the signal only to the JVM rather than its control group + KillMode=process + + # Java process is never killed + SendSIGKILL=no + + # When a JVM receives a SIGTERM signal it exits with code 143 + SuccessExitStatus=143 + + # Hardening options + # CapabilityBoundingSet= + # AmbientCapabilities=CAP_NET_BIND_SERVICES + # NoNewPrivileges=true + # Fails with: + # Failed to set up mount namespacing: /run/systemd/unit-root/var/lib/keycloak: No such file or directory + # ProtectHome=true + # ProtectSystem=strict + # ProtectKernelTunables=true + # ProtectKernelModules=true + # ProtectControlGroups=true + # PrivateTmp=true + # PrivateDevices=true + # LockPersonality=true + + [Install] + WantedBy=multi-user.target + ''; + }; + + dependsOn = { + inherit KeycloakPostgresDB; + }; + type = "systemd-unit"; }