OpenLDAP 和 SSL
我在尝试连接到我设置的安全 OpenLDAP 服务器时遇到问题。在运行 LDAP 客户端代码时
java -Djavax.net.debug=ssl LDAPConnector
,我收到以下异常跟踪(java 版本 1.6.0_17)
trigger seeding of SecureRandom
done seeding SecureRandom
%% No cached client session
*** ClientHello, TLSv1
RandomCookie: GMT: 1256110124 bytes = { 224, 19, 193, 148, 45, 205, 108, 37, 101, 247, 112, 24, 157, 39, 111, 177, 43, 53, 206, 224, 68, 165, 55, 185, 54, 203, 43, 91 }
Session ID: {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_W
ITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SH
A, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
Compression Methods: { 0 }
***
Thread-0, WRITE: TLSv1 Handshake, length = 73
Thread-0, WRITE: SSLv2 client hello message, length = 98
Thread-0, received EOFException: error
Thread-0, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
Thread-0, SEND TLSv1 ALERT: fatal, description = handshake_failure
Thread-0, WRITE: TLSv1 Alert, length = 2
Thread-0, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
javax.naming.CommunicationException: simple bind failed: ldap.natraj.com:636 [Root exception is javax.net.ssl.SSLHandshakeException: Remote host closed connection during hands
hake]
at com.sun.jndi.ldap.LdapClient.authenticate(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.connect(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.<init>(Unknown Source)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(Unknown Source)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(Unknown Source)
at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(Unknown Source)
at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(Unknown Source)
at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.init(Unknown Source)
at javax.naming.InitialContext.<init>(Unknown Source)
at javax.naming.directory.InitialDirContext.<init>(Unknown Source)
at LDAPConnector.CallSecureLDAPServer(LDAPConnector.java:43)
at LDAPConnector.main(LDAPConnector.java:237)
Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read1(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at com.sun.jndi.ldap.Connection.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
at com.sun.net.ssl.internal.ssl.InputRecord.read(Unknown Source)
... 9 more
,但是如果我使用另一个版本的 java (1.6 .0_14)
我已在两个 JRE 的 cacerts 中创建并安装了服务器证书,如本指南中所述 --> 使用 SSL 的 OpenLDAP
我在运行 openssl s_client -connect ldap.natraj.com:636 -showcerts
的服务器上运行 ldapsearch -x
# extended LDIF
#
# LDAPv3
# base <dc=localdomain> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# localdomain
dn: dc=localdomain
objectClass: top
objectClass: dcObject
objectClass: organization
o: localdomain
dc: localdomain
# admin, localdomain
dn: cn=admin,dc=localdomain
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
# search result
search: 2
result: 0 Success
# numResponses: 3
# numEntries: 2
,我获得了自签名证书。
我的 slapd.conf 文件如下
#######################################################################
# Global Directives:
# Features to permit
#allow bind_v2
# Schema and objectClass definitions
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/inetorgperson.schema
# Where the pid file is put. The init.d script
# will not stop the server if you change this.
pidfile /var/run/slapd/slapd.pid
# List of arguments that were passed to the server
argsfile /var/run/slapd/slapd.args
# Read slapd.conf(5) for possible values
loglevel none
# Where the dynamically loaded modules are stored
modulepath /usr/lib/ldap
moduleload back_hdb
# The maximum number of entries that is returned for a search operation
sizelimit 500
# The tool-threads parameter sets the actual amount of cpu's that is used
# for indexing.
tool-threads 1
#######################################################################
# Specific Backend Directives for hdb:
# Backend specific directives apply to this backend until another
# 'backend' directive occurs
backend hdb
#######################################################################
# Specific Backend Directives for 'other':
# Backend specific directives apply to this backend until another
# 'backend' directive occurs
#backend <other>
#######################################################################
# Specific Directives for database #1, of type hdb:
# Database specific directives apply to this databasse until another
# 'database' directive occurs
database hdb
# The base of your directory in database #1
suffix "dc=localdomain"
# rootdn directive for specifying a superuser on the database. This is needed
# for syncrepl.
rootdn "cn=admin,dc=localdomain"
# Where the database file are physically stored for database #1
directory "/var/lib/ldap"
# The dbconfig settings are used to generate a DB_CONFIG file the first
# time slapd starts. They do NOT override existing an existing DB_CONFIG
# file. You should therefore change these settings in DB_CONFIG directly
# or remove DB_CONFIG and restart slapd for changes to take effect.
# For the Debian package we use 2MB as default but be sure to update this
# value if you have plenty of RAM
dbconfig set_cachesize 0 2097152 0
# Sven Hartge reported that he had to set this value incredibly high
# to get slapd running at all. See http://bugs.debian.org/303057 for more
# information.
# Number of objects that can be locked at the same time.
dbconfig set_lk_max_objects 1500
# Number of locks (both requested and granted)
dbconfig set_lk_max_locks 1500
# Number of lockers
dbconfig set_lk_max_lockers 1500
# Indexing options for database #1
index objectClass eq
# Save the time that the entry gets modified, for database #1
lastmod on
# Checkpoint the BerkeleyDB database periodically in case of system
# failure and to speed slapd shutdown.
checkpoint 512 30
# Where to store the replica logs for database #1
# replogfile /var/lib/ldap/replog
# The userPassword by default can be changed
# by the entry owning it if they are authenticated.
# Others should not be able to see it, except the
# admin entry below
# These access lines apply to database #1 only
access to attrs=userPassword,shadowLastChange
by dn="cn=admin,dc=localdomain" write
by anonymous auth
by self write
by * none
# Ensure read access to the base for things like
# supportedSASLMechanisms. Without this you may
# have problems with SASL not knowing what
# mechanisms are available and the like.
# Note that this is covered by the 'access to *'
# ACL below too but if you change that as people
# are wont to do you'll still need this if you
# want SASL (and possible other things) to work
# happily.
access to dn.base="" by * read
# The admin dn has full write access, everyone else
# can read everything.
access to *
by dn="cn=admin,dc=localdomain" write
by * read
# For Netscape Roaming support, each user gets a roaming
# profile for which they have write access to
#access to dn=".*,ou=Roaming,o=morsnet"
# by dn="cn=admin,dc=localdomain" write
# by dnattr=owner write
#######################################################################
# Specific Directives for database #2, of type 'other' (can be hdb too):
# Database specific directives apply to this databasse until another
# 'database' directive occurs
#database <other>
# The base of your directory for database #2
#suffix "dc=debian,dc=org"
#######################################################################
# SSL:
# Uncomment the following lines to enable SSL and use the default
# snakeoil certificates.
#TLSCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
#TLSCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
TLSCipherSuite TLS_RSA_AES_256_CBC_SHA
TLSCACertificateFile /etc/ldap/ssl/server.pem
TLSCertificateFile /etc/ldap/ssl/server.pem
TLSCertificateKeyFile /etc/ldap/ssl/server.pem
我的 ldap.conf 文件是
#
# LDAP Defaults
#
# See ldap.conf(5) for details
# This file should be world readable but not world writable.
HOST ldap.natraj.com
PORT 636
BASE dc=localdomain
URI ldaps://ldap.natraj.com
TLS_CACERT /etc/ldap/ssl/server.pem
TLS_REQCERT allow
#SIZELIMIT 12
#TIMELIMIT 15
#DEREF never
为什么我可以使用一个版本的 JRE 连接到同一服务器,而不能使用另一个版本?
I am having trouble trying to connect to a secure OpenLDAP server which I have set up. On running my LDAP client code
java -Djavax.net.debug=ssl LDAPConnector
I get the following exception trace (java version 1.6.0_17)
trigger seeding of SecureRandom
done seeding SecureRandom
%% No cached client session
*** ClientHello, TLSv1
RandomCookie: GMT: 1256110124 bytes = { 224, 19, 193, 148, 45, 205, 108, 37, 101, 247, 112, 24, 157, 39, 111, 177, 43, 53, 206, 224, 68, 165, 55, 185, 54, 203, 43, 91 }
Session ID: {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_W
ITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SH
A, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
Compression Methods: { 0 }
***
Thread-0, WRITE: TLSv1 Handshake, length = 73
Thread-0, WRITE: SSLv2 client hello message, length = 98
Thread-0, received EOFException: error
Thread-0, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
Thread-0, SEND TLSv1 ALERT: fatal, description = handshake_failure
Thread-0, WRITE: TLSv1 Alert, length = 2
Thread-0, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
javax.naming.CommunicationException: simple bind failed: ldap.natraj.com:636 [Root exception is javax.net.ssl.SSLHandshakeException: Remote host closed connection during hands
hake]
at com.sun.jndi.ldap.LdapClient.authenticate(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.connect(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.<init>(Unknown Source)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(Unknown Source)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(Unknown Source)
at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(Unknown Source)
at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(Unknown Source)
at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.init(Unknown Source)
at javax.naming.InitialContext.<init>(Unknown Source)
at javax.naming.directory.InitialDirContext.<init>(Unknown Source)
at LDAPConnector.CallSecureLDAPServer(LDAPConnector.java:43)
at LDAPConnector.main(LDAPConnector.java:237)
Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read1(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at com.sun.jndi.ldap.Connection.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
at com.sun.net.ssl.internal.ssl.InputRecord.read(Unknown Source)
... 9 more
I am able to connect to the same secure LDAP server however if I use another version of java (1.6.0_14)
I have created and installed the server certificates in the cacerts of both the JRE's as mentioned in this guide --> OpenLDAP with SSL
When I run ldapsearch -x
on the server I get
# extended LDIF
#
# LDAPv3
# base <dc=localdomain> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# localdomain
dn: dc=localdomain
objectClass: top
objectClass: dcObject
objectClass: organization
o: localdomain
dc: localdomain
# admin, localdomain
dn: cn=admin,dc=localdomain
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
# search result
search: 2
result: 0 Success
# numResponses: 3
# numEntries: 2
On running openssl s_client -connect ldap.natraj.com:636 -showcerts
, I obtain the self signed certificate.
My slapd.conf file is as follows
#######################################################################
# Global Directives:
# Features to permit
#allow bind_v2
# Schema and objectClass definitions
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/inetorgperson.schema
# Where the pid file is put. The init.d script
# will not stop the server if you change this.
pidfile /var/run/slapd/slapd.pid
# List of arguments that were passed to the server
argsfile /var/run/slapd/slapd.args
# Read slapd.conf(5) for possible values
loglevel none
# Where the dynamically loaded modules are stored
modulepath /usr/lib/ldap
moduleload back_hdb
# The maximum number of entries that is returned for a search operation
sizelimit 500
# The tool-threads parameter sets the actual amount of cpu's that is used
# for indexing.
tool-threads 1
#######################################################################
# Specific Backend Directives for hdb:
# Backend specific directives apply to this backend until another
# 'backend' directive occurs
backend hdb
#######################################################################
# Specific Backend Directives for 'other':
# Backend specific directives apply to this backend until another
# 'backend' directive occurs
#backend <other>
#######################################################################
# Specific Directives for database #1, of type hdb:
# Database specific directives apply to this databasse until another
# 'database' directive occurs
database hdb
# The base of your directory in database #1
suffix "dc=localdomain"
# rootdn directive for specifying a superuser on the database. This is needed
# for syncrepl.
rootdn "cn=admin,dc=localdomain"
# Where the database file are physically stored for database #1
directory "/var/lib/ldap"
# The dbconfig settings are used to generate a DB_CONFIG file the first
# time slapd starts. They do NOT override existing an existing DB_CONFIG
# file. You should therefore change these settings in DB_CONFIG directly
# or remove DB_CONFIG and restart slapd for changes to take effect.
# For the Debian package we use 2MB as default but be sure to update this
# value if you have plenty of RAM
dbconfig set_cachesize 0 2097152 0
# Sven Hartge reported that he had to set this value incredibly high
# to get slapd running at all. See http://bugs.debian.org/303057 for more
# information.
# Number of objects that can be locked at the same time.
dbconfig set_lk_max_objects 1500
# Number of locks (both requested and granted)
dbconfig set_lk_max_locks 1500
# Number of lockers
dbconfig set_lk_max_lockers 1500
# Indexing options for database #1
index objectClass eq
# Save the time that the entry gets modified, for database #1
lastmod on
# Checkpoint the BerkeleyDB database periodically in case of system
# failure and to speed slapd shutdown.
checkpoint 512 30
# Where to store the replica logs for database #1
# replogfile /var/lib/ldap/replog
# The userPassword by default can be changed
# by the entry owning it if they are authenticated.
# Others should not be able to see it, except the
# admin entry below
# These access lines apply to database #1 only
access to attrs=userPassword,shadowLastChange
by dn="cn=admin,dc=localdomain" write
by anonymous auth
by self write
by * none
# Ensure read access to the base for things like
# supportedSASLMechanisms. Without this you may
# have problems with SASL not knowing what
# mechanisms are available and the like.
# Note that this is covered by the 'access to *'
# ACL below too but if you change that as people
# are wont to do you'll still need this if you
# want SASL (and possible other things) to work
# happily.
access to dn.base="" by * read
# The admin dn has full write access, everyone else
# can read everything.
access to *
by dn="cn=admin,dc=localdomain" write
by * read
# For Netscape Roaming support, each user gets a roaming
# profile for which they have write access to
#access to dn=".*,ou=Roaming,o=morsnet"
# by dn="cn=admin,dc=localdomain" write
# by dnattr=owner write
#######################################################################
# Specific Directives for database #2, of type 'other' (can be hdb too):
# Database specific directives apply to this databasse until another
# 'database' directive occurs
#database <other>
# The base of your directory for database #2
#suffix "dc=debian,dc=org"
#######################################################################
# SSL:
# Uncomment the following lines to enable SSL and use the default
# snakeoil certificates.
#TLSCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
#TLSCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
TLSCipherSuite TLS_RSA_AES_256_CBC_SHA
TLSCACertificateFile /etc/ldap/ssl/server.pem
TLSCertificateFile /etc/ldap/ssl/server.pem
TLSCertificateKeyFile /etc/ldap/ssl/server.pem
My ldap.conf file is
#
# LDAP Defaults
#
# See ldap.conf(5) for details
# This file should be world readable but not world writable.
HOST ldap.natraj.com
PORT 636
BASE dc=localdomain
URI ldaps://ldap.natraj.com
TLS_CACERT /etc/ldap/ssl/server.pem
TLS_REQCERT allow
#SIZELIMIT 12
#TIMELIMIT 15
#DEREF never
Why is it that I can connect to the same server using one version of JRE while I cannot with another ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
解决了这个问题。出现此问题的原因是 JRE(版本 1.6.0_17)发送的 CipherSuites 与服务器接受的 CipherSuites 不匹配。
服务器的 slapd.conf 包含该行
当这个特定的 Java 客户端发送一组包含 TLS_RSA_AES_128_CBC_SHA 的套件时, 。只需在 slapd.conf 中注释掉上述行即可解决该问题。造成混乱的原因是,当问题涉及 CipherSuites 时,服务器返回了 EOF 异常。
然而,JRE(版本 1.6.0_14)发送 TLS_RSA_AES_256_CBC_SHA 作为它接受的 CipherSuites 的一部分,因此相同的代码适用于此版本。
Fixed the problem. The issue was arising because the CipherSuites which were being sent by the JRE (version 1.6.0_17) did not match with the CipherSuites accepted by the server.
The server's slapd.conf contained the line
while this particular Java client was sending a set of suites which included TLS_RSA_AES_128_CBC_SHA. The problem was solved by simply commenting out the above mentioned line in slapd.conf. The confusion was because the server returned an EOF exception when the problem was invloving CipherSuites.
JRE (version 1.6.0_14) however, was sending TLS_RSA_AES_256_CBC_SHA as part of the CipherSuites it was accepting and thus the same code worked with this version.
正如您在发送 SSLv2 ClientHello 后直接看到的那样,您应该尝试禁用 SSlv2ClientHello。请参阅 JSSE 参考指南。
As you got this straight after sending the SSLv2 ClientHello, you should try disabling SSlv2ClientHello. See the JSSE Reference Guide.