- Added Keycloak service with PostgreSQL backend - Configured OIDC for both Headscale and Headplane - Added systemd service to auto-create /var/lib/headplane directory - Updated Keycloak realm JSON with required client scopes (openid, profile, email) - Generated and configured Headscale API key for Headplane OIDC - Added production hardening: auto-restart, garbage collection, boot cleanup The setup now supports: - User login via Keycloak OIDC at https://auth.kennys.mom - Headplane web UI with SSO at https://headplane.kennys.mom/admin - Fallback API key authentication - Automated secret generation and permissions management
91 lines
2.5 KiB
Nix
91 lines
2.5 KiB
Nix
{ config, pkgs, lib, ... }:
|
|
let
|
|
domain = "kennys.mom";
|
|
authDomain = "auth.${domain}";
|
|
in
|
|
{
|
|
# PostgreSQL for Keycloak
|
|
services.postgresql = {
|
|
enable = true;
|
|
ensureDatabases = [ "keycloak" ];
|
|
ensureUsers = [{
|
|
name = "keycloak";
|
|
ensureDBOwnership = true;
|
|
}];
|
|
};
|
|
|
|
# Keycloak service
|
|
services.keycloak = {
|
|
enable = true;
|
|
database = {
|
|
type = "postgresql";
|
|
username = "keycloak";
|
|
name = "keycloak";
|
|
host = "localhost";
|
|
createLocally = false;
|
|
passwordFile = "/var/lib/keycloak-credentials/db-password";
|
|
};
|
|
settings = {
|
|
hostname = authDomain;
|
|
http-host = "127.0.0.1";
|
|
http-port = 8080;
|
|
http-enabled = true;
|
|
proxy-headers = "xforwarded";
|
|
hostname-strict-https = false;
|
|
};
|
|
};
|
|
|
|
# Generate database password and use LoadCredential
|
|
systemd.services.keycloak = {
|
|
serviceConfig = {
|
|
LoadCredential = [ "db-password:/var/lib/keycloak-credentials/db-password" ];
|
|
TimeoutStartSec = "5min";
|
|
};
|
|
};
|
|
|
|
systemd.services.keycloak-db-password = {
|
|
description = "Generate Keycloak database password";
|
|
wantedBy = [ "multi-user.target" ];
|
|
before = [ "keycloak.service" ];
|
|
after = [ "postgresql.service" ];
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
RemainAfterExit = true;
|
|
};
|
|
script = ''
|
|
mkdir -p /var/lib/keycloak-credentials
|
|
|
|
if [ ! -f /var/lib/keycloak-credentials/db-password ]; then
|
|
echo "Generating Keycloak database password..."
|
|
DB_PASS=$(${pkgs.openssl}/bin/openssl rand -base64 32)
|
|
echo -n "$DB_PASS" > /var/lib/keycloak-credentials/db-password
|
|
chmod 600 /var/lib/keycloak-credentials/db-password
|
|
|
|
# Set the password in PostgreSQL
|
|
${pkgs.sudo}/bin/sudo -u postgres ${config.services.postgresql.package}/bin/psql -c "ALTER USER keycloak WITH PASSWORD '$DB_PASS';"
|
|
|
|
echo "Database password set"
|
|
fi
|
|
'';
|
|
};
|
|
|
|
# Ngin configuration for Keycloak
|
|
services.nginx.virtualHosts."${authDomain}" = {
|
|
forceSSL = true;
|
|
enableACME = true;
|
|
locations."/" = {
|
|
proxyPass = "http://127.0.0.1:8080";
|
|
extraConfig = ''
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_set_header X-Forwarded-Host $host;
|
|
proxy_buffer_size 128k;
|
|
proxy_buffers 4 256k;
|
|
proxy_busy_buffers_size 256k;
|
|
'';
|
|
};
|
|
};
|
|
}
|