{ config, pkgs, lib, ... }: with lib; let cfgBase = config.base; cfg = config.services.ppKeycloak; in { options.services.ppKeycloak = { domain = mkOption { type = types.str; default = "auth.${cfgBase.domainName}"; example = "auth.example.com"; description = "The domain of the server"; }; initialAdminPassword = mkOption { type = types.str; description = "Change on first login, the initial password for the keycloak admin"; }; dbPasswordFile = mkOption { type = types.str; default = "/etc/kc_db_pwd"; description = "The file containing the database password. Be sure to secure it."; }; }; config = { services.keycloak.enable = true; services.keycloak.settings = { hostname = cfg.domain; http-host = "127.0.0.1"; http-port = 8080; https-port = 8443; proxy = "edge"; # TODO: change to reencrypt or passthrough hostname-strict-backchannel = true; }; services.keycloak.initialAdminPassword = cfg.initialAdminPassword; services.keycloak.database.passwordFile = cfg.dbPasswordFile; # Set the permittions for the db file system.activationScripts = { keycloakDbFilePermission.text = '' chmod 400 ${cfg.dbPasswordFile} chown keycloak ${cfg.dbPasswordFile} ''; }; services.keycloak.database.createLocally = true; # TODO: enable client cert lookup: https://www.keycloak.org/server/reverseproxy#_enabling_client_certificate_lookup # NGINX security.acme.acceptTerms = true; security.acme.defaults.email = cfgBase.adminEmail; services.nginx = { enable = true; virtualHosts = { "${cfg.domain}" = { forceSSL = true; enableACME = true; # TODO: reduce attack surface https://www.keycloak.org/server/reverseproxy#_enabling_client_certificate_lookup locations."/" = { proxyPass = "http://127.0.0.1:8080"; extraConfig = '' proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $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 Host $host; proxy_pass_request_headers on; ''; }; }; }; }; networking.firewall.allowedTCPPorts = [ 80 443 ]; }; }