Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/kanidm: add option to automatically generate self-signed cert #381636

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 51 additions & 2 deletions nixos/modules/services/security/kanidm.nix
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ in
extraDescription = "If not set will receive a specific version based on stateVersion. Set to `pkgs.kanidm` to always receive the latest version, with the understanding that this could introduce breaking changes.";
};

generateSelfSigned = mkEnableOption "the generation of a self-signed certificate for kanidm. Useful if kanidm is behind a reverse proxy.";

serverSettings = mkOption {
type = types.submodule {
freeformType = settingsFormat.type;
Expand Down Expand Up @@ -645,7 +647,12 @@ in

# Accumulate entities by name. Track corresponding entity types for later duplicate check.
entitiesByName = foldl' (
acc: { type, name }: acc // { ${name} = (acc.${name} or [ ]) ++ [ type ]; }
acc:
{ type, name }:
acc
// {
${name} = (acc.${name} or [ ]) ++ [ type ];
}
) { } entities;

assertGroupsKnown =
Expand Down Expand Up @@ -824,6 +831,11 @@ in
in
lib.mkDefault pkg;

services.kanidm.serverSettings = mkIf cfg.generateSelfSigned {
tls_chain = lib.mkDefault "/var/lib/kanidm/self-signed/chain.pem";
tls_key = lib.mkDefault "/var/lib/kanidm/self-signed/key.pem";
};

environment.systemPackages = mkIf cfg.enableClient [ cfg.package ];

systemd.tmpfiles.settings."10-kanidm" = {
Expand Down Expand Up @@ -879,6 +891,41 @@ in
environment.RUST_LOG = "info";
};

systemd.services.kanidm-generate-self-signed = mkIf cfg.generateSelfSigned {
description = "small script to generate a self-signed certificate for kanidm";
requiredBy = [ "kanidm.service" ];
before = [ "kanidm.service" ];
enableStrictShellChecks = true;
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script =
let
certtool = "${pkgs.gnutls.bin}/bin/certtool";
template_file = pkgs.writeText "kanidm-selfsigned-certtool-template" ''
cn = "${cfg.serverSettings.domain}"
expiration_days = -1
signing_key
encryption_key
tls_www_server
'';
inherit (cfg.serverSettings) tls_chain tls_key;
esc = lib.escapeShellArg;
in
''
if [[ ! -f ${esc tls_chain} ]]; then
directories=("$(dirname ${esc tls_chain})" "$(dirname ${esc tls_key})")
mkdir -p "''${directories[@]}"
${certtool} --generate-privkey --outfile=${esc tls_key} --key-type=rsa --sec-param=high
${certtool} --generate-self-signed --load-privkey=${esc tls_key} --outfile=${esc tls_chain} --template=${template_file}
chmod 0500 "''${directories[@]}"
chmod 0400 ${esc tls_key} ${esc tls_chain}
chown kanidm:kanidm ${esc tls_key} ${esc tls_chain} "''${directories[@]}"
fi
'';
};

systemd.services.kanidm-unixd = mkIf cfg.enablePam {
description = "Kanidm PAM daemon";
wantedBy = [ "multi-user.target" ];
Expand Down Expand Up @@ -973,7 +1020,9 @@ in

# These paths are hardcoded
environment.etc = mkMerge [
(mkIf cfg.enableServer { "kanidm/server.toml".source = serverConfigFile; })
(mkIf cfg.enableServer {
"kanidm/server.toml".source = serverConfigFile;
})
(mkIf options.services.kanidm.clientSettings.isDefined {
"kanidm/config".source = clientConfigFile;
})
Expand Down
1 change: 1 addition & 0 deletions nixos/tests/all-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ in {
kafka = handleTest ./kafka.nix {};
kanboard = handleTest ./web-apps/kanboard.nix {};
kanidm = handleTest ./kanidm.nix {};
kanidm-generate-selfsigned = handleTest ./kanidm-generate-selfsigned.nix {};
kanidm-provisioning = handleTest ./kanidm-provisioning.nix {};
karma = handleTest ./karma.nix {};
kavita = handleTest ./kavita.nix {};
Expand Down
46 changes: 46 additions & 0 deletions nixos/tests/kanidm-generate-selfsigned.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import ./make-test-python.nix (
{ pkgs, ... }:
let
serverDomain = "kanidm.test";
in
{
name = "kanidm";
meta.maintainers = with pkgs.lib.maintainers; [
Flakebi
oddlama
];

nodes.server =
{ pkgs, ... }:
{
services.kanidm = {
enableServer = true;
generateSelfSigned = true;
serverSettings = {
origin = "https://${serverDomain}";
domain = serverDomain;
bindaddress = "[::]:443";
ldapbindaddress = "[::1]:636";
};
};

networking.hosts."::1" = [ serverDomain ];
networking.firewall.allowedTCPPorts = [ 443 ];

users.users.kanidm.shell = pkgs.bashInteractive;

environment.systemPackages = with pkgs; [
kanidm
openldap
ripgrep
];
};

testScript = ''
server.start()
server.wait_for_unit("kanidm.service")
with subtest("Test HTTP interface"):
server.wait_until_succeeds("curl -kLsf https://${serverDomain} | grep Kanidm")
'';
}
)
2 changes: 1 addition & 1 deletion pkgs/by-name/ka/kanidm/generic.nix
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ rustPlatform.buildRustPackage rec {

passthru = {
tests = {
inherit (nixosTests) kanidm kanidm-provisioning;
inherit (nixosTests) kanidm kanidm-provisioning kanidm-generate-selfsigned;
};

updateScript = lib.optionals (!enableSecretProvisioning) (nix-update-script {
Expand Down