Hi,
I'm tying achieve the following with OpenLDAP RE24 from last week:
Connections on ldapi:/// are plain text and ldap connections require TLS with client cert auth. I thought I could do that with:
# global configuration settings dn: cn=config objectClass: olcGlobal cn: config olcArgsFile: /var/run/openldap34/slapd34.args olcPidFile: /var/run/openldap34/slapd34.pid olcLogFile: /var/log/openldap34/slapd34.log olcLogLevel: -1 olcTLSCACertificateFile: /etc/pki/tls/certs/ca.crt olcTLSCertificateFile: /etc/pki/tls/certs/server.crt olcTLSCertificateKeyFile: /etc/pki/tls/private/server.key olcTLSCipherSuite: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH olcTLSVerifyClient: demand <--- olcLocalSSF: 0 <--- olcSecurity: tls=256 <---
Since I'm seeing the error below clearly I thought wrong:
5121a107 >>> slap_listener(ldapi:///) 5121a107 daemon: listen=11, new connection on 15 5121a107 daemon: added 15r (active) listener=(nil) 5121a107 conn=1009 fd=15 ACCEPT from PATH=/var/run/ldapi (PATH=/var/run/ldapi) [snip] 5121a107 conn=1009 op=0 BIND dn="cn=ReadOnly,dc=example,dc=com" method=128 5121a107 do_bind: version=3 dn="cn=ReadOnly,dc=example,dc=com" method=128 5121a107 send_ldap_result: conn=1009 op=0 p=3 5121a107 send_ldap_result: err=13 matched="" text="TLS confidentiality required" [snip] 5121a107 conn=1009 op=0 RESULT tag=97 err=13 text=TLS confidentiality required
Anyone have an idea how I can achieve my goal?
Thanks! Patrick
On Mon, 18 Feb 2013, Patrick Lists wrote:
I'm tying achieve the following with OpenLDAP RE24 from last week:
Connections on ldapi:/// are plain text and ldap connections require TLS with client cert auth.
Perhaps it would be help if you started by answering, at least for yourself, what problem you're trying to solve. For example, "prevent passwords from being sent on physical networks in the clear or under a symmetric cipher of fewer than 256bits"
(I use that example because it's a plausible match for what you describe...and it's impossible to achieve.)
Until you describe *why* you're doing something, you can't know whether you're actually acheiving it.
I thought I could do that with:
...
olcLocalSSF: 0 <---
So, you've told slapd that ldapi:// connections are to be treated as completely insecure, like ldap:// conections without TLS. That doesn't seem to match your intention.
olcSecurity: tls=256 <---
To quote slapd-config(5): olcSecurity: <factors> Specify a set of security strength factors (separated by white space) to require (see olcSaslSecprops's minssf option for a description of security strength factors). The directive may be specified globally and/or per-database. ... tls=<n> specifies the TLS security strength factor.
So, this tells slapd to require *ALL* connections, regardless of how they connect, to use SSL/TLS with an SSF of at least 256. That clearly doesn't match your intention.
My guess, not knowing your actual _purpose_, would be you want to require a minssf of some 256, and give local (ldapi://) connetions that same SSF.
Of course, that doesn't stop a client from connecting and sending a BIND request in cleartext. It won't succeed, but it'll still go out in cleartext.
Philip Guenther
Thank you for your feedback Philip. Comments inline.
On 02/18/2013 07:16 AM, Philip Guenther wrote:
On Mon, 18 Feb 2013, Patrick Lists wrote:
I'm tying achieve the following with OpenLDAP RE24 from last week:
Connections on ldapi:/// are plain text and ldap connections require TLS with client cert auth.
Perhaps it would be help if you started by answering, at least for yourself, what problem you're trying to solve. For example, "prevent passwords from being sent on physical networks in the clear or under a symmetric cipher of fewer than 256bits"
The problem is that there is an application (running on the same box as the LDAP server) which does not support client certificate authentication yet it needs read-only access to the LDAP server. So I thought I give that app access via a socket and secure the rest with TLS + olcTLSVerifyClient: demand. If there is a better way to solve this then I am all ears.
I tried to figure out how to allow the app and clients access to localhost without TLS and the rest with TLS + client cert auth using what seems the only example in existence:
# first, make sure TLS or localhost access to * by tls_ssf=1 none break by peername.ip="127.0.0.1" none break by * none
# "real" ACL(s) go here
But that did not work and the why this should work (assuming the example is correct) eludes me, with the guide and man pages being of little help as I'm no software developer nor do I have Einstein's brainpower :-)
[snip]
Until you describe *why* you're doing something, you can't know whether you're actually acheiving it.
See problem description above.
I thought I could do that with:
...
olcLocalSSF: 0 <---
So, you've told slapd that ldapi:// connections are to be treated as completely insecure, like ldap:// conections without TLS. That doesn't seem to match your intention.
It does. Insecure socket access for the app which does not support client cert auth and TLS+client cert auth for access via ldap/ldaps.
olcSecurity: tls=256 <---
To quote slapd-config(5): olcSecurity: <factors> Specify a set of security strength factors (separated by white space) to require (see olcSaslSecprops's minssf option for a description of security strength factors). The directive may be specified globally and/or per-database. ... tls=<n> specifies the TLS security strength factor.
So, this tells slapd to require *ALL* connections, regardless of how they connect, to use SSL/TLS with an SSF of at least 256. That clearly doesn't match your intention.
Thank you for that explanation. It would have been nice if that section mentioned that it applies to *all* connections with no exceptions and no matter what else I might have configured. At least I learned something :-)
My guess, not knowing your actual _purpose_, would be you want to require a minssf of some 256, and give local (ldapi://) connetions that same SSF.
Hopefully my intentions are clear from what I described above: TLS (256) with client cert auth on anything but ldapi so I can give the locally running app access to the LDAP server via a socket.
Of course, that doesn't stop a client from connecting and sending a BIND request in cleartext. It won't succeed, but it'll still go out in cleartext.
That's clear. Access to the box is only possible via a VPN and there's no pubic access to the LDAP server.
Regards, Patrick
On Mon, 18 Feb 2013, Patrick Lists wrote:
On 02/18/2013 07:16 AM, Philip Guenther wrote:
On Mon, 18 Feb 2013, Patrick Lists wrote:
I'm tying achieve the following with OpenLDAP RE24 from last week:
Connections on ldapi:/// are plain text and ldap connections require TLS with client cert auth.
Perhaps it would be help if you started by answering, at least for yourself, what problem you're trying to solve. For example, "prevent passwords from being sent on physical networks in the clear or under a symmetric cipher of fewer than 256bits"
The problem is that there is an application (running on the same box as the LDAP server) which does not support client certificate authentication yet it needs read-only access to the LDAP server.
That's the situation, but that's not a problem unless you have some sort of security requirement. So, what's the security requirement? I can imagine it being something like:
"We need to protect corporate data in LDAP from being modified or even accessed by untrusted resources.
The next question is then of course why do you want to require TLS w/client certs and not just "must bind with a password, with TLS to protect the passwords", which is much more common? The answer might be something like:
"Because some of the applications cannot be configured to bind non-anonymously but they all (except for that one) _can_ be configured to always use StartTLS and provide a client certificate, we want to require that all ldap:// connections use the StartTLS operation with a client cert before performing any LDAP operations that access or modify data.
(That's a complete guess and probably not your real reason. Client certs are just another form of secret which are, IMO, a bigger pain to generate and manage.)
I tried to figure out how to allow the app and clients access to localhost without TLS and the rest with TLS + client cert auth using what seems the only example in existence:
# first, make sure TLS or localhost access to * by tls_ssf=1 none break by peername.ip="127.0.0.1" none break by * none
# "real" ACL(s) go here
But that did not work and the why this should work (assuming the example is correct) eludes me, with the guide and man pages being of little help as I'm no software developer nor do I have Einstein's brainpower :-)
Well, for starters, the peername.ip="127.0.0.1" clause does *NOT* match ldapi:// connections. It matches ldap://127.0.0.1/ and ldaps://127.0.0.1/ connections.
I thought I could do that with:
...
olcLocalSSF: 0 <---
So, you've told slapd that ldapi:// connections are to be treated as completely insecure, like ldap:// conections without TLS. That doesn't seem to match your intention.
It does. Insecure socket access for the app which does not support client cert auth and TLS+client cert auth for access via ldap/ldaps.
In what way is an ldapi:// connection insecure? It's a UNIX domain socket for which the data never goes over a physical net and that therefore cannot be snooped. That's *MORE* secure than a TCP connection secured with TLS! You can even authenticate it via the uid and gid of the process that opened the connection!
Anyway, if you want to permit only
a) read-only ldapi:// connections and
b) ldap:// connections using TLS w/client certs
then *I think* you can do that with three options in the config:
# require clients that clients that do TLS provide a client cert olcTLSVerifyClient: demand # treat ldapi:// connections as at least as secure as a 256bit cipher olcLocalSSF: 256 # require connections to be at least as secure as a 256bit cipher to do # anything at all (the "ssf=256") clause, and specifically require that # they be using TLS (and not just ldapi) with 256bit cipher to do updates olcSecurity: ssf=256 update_tls=256
But I haven't tested it.
To quote slapd-config(5): olcSecurity: <factors> Specify a set of security strength factors (separated by white space) to require (see olcSaslSecprops's minssf option for a description of security strength factors). The directive may be specified globally and/or per-database. ... tls=<n> specifies the TLS security strength factor.
So, this tells slapd to require *ALL* connections, regardless of how they connect, to use SSL/TLS with an SSF of at least 256. That clearly doesn't match your intention.
Thank you for that explanation. It would have been nice if that section mentioned that it applies to *all* connections with no exceptions and no matter what else I might have configured. At least I learned something :-)
Yes, an unconditional "require blah" should be taken to be unconditional.
Philip Guenther
Hi Philip,
Thank you for your elaborate feedback. Comments inline.
On 02/19/2013 03:42 AM, Philip Guenther wrote: [snip]
"We need to protect corporate data in LDAP from being modified or even accessed by untrusted resources.
Yes.
[snip]
"Because some of the applications cannot be configured to bind non-anonymously but they all (except for that one) _can_ be configured to always use StartTLS and provide a client certificate, we want to require that all ldap:// connections use the StartTLS operation with a client cert before performing any LDAP operations that access or modify data.
Yes. Client certificate authentication is used everywhere where possible (for things like corporate web access, email, VPN).
(That's a complete guess and probably not your real reason. Client certs are just another form of secret which are, IMO, a bigger pain to generate and manage.)
Thankfully the security overlords who came up with this one are also the ones who have to generate and manage the certs :-)
[snip]
Well, for starters, the peername.ip="127.0.0.1" clause does *NOT* match ldapi:// connections. It matches ldap://127.0.0.1/ and ldaps://127.0.0.1/ connections.
I did not try to use ldapi with this setup. I used ldap on 127.0.0.1. Sorry if that was not clear.
[snip]
In what way is an ldapi:// connection insecure? It's a UNIX domain socket for which the data never goes over a physical net and that therefore cannot be snooped. That's *MORE* secure than a TCP connection secured with TLS! You can even authenticate it via the uid and gid of the process that opened the connection!
Agreed. The authentication via uid/gid is a nice one I did not know was possible. Will look into that.
Anyway, if you want to permit only a) read-only ldapi:// connections and b) ldap:// connections using TLS w/client certs
then *I think* you can do that with three options in the config:
# require clients that clients that do TLS provide a client cert olcTLSVerifyClient: demand # treat ldapi:// connections as at least as secure as a 256bit cipher olcLocalSSF: 256 # require connections to be at least as secure as a 256bit cipher to do # anything at all (the "ssf=256") clause, and specifically require that # they be using TLS (and not just ldapi) with 256bit cipher to do updates olcSecurity: ssf=256 update_tls=256
Your example had me stumped. Upon reading the olcLocalSSF section again I realized I made a mistake. Although it says "Specifies the Security Strength Factor (SSF) to be *given* local LDAP sessions" my mind munched it into "Specifies the Security Strength Factor (SSF) to *require* for local LDAP sessions". Obviously setting it to 0 did not help... Staring at the screen too long I guess. So thanks for making me read the man page again :-)
But I haven't tested it.
Works like a charm.
[snip]
Yes, an unconditional "require blah" should be taken to be unconditional.
Duly noted.
Thank you very much for all your help and enlightening comments. Much appreciated.
Regards, Patrick
openldap-technical@openldap.org