2025-03-26 12:51:53 +01:00

269 lines
8.9 KiB
Nix

{ nixpkgs }:
(
{ pkgs, ... }:
{
name = "kerberos_server-heimdal";
nodes = {
server =
{ config, pkgs, ... }:
{
disabledModules = [ "services/system/kerberos/default.nix" ];
imports = [
"${nixpkgs}/nixos/tests/common/user-account.nix"
./module
];
users.users.alice.extraGroups = [ "wheel" ];
services.getty.autologinUser = "alice";
virtualisation.vlans = [ 1 ];
time.timeZone = "Etc/UTC";
networking = {
domain = "foo.bar";
useDHCP = false;
firewall.enable = false;
hosts."10.0.0.1" = [ "server.foo.bar" ];
hosts."10.0.0.2" = [ "client.foo.bar" ];
};
systemd.network.networks."01-eth1" = {
name = "eth1";
networkConfig.Address = "10.0.0.1/24";
};
security.krb5 = {
enable = true;
package = pkgs.heimdal;
settings = {
libdefaults.default_realm = "FOO.BAR";
# Enable extra debug output
logging = {
admin_server = "SYSLOG:DEBUG:AUTH";
default = "SYSLOG:DEBUG:AUTH";
kdc = "SYSLOG:DEBUG:AUTH";
};
realms = {
"FOO.BAR" = {
admin_server = "server.foo.bar";
kpasswd_server = "server.foo.bar";
kdc = [ "server.foo.bar" ];
};
};
};
};
services.kerberos_server = {
enable = true;
settings.realms = {
"FOO.BAR" = {
acl = [
{
principal = "kadmin/admin@FOO.BAR";
access = "all";
}
{
principal = "alice/admin@FOO.BAR";
access = [
"add"
"cpw"
"delete"
"get"
"list"
"modify"
];
}
];
};
};
};
};
client =
{ config, pkgs, ... }:
{
disabledModules = [ "services/system/kerberos/default.nix" ];
imports = [
"${nixpkgs}/nixos/tests/common/user-account.nix"
./module
];
users.users.alice.extraGroups = [ "wheel" ];
services.getty.autologinUser = "alice";
virtualisation.vlans = [ 1 ];
time.timeZone = "Etc/UTC";
networking = {
domain = "foo.bar";
useDHCP = false;
hosts."10.0.0.1" = [ "server.foo.bar" ];
hosts."10.0.0.2" = [ "client.foo.bar" ];
};
systemd.network.networks."01-eth1" = {
name = "eth1";
networkConfig.Address = "10.0.0.2/24";
};
security.krb5 = {
enable = true;
package = pkgs.heimdal;
settings = {
libdefaults.default_realm = "FOO.BAR";
logging = {
admin_server = "SYSLOG:DEBUG:AUTH";
default = "SYSLOG:DEBUG:AUTH";
kdc = "SYSLOG:DEBUG:AUTH";
};
realms = {
"FOO.BAR" = {
admin_server = "server.foo.bar";
kpasswd_server = "server.foo.bar";
kdc = [ "server.foo.bar" ];
};
};
};
};
};
};
testScript =
{ nodes, ... }:
''
import string
import random
random.seed(0)
start_all()
with subtest("Server: initialize realm"):
# for unit in ["kadmind.service", "kdc.socket", "kpasswdd.socket"]:
for unit in ["kadmind.service", "kdc.service", "kpasswdd.service"]:
server.wait_for_unit(unit)
server.succeed("kadmin -l init --realm-max-ticket-life='8 day' --realm-max-renewable-life='10 day' FOO.BAR")
for unit in ["kadmind.service", "kdc.service", "kpasswdd.service"]:
server.systemctl(f"restart {unit}")
alice_krb_pw = "alice_hunter2"
alice_old_krb_pw = ""
alice_krb_admin_pw = "alice_admin_hunter2"
def random_password():
password_chars = string.ascii_letters + string.digits + string.punctuation.replace('"', "")
return "".join(random.choice(password_chars) for _ in range(16))
with subtest("Server: initialize user principals and keytabs"):
server.succeed(f'kadmin -l add --password="{alice_krb_admin_pw}" --use-defaults alice/admin')
server.succeed("kadmin -l ext_keytab --keytab=admin.keytab alice/admin")
server.succeed(f'kadmin -p alice/admin -K admin.keytab add --password="{alice_krb_pw}" --use-defaults alice')
server.succeed("kadmin -l ext_keytab --keytab=alice.keytab alice")
server.wait_for_unit("getty@tty1.service")
server.wait_until_succeeds("pgrep -f 'agetty.*tty1'")
server.wait_for_unit("default.target")
with subtest("Server: initialize host principal with keytab"):
server.send_chars("sudo ktutil get -p alice/admin host/server.foo.bar\n")
server.wait_until_tty_matches("1", "password for alice:")
server.send_chars("${nodes.server.config.users.users.alice.password}\n")
server.wait_until_tty_matches("1", "alice/admin@FOO.BAR's Password:")
server.send_chars(f'{alice_krb_admin_pw}\n')
server.wait_for_file("/etc/krb5.keytab")
ktutil_list = server.succeed("sudo ktutil list")
if not "host/server.foo.bar" in ktutil_list:
exit(1)
server.send_chars("clear\n")
client.systemctl("start network-online.target")
client.wait_for_unit("network-online.target")
client.wait_for_unit("getty@tty1.service")
client.wait_until_succeeds("pgrep -f 'agetty.*tty1'")
client.wait_for_unit("default.target")
with subtest("Client: initialize host principal with keytab"):
client.succeed(
f'echo "{alice_krb_admin_pw}" > pw.txt',
"kinit -p --password-file=pw.txt alice/admin",
)
client.send_chars("sudo ktutil get -p alice/admin host/client.foo.bar\n")
client.wait_until_tty_matches("1", "password for alice:")
client.send_chars("${nodes.client.config.users.users.alice.password}\n")
client.wait_until_tty_matches("1", "alice/admin@FOO.BAR's Password:")
client.send_chars(f"{alice_krb_admin_pw}\n")
client.wait_for_file("/etc/krb5.keytab")
ktutil_list = client.succeed("sudo ktutil list")
if not "host/client.foo.bar" in ktutil_list:
exit(1)
client.send_chars("clear\n")
with subtest("Client: kinit alice"):
client.succeed(
f"echo '{alice_krb_pw}' > pw.txt",
"kinit -p --password-file=pw.txt alice",
)
tickets = client.succeed("klist")
assert "Principal: alice@FOO.BAR" in tickets
client.send_chars("clear\n")
with subtest("Client: kpasswd alice"):
alice_old_krb_pw = alice_krb_pw
alice_krb_pw = random_password()
client.send_chars("kpasswd\n")
client.wait_until_tty_matches("1", "alice@FOO.BAR's Password:")
client.send_chars(f"{alice_old_krb_pw}\n", 0.1)
client.wait_until_tty_matches("1", "New password:")
client.send_chars(f"{alice_krb_pw}\n", 0.1)
client.wait_until_tty_matches("1", "Verify password - New password:")
client.send_chars(f"{alice_krb_pw}\n", 0.1)
client.wait_until_tty_matches("1", "Success : Password changed")
client.send_chars("clear\n")
with subtest("Server: kinit alice"):
server.succeed(
"echo 'alice_pw_2' > pw.txt"
"kinit -p --password-file=pw.txt alice",
)
tickets = client.succeed("klist")
assert "Principal: alice@FOO.BAR" in tickets
server.send_chars("clear\n")
with subtest("Server: kpasswd alice"):
alice_old_krb_pw = alice_krb_pw
alice_krb_pw = random_password()
server.send_chars("kpasswd\n")
server.wait_until_tty_matches("1", "alice@FOO.BAR's Password:")
server.send_chars(f"{alice_old_krb_pw}\n", 0.1)
server.wait_until_tty_matches("1", "New password:")
server.send_chars(f"{alice_krb_pw}\n", 0.1)
server.wait_until_tty_matches("1", "Verify password - New password:")
server.send_chars(f"{alice_krb_pw}\n", 0.1)
server.wait_until_tty_matches("1", "Success : Password changed")
server.send_chars("clear\n")
'';
meta.maintainers = pkgs.heimdal.meta.maintainers;
}
)