I'd like to propose a new feature to substantially strengthen the existing access controls in slapd. This follows on from comments made in the discussion around Issue 10065. In particular Comment 17 and Comment 19.
The objective here is to validate the credentials supplied by external security mechanisms BEFORE the main server loop starts, and terminate the connection if the client is not "known".
It was noted that the olcAuthzRegexp configuration option already deals with externally supplied Authentication ID. My idea is to build on that.
I propose a new flag for "olcDisallows" that is "unmatched_external_authid".
Setting this flag would instruct slapd to drop the connection if the externally supplied authid did not match any of the olcAuthzRegexp rules.
Currently the olcAuthzRegexp rules are only applied after a command arrives. My proposal does not change that, instead I propose that olcAuthzRegexp be evaluated at "connection time" as well as at "execution time". This would reduce the chance of any unexpected side effects.
The only real issue I can think of is - is it possible for olcAuthzRegexp to match an AuthID without changing it. Is there any recursion in the application of these rules?
Any thoughts?
On Thu, Jun 15, 2023 at 08:23:07AM +1000, Sean Gallagher wrote:
I'd like to propose a new feature to substantially strengthen the existing access controls in slapd. This follows on from comments made in the discussion around Issue 10065. In particular Comment 17 and Comment 19.
The objective here is to validate the credentials supplied by external security mechanisms BEFORE the main server loop starts, and terminate the connection if the client is not "known".
It was noted that the olcAuthzRegexp configuration option already deals with externally supplied Authentication ID. My idea is to build on that.
Hi Sean, olcAuthzRegexp deals with Bind requests only.
Any thoughts?
By the sounds of it, you want to react to a connection being established. There's already a callback for this: bi_connection_init, so you can write your own module/overlay/etc. that would quarantine it until it was set up or find another hook that is closer to that.
We might have to delay calling backend_connection_init() while c_needs_tls_accept is set. Or maybe add another callback for this, any thoughts on that Howard?
Regards,
It seems there is no interest in this. That's disappointing but not unexpected. Personally, I find it reckless that slapd would accept and process packets from parties that would happily take a flame thrower to your server if it got them any advantage.
I would strongly encourage the OpenLDAP team to properly validate PKI client certificates and CLOSE THE CONNECTION if the client fails authentication.
I have made one proposal about how to add this functionality but I'm sure there are many ways to approach it.
In the mean time, I will continue using the proxy in front of slapd and would strongly recommend anyone using client certs for authentication without a dedicated CA to do the same.
In all other repects,
thanks for a great product.
Sean.
Sean Gallagher wrote:
It seems there is no interest in this. That's disappointing but not unexpected. Personally, I find it reckless that slapd would accept and process packets from parties that would happily take a flame thrower to your server if it got them any advantage.
I would strongly encourage the OpenLDAP team to properly validate PKI client certificates and CLOSE THE CONNECTION if the client fails authentication.
That feature is already available using TLSVerifyClient in the slapd config.
I have made one proposal about how to add this functionality but I'm sure there are many ways to approach it.
In the mean time, I will continue using the proxy in front of slapd and would strongly recommend anyone using client certs for authentication without a dedicated CA to do the same.
Pure nonsense.
In all other repects,
thanks for a great product.
Sean.
On 26/06/2023 7:40 pm, Howard Chu wrote:
That feature is already available using TLSVerifyClient in the slapd config.
Not really. Using the TLSVerifyClient mechanism could be made to work and would be a nice solution but it isn't there yet. To make this this work, you would need to pass to libldap, some type of specification of the names of legitimate clients. Then in the tls_o.c:tlso_verify_cb() function, compare the name on the client cert with the specification and return the pass/fail status back to the TLS layer. Then it would all "just work".
The average user might be surprised to learn that TLSVerifyClient does not currently involve checking the client's name. You would intuitively think that was pretty important.
Pure nonsense.
Pure hubris.
It's sad when it takes a disaster to affect real change.
TLDR: Ignore this post if you are using a private certificate authority to issue your client certificates - as is commonly done and recommended.
On 15/06/2023 8:23 am, Sean Gallagher wrote:
I'd like to propose a new feature to substantially strengthen the existing access controls in slapd. This follows on from comments made in the discussion around Issue 10065. In particular Comment 17 and Comment 19.
The objective here is to validate the credentials supplied by external security mechanisms BEFORE the main server loop starts, and terminate the connection if the client is not "known".
If the reader has been following along on this discussion and is considering installing a proxy in front of their slapd instance but is not sure how, I have posted here a genericised version of my haproxy.cfg file. This does more than is strictly necessary. I have precisely no expertise in haproxy and make no warranties about this whatsoever but if you find it useful, that's great. If you have questions, I'm not the one to answer them. I suggest a haproxy user's forum. Comments on improvements are welcome.
I have set up slapd to listen on unix domain sockets, so I can identify which client I am talking to in the ACL ruleset. This is an ugly implementation but works. It may be possible to configure haproxy to re-use the client's certificate presented to the front end, again on the back end. This would undoubtedly lead to a cleaner ruleset - but is not what I have done, simply because I don't know how.
The slapd.conf ACL rules look like this:
access to * by dn.base="cn=managersock,dc=example,dc=com" manage stop by * sockname.exact="PATH=/var/run/openldap/c1.sock" none break by * sockname.exact="PATH=/var/run/openldap/c2.sock" none break by * sockname.exact="PATH=/var/run/openldap/c3.sock" none break by * sockname.exact="PATH=/var/run/openldap/c4.sock" none break
The haproxy.cfg file
global # pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon
# turn on stats unix socket stats socket /var/lib/haproxy/stats #log /dev/log local0 warning log /dev/log local0 debug
ssl-default-bind-options ssl-min-ver TLSv1.2 ssl-default-bind-options ssl-max-ver TLSv1.3 ssl-dh-param-file /etc/ssl/private/dhparam
defaults mode tcp log global retries 3 timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout check 10s maxconn 3000
frontend main option tcplog bind ipv4@10.0.0.10:636 ssl verify required ciphers DHE-RSA-AES256-GCM-SHA384 ciphersuites TLS_AES_256_GCM_SHA384 ca-verify-file /etc/ssl/select_ca_ldapclients.pem crt /etc/ssl/ttldap.example.com.crt
tcp-request inspect-delay 2s tcp-request content accept if { req.ssl_hello_type 1 }
acl c1_sip src 10.0.0.1 acl c1_sdn ssl_c_s_dn -m str "/CN=client1.example.com" acl c1_idn ssl_c_i_dn -m str "/C=US/O=Let's Encrypt/CN=R3" acl c1_sni ssl_fc_sni -m str "ldap.example.com"
acl c2_sip src 10.0.0.2 acl c2_sdn ssl_c_s_dn -m str "/CN=client2.example.com" acl c2_idn ssl_c_i_dn -m str "/C=US/O=Let's Encrypt/CN=R3" acl c2_sni ssl_fc_sni -m str "ldap.example.com"
acl c3_sip src 10.0.0.3 acl c3_sdn ssl_c_s_dn -m str "/CN=client3.example.com" acl c3_idn ssl_c_i_dn -m str "/C=US/O=Let's Encrypt/CN=R3" acl c3_sni ssl_fc_sni -m str "ldap.example.com"
acl c4_sip src 10.0.0.4 acl c4_sdn ssl_c_s_dn -m str "/CN=client4.example.com" acl c4_idn ssl_c_i_dn -m str "/C=US/O=Let's Encrypt/CN=R3" acl c4_sni ssl_fc_sni -m str "ldap.example.com"
use_backend c1_be if c1_sip c1_sdn c1_idn c1_sni use_backend c2_be if c2_sip c2_sdn c2_idn c2_sni use_backend c3_be if c3_sip c3_sdn c3_idn c3_sni use_backend c4_be if c4_sip c4_sdn c4_idn c4_sni
backend c1_be server smtps unix@/var/run/openldap/c1.sock
backend c2_be server pwgui unix@/var/run/openldap/c2.sock
backend c3_be server imaps unix@/var/run/openldap/c3.sock
backend c4_be server samba unix@/var/run/openldap/c4.sock
Sean.
openldap-technical@openldap.org