[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: Certificate authentication and back-ldap proxy
Thank you very much.
We have followed your instructions and we have fixed the back-ldap proxy
slapd.conf file:
#
# Security SSL
#
TLSCipherSuite HIGH:MEDIUM:+SSLv3
TLSCACertificatePath /etc/ssl/cacerts/
TLSCertificateFile /etc/ssl/certs/proxy-server1.example.com.pem
TLSCertificateKeyFile /etc/ssl/private/proxy-server1.example.com.key
TLSVerifyClient demand
# Log level
loglevel 256
#######################################################################
# Database definitions
#######################################################################
database ldap
rebind-as-user true
suffix "dc=example,dc=com"
uri "ldaps://server1.example.com"
idassert-bind bindmethod=simple
binddn="cn=proxy_id,dc=example,dc=com"
credentials="secret"
mode=self
-------------------------
-------------------------
In the master server we have included the authz-policy and authz-regexp
sentences:
access to dn.base=""
by * read
access to dn.base="cn=Subschema"
by * read
access to attrs=userPassword,userPKCS12
by self write
by dn.exact="cn=admin_w_cert,ou=admins,dc=example,dc=com" read
by * auth
access to attrs=shadowLastChange
by self write
by * read
access to *
by * read
#
# Security SSL
#
TLSCipherSuite HIGH:MEDIUM:+SSLv3
TLSCertificateFile /etc/ssl/certs/server1.example.com.pem
TLSCertificateKeyFile /etc/ssl/private/server1.example.com.key
TLSCACertificatePath /etc/ssl/cacerts/
TLSVerifyClient demand
#
#Log level
#
loglevel -1
# Require authentication
require authc
#
# Authz
#
authz-policy to
authz-regexp "CN=([^,]*),O=Internet Widgits Pty Ltd,ST=Some-State,C=AU"
CN=$1,ou=admins,dc=example,dc=com
#######################################################################
# HDB database definitions
#######################################################################
database hdb
suffix "dc=example,dc=com"
checkpoint 1024 5
cachesize 10000
rootdn "cn=Manager,dc=example,dc=com"
rootpw secret
# Indices to maintain
index objectClass eq
#
# Overlay ppolicy
#
overlay ppolicy
-------------------------
-------------------------
Also we have included some entries in the tree:
dn: ou=admins,dc=example,dc=com
objectclass: top
objectclass: organizationalUnit
ou: admins
dn: cn=admin_w_cert,ou=admins,dc=example,dc=com
cn: Admin with Cert Mapping
cn: admin_w_cert
objectclass: top
objectclass: person
sn: Admin with Cert Mapping
dn: cn=proxy_id,dc=example,dc=com
cn: Proxy ID
cn: proxy_id
objectclass: top
objectclass: person
sn: Proxy ID
userpassword: {SSHA}vPXnQ9g0JzITK3+SczbcDq/fwaDRAewf
authzTo: ldap:///ou=admins,dc=example,dc=com??sub?(objectClass=person)
-------------------------
-------------------------
Now the search works:
ldapsearch -LLL -b 'uid=user_w_pass,ou=people,dc=example,dc=com' -H
ldaps://proxy-server1.example.com:1636 userPassword
SASL/EXTERNAL authentication started
SASL username: CN=admin_w_cert,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU
SASL SSF: 0
dn: uid=user_w_pass,ou=people,dc=example,dc=com
userPassword:: e2NyeXB0fTcyMXpQbU4waWdKaU0=
Thanks again.
>> Hi,
>>
>> We have some problems with certificate authentication when the master
>> server is behind a back-ldap proxy.
>>
>> We have openldap 2.4.21 on Suse Linux Enterprise Server 10 SP3 and
>> these are the details of our scenario:
>>
>> The master server: server1.example.com has the following slapd.conf
>> file:
>>
>> access to dn.base=""
>> by * read
>>
>> access to dn.base="cn=Subschema"
>> by * read
>>
>> access to attrs=userPassword,userPKCS12
>> by self write
>> by dn.exact="CN=admin_w_cert,O=Internet Widgits Pty
>> Ltd,ST=Some-State,C=AU" read
>> by *
>> auth
>>
>> access to attrs=shadowLastChange
>> by self write
>> by * read
>>
>> access to *
>> by * read
>>
>> #
>> # Security SSL
>> #
>> TLSCipherSuite HIGH:MEDIUM:+SSLv3
>> TLSCertificateFile /etc/ssl/certs/server1.example.com.pem
>> TLSCertificateKeyFile /etc/ssl/private/server1.example.com.key
>> TLSCACertificatePath /etc/ssl/cacerts/
>> TLSVerifyClient demand
>>
>> #
>> #Log level
>> #
>> loglevel 256
>>
>> # Require authentication
>> require authc
>>
>> #######################################################################
>> # HDB database definitions
>> #######################################################################
>>
>> database hdb
>> suffix "dc=example,dc=com"
>> checkpoint 1024 5
>> cachesize 10000
>> rootdn "cn=Manager,dc=example,dc=com"
>>
>> rootpw secret
>>
>> # Indices to maintain
>> index objectClass eq
>>
>> # Overlay ppolicy
>> overlay ppolicy
>>
>> ----------------------
>>
>> Authentication is required, and we give access to the user passwords
>> for the dn of a certificate.
>>
>> When we search for passwords using the certificate we get the
>> following:
>>
>> root# ldapsearch -LLL -b 'uid=user_w_pass,ou=people,dc=example,dc=com'
>> -H ldaps://server1.example.com userPassword
>>
>> SASL/EXTERNAL authentication started
>> SASL username: CN=admin_w_cert,O=Internet Widgits Pty
>> Ltd,ST=Some-State,C=AU
>> SASL SSF: 0
>> dn: uid=user_w_pass,ou=people,dc=example,dc=com
>> userPassword:: e2NyeXB0fTcyMXpQbU4waWdKaU0=
>>
>> -----------------------
>>
>> The root user (ldap client) has a ~/.ldaprc file with:
>> TLS_CACERTDIR /etc/ssl/cacerts/
>> TLS_CERT /etc/ssl/certs/admin_w_cert.pem
>> TLS_KEY /etc/ssl/private/admin_w_cert.key
>> TLS_REQCERT demand
>> SASL_MECH EXTERNAL
>>
>> In /var/log/messages we get:
>> ldap-master[22358]: conn=1000 fd=11 ACCEPT from
>> IP=server1.example.com:40899 (IP=server1.example.com:636)
>> ldap-master[22358]: conn=1000 fd=11 TLS established tls_ssf=256 ssf=256
>> ldap-master[22358]: conn=1000 op=0 BIND dn="" method=163
>> ldap-master[22358]: conn=1000 op=0 BIND
>> authcid="cn=admin_w_cert,o=internet widgits pty ltd,st=some-state,c=au"
>> authzid="cn=admin_w_cert,o=internet widgits pty ltd,st=some-state,c=au"
>> ldap-master[22358]: conn=1000 op=0 BIND dn="cn=admin_w_cert,o=internet
>> widgits pty ltd,st=some-state,c=au" mech=EXTERNAL sasl_ssf=0 ssf=256
>> ldap-master[22358]: conn=1000 op=0 RESULT tag=97 err=0 text=
>> ldap-master[22358]: conn=1000 op=1 SRCH
>> base="uid=user_w_pass,ou=people,dc=example,dc=com" scope=2 deref=0
>> filter="(objectClass=*)"
>> ldap-master[22358]: conn=1000 op=1 SRCH attr=userPassword
>> ldap-master[22358]: conn=1000 op=1 SEARCH RESULT tag=101 err=0
>> nentries=1 text=
>> ldap-master[22358]: conn=1000 op=2 UNBIND
>> ldap-master[22358]: conn=1000 fd=11 closed
>>
>> This is the correct behavior for us. The problem appears when we
>> introduce a back-ldap proxy between the client and the master.
>> The proxy server (proxy-server1.example.com) is listening in port
>> 1636 and its slapd.conf file is:
>>
>> #
>> # Security SSL
>> #
>> TLSCipherSuite HIGH:MEDIUM:+SSLv3
>> TLSCACertificatePath /etc/ssl/cacerts/
>> TLSCertificateFile /etc/ssl/certs/proxy-server1.example.com.pem
>> TLSCertificateKeyFile /etc/ssl/private/proxy-server1.example.com.key
>> TLSVerifyClient demand
>>
>> # Log level
>> loglevel 256
>>
>> #######################################################################
>> # Database definitions
>> #######################################################################
>> database ldap
>>
>> rebind-as-user true
>>
>> suffix "dc=example,dc=com"
>>
>> uri "ldaps://server1.example.com"
>> tls ldaps
>> tls_cert=/etc/ssl/certs/proxy-server1.example.com.pem
>> tls_key=/etc/ssl/private/proxy-server1.example.com.key
>> tls_cacertdir=/etc/ssl/cacerts/
>>
>> ----------------------
>>
>> If we search for passwords through the proxy we get:
>> root # ldapsearch -LLL -b 'uid=user_w_pass,ou=people,dc=example,dc=com'
>> -H ldaps://proxy-server1.example.com:1636 userPassword
>>
>> SASL/EXTERNAL authentication started
>> SASL username: CN=admin_w_cert,O=Internet Widgits Pty
>> Ltd,ST=Some-State,C=AU
>> SASL SSF: 0
>> Server is unwilling to perform (53)
>> Additional information: authentication required
>>
>> In the /var/log/messages the following messages appear:
>> ldap-proxy[22802]: conn=1001 fd=8 ACCEPT from
>> IP=proxy-server1.example.com:60712 (IP=proxy-server1.example.com:1636)
>> ldap-proxy[22802]: conn=1001 fd=8 TLS established tls_ssf=256 ssf=256
>> ldap-proxy[22802]: conn=1001 op=0 BIND dn="" method=163
>> ldap-proxy[22802]: conn=1001 op=0 BIND
>> authcid="cn=admin_w_cert,o=internet widgits pty ltd,st=some-state,c=au"
>> authzid="cn=admin_w_cert,o=internet widgits pty ltd,st=some-state,c=au"
>> ldap-proxy[22802]: conn=1001 op=0 BIND dn="cn=admin_w_cert,o=internet
>> widgits pty ltd,st=some-state,c=au" mech=EXTERNAL sasl_ssf=0 ssf=256
>> ldap-proxy[22802]: conn=1001 op=0 RESULT tag=97 err=0 text=
>> ldap-proxy[22802]: conn=1001 op=1 SRCH
>> base="uid=user_w_pass,ou=people,dc=example,dc=com" scope=2 deref=0
>> filter="(objectClass=*)"
>> ldap-proxy[22802]: conn=1001 op=1 SRCH attr=userPassword
>>
>> ldap-master[22358]: conn=1008 op=2 SRCH
>> base="uid=user_w_pass,ou=people,dc=example,dc=com" scope=2 deref=0
>> filter="(objectClass=*)"
>> ldap-master[22358]: conn=1008 op=2 SRCH attr=userPassword
>> ldap-master[22358]: conn=1008 op=2 SEARCH RESULT tag=101 err=53
>> nentries=0 text=authentication required
>>
>> ldap-proxy[22802]: conn=1001 op=1 SEARCH RESULT tag=101 err=53
>> nentries=0 text=authentication required
>> ldap-proxy[22802]: conn=1001 op=2 UNBIND
>> ldap-proxy[22802]: conn=1001 fd=8 closed
>>
>> The /root/.ldaprc file is the same than the previous one.
>>
>> When we increase the logging level we discover this:
>> ....
>> ldap-proxy[23008]: conn=1000 op=0 do_bind
>> ldap-proxy[23008]: >>> dnPrettyNormal: <>
>> ldap-proxy[23008]: <<< dnPrettyNormal: <>, <>
>> ldap-proxy[23008]: conn=1000 op=0 BIND dn="" method=163
>> ldap-proxy[23008]: do_bind: dn () SASL mech EXTERNAL
>> ldap-proxy[23008]: ==> sasl_bind: dn="" mech=EXTERNAL datalen=0
>> ldap-proxy[23008]: SASL Canonicalize [conn=1000]:
>> authcid="cn=admin_w_cert,o=internet widgits pty ltd,st=some-state,c=au"
>> ldap-proxy[23008]: slap_sasl_getdn: conn 1000
>> id=cn=admin_w_cert,o=internet widgits pty ltd,st=some-state,c=au [len=61]
>> ldap-proxy[23008]: ==>slap_sasl2dn: converting SASL name
>> cn=admin_w_cert,o=internet widgits pty ltd,st=some-state,c=au to a DN
>> ldap-proxy[23008]: <==slap_sasl2dn: Converted SASL name to <nothing>
>> ldap-proxy[23008]: SASL Canonicalize [conn=1000]:
>> slapAuthcDN="cn=admin_w_cert,o=internet widgits pty
>> ltd,st=some-state,c=au"
>> ldap-proxy[23008]: SASL proxy authorize [conn=1000]:
>> authcid="cn=admin_w_cert,o=internet widgits pty ltd,st=some-state,c=au"
>> authzid="cn=admin_w_cert,o=internet widgits pty ltd,st=some-state,c=au"
>> ldap-proxy[23008]: conn=1000 op=0 BIND
>> authcid="cn=admin_w_cert,o=internet widgits pty ltd,st=some-state,c=au"
>> authzid="cn=admin_w_cert,o=internet widgits pty ltd,st=some-state,c=au"
>> ldap-proxy[23008]: SASL Authorize [conn=1000]: proxy authorization
>> allowed authzDN=""
>> ldap-proxy[23008]: send_ldap_sasl: err=0 len=-1
>> ldap-proxy[23008]: conn=1000 op=0 BIND dn="cn=admin_w_cert,o=internet
>> widgits pty ltd,st=some-state,c=au" mech=EXTERNAL sasl_ssf=0 ssf=256
>> ldap-proxy[23008]: do_bind: SASL/EXTERNAL bind:
>> dn="cn=admin_w_cert,o=internet widgits pty ltd,st=some-state,c=au"
>> sasl_ssf=0
>> ldap-proxy[23008]: send_ldap_response: msgid=1 tag=97 err=0
>> ldap-proxy[23008]: conn=1000 op=0 RESULT tag=97 err=0 text=
>> ldap-proxy[23008]: <== slap_sasl_bind: rc=0
>> ....
>> ldap-proxy[23008]: conn=1000 op=1 SRCH
>> base="uid=user_w_pass,ou=people,dc=example,dc=com" scope=2 deref=0
>> filter="(objectClass=*)"
>> ldap-proxy[23008]: conn=1000 op=1 SRCH attr=userPassword
>> ldap-proxy[23008]: ==> limits_get: conn=1000 op=1
>> self="cn=admin_w_cert,o=internet widgits pty ltd,st=some-state,c=au"
>> this="uid=user_w_pass,ou=people,dc=example,dc=com"
>> ldap-master[22983]: daemon: activity on 1 descriptor
>> ldap-master[22983]: daemon: activity on:
>> ldap-master[22983]:
>> ldap-master[22983]: slap_listener_activate(7):
>> ldap-master[22983]: daemon: epoll: listen=7 busy
>> ldap-master[22983]: >>> slap_listener(ldaps://server1.example.com)
>> .....
>> ldap-master[22983]: conn=1000 op=0 do_bind
>> ldap-master[22983]: >>> dnPrettyNormal: <>
>> ldap-master[22983]: <<< dnPrettyNormal: <>, <>
>> ldap-master[22983]: conn=1000 op=0 BIND dn="" method=128
>> ldap-master[22983]: do_bind: version=3 dn="" method=128
>> ldap-master[22983]: send_ldap_result: conn=1000 op=0 p=3
>> ldap-master[22983]: send_ldap_result: err=0 matched="" text=""
>> ldap-master[22983]: send_ldap_response: msgid=1 tag=97 err=0
>> ldap-master[22983]: conn=1000 op=0 RESULT tag=97 err=0 text=
>> ldap-master[22983]: do_bind: v3 anonymous bind
>>
>> ----------------
>>
>> Therefore the proxy is binding anonymously in the master, instead of
>> using the dn of the certificate.
>>
>> Is there any problem with the SASL EXTERNAL method?
>>
>> If we use SIMPLE authentication through the proxy, there is no problem:
>> root # ldapsearch -LLL -x -b
>> 'uid=user_w_pass,ou=people,dc=example,dc=com' -H
>> ldaps://proxy-server1.example.com:1636 -D
>> 'uid=user_w_pass,ou=people,dc=example,dc=com' -W userPassword
>> Enter LDAP Password:
>>
>> dn: uid=user_w_pass,ou=people,dc=example,dc=com
>> userPassword:: e2NyeXB0fTcyMXpQbU4waWdKaU0=
>>
>
> The problem is that you probably do not realize that the proxy cannot do a
> cert-based authentication on behalf of the client because it doesn't have
> the client's private key (which is correct). You need the proxy perform
> an identity assertion: bind to the remote server with its own identity,
> and then assert the client's identity using proxy authorization.
>
> To do this, you need to:
>
> a) define some means for the proxy to bind to the remote server, e.g.
> using cert-based SASL EXTERNAL, or simple bind under TLS, or whatever;
>
> b) configure the remote server so that the proxy's identity defined in (a)
> is allowed to proxy authz as whatever client's identity you want to
> accept; this requires to use the directive "authz-policy"; you may need to
> use the "authz-regexp" if you intend to map the client's identity; and
> you'll need to populate the "authzTo" operational attribute of the entry
> corresponding to the proxy's identity.
>
> c) add to the proxy configuration the directive
>
> idassert-bind bindmethod=<what you chose for (a)>
> <bind parameters for (a)>
> mode=self
>
> This way, the proxy will:
>
> - authc the client locally
>
> - authc as itself with respect to the remote host
>
> - proxy operations adding the proxyAuthz control with the identity of the
> client
>
> See slapd-ldap(5) for details on the syntax of the idassert-* directives.
>
> p.
>
>
---------------------------------------------------------------------------------------------
ADVERTENCIA: Sobre la privacidad y cumplimiento de la Ley de Protección de Datos, acceda a http://www.iac.es/disclaimer.php
WARNING: For more information on privacy and fulfilment of the Law concerning the Protection of Data, consult http://www.iac.es/disclaimer.php?lang=en