Navigation Menu

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/openldap: switch to slapd.d configuration with structured settings #94610

Merged
merged 13 commits into from Nov 21, 2020

Conversation

kwohlfahrt
Copy link
Contributor

Motivation for this change

The current configuration options are rather limited (without escaping from NixOS via configDir or extraConfig).

Second, the use of slapd.conf, which is what NixOS currently generates, is deprecated upstream. As a result, extraConfig is not a good long-term solution for complex configurations (and configDir completely removes the configuration from NixOS's control, so this is not a good solution either).

Things done
  • Add a structured services.openldap.settings, that mirrors the structure of OpenLDAP's configuration. This is used to generate an LDIF file to load and test the configuration at run-time.
  • Deprecate extraConfig and extraDatabaseConfig. This is deprecated upstream. Provide instructions to hopefully ease migration.
  • Deprecate the old top-level options, with instructions on how to translate them to the new settings. They could still be supported, but the current API is poor in some respects (e.g. support for only one database), so for now I've deprecated them pending discussion.
  • Use Type = forking, this way the service is not reported as up until it is ready to service requests.
  • Add myself as a maintainer. It's only fair I look after the damage I've done here 😛

This conflicts with #92544 (sorry!). I'm happy to add support for initial (as opposed to declarative) contents on top of this PR but haven't included that work here to keep the scope down a little.

  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@kwohlfahrt
Copy link
Contributor Author

kwohlfahrt commented Aug 3, 2020

I've removed the static UIDs/GIDs as suggested in NixOS/rfcs#52, I think this is backwards compatible.

DynamicUser should be possible with ExecStart = !slapd ... (we need root initially to open sockets) and continuing to rely on slapd to drop permissions. This would not be compatible with user-defined data directories, if people are OK with that I can work on implementing it.

@Mic92
Copy link
Member

Mic92 commented Aug 9, 2020

@GrahamcOfBorg eval

@Mic92
Copy link
Member

Mic92 commented Aug 9, 2020

@GrahamcOfBorg build openldap

@Mic92
Copy link
Member

Mic92 commented Aug 9, 2020

@GrahamcOfBorg test openldap

Copy link
Contributor Author

@kwohlfahrt kwohlfahrt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review, I've committed the suggestions.

I'm a bit confused about the grahamcofborg-eval failure (This PR does not cleanly list package outputs after merging.), with the error message:

nix-env failed:
warning: ignoring the user-specified setting 'restrict-eval', because it is a restricted setting and you are not a trusted user
error: stack overflow (possible infinite recursion)

I'm not sure what in this change triggers this, or what I can do to resolve it so advice is appreciated.

@Mic92
Copy link
Member

Mic92 commented Aug 9, 2020

Thanks for the review, I've committed the suggestions.

I'm a bit confused about the grahamcofborg-eval failure (This PR does not cleanly list package outputs after merging.), with the error message:

nix-env failed:
warning: ignoring the user-specified setting 'restrict-eval', because it is a restricted setting and you are not a trusted user
error: stack overflow (possible infinite recursion)

I'm not sure what in this change triggers this, or what I can do to resolve it so advice is appreciated.

I can reproduce this by building the manual:

$ nix-build nixos/release.nix -A manual
error: stack overflow (possible infinite recursion)

@kwohlfahrt
Copy link
Contributor Author

Ah, the reason seems to be here:

ldapAttrsType = types.submodule {
  children = mkOption {
    # If I replace this with just types.attrs, the error does not occur
    type = types.attrsOf ldapAttrsType;
  };
};

Is there a way to override the documentation type for this case, so it doesn't go into the infinite recursion here?

@Mic92
Copy link
Member

Mic92 commented Aug 11, 2020

Ah, the reason seems to be here:

ldapAttrsType = types.submodule {
  children = mkOption {
    # If I replace this with just types.attrs, the error does not occur
    type = types.attrsOf ldapAttrsType;
  };
};

Is there a way to override the documentation type for this case, so it doesn't go into the infinite recursion here?

Maybe lazyAttrsOf? https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/misc/home-assistant.nix#L106
Don't ask me what it does but it seems to support recursion. @infinisil might have better insights on this.

@kwohlfahrt
Copy link
Contributor Author

I think this is fixed now, by simply marking all options below the top-level of openldap.settings as visible = false. It's not super clean, but could be worse.

@kwohlfahrt kwohlfahrt requested a review from Mic92 August 15, 2020 19:40
@kwohlfahrt
Copy link
Contributor Author

kwohlfahrt commented Aug 15, 2020

I'm not sure why CI hasn't triggered yet... Nevermind, there it goes.

upstream. Please migrate to `services.openldap.settings`.

You can run:
slapcat -F ${configDir} -n0 -H 'ldap:///???(!(objectClass=olcSchemaConfig))'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get:

$ slapcat -F /etc/openldap/slapd.d -n0 -H 'ldap:///???(!(objectClass=olcSchemaConfig))'
5f395c1f invalid config directory /etc/openldap/slapd.d, error 2

I think we should include that you need to deploy your old configuration at least once before the directory is created?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using this configuration: https://github.com/Mic92/dotfiles/blob/master/nixos/eve/modules/openldap/default.nix#L19

it also seems to not pick up yet my schema:

● openldap.service - LDAP server
Loaded: loaded (/nix/store/a0vf2f37b63h1cziws81ml9f4m0v4cv2-unit-openldap.service/openldap.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Sun 2020-08-16 16:41:32 UTC; 6min ago
Process: 6127 ExecStartPre=/nix/store/0fyrxmxa7ibkca2b4n3pjwfr536n3579-unit-script-openldap-pre-start/bin/openldap-pre-start (code=exited, status=1/FAILURE)
IP: 0B in, 0B out
CPU: 36ms

Aug 16 16:41:32 eve systemd[1]: Starting LDAP server...
Aug 16 16:41:32 eve openldap-pre-start[6184]: config file testing succeeded
Aug 16 16:41:32 eve slaptest[6184]: DIGEST-MD5 common mech free
Aug 16 16:41:32 eve openldap-pre-start[6306]: 5f3961bc olcObjectClasses: value #0 olcObjectClasses: ObjectClass not found: "uidObject"
Aug 16 16:41:32 eve openldap-pre-start[6306]: 5f3961bc config error processing cn=config: olcObjectClasses: ObjectClass not found: "uidObject"
Aug 16 16:41:32 eve openldap-pre-start[6306]: slaptest: bad configuration directory!
Aug 16 16:41:32 eve systemd[1]: openldap.service: Control process exited, code=exited, status=1/FAILURE
Aug 16 16:41:32 eve systemd[1]: openldap.service: Failed with result 'exit-code'.
Aug 16 16:41:32 eve systemd[1]: Failed to start LDAP server.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should include that you need to deploy your old configuration at least once before the directory is created?

Yes, good point.

I'll check out the schema issue.

@kwohlfahrt kwohlfahrt force-pushed the openldap branch 2 times, most recently from e2dcd5b to be6963a Compare August 16, 2020 16:57
@Mic92
Copy link
Member

Mic92 commented Aug 16, 2020

Does it not include the schemas?

╭─[~/result]─joerg@eve
╰─ % sudo /nix/store/r5zff1swk044mjcx69k141i7f28rkn4s-openldap-2.4.50/bin/slaptest -f /nix/store/v1q6gl85rim8s9f1xbgna5h4yjkr35x3-slapd.conf -F /etc/openldap/slapd.d

config file testing succeeded

╭─[~/result]─joerg@eve
╰─ % sudo /nix/store/r5zff1swk044mjcx69k141i7f28rkn4s-openldap-2.4.50/bin/slaptest -u -F /etc/openldap/slapd.d
5f39668c olcObjectClasses: value #0 olcObjectClasses: ObjectClass not found: "uidObject"
5f39668c config error processing cn=config: olcObjectClasses: ObjectClass not found: "uidObject"
slaptest: bad configuration directory!

@Mic92
Copy link
Member

Mic92 commented Aug 16, 2020

I think the schemas are correctly included by openldap.
It is just my own schemas that need to be move first into the schema domain or they cannot pick up the included schemas.

config.ldif.txt

@kwohlfahrt
Copy link
Contributor Author

kwohlfahrt commented Aug 16, 2020

Hm, I'm surprised that this PR caused changes here. Could you post the shell commands to reproduce after deployment? I'm assuming something like:

slapadd -F /etc/openldap/slapd.d -n0 -l ./config.ldif.txt
slaptest -u -F /etc/openldap/slapd.d

Anything else? Are you using a declarativeContents?

Could you try loading your schema with extraConfig (i.e. include /path/to/my/mySchema.schema)? The conversion using slaptest should handle this.

@kwohlfahrt
Copy link
Contributor Author

OK, I think all comments are addressed. Overall, I think it might be nice to keep the top-level defaultSchemas option, specifying "cn=schema.includes" = [ ... ] is tedious, but on the other hand only needs to be done once per config. Yes/no?

I'd also like some way of defaulting olcDbDirectory so it doesn't have to be explicitly specified, but can't think of a sensible way of doing this. As pointed out earlier, some database types don't persist to disk at all, and we'd have to find a way to avoid conflicts when multiple databases are present. Any suggestions?

Apart from those two points, I think this is ready to go now.

The old slapd.conf is deprecated. Replace with slapd.d, and use this
opportunity to write some structured settings.

Incidentally, this fixes the fact that openldap is reported up before
any checks have completed, by using forking mode.
Adding by index could be an issue if the user wanted the data to be
added to a DB other than the first.
Instead of deprecating, as per PR feedback
This offers less helpful warnings, but makes the implementation
considerably more straightforward.
Use this as a test of the migration warnings/functionality.
@kwohlfahrt
Copy link
Contributor Author

@Mic92 and @infinisil, thanks for the review. I think I've addressed all of the comments here and resolved the merge conflict. Is there anything else here that requires more discussion/work?

@ajs124 ajs124 requested a review from dasJ November 21, 2020 17:11
@Mic92
Copy link
Member

Mic92 commented Nov 21, 2020

Thanks. This looks a lot better now: Mic92/dotfiles@d1eb62a

@Mic92 Mic92 merged commit 258903e into NixOS:master Nov 21, 2020
@kwohlfahrt kwohlfahrt deleted the openldap branch June 20, 2021 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants