Merge pull request #31832 from kwohlfahrt/kerberos
kerberos_server: allow choosing MIT or Heimdal
This commit is contained in:
commit
eefbc088a7
10 changed files with 322 additions and 66 deletions
|
@ -690,7 +690,7 @@
|
||||||
./services/system/dbus.nix
|
./services/system/dbus.nix
|
||||||
./services/system/earlyoom.nix
|
./services/system/earlyoom.nix
|
||||||
./services/system/localtime.nix
|
./services/system/localtime.nix
|
||||||
./services/system/kerberos.nix
|
./services/system/kerberos/default.nix
|
||||||
./services/system/nscd.nix
|
./services/system/nscd.nix
|
||||||
./services/system/saslauthd.nix
|
./services/system/saslauthd.nix
|
||||||
./services/system/uptimed.nix
|
./services/system/uptimed.nix
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
{pkgs, config, lib, ...}:
|
|
||||||
|
|
||||||
let
|
|
||||||
|
|
||||||
inherit (lib) mkOption mkIf;
|
|
||||||
|
|
||||||
inherit (pkgs) heimdalFull;
|
|
||||||
|
|
||||||
stateDir = "/var/heimdal";
|
|
||||||
in
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
###### interface
|
|
||||||
|
|
||||||
options = {
|
|
||||||
|
|
||||||
services.kerberos_server = {
|
|
||||||
|
|
||||||
enable = mkOption {
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Enable the kerberos authentification server.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
###### implementation
|
|
||||||
|
|
||||||
config = mkIf config.services.kerberos_server.enable {
|
|
||||||
|
|
||||||
environment.systemPackages = [ heimdalFull ];
|
|
||||||
|
|
||||||
services.xinetd.enable = true;
|
|
||||||
services.xinetd.services = lib.singleton
|
|
||||||
{ name = "kerberos-adm";
|
|
||||||
flags = "REUSE NAMEINARGS";
|
|
||||||
protocol = "tcp";
|
|
||||||
user = "root";
|
|
||||||
server = "${pkgs.tcp_wrappers}/bin/tcpd";
|
|
||||||
serverArgs = "${pkgs.heimdalFull}/libexec/heimdal/kadmind";
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.kdc = {
|
|
||||||
description = "Key Distribution Center daemon";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
preStart = ''
|
|
||||||
mkdir -m 0755 -p ${stateDir}
|
|
||||||
'';
|
|
||||||
script = "${heimdalFull}/libexec/heimdal/kdc";
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.kpasswdd = {
|
|
||||||
description = "Kerberos Password Changing daemon";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
script = "${heimdalFull}/libexec/heimdal/kpasswdd";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
80
nixos/modules/services/system/kerberos/default.nix
Normal file
80
nixos/modules/services/system/kerberos/default.nix
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
{pkgs, config, lib, ...}:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib) mkOption mkIf types length attrNames;
|
||||||
|
cfg = config.services.kerberos_server;
|
||||||
|
kerberos = config.krb5.kerberos;
|
||||||
|
|
||||||
|
aclEntry = {
|
||||||
|
options = {
|
||||||
|
principal = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "Which principal the rule applies to";
|
||||||
|
};
|
||||||
|
access = mkOption {
|
||||||
|
type = types.either
|
||||||
|
(types.listOf (types.enum ["add" "cpw" "delete" "get" "list" "modify"]))
|
||||||
|
(types.enum ["all"]);
|
||||||
|
default = "all";
|
||||||
|
description = "The changes the principal is allowed to make.";
|
||||||
|
};
|
||||||
|
target = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "*";
|
||||||
|
description = "The principals that 'access' applies to.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
realm = {
|
||||||
|
options = {
|
||||||
|
acl = mkOption {
|
||||||
|
type = types.listOf (types.submodule aclEntry);
|
||||||
|
default = [
|
||||||
|
{ principal = "*/admin"; access = "all"; }
|
||||||
|
{ principal = "admin"; access = "all"; }
|
||||||
|
];
|
||||||
|
description = ''
|
||||||
|
The privileges granted to a user.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./mit.nix
|
||||||
|
./heimdal.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
options = {
|
||||||
|
services.kerberos_server = {
|
||||||
|
enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable the kerberos authentification server.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
realms = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule realm);
|
||||||
|
description = ''
|
||||||
|
The realm(s) to serve keys for.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
environment.systemPackages = [ kerberos ];
|
||||||
|
assertions = [{
|
||||||
|
assertion = length (attrNames cfg.realms) <= 1;
|
||||||
|
message = "Only one realm per server is currently supported.";
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
}
|
68
nixos/modules/services/system/kerberos/heimdal.nix
Normal file
68
nixos/modules/services/system/kerberos/heimdal.nix
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
{ pkgs, config, lib, ... } :
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib) mkIf concatStringsSep concatMapStrings toList mapAttrs
|
||||||
|
mapAttrsToList attrValues;
|
||||||
|
cfg = config.services.kerberos_server;
|
||||||
|
kerberos = config.krb5.kerberos;
|
||||||
|
stateDir = "/var/heimdal";
|
||||||
|
aclFiles = mapAttrs
|
||||||
|
(name: {acl, ...}: pkgs.writeText "${name}.acl" (concatMapStrings ((
|
||||||
|
{principal, access, target, ...} :
|
||||||
|
"${principal}\t${concatStringsSep "," (toList access)}\t${target}\n"
|
||||||
|
)) acl)) cfg.realms;
|
||||||
|
|
||||||
|
kdcConfigs = mapAttrsToList (name: value: ''
|
||||||
|
database = {
|
||||||
|
dbname = ${stateDir}/heimdal
|
||||||
|
acl_file = ${value}
|
||||||
|
}
|
||||||
|
'') aclFiles;
|
||||||
|
kdcConfFile = pkgs.writeText "kdc.conf" ''
|
||||||
|
[kdc]
|
||||||
|
${concatStringsSep "\n" kdcConfigs}
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
# No documentation about correct triggers, so guessing at them.
|
||||||
|
|
||||||
|
config = mkIf (cfg.enable && kerberos == pkgs.heimdalFull) {
|
||||||
|
systemd.services.kadmind = {
|
||||||
|
description = "Kerberos Administration Daemon";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
preStart = ''
|
||||||
|
mkdir -m 0755 -p ${stateDir}
|
||||||
|
'';
|
||||||
|
serviceConfig.ExecStart =
|
||||||
|
"${kerberos}/libexec/heimdal/kadmind --config-file=/etc/heimdal-kdc/kdc.conf";
|
||||||
|
restartTriggers = [ kdcConfFile ];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.kdc = {
|
||||||
|
description = "Key Distribution Center daemon";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
preStart = ''
|
||||||
|
mkdir -m 0755 -p ${stateDir}
|
||||||
|
'';
|
||||||
|
serviceConfig.ExecStart =
|
||||||
|
"${kerberos}/libexec/heimdal/kdc --config-file=/etc/heimdal-kdc/kdc.conf";
|
||||||
|
restartTriggers = [ kdcConfFile ];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.kpasswdd = {
|
||||||
|
description = "Kerberos Password Changing daemon";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
preStart = ''
|
||||||
|
mkdir -m 0755 -p ${stateDir}
|
||||||
|
'';
|
||||||
|
serviceConfig.ExecStart = "${kerberos}/libexec/heimdal/kpasswdd";
|
||||||
|
restartTriggers = [ kdcConfFile ];
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc = {
|
||||||
|
# Can be set via the --config-file option to KDC
|
||||||
|
"heimdal-kdc/kdc.conf".source = kdcConfFile;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
68
nixos/modules/services/system/kerberos/mit.nix
Normal file
68
nixos/modules/services/system/kerberos/mit.nix
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
{ pkgs, config, lib, ... } :
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib) mkIf concatStrings concatStringsSep concatMapStrings toList
|
||||||
|
mapAttrs mapAttrsToList attrValues;
|
||||||
|
cfg = config.services.kerberos_server;
|
||||||
|
kerberos = config.krb5.kerberos;
|
||||||
|
stateDir = "/var/lib/krb5kdc";
|
||||||
|
PIDFile = "/run/kdc.pid";
|
||||||
|
aclMap = {
|
||||||
|
add = "a"; cpw = "c"; delete = "d"; get = "i"; list = "l"; modify = "m";
|
||||||
|
all = "*";
|
||||||
|
};
|
||||||
|
aclFiles = mapAttrs
|
||||||
|
(name: {acl, ...}: (pkgs.writeText "${name}.acl" (concatMapStrings (
|
||||||
|
{principal, access, target, ...} :
|
||||||
|
let access_code = map (a: aclMap.${a}) (toList access); in
|
||||||
|
"${principal} ${concatStrings access_code} ${target}\n"
|
||||||
|
) acl))) cfg.realms;
|
||||||
|
kdcConfigs = mapAttrsToList (name: value: ''
|
||||||
|
${name} = {
|
||||||
|
acl_file = ${value}
|
||||||
|
}
|
||||||
|
'') aclFiles;
|
||||||
|
kdcConfFile = pkgs.writeText "kdc.conf" ''
|
||||||
|
[realms]
|
||||||
|
${concatStringsSep "\n" kdcConfigs}
|
||||||
|
'';
|
||||||
|
env = {
|
||||||
|
# What Debian uses, could possibly link directly to Nix store?
|
||||||
|
KRB5_KDC_PROFILE = "/etc/krb5kdc/kdc.conf";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
config = mkIf (cfg.enable && kerberos == pkgs.krb5Full) {
|
||||||
|
systemd.services.kadmind = {
|
||||||
|
description = "Kerberos Administration Daemon";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
preStart = ''
|
||||||
|
mkdir -m 0755 -p ${stateDir}
|
||||||
|
'';
|
||||||
|
serviceConfig.ExecStart = "${kerberos}/bin/kadmind -nofork";
|
||||||
|
restartTriggers = [ kdcConfFile ];
|
||||||
|
environment = env;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.kdc = {
|
||||||
|
description = "Key Distribution Center daemon";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
preStart = ''
|
||||||
|
mkdir -m 0755 -p ${stateDir}
|
||||||
|
'';
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "forking";
|
||||||
|
PIDFile = PIDFile;
|
||||||
|
ExecStart = "${kerberos}/bin/krb5kdc -P ${PIDFile}";
|
||||||
|
};
|
||||||
|
restartTriggers = [ kdcConfFile ];
|
||||||
|
environment = env;
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc = {
|
||||||
|
"krb5kdc/kdc.conf".source = kdcConfFile;
|
||||||
|
};
|
||||||
|
environment.variables = env;
|
||||||
|
};
|
||||||
|
}
|
|
@ -107,6 +107,7 @@ in
|
||||||
ipv6 = handleTest ./ipv6.nix {};
|
ipv6 = handleTest ./ipv6.nix {};
|
||||||
jenkins = handleTest ./jenkins.nix {};
|
jenkins = handleTest ./jenkins.nix {};
|
||||||
kafka = handleTest ./kafka.nix {};
|
kafka = handleTest ./kafka.nix {};
|
||||||
|
kerberos = handleTest tests/kerberos/default.nix {};
|
||||||
kernel-latest = handleTest ./kernel-latest.nix {};
|
kernel-latest = handleTest ./kernel-latest.nix {};
|
||||||
kernel-lts = handleTest ./kernel-lts.nix {};
|
kernel-lts = handleTest ./kernel-lts.nix {};
|
||||||
keymap = handleTest ./keymap.nix {};
|
keymap = handleTest ./keymap.nix {};
|
||||||
|
|
5
nixos/tests/kerberos/default.nix
Normal file
5
nixos/tests/kerberos/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{ system ? builtins.currentSystem }:
|
||||||
|
{
|
||||||
|
mit = import ./mit.nix { inherit system; };
|
||||||
|
heimdal = import ./heimdal.nix { inherit system; };
|
||||||
|
}
|
53
nixos/tests/kerberos/heimdal.nix
Normal file
53
nixos/tests/kerberos/heimdal.nix
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import ../make-test.nix ({pkgs, ...}: {
|
||||||
|
name = "kerberos_server-heimdal";
|
||||||
|
machine = { config, libs, pkgs, ...}:
|
||||||
|
{ services.kerberos_server =
|
||||||
|
{ enable = true;
|
||||||
|
realms = {
|
||||||
|
"FOO.BAR".acl = [{principal = "admin"; access = ["add" "cpw"];}];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
krb5 = {
|
||||||
|
enable = true;
|
||||||
|
kerberos = pkgs.heimdalFull;
|
||||||
|
libdefaults = {
|
||||||
|
default_realm = "FOO.BAR";
|
||||||
|
};
|
||||||
|
realms = {
|
||||||
|
"FOO.BAR" = {
|
||||||
|
admin_server = "machine";
|
||||||
|
kdc = "machine";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
$machine->start;
|
||||||
|
|
||||||
|
$machine->succeed(
|
||||||
|
"kadmin -l init --realm-max-ticket-life='8 day' \\
|
||||||
|
--realm-max-renewable-life='10 day' FOO.BAR"
|
||||||
|
);
|
||||||
|
|
||||||
|
$machine->succeed("systemctl restart kadmind.service kdc.service");
|
||||||
|
$machine->waitForUnit("kadmind.service");
|
||||||
|
$machine->waitForUnit("kdc.service");
|
||||||
|
$machine->waitForUnit("kpasswdd.service");
|
||||||
|
|
||||||
|
$machine->succeed(
|
||||||
|
"kadmin -l add --password=admin_pw --use-defaults admin"
|
||||||
|
);
|
||||||
|
$machine->succeed(
|
||||||
|
"kadmin -l ext_keytab --keytab=admin.keytab admin"
|
||||||
|
);
|
||||||
|
$machine->succeed(
|
||||||
|
"kadmin -p admin -K admin.keytab add --password=alice_pw --use-defaults \\
|
||||||
|
alice"
|
||||||
|
);
|
||||||
|
$machine->succeed(
|
||||||
|
"kadmin -l ext_keytab --keytab=alice.keytab alice"
|
||||||
|
);
|
||||||
|
$machine->succeed("kinit -kt alice.keytab alice");
|
||||||
|
'';
|
||||||
|
})
|
45
nixos/tests/kerberos/mit.nix
Normal file
45
nixos/tests/kerberos/mit.nix
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import ../make-test.nix ({pkgs, ...}: {
|
||||||
|
name = "kerberos_server-mit";
|
||||||
|
machine = { config, libs, pkgs, ...}:
|
||||||
|
{ services.kerberos_server =
|
||||||
|
{ enable = true;
|
||||||
|
realms = {
|
||||||
|
"FOO.BAR".acl = [{principal = "admin"; access = ["add" "cpw"];}];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
krb5 = {
|
||||||
|
enable = true;
|
||||||
|
kerberos = pkgs.krb5Full;
|
||||||
|
libdefaults = {
|
||||||
|
default_realm = "FOO.BAR";
|
||||||
|
};
|
||||||
|
realms = {
|
||||||
|
"FOO.BAR" = {
|
||||||
|
admin_server = "machine";
|
||||||
|
kdc = "machine";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
users.extraUsers.alice = { isNormalUser = true; };
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
$machine->start;
|
||||||
|
|
||||||
|
$machine->succeed(
|
||||||
|
"kdb5_util create -s -r FOO.BAR -P master_key"
|
||||||
|
);
|
||||||
|
|
||||||
|
$machine->succeed("systemctl restart kadmind.service kdc.service");
|
||||||
|
$machine->waitForUnit("kadmind.service");
|
||||||
|
$machine->waitForUnit("kdc.service");
|
||||||
|
|
||||||
|
$machine->succeed(
|
||||||
|
"kadmin.local add_principal -pw admin_pw admin"
|
||||||
|
);
|
||||||
|
$machine->succeed(
|
||||||
|
"kadmin -p admin -w admin_pw addprinc -pw alice_pw alice"
|
||||||
|
);
|
||||||
|
$machine->succeed("echo alice_pw | sudo -u alice kinit");
|
||||||
|
'';
|
||||||
|
})
|
|
@ -65,7 +65,7 @@ stdenv.mkDerivation rec {
|
||||||
|
|
||||||
# not via outputBin, due to reference from libkrb5.so
|
# not via outputBin, due to reference from libkrb5.so
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
moveToOutput bin "$dev"
|
moveToOutput bin/krb5-config "$dev"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
enableParallelBuilding = true;
|
enableParallelBuilding = true;
|
||||||
|
|
Loading…
Reference in a new issue