-
Notifications
You must be signed in to change notification settings - Fork 13
Eel: host for kerberos kdc and ldap #326
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
base: main
Are you sure you want to change the base?
Changes from all commits
1c2ec9c
dc768aa
2eebbd3
a68f0db
9ebc0e5
ba0900a
52cd212
2c97b1f
3853184
bcf8783
0352865
9655a2e
19c6b9f
d51cb62
e6f69e8
c011087
20b3ffb
cc6cb22
93a6c6f
771b9f4
c4c61f8
153e62f
8389c23
b9e28cf
2ab8319
b74efb7
e36852b
00dd7dc
52ee4f5
9916dfb
d7516ec
a47d913
48d7103
0f074ef
c3d92d9
28ea16f
7cf9918
c9ab2dd
2ef45b7
adc9e86
e657c91
add6ed6
90e8ab0
59b721b
5ad2e2e
e1b0feb
0b25818
689d47c
cacf0c6
6862d74
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| { | ||
| pkgs, | ||
| lib, | ||
| config, | ||
| ... | ||
| }: | ||
|
|
||
| { | ||
| imports = [ ../../hardware/virtualized.nix ]; | ||
|
|
||
| networking.hostName = "eel"; | ||
|
|
||
| ocf.motd.description = '' | ||
| LDAP and Kerberos server; crucial to the rest of our infrastucture working. | ||
| ''; | ||
|
|
||
| ocf.network = { | ||
| enable = true; | ||
| lastOctet = 98; | ||
| }; | ||
|
|
||
| ocf.kerberosKdc.enable = true; | ||
| ocf.ldapServer.enable = true; | ||
|
|
||
| ocf.acme.extraCerts = [ | ||
| "ldap0.ocf.berkeley.edu" | ||
| "kdc.ocf.berkeley.edu" | ||
| ]; | ||
|
|
||
| system.stateVersion = "25.11"; | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this can be done natively with kerberos, and all clients can enforce passwords by writing to kerberos and handling the error + maybe parsing the policy to get the password requirements.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this does not need to be fixed now and is not a regression. will create an issue |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| #!/usr/bin/env python3 | ||
| """Enforce OCF account password complexity. | ||
|
|
||
| Designed to be used as an external password check program by Heimdal. Uses | ||
| ocflib to validate password strength with the same requirements as all other | ||
| password changing tools. | ||
|
|
||
| Details on interface Heimdal uses: | ||
| http://www.h5l.org/manual/HEAD/info/heimdal/Password-changing.html | ||
|
|
||
| Example usage: | ||
| $ echo -e "principal: ckuehl@OCF.BERKELEY.EDU\nnew-password: hello" | ./check-pass-strength | ||
|
|
||
| (ported directly from our old puppet module: https://github.com/ocf/puppet/blob/master/modules/ocf_kerberos/files/check-pass-strength) | ||
| """ | ||
| import sys | ||
|
|
||
| import ocflib.account.utils as utils | ||
| import ocflib.account.validators as validators | ||
|
|
||
|
|
||
| if __name__ == '__main__': | ||
| data = {} | ||
| while True: | ||
| line = sys.stdin.readline().rstrip('\n') | ||
| if line == 'end' or not line: | ||
| break | ||
| else: | ||
| line = line.split(':') | ||
| assert len(line) == 2, 'Could not parse input: ' + str(line) | ||
| data[line[0]] = line[1][1:] | ||
| try: | ||
| username = utils.extract_username_from_principal(data['principal']) | ||
| password = data['new-password'] | ||
| except (KeyError, ValueError): | ||
| print('Did not receive principal or password from input', file=sys.stderr) | ||
| sys.exit(1) | ||
| else: | ||
| try: | ||
| validators.validate_password(username, password) | ||
| except ValueError as e: | ||
| print(e, file=sys.stderr) | ||
| else: | ||
| print('APPROVED') |
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we are missing options specified in ocf/puppet. some might be default, but we should double check or specify anyway.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you moved |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| { | ||
| lib, | ||
| config, | ||
| pkgs, | ||
| ... | ||
| }: | ||
|
|
||
| let | ||
| cfg = config.ocf.kerberosKdc; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Kdc should be KDC but whatever lol |
||
|
|
||
| # check-pass-strength wrapped with a Python environment that has ocflib. | ||
| checkPassStrength = pkgs.writeShellScript "check-pass-strength" '' | ||
| exec ${pkgs.python312.withPackages (ps: [ ps.ocflib ])}/bin/python3 \ | ||
| ${./check-pass-strength.py} "$@" | ||
| ''; | ||
| in | ||
| { | ||
| options.ocf.kerberosKdc = { | ||
| enable = lib.mkEnableOption "OCF Kerberos KDC server (Heimdal)"; | ||
| }; | ||
|
|
||
| # The KDC database lives in /var/lib/heimdal/ and must be initialized manually: | ||
| # kadmin -l init OCF.BERKELEY.EDU | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i was going to say do this automatically, but i am leaning on letting it fail so that the person deploying knows that they have to either init an empty kdc or migrate. so i think this is ok 👍 |
||
| # For migration between hosts, dump with: kadmin -l dump <file> | ||
| # and restore with: kadmin -l load <file> | ||
|
|
||
| config = lib.mkIf cfg.enable { | ||
| services.kerberos_server = { | ||
| enable = true; | ||
| settings = { | ||
| kdc.extra-addresses = "127.0.0.2"; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this necessary |
||
| kdc.enable-fast = false; | ||
|
|
||
| realms."OCF.BERKELEY.EDU" = { | ||
| acl = [ | ||
| # Staff /admin principals have full KDC access | ||
| { | ||
| principal = "*/admin"; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we check if a wildcard like this is ok? ocf/puppet explicitly specifies each user's admin and root principal |
||
| access = [ "all" ]; | ||
| } | ||
| # Staff /root principals can change any principal's password | ||
| { | ||
| principal = "*/root"; | ||
| access = [ "cpw" ]; | ||
| target = "*@OCF.BERKELEY.EDU"; | ||
| } | ||
| # create/admin is used by account creation tooling (ocflib) | ||
| { | ||
| principal = "create/admin"; | ||
| access = [ | ||
| "add" | ||
| "get" | ||
| "cpw" | ||
| ]; | ||
| target = "*@OCF.BERKELEY.EDU"; | ||
| } | ||
| ]; | ||
| }; | ||
|
|
||
| # a wrapper for ocflib's `validate_password`. more complex than doing | ||
| # it natively, but good to standardize password requirements across | ||
| # ocf/utils and ocf/ocfweb. heimdal's external password checking like | ||
| # this might not be easily possible in MIT...? consider if migrating | ||
| # off of heimdal kerb. | ||
|
|
||
| password_quality = { | ||
| policies = "external-check"; | ||
| external_program = "${checkPassStrength}"; | ||
| }; | ||
| }; | ||
| }; | ||
|
|
||
| # KDC must start after slapd so SASL/GSSAPI is available for KDC → LDAP lookups | ||
| systemd.services.kdc.after = [ "openldap.service" ]; | ||
|
|
||
| environment.systemPackages = [ pkgs.heimdal ]; | ||
|
|
||
| networking.firewall = { | ||
| allowedTCPPorts = [ | ||
| 88 # kerberos | ||
| 749 # kadmin | ||
| ]; | ||
| allowedUDPPorts = [ | ||
| 88 # kerberos | ||
| 464 # kpasswd | ||
| ]; | ||
| }; | ||
|
|
||
| systemd.tmpfiles.rules = [ | ||
| "d /var/backups/kerberos 0700 root root -" | ||
| ]; | ||
|
|
||
| # unlike LDAP, not uploaded to github (for now?) | ||
| systemd.services.kerberos-git-backup = { | ||
| description = "Kerberos KDC git backup"; | ||
| after = [ "kdc.service" ]; | ||
| requires = [ "kdc.service" ]; | ||
| path = [ | ||
| pkgs.heimdal | ||
| pkgs.git | ||
| ]; | ||
| serviceConfig = { | ||
| Type = "oneshot"; | ||
| User = "root"; | ||
| UMask = "0077"; | ||
| }; | ||
| script = '' | ||
| dir=/var/backups/kerberos | ||
| [ -d "$dir/.git" ] || git -C "$dir" init -q | ||
| kadmin -l dump --decrypt "$dir/kerberos.dump" | ||
| git -C "$dir" add kerberos.dump | ||
| git -C "$dir" commit -q -m 'kerberos-git-backup' --allow-empty kerberos.dump | ||
| git -C "$dir" gc --auto --quiet | ||
| ''; | ||
| }; | ||
|
|
||
| systemd.timers.kerberos-git-backup = { | ||
| description = "Run Kerberos KDC git backup daily"; | ||
| wantedBy = [ "timers.target" ]; | ||
| timerConfig = { | ||
| # Run before rsnapshot so the backup server gets a fresh daily snapshot | ||
| OnCalendar = "*-*-* 01:00:00"; | ||
| Persistent = true; | ||
| }; | ||
| }; | ||
|
|
||
| }; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the
extraCertsurls should be passed into a url module options in the respective modules. this would enforce correct behavior as the modules would be able to require that certs are added forldaps://*to work properly. make sure that the module throws an error when it is enabled without adding a tls cert