+1
nixos/tests/kerberos/default.nix
+1
nixos/tests/kerberos/default.nix
+7
nixos/tests/kerberos/ldap/default.nix
+7
nixos/tests/kerberos/ldap/default.nix
+192
nixos/tests/kerberos/ldap/mit.nix
+192
nixos/tests/kerberos/ldap/mit.nix
···
1
+
import ../../make-test-python.nix (
2
+
{ pkgs, ... }:
3
+
let
4
+
DITRoot = "dc=example,dc=com";
5
+
realm = "EXAMPLE.COM";
6
+
7
+
krb5Package = pkgs.krb5.override { withLdap = true; };
8
+
9
+
# Password used by Kerberos services to bind to their identities
10
+
krbSrvPwd = "kerberos_service_password";
11
+
# Stash file read by Kerberos daemons containing the service password
12
+
# DO NOT DO THIS IN PRODUCTION! The stash file is a fundamental secret!
13
+
krbPwdStash = pkgs.runCommand "krb-pwd-stash" { } ''
14
+
for srv in cn=kadmin,${DITRoot} cn=kdc,${DITRoot}
15
+
do
16
+
echo -e "${krbSrvPwd}\n${krbSrvPwd}" | \
17
+
${krb5Package}/bin/kdb5_ldap_util -r ${realm} stashsrvpw -f $out $srv 2>&1 > /dev/null
18
+
done
19
+
'';
20
+
21
+
# The LDAP schema for Kerberos 5 objects is part of the source distribution of Kerberos 5
22
+
krbLdapSchema = pkgs.runCommand "krb-ldap-schema" { } ''
23
+
tar -Oxf ${krb5Package.src} \
24
+
${krb5Package.sourceRoot}/plugins/kdb/ldap/libkdb_ldap/kerberos.openldap.ldif > $out
25
+
'';
26
+
27
+
# Initial LDAP tree containing only the Kerberos services
28
+
ldapDIT = ''
29
+
dn: ${DITRoot}
30
+
objectClass: organization
31
+
objectClass: dcObject
32
+
dc: example
33
+
o: Example Company
34
+
35
+
dn: cn=kdc,${DITRoot}
36
+
objectClass: krbKdcService
37
+
objectClass: simpleSecurityObject
38
+
cn: kdc
39
+
userPassword: ${krbSrvPwd}
40
+
41
+
dn: cn=kadmin,${DITRoot}
42
+
objectClass: krbAdmService
43
+
objectClass: simpleSecurityObject
44
+
cn: kadmin
45
+
userPassword: ${krbSrvPwd}
46
+
'';
47
+
48
+
rootDnPwd = "ldap_root_password";
49
+
in
50
+
{
51
+
name = "kerberos_server-mit-ldap";
52
+
53
+
nodes.machine =
54
+
{ pkgs, ... }:
55
+
{
56
+
57
+
services.openldap = {
58
+
enable = true;
59
+
urlList = [
60
+
"ldapi:///"
61
+
"ldap://"
62
+
];
63
+
declarativeContents."${DITRoot}" = ldapDIT;
64
+
settings = {
65
+
children = {
66
+
"cn=schema".includes = [
67
+
"${pkgs.openldap}/etc/schema/core.ldif"
68
+
"${pkgs.openldap}/etc/schema/cosine.ldif"
69
+
"${pkgs.openldap}/etc/schema/inetorgperson.ldif"
70
+
"${pkgs.openldap}/etc/schema/nis.ldif"
71
+
"${krbLdapSchema}"
72
+
];
73
+
"olcDatabase={0}config" = {
74
+
attrs = {
75
+
objectClass = [ "olcDatabaseConfig" ];
76
+
olcDatabase = "{0}config";
77
+
};
78
+
};
79
+
"olcDatabase={1}mdb" = {
80
+
attrs = {
81
+
objectClass = [
82
+
"olcDatabaseConfig"
83
+
"olcMdbConfig"
84
+
];
85
+
olcDatabase = "{1}mdb";
86
+
olcDbDirectory = "/var/lib/openldap/db";
87
+
olcSuffix = DITRoot;
88
+
olcRootDN = "cn=root,${DITRoot}";
89
+
olcRootPW = rootDnPwd;
90
+
# A tiny but realistic ACL
91
+
olcAccess = [
92
+
''
93
+
to attrs=userPassword
94
+
by anonymous auth
95
+
by * none''
96
+
''
97
+
to dn.subtree="cn=${realm},cn=realms,${DITRoot}"
98
+
by dn.exact="cn=kdc,${DITRoot}" write
99
+
by dn.exact="cn=kadmin,${DITRoot}" write
100
+
by * none''
101
+
''
102
+
to *
103
+
by * read''
104
+
];
105
+
};
106
+
};
107
+
};
108
+
};
109
+
};
110
+
111
+
services.kerberos_server = {
112
+
enable = true;
113
+
settings = {
114
+
libdefaults.default_realm = realm;
115
+
realms = {
116
+
"${realm}" = {
117
+
acl = [
118
+
{
119
+
principal = "admin";
120
+
access = "all";
121
+
}
122
+
];
123
+
};
124
+
};
125
+
dbmodules = {
126
+
"${realm}" = {
127
+
db_library = "kldap";
128
+
ldap_kerberos_container_dn = "cn=realms,${DITRoot}";
129
+
ldap_kdc_dn = "cn=kdc,${DITRoot}";
130
+
ldap_kadmind_dn = "cn=kadmin,${DITRoot}";
131
+
ldap_service_password_file = toString krbPwdStash;
132
+
ldap_servers = "ldapi:///";
133
+
};
134
+
};
135
+
};
136
+
};
137
+
138
+
security.krb5 = {
139
+
enable = true;
140
+
package = krb5Package;
141
+
settings = {
142
+
libdefaults = {
143
+
default_realm = realm;
144
+
};
145
+
realms = {
146
+
"${realm}" = {
147
+
admin_server = "machine";
148
+
kdc = "machine";
149
+
};
150
+
};
151
+
};
152
+
};
153
+
154
+
users.extraUsers.alice = {
155
+
isNormalUser = true;
156
+
};
157
+
};
158
+
159
+
testScript = ''
160
+
machine.wait_for_unit("openldap.service")
161
+
162
+
with subtest("realm container initialization"):
163
+
machine.succeed(
164
+
# Passing a master key directly avoids the need for a separate master key stash file
165
+
"kdb5_ldap_util -D cn=root,${DITRoot} create -w ${rootDnPwd} -s -P master_key",
166
+
)
167
+
168
+
# These units are bound to fail, as they are started before the directory service is ready
169
+
machine.execute("systemctl restart kadmind.service kdc.service")
170
+
171
+
with subtest("service bind"):
172
+
for unit in ["kadmind", "kdc"]:
173
+
machine.wait_for_unit(f"{unit}.service")
174
+
175
+
with subtest("administration principal initialization"):
176
+
machine.succeed("kadmin.local add_principal -pw admin_pw admin")
177
+
178
+
with subtest("user principal creation and kinit"):
179
+
machine.succeed(
180
+
"kadmin -p admin -w admin_pw addprinc -pw alice_pw alice",
181
+
"echo alice_pw | sudo -u alice kinit",
182
+
)
183
+
# Make extra sure that the user principal actually exists in the directory
184
+
machine.succeed(
185
+
"ldapsearch -x -D cn=root,${DITRoot} -w ${rootDnPwd} \
186
+
-b ${DITRoot} 'krbPrincipalName=alice@${realm}' | grep 'numEntries: 1'"
187
+
)
188
+
'';
189
+
190
+
meta.maintainers = [ pkgs.lib.maintainers.nessdoor ];
191
+
}
192
+
)