https://bugs.openldap.org/show_bug.cgi?id=10065
Issue ID: 10065 Summary: slapd needs a config option for the ssf of an external security proxy using "proxy protocol v2" Product: OpenLDAP Version: unspecified Hardware: All OS: All Status: UNCONFIRMED Keywords: needs_review Severity: normal Priority: --- Component: slapd Assignee: bugs@openldap.org Reporter: sean@teletech.com.au Target Milestone: ---
Commit 146889f introduced support for the haproxy "proxy protocol v2". A very welcome addition that allows an external security layer to be implemented. This implementation is however somewhat hobbled.
Cyrus SASL uses "Security Strength Factors" or "ssf" to determine what Authentication mechanisms to offer. slapd conveys the implicit security of UNIX domain sockets to the SASL layer by specifying a non-zero ssf for these connections. This can be configured with the "olcLocalSSF" config setting.
For implicit/explicit TLS connections, the "olcSecurity: tls=<n>" provides the cryptographic strength of the TLS layer to the SASL layer.
For an external TLS-terminating proxy, there does not appear to be any way to inform Cyrus SASL of the presence of TLS security on these proxied connections.
The outcome of this is that PLAIN and EXTERNAL authentication mechanisms are not offered to clients connecting through the secure proxy.
This can be overcome by weakening the security properties of the SASL layer with the olcSaslSecProps configuration option, but this weakening will apply to all clients, not just clients connecting via the secure proxy.
What is required is some way to tell slapd and it's integrated SASL layer about the presence of TLS encryption on the proxy's input. As a precaution, this might be restricted to slapd connections in the 127.0.0.0/8 [IPv6:::] address ranges.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #1 from Quanah Gibson-Mount quanah@openldap.org --- Pretty much everything in this report is incorrect and is not how things function. I suggest reading the slapd.conf(5) man page in better detail.
I would note that the EXTERNAL SASL mechanism has nothing to do with cyrus-sasl.
An olcSecurity: tls=X would mandate TLS encryption on the connection, i.e., it would apply to simply binds as well as SASL mechanisms.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #2 from sean@teletech.com.au --- ** Motivation **
slapd employs a very fine-grained access permission model with many permission categories that can be applied down to the attribute level. This is complex code that presents a very large attack surface to the network. Additionally, specifying access rules is complex and error prone.
In many cases, the ldap server will have only a few fixed clients and a much more coarse-grained approach can be taken to access control. This does not prevent fine grained controls but rather, summarily denies access to actors without valid credentials. It also dramatically reduces the attack surface available to unauthenticated actors. It also benefits from the greater scrutiny of the TLS code in the proxy (that is used to provide TLS security to a wide range of applications).
** Use Case **
+-------------+ | LDAP client |--+ +-------------+ | | haproxy slapd +-------------+ | ldaps +---------+ pldap +-------------+ | LDAP client |--+--------| proxy |---------| LDAP server | +-------------+ | +---------+ 127/8 +-------------+ | +-------------+ | | LDAP client |--+ +-------------+
** Implementation considerations **
Normally LDAP servers will not allow plaintext logins over unencrypted channels. The LDAP clients would expect the "PLAIN" and "EXTERNAL" mechanisms to be available after authenticating with TLS to the LDAP proxy. In a naive arrangement, the LDAP server would be unaware of the security provided by the proxy and would therfore, NOT offer "PLAIN" and "EXTERNAL" mechanisms.
But slapd is NOT naive. It supports the haproxy "Proxy Protocol V2". This protocol allows the proxy to send information to slapd about the LDAP client that has connected. This information would normally include the client's IP protocol and IP address. It may also include details of the encryption used. See "proxy-protocol.txt" section 2.2.6. (See references)
The information about encryption may not always be available however, so static configuration of slapd may also be advantagious.
** Security Considerations **
Access to the "pldap" port of the slapd server must be secured at the network level. Anyone able to access this port could impersonate a valid user without having their credentials.
One way this may be achieved is by configuring slapd to listen on the "localhost" address. As external machines are forbidden by the operating system to access this address, this will immediately restrict access to processes running on the same machine.
Alternately, the connections may be carried over a UNIX domain IPC socket. This is not currently supported by slapd.
As a third alternative, the slapd <-> proxy link may itself be encrypted with TLS using the "pldaps" scheme. This would however, have the undesirable side effect of erasing the "authid" provided by the proxy's TLS layer.
** SLAPD CHANGES REQUIRED **
Slapd employs the Cyrus-sasl library to implement the SASL functions of the LDAP service. The decision on which authentication mechanisms to offer is taken by the Cyrus-sasl library based on information provided by the application (i.e. slapd). In particular, Cyrus-sasl will offer the "EXTERNAL" authentication mechanism if slapd passes it an "authid" and it will offer the "PLAIN" authentication mechanism if slapd informs it that the connection is encrypted (this can be overridden).
The "EXTERNAL" mechanism
By default, slapd does not construct an authid, and so "EXTERNAL" authentication will not be offered. For "ldapi" scheme connections, slapd constructs an authid based on the socket name and user id. For "ldaps" scheme connections, slapd constructs an authid based on the certificate subject DN. See https://openldap.org/doc/admin26/sasl.html section 15.2.4 In these two cases, the "EXTERNAL" mechanism will be offered. For "pldap" scheme connections, slapd does NOT construct an authid.
** THIS SHOULD BE CONFIGURABLE **
For "pldap" scheme connections, the "EXTERNAL" mechanism will NOT be offered.
The "PLAIN" mechanism
By default, slapd specifies a "Security Strength Factor" (ssf) of zero. This informs Cyrus-sasl that the connection is not encrypted and the "PLAIN" mechanism should not be offered. For "ldapi" scheme connections, slapd specifes an ssf of "olcLocalSSF" from it's configuration or 71 if "olcLocalSSF" has not been set. For "ldaps" scheme connections, slapd queries the TLS layer for the encryption strength and sets the ssf as reported by the TLS layer. In these two cases, the "PLAIN" mechanism will be offered. For "pldap" scheme connections, slapd specifies an ssf of zero.
** THIS SHOULD BE CONFIGURABLE **
For "pldap" scheme connections, the "PLAIN" mechanism will NOT be offered.
** Looking at the code **
Below is an analysis of pertinent lines in the slapd source. The line numbers were taken from the Github mirror "https://github.com/openldap/openldap/blob/master/" at the time of writing.
We see in daemon.c. line 2290 where the "Proxy Protocol V2" information gets decoded. It is at this point that a decision should be made about the security properties of the link between the LDAP client and the proxy. The "authid" and "ssf" local variables should be set to reflect the security provided by the external proxy.
Two approaches could be taken, either: 1) Additional TLS related information in the protocol packet could be decoded and an "authid" constructed with that information. The ssf could also be derived from the reported ciphers. 2) An "authid" could be constructed from the IP address. As the address has been securely bound to the authentication credentials by the proxy TLS layer, this should be safe. The ssf could be provided in the slapd configuration in a similar manner to olcLocalSSF. Eg "olcProxySSF" ??
Project: OpenLAP/slapd...
servers/slapd/daemon.c:2101: slap_listener() { servers/slapd/daemon.c:2109: slap_ssf_t ssf = 0; /* "PLAIN" is NOT offered by default */ servers/slapd/daemon.c:2109: struct berval authid = BER_BVNULL; /* "EXTERNAL" is NOT offered by default */
servers/slapd/daemon.c:2247: case AF_LOCAL: servers/slapd/daemon.c:2259: slap_ssf_t ssf = local_ssf; /* "PLAIN" IS offered on AF_LOCAL */ servers/slapd/daemon.c:2272 sprintf( authid.bv_val, ... ) /* "EXTERNAL" IS offered on AF_LOCAL */
servers/slapd/daemon.c:2288: case AF_INET: servers/slapd/daemon.c:2289: if ( sl->sl_is_proxied ) { servers/slapd/daemon.c:2290: proxyp() servers/slapd/daemon.c:????: ssf = **FIXME** /* "PLAIN" MAY be desired here */ servers/slapd/daemon.c:????: authid = **FIXME** /* "EXTERNAL" MAY be desired here */
servers/slapd/daemon.c:2364: connection_init(,,,,, ssf , authid ,); servers/slapd/connection.c:307: connection_init(,,,,, ssf , authid ,) { servers/slapd/connection.c:535: slap_sasl_external( , ssf , authid ); servers/slapd/sasl.c:1482: sasl_setprop(, SASL_SSF_EXTERNAL, &sasl_ssf );
/* "PLAIN" and "EXTERNAL" for TLS */ servers/slapd/connection.c:1342: if ( c->c_is_tls ) { servers/slapd/connection.c:1343: ldap_pvt_tls_accept(,) servers/slapd/connection.c:1367: c->c_tls_ssf = (slap_ssf_t) ldap_pvt_tls_get_strength( ssl ); libraries/libldap/tls_o.c:1018: SSL_CIPHER_get_bits(SSL_get_current_cipher(s), NULL); servers/slapd/connection.c:1383: slap_sasl_external(, c->c_tls_ssf, &authid); servers/slapd/sasl.c:1482: sasl_setprop(, SASL_SSF_EXTERNAL, &sasl_ssf );
servers/slapd/root_dse.c:334: supportedSASLMechanisms = slap_sasl_mechs( conn ); servers/slapd/sasl.c:1538: slap_sasl_mechs() { servers/slapd/sasl.c:1551: sasl_listmech()
** References **
RFC4512 / 5.1 Specifies the "root DSE" and in particular "supportedSASLMechanisms" RFC4513 Specifies LDAP's use of SASL RFC4422 Specifies SASL http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt Haproxy, "Proxy Protocol V2" specification https://openldap.org/doc/admin26/sasl.html section 15.2.4
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #3 from sean@teletech.com.au --- (In reply to Quanah Gibson-Mount from comment #1)
Pretty much everything in this report is incorrect and is not how things function. I suggest reading the slapd.conf(5) man page in better detail.
This is not helpful. I have put a lot of detail into the report. A little detail in the reply is not unreasonable. I reject the assertion that "everything" is incorrect.
I would note that the EXTERNAL SASL mechanism has nothing to do with cyrus-sasl.
cyrus-sasl decides if EXTERNAL will be offered. That's something.
An olcSecurity: tls=X would mandate TLS encryption on the connection, i.e., it would apply to simply binds as well as SASL mechanisms.
Yes, I didn't read that paragraph very carefully. I was trying to work out how slapd got the ssf for TLS and mistakenly thought that was it. I had to read the code more to find the calls to openssl. sorry.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #4 from Howard Chu hyc@openldap.org ---
The LDAP clients would expect the "PLAIN" and "EXTERNAL" mechanisms to be available after authenticating with TLS to the LDAP proxy.
LDAP clients do not use SASL/PLAIN. See RFC4513 section 5.2.1.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #5 from sean@teletech.com.au --- (In reply to Howard Chu from comment #4)
The LDAP clients would expect the "PLAIN" and "EXTERNAL" mechanisms to be available after authenticating with TLS to the LDAP proxy.
LDAP clients do not use SASL/PLAIN. See RFC4513 section 5.2.1.
"typically not used" is a long way from "SHALL NOT". For what it's worth, slapd DOES return PLAIN in the supportedSASLMechanisms when it is available.
In either case, I personally am more interested in EXTERNAL.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #6 from Quanah Gibson-Mount quanah@openldap.org --- Ok, I was incorrect about SASL/EXTERNAL although I swear I was told at one point it doesn't require cyrus-sasl (which IMHO would be rather nice).
Generally, the gist here is that it would be useful for the SASL SSF to be propagated through to the end slapd server when haproxy protocol v2 is enabled.
I'd also note we use SASL/PLAIN at my current job, so Howard's definitely incorrect.
openldap-its@openldap.org wrote:
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #6 from Quanah Gibson-Mount quanah@openldap.org --- Ok, I was incorrect about SASL/EXTERNAL although I swear I was told at one point it doesn't require cyrus-sasl (which IMHO would be rather nice).
Generally, the gist here is that it would be useful for the SASL SSF to be propagated through to the end slapd server when haproxy protocol v2 is enabled.
I'd also note we use SASL/PLAIN at my current job, so Howard's definitely incorrect.
By default, slapd disallows use of SASL/PLAIN. So either your current job isn't using OpenLDAP, or you've explicitly weakened its security properties in your config.
Regardless, support of SASL/PLAIN is certainly not a priority.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #7 from sean@teletech.com.au --- (In reply to Quanah Gibson-Mount from comment #6)
I was told at one point it doesn't require cyrus-sasl (which IMHO would be rather nice).
I have really only spoken about what slapd puts into it's "supportedSASLMechanisms" attribute. If the client is preconfigured to use a particular mechanism, it would probably not query the supportedSASLMechanisms value. If the client requests "EXTERNAL" without checking it's availability, authentication should still succeed - provided slapd has constructed an authid. But this interaction is still mediated by Cyrus-sasl. Indeed, it is SASL that defined the semantics of "EXTERNAL", it would be hard completely remove it. I suppose if the ONLY mechanisms supported were PLAIN and EXTERNAL, you could create a trivial SASL implementation and do without Cyrus-sasl. That might be a good way to reduce the attack surface, but a better way would be to put the TLS layer into a separate process. Back to idea of using an external proxy.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #8 from sean@teletech.com.au --- (In reply to sean from comment #7)
it would be hard completely remove it.
Thinking more about this. I see in RFC4513 Section 4: "Upon initial establishment of the LDAP session, the session has an anonymous authorization identity."
I also note that LDAPS has never been formally standardized. One can only speculate about allowing an initial (non-anonymous) identity by some future LDAPS standard. (RFC4513 specifies StartTLS and IPSEC, but not Implict TLS). I note from RFC4513 section 1 "LDAP may also be protected by means outside the LDAP protocol". They must have been aware of LDAPS and chosen not to include it for some reason.
Tangential... This continues a general preference seen in the RFC's towards explicit TLS. I personally consider "explicit TLS" to be a strategic mistake by the standards making bodies. Back in the day when they were thinking "We can't waste ports having a separate plain and encrypted port", they should have said security comes first! If people want unencrypted, they can negotiate a null cypher.
Back on topic... LDAP V3 does not require a "bind" operation. One could imagine a very nice and clean arrangement where a client connects with a client TLS certificate and immediately starts work (without the bind). The TLS server just taking the client's identity from the client's certificate. Unfortunately, just a pipe dream at the moment.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #9 from Ondřej Kuzník ondra@mistotebe.net --- On Mon, Jun 12, 2023 at 01:01:25AM +0000, openldap-its@openldap.org wrote:
I have really only spoken about what slapd puts into it's "supportedSASLMechanisms" attribute. If the client is preconfigured to use a particular mechanism, it would probably not query the supportedSASLMechanisms value. If the client requests "EXTERNAL" without checking it's availability, authentication should still succeed - provided slapd has constructed an authid.
Hi Sean, I think you're overcomplicating things. Trying to have clients that ignore the rootDSE isn't going to land well when it's possible to do things according to the protocol.
The relevant capabilities exist in the PROXY protocol already and somehow I can't see any reference to that in your analysis. Together with a wall of unnecessary text that is in part inflammatory that you just lob at the ticket, this didn't help[0].
Be straight to the point and sure, attach/reference things for people that want to read them if you think it's helpful but I'd always appreciate a TL;DR in that case.
But this interaction is still mediated by Cyrus-sasl. Indeed, it is SASL that defined the semantics of "EXTERNAL", it would be hard completely remove it. I suppose if the ONLY mechanisms supported were PLAIN and EXTERNAL, you could create a trivial SASL implementation and do without Cyrus-sasl. That might be a good way to reduce the attack surface, but a better way would be to put the TLS layer into a separate process. Back to idea of using an external proxy.
Even without a libsasl, EXTERNAL mechanism implementation is available in slapd. PLAIN isn't and won't as it requires decoding the SASL payload and a state machine.
You are welcome to implement relevant bits of the PROXY protocol to inject the reported authid/session existence into the connection when provided and post it for review. It might not be the easiest part of slapd to get started in but should be doable given you've looked into it already.
[0]. For one, the whole first paragraph painting ACLs as insecure while ignoring the fact that everything that you propose should be achievable with an ldaps:// listener that requires a client certificate to be provided at the time of TLS negotiation. That way it is the same gatekeeper to ACL machinery as your proxy would. That's not hard to audit, test or maintain, leaving ACLs to implement any remaining policy that would be there regardless.
Regards,
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #10 from sean@teletech.com.au ---
I think you're overcomplicating things. Trying to have clients that ignore the rootDSE isn't going to land well when it's possible to do things according to the protocol.
Firstly, this post was written in reply to Quanah Gibson-Mount who expressed an interest in removing the Cyrus-sasl dependency. I wrote this to explore the possibility. Personally, I have no problem with Cyrus SASL.
Secondly, My comments were based on the openLDAP clients. I have observed that if you specify a mechanism with the -Y switch, they do not do a query for the available mechanisms. If this behavior is non-standard, we all have a problem.
The relevant capabilities exist in the PROXY protocol already and somehow I can't see any reference to that in your analysis.
Yes I did mention it. << Additional TLS related information in the protocol packet could be decoded and an "authid" constructed with that information. The ssf could also be derived from the reported ciphers. >>
with a wall of unnecessary text that is in part inflammatory that you just lob at the ticket, this didn't help[0].
Sorry, I meant no offense. I wrote the "wall of unnecessary text" after my first post was completely misunderstood. Still, better to say too much than too little. I am not involved in the OpenLDAP project and don't know how things work around here. It seemed like something that should go in a bug report so that's what I did. Again - sorry.
Be straight to the point and sure, attach/reference things for people that want to read them if you think it's helpful but I'd always appreciate a TL;DR in that case.
Noted.
You are welcome to implement relevant bits of the PROXY protocol to inject the reported authid/session existence into the connection when provided and post it for review. It might not be the easiest part of slapd to get started in but should be doable given you've looked into it already.
I'll give it some thought but am seriously pressed for time at the moment.
[0]. For one, the whole first paragraph painting ACLs as insecure while ignoring the fact that everything that you propose should be achievable with an ldaps:// listener that requires a client certificate to be provided at the time of TLS negotiation. That way it is the same gatekeeper to ACL machinery as your proxy would. That's not hard to audit, test or maintain, leaving ACLs to implement any remaining policy that would be there regardless.
I'm sure that would work, because that is exactly how I have my system configured at the moment. I have four clients and slapd listens on four sockets and I can identify the client by the name of the socket. The proxy is still there mind you. The clients connect over TLS.
The drawback there was that olcAuthzRegexp works on DNs whereas the socket is distinguished by the peername or sockname. I can't rewrite the sockname to something more readable so the ruleset looks UGLY. Also, having one socket per client is not very scalable. Using the proxy protocol seemed to be a much better approach - until I found it's weakness.
Again - please do not take offense. In these situations, I always try to stay focused on what I am trying to achieve. I.e. better software for all.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #11 from Ondřej Kuzník ondra@mistotebe.net --- On Mon, Jun 12, 2023 at 11:00:29AM +0000, openldap-its@openldap.org wrote:
Secondly, My comments were based on the openLDAP clients. I have observed that if you specify a mechanism with the -Y switch, they do not do a query for the available mechanisms. If this behavior is non-standard, we all have a problem.
Right, I didn't notice. Still worth keeping slapd consistent in what gets exposed in rootDSE vs. what's accepted is what I meant. (Even our) clients are free to disregard at their own peril.
The relevant capabilities exist in the PROXY protocol already and somehow I can't see any reference to that in your analysis.
Yes I did mention it. << Additional TLS related information in the protocol packet could be decoded and an "authid" constructed with that information. The ssf could also be derived from the reported ciphers. >>
I must have misunderstood it, proposing that we just accept the certificate DN as the starting point, reading your suggestion as trying to construct it based on something like the reported IP address etc. (p.s.: and going by the below it seems I did read it correctly the first time?)
with a wall of unnecessary text that is in part inflammatory that you just lob at the ticket, this didn't help[0].
Sorry, I meant no offense. I wrote the "wall of unnecessary text" after my first post was completely misunderstood. Still, better to say too much than too little. I am not involved in the OpenLDAP project and don't know how things work around here. It seemed like something that should go in a bug report so that's what I did. Again - sorry.
No offense taken, just that that approach didn't make we *want* to take it seriously which might have happened with others reading this too.
You are welcome to implement relevant bits of the PROXY protocol to inject the reported authid/session existence into the connection when provided and post it for review. It might not be the easiest part of slapd to get started in but should be doable given you've looked into it already.
I'll give it some thought but am seriously pressed for time at the moment.
Sure, at the very least we have some analysis in place for whoever feels so inclined.
[0]. For one, the whole first paragraph painting ACLs as insecure while ignoring the fact that everything that you propose should be achievable with an ldaps:// listener that requires a client certificate to be provided at the time of TLS negotiation. That way it is the same gatekeeper to ACL machinery as your proxy would. That's not hard to audit, test or maintain, leaving ACLs to implement any remaining policy that would be there regardless.
I'm sure that would work, because that is exactly how I have my system configured at the moment. I have four clients and slapd listens on four sockets and I can identify the client by the name of the socket. The proxy is still there mind you. The clients connect over TLS.
The drawback there was that olcAuthzRegexp works on DNs whereas the socket is distinguished by the peername or sockname. I can't rewrite the sockname to something more readable so the ruleset looks UGLY. Also, having one socket per client is not very scalable. Using the proxy protocol seemed to be a much better approach - until I found it's weakness.
Wait a minute, so are you using the DN or identity of the sockname? You can always prepend a few ACL rules to screen clients accordingly, but using sockname to distinguish clients probably isn't the best idea. You might be better off running several servers each dedicated to its network if network identity is the only way you can distinguish them.
I don't think encoding the reported sockname to authzid when accepting a connection on ldapp:// would be accepted. You might be better off just writing an ACI module there.
Again - please do not take offense. In these situations, I always try to stay focused on what I am trying to achieve. I.e. better software for all.
All is well.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #12 from sean@teletech.com.au --- (In reply to Ondřej Kuzník from comment #11)
On Mon, Jun 12, 2023 at 11:00:29AM +0000, openldap-its@openldap.org wrote:
Wait a minute, so are you using the DN or identity of the sockname?
All the sockets have the same DN because they all come form haproxy and so, identify the haproxy uid. the sockname is the only thing I can use.
can always prepend a few ACL rules to screen clients accordingly, but using sockname to distinguish clients probably isn't the best idea. You
Yeah, it feels like a kludge - but it works. It didn't sit well with me relying of the ACLs to deny access, attribute by attribute to a potential bad actor. It's like letting criminals into the building because you are "pretty sure" all the filing cabinets are locked.
might be better off running several servers each dedicated to its network if network identity is the only way you can distinguish them.
Well, I wanted to use the TLS client certificate to distinguish them. This is what I do in the haproxy ruleset. I also enforce the IP address but the certificate is much stronger authentication.
I don't think encoding the reported sockname to authzid when accepting a connection on ldapp:// would be accepted.
I wouldn't even suggest it. I would have preferred to run proxy protocol over an IPC socket but that wasn't supported and I didn't want to court controversy by suggesting it should be, so I tried a TCP socket listening on localhost. It's reasonably efficient and reasonably secure.
But all things considered, it seems to me, the best path forward is to decode the TLS information passed from haproxy and if possible, construct an authid in the same form as that constructed for non-proxied TLS connections.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #13 from Ondřej Kuzník ondra@mistotebe.net --- On Mon, Jun 12, 2023 at 12:33:49PM +0000, openldap-its@openldap.org wrote:
Wait a minute, so are you using the DN or identity of the sockname?
All the sockets have the same DN because they all come form haproxy and so, identify the haproxy uid. the sockname is the only thing I can use.
can always prepend a few ACL rules to screen clients accordingly, but using sockname to distinguish clients probably isn't the best idea. You
Yeah, it feels like a kludge - but it works. It didn't sit well with me relying of the ACLs to deny access, attribute by attribute to a potential bad actor. It's like letting criminals into the building because you are "pretty sure" all the filing cabinets are locked.
You can always make this the first ACL in the list (in your analogy, putting a security guard/gate that checks people even get access to the building):
access to * by <your allowlist expressed as peername/sockname> break by * none
That is what I meant by "easy to manage, test and audit" as no further ACL processing (potentially granting access) is done for your potential bad actors.
might be better off running several servers each dedicated to its network if network identity is the only way you can distinguish them.
Well, I wanted to use the TLS client certificate to distinguish them. This is what I do in the haproxy ruleset. I also enforce the IP address but the certificate is much stronger authentication.
I think we're on the same page now, you want to use the DN of the client certificate but can't (yet) and propose acting on the PP2_SUBTYPE_SSL* TLVs, at the very least PP2_TYPE_SSL and PP2_SUBTYPE_SSL_CN.
Except that rereading the spec, we don't actually get to see the whole DN, just the CN part so that is not viable unless a new field were defined for it.
I don't think encoding the reported sockname to authzid when accepting a connection on ldapp:// would be accepted.
I wouldn't even suggest it. I would have preferred to run proxy protocol over an IPC socket but that wasn't supported and I didn't want to court controversy by suggesting it should be, so I tried a TCP socket listening on localhost. It's reasonably efficient and reasonably secure.
But all things considered, it seems to me, the best path forward is to decode the TLS information passed from haproxy and if possible, construct an authid in the same form as that constructed for non-proxied TLS connections.
What is preventing you from exposing slapd to your clients directly?
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #14 from sean@teletech.com.au --- (In reply to Ondřej Kuzník from comment #13)
On Mon, Jun 12, 2023 at 12:33:49PM +0000, openldap-its@openldap.org wrote:
You can always make this the first ACL in the list (in your analogy, putting a security guard/gate that checks people even get access to the building):
access to * by <your allowlist expressed as peername/sockname> break by * none
An awful lot of lines of code need to run to parse and interpret the ruleset, and parse and interpret LDAP commands, seems how the ruleset isn't applied until it is presented with a command. I'm not saying there IS anything wrong with that code, I just don't know. And I have the option of putting a proxy in front of it and then I can sleep better.
I think we're on the same page now, you want to use the DN of the client certificate but can't (yet) and propose acting on the PP2_SUBTYPE_SSL* TLVs, at the very least PP2_TYPE_SSL and PP2_SUBTYPE_SSL_CN.
Exactly.
Except that rereading the spec, we don't actually get to see the whole DN, just the CN part so that is not viable unless a new field were defined for it.
Yeah, I was worried about that too. Luckily for me at least, My client certificate's DN's only have a single CN - so no information lost. I'm sure this is not true in general. But so long as the CN's are unique, I could use the DN rewriting to fill in all the missing RDNs.
What is preventing you from exposing slapd to your clients directly?
I just couldn't convince myself that it would be sufficiently secure. Too many things have to just right, and I don't trust myself that much.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #15 from Ondřej Kuzník ondra@mistotebe.net --- On Mon, Jun 12, 2023 at 01:15:21PM +0000, openldap-its@openldap.org wrote:
You can always make this the first ACL in the list (in your analogy, putting a security guard/gate that checks people even get access to the building):
access to * by <your allowlist expressed as peername/sockname> break by * none
An awful lot of lines of code need to run to parse and interpret the ruleset, and parse and interpret LDAP commands, seems how the ruleset isn't applied until it is presented with a command. I'm not saying there IS anything wrong with that code, I just don't know. And I have the option of putting a proxy in front of it and then I can sleep better.
Slightly off-topic but if you configure ldaps:// and *require* client certs, the session won't get set up to the point of touching anything LDAP related until the client's proved it holds a certificate you trust.
That's more or less what you're using haproxy for? If so, I think you're in the clear even if you don't wish to trust the ACL machinery is being completely and consistently enforced.
Except that rereading the spec, we don't actually get to see the whole DN, just the CN part so that is not viable unless a new field were defined for it.
Yeah, I was worried about that too. Luckily for me at least, My client certificate's DN's only have a single CN - so no information lost. I'm sure this is not true in general. But so long as the CN's are unique, I could use the DN rewriting to fill in all the missing RDNs.
Well, that by itself doesn't sound like enough for the OpenLDAP side, hence the need for a new field.
https://bugs.openldap.org/show_bug.cgi?id=10065
Quanah Gibson-Mount quanah@openldap.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords|needs_review | Target Milestone|--- |2.7.0
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #16 from sean@teletech.com.au --- (In reply to Ondřej Kuzník from comment #15)
On Mon, Jun 12, 2023 at 01:15:21PM +0000, openldap-its@openldap.org wrote:
Slightly off-topic but if you configure ldaps:// and *require* client certs, the session won't get set up to the point of touching anything LDAP related until the client's proved it holds a certificate you trust.
That's only true to a point. The client only needs to hold a certificate from a CA that I trust. The name on the certificate is validated with the ruleset. CAs issues many certificates, even to people with bad intentions.
Well, that by itself doesn't sound like enough for the OpenLDAP side, hence the need for a new field.
I suspect haproxy was looking at the size of the proxy-protocol packet when they decided not to give the full DN. The protocol packet really needs to fit in a single network packet. That might actually end up being a show stopper.
And I still haven't looked at what haproxy _actually_ provides. Just because they put it in the spec doesn't mean they have implemented it.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #17 from sean@teletech.com.au --- This is looking much more complex than what I first envisioned. When I first lodged this report I thought it was the ssf that governed the EXTERNAL mechanism and that getting it to work would be as simple as plugging in an ssf for the proxy. I see now that won't work. the authid is what is needed.
Coming back to
What is preventing you from exposing slapd to your clients directly?
If there was a simple qualification check that was applied to the authid immediately after it was created, and the connection closed immediately if it failed, I would happily do away with the proxy.
Something like
olcAuthzQualifyRegExp: <match> [ACCEPT|REJECT]
This seemed like a much bigger ask at the time. Now I'm not so sure.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #18 from Ondřej Kuzník ondra@mistotebe.net --- On Mon, Jun 12, 2023 at 09:06:16PM +0000, openldap-its@openldap.org wrote:
Slightly off-topic but if you configure ldaps:// and *require* client certs, the session won't get set up to the point of touching anything LDAP related until the client's proved it holds a certificate you trust.
That's only true to a point. The client only needs to hold a certificate from a CA that I trust. The name on the certificate is validated with the ruleset. CAs issues many certificates, even to people with bad intentions.
You choose what CAs are trusted to issue client certificates and this is independent from the CAs you trust for server certs. Could that be the trust anchor you're missing?
I suspect haproxy was looking at the size of the proxy-protocol packet when they decided not to give the full DN. The protocol packet really needs to fit in a single network packet. That might actually end up being a show stopper.
They probably were and that would be an implementation concern but I think they only ask for the initial part to be in the first packet.
Implementation in slapd might have to be stricter on this point and I would have highlighted it once it came to an implementation. Lloadd's connection set up is more flexible and permits even this part of connection establishment to be async.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #19 from Ondřej Kuzník ondra@mistotebe.net --- On Mon, Jun 12, 2023 at 10:52:56PM +0000, openldap-its@openldap.org wrote:
If there was a simple qualification check that was applied to the authid immediately after it was created, and the connection closed immediately if it failed, I would happily do away with the proxy.
Something like
olcAuthzQualifyRegExp: <match> [ACCEPT|REJECT]
This seemed like a much bigger ask at the time. Now I'm not so sure.
If you can rework e.g. olcAuthzRegexp to give you this power, I've seen other people calling for a similar feature. However no ideas yet on my part how to achieve this.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #20 from sean@teletech.com.au --- (In reply to Ondřej Kuzník from comment #18)
You choose what CAs are trusted to issue client certificates and this is independent from the CAs you trust for server certs. Could that be the trust anchor you're missing?
Yeah, I understand that - and I don't use the ca bundle for that very reason, just the single CA that I need to validate my clients, but it still isn't a very exclusive club. That CA is Let's Encrypt.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #21 from Howard Chu hyc@openldap.org --- (In reply to sean from comment #20)
(In reply to Ondřej Kuzník from comment #18)
You choose what CAs are trusted to issue client certificates and this is independent from the CAs you trust for server certs. Could that be the trust anchor you're missing?
Yeah, I understand that - and I don't use the ca bundle for that very reason, just the single CA that I need to validate my clients, but it still isn't a very exclusive club. That CA is Let's Encrypt.
Use slapo-autoca to create your own CA cert to manage your client certs.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #22 from sean@teletech.com.au --- (In reply to Howard Chu from comment #21)
Use slapo-autoca to create your own CA cert to manage your client certs.
I wasn't aware you had your own CA infrastructure. Thanks for bringing it up. It certainly deserves a mention in this context. I actually already have a private CA which I could use for LDAP, but I wanted my clients to have public CA certs on their front-facing ports. I could use private CA certs for the back facing ports but I think it's easier to just have the proxy.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #23 from Ondřej Kuzník ondra@mistotebe.net --- On Tue, Jun 13, 2023 at 10:08:28PM +0000, openldap-its@openldap.org wrote:
Use slapo-autoca to create your own CA cert to manage your client certs.
I wasn't aware you had your own CA infrastructure. Thanks for bringing it up. It certainly deserves a mention in this context. I actually already have a private CA which I could use for LDAP, but I wanted my clients to have public CA certs on their front-facing ports. I could use private CA certs for the back facing ports but I think it's easier to just have the proxy.
Why do you need the same certificate for someone's inbound traffic and the one they use to identify themselves to OpenLDAP (client certificate)?
BTW we should move this part of the discussion to -technical.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #24 from sean@teletech.com.au --- (In reply to Ondřej Kuzník from comment #23)
Why do you need the same certificate for someone's inbound traffic and the one they use to identify themselves to OpenLDAP (client certificate)?
Not some-one, some-thing. My client certs are regular machine certs. Actual account authentication is done with passwords (stored in the LDAP database). The public CA certs are for machines that commodity user agents connect to. They are public CA certs so I don't have to install the private root CA all over the place. So the machines have a certificate to identify themselves with, just sitting there, why not use it to authenticate with LDAP.
I don't _need_ to use the same certs in both directions but if I have to choose between running a proxy and running a private CA, I'll run the proxy.
BTW we should move this part of the discussion to -technical.
How? I'm not on any mailing list.
https://bugs.openldap.org/show_bug.cgi?id=10065
--- Comment #25 from Quanah Gibson-Mount quanah@openldap.org --- (In reply to sean from comment #24)
How? I'm not on any mailing list.
https://lists.openldap.org as noted on the front page of the https://www.openldap.org website under Support -> Mailing lists.
https://bugs.openldap.org/show_bug.cgi?id=10065
Quanah Gibson-Mount quanah@openldap.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|2.7.0 |--- Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID
https://bugs.openldap.org/show_bug.cgi?id=10065
Quanah Gibson-Mount quanah@openldap.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |VERIFIED