Bug 1519080
| Summary: | perl-LDAP not to default to TLS 1.0 in an explicit STARTTLS LDAP protocol upgrade | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 6 | Reporter: | amitkuma | ||||||
| Component: | perl-LDAP | Assignee: | perl-maint-list | ||||||
| Status: | CLOSED NEXTRELEASE | QA Contact: | BaseOS QE Security Team <qe-baseos-security> | ||||||
| Severity: | urgent | Docs Contact: | Lenka Špačková <lkuprova> | ||||||
| Priority: | unspecified | ||||||||
| Version: | 6.3 | CC: | amitkuma, cww, gswami, jorton, jwright, mlstarling31, perl-maint-list, ppisar, psabata, toneata | ||||||
| Target Milestone: | rc | Keywords: | FutureFeature, Patch, Reopened, Triaged | ||||||
| Target Release: | --- | ||||||||
| Hardware: | x86_64 | ||||||||
| OS: | Unspecified | ||||||||
| Whiteboard: | |||||||||
| Fixed In Version: | Doc Type: | Release Note | |||||||
| Doc Text: |
Feature:
Net::LDAP Perl module should not default to TLS 1.0
protocol when used to upgrade the unsecured LDAP
connection to TLS-protected one.
Reason:
TLS 1.0 is considered insecure today. To chose a stronger
TLS version Net::LDAP clients have to explicitly override
the TLS version by passing 'sslversion' argument to
start_tls() method. Net::LDAP module should not default to
insecure TLS version to ease writing secure Net::LDAP
clients.
Result:
Upstream fixes that remove default TLS version overrides
from the Net::LDAP Perl module were ported to perl-LDAP
RPM package. Now both implicit (LDAPS schema) and explicit
(LDAP schema) TLS protocols rely on IO::Socket::SSL's
default TLS version selection.
|
Story Points: | --- | ||||||
| Clone Of: | |||||||||
| : | 1520364 (view as bug list) | Environment: | |||||||
| Last Closed: | 2019-08-21 13:03:25 UTC | Type: | Bug | ||||||
| Regression: | --- | Mount Type: | --- | ||||||
| Documentation: | --- | CRM: | |||||||
| Verified Versions: | Category: | --- | |||||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||||
| Embargoed: | |||||||||
| Bug Depends On: | |||||||||
| Bug Blocks: | 1494503 | ||||||||
| Attachments: |
|
||||||||
Latest TLS version is 1.2 (1.3 is a draft). There is nothing like TLS 3.2 or 3.3. Could you please tell what LDAP server (RPM package release) are you running? What smbldap-passwd package belongs to? Finally RHEL-6.3 is not up-to-date. You should upgrade. perl-IO-Socket-SSL-1.31-3.el6_8.2.noarch can connect to TLS 1.2 only server:
If I generate a key and certificate and start TLS server on TCP port 2000 that enables TLS 1.2 only:
$ openssl s_server -cert cert -key key -accept 2000 -www -tls1_2
Using default temp DH parameters
Using default temp ECDH parameters
ACCEPT
The IO::Socket:SSL client will connect successfully:
$ perl -MIO::Socket::SSL -e 'my $cl = IO::Socket::SSL->new(PeerAddr => "localhost:2000") or die $!; print $cl "GET / HTTP/1.0\r\n\r\n";print <$cl>;'HTTP/1.0 200 ok
Content-type: text/html
[...]
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID:
Session-ID-ctx: 01000000
Master-Key: F40FD8419B83C595515A7D85FF1C5B2CCCC5FD99EB835031EC0B8FF3812122C9E4C99A06792F183311C41B474A5B0C5D
Key-Arg : None
Krb5 Principal: None
PSK identity: None
PSK identity hint: None
Start Time: 1512039040
Timeout : 7200 (sec)
[...]
I think your problem lays somewhere else. Maybe your server or your client disables some cipher or mode or hash algorithm or DHE curve and thus the TLS negotiation fails.
Please test this with OpenLDAP. This is where I am seeing the issue. Perhaps the problem lies in the OpenLDAP packages. I don't know anything about OpenLDAP. The package does not have slapd.conf file. Do you use explicit TLS or implicit one on a different port? In the first case it matters what LDAP client you use. You still did not divulge what client exhibits the error. I don't know these details. But you know them. Please test it yourself, or explain me your exact settings. I managed to get openldap-servers-2.4.40-16.el6 with nss-3.27.1-13.el6 configured to use TLS. I restricted the server to enable TLS 1.2 only and tried openssl-1.0.1e-57.el6 and perl-IO-Socket-SSL-1.31-3.el6_8.2 with perl-Net-SSLeay-1.35-10.el6_8.1 clients to connect to server.
If I kept the client to negotiate any TLS/SSL protocol or forced them to TLS 1.2, they were able to connect:
Server log:
5a215f18 connection_get(12)
TLS: info: SSL supported protocol version range is (0x300, 0x303) (SSL_VersionRangeGetSupported).
TLS: info: SSL default protocol version range is (0x300, 0x303) (SSL_VersionRangeGetDefault).
TLS: info: TLS configured protocol minimal version is 0x303.
TLS: info: SSL set protocol version range is (0x303, 0x303) (SSL_VersionRangeGet).
TLS: certificate 'localhost' successfully loaded from moznss database.
TLS: no unlocked certificate for certificate 'CN=localhost,O=Default Company Ltd,L=Default City,C=XX'.
TLS: Warning: ignoring error for certificate [CN=localhost,O=Default Company Ltd,L=Default City,C=XX] - error -8172:Peer's certificate issuer has been marked as not trusted by the user..
Clients:
$ perl -MIO::Socket::SSL -e 'my $cl = IO::Socket::SSL->new(PeerAddr => q{localhost:ldaps}, SSL_version => q{TLSv1_2}) or die $!; print qq{Connected.\n};'
Connected.
$ openssl s_client -connect localhost:ldaps -CAfile /etc/openldap/cert
s/cert -tls1_2
CONNECTED(00000003)
[...]
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
[...]
If I forced clients to use TLS 1.1, the TLS handshake failed as expected:
Server log:
5a215f99 daemon: epoll: listen=11 active_threads=0 tvp=NULL
TLS: info: SSL supported protocol version range is (0x300, 0x303) (SSL_VersionRangeGetSupported).
TLS: info: SSL default protocol version range is (0x300, 0x303) (SSL_VersionRangeGetDefault).
TLS: info: TLS configured protocol minimal version is 0x303.
TLS: info: SSL set protocol version range is (0x303, 0x303) (SSL_VersionRangeGet).
TLS: certificate 'localhost' successfully loaded from moznss database.
TLS: no unlocked certificate for certificate 'CN=localhost,O=Default Company Ltd,L=Default City,C=XX'.
TLS: Warning: ignoring error for certificate [CN=localhost,O=Default Company Ltd,L=Default City,C=XX] - error -8172:Peer's certificate issuer has been marked as not trusted by the user..
TLS: error: accept - force handshake failure: errno 13 - moznss error -12279
TLS: can't accept: TLS error -12279:Peer using unsupported version of security protocol..
5a215f99 connection_closing: readying conn=1000 sd=12 for close
Clients:
$ perl -MIO::Socket::SSL -e 'my $cl = IO::Socket::SSL->new(PeerAddr => q{localhost:ldaps}, SSL_version => q{TLSv1_1}) or die $!; print qq{Connected.\n};'
Transport endpoint is not connected at -e line 1.
$ openssl s_client -connect localhost:ldaps -CAfile /etc/openldap/certs/cert -tls1_1
CONNECTED(00000003)
139702844843848:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:339:
[...]
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.1
Therefore I conclude IO::Socket::SSL works for me against slapd.
I am using startTLS over 389 not LDAPS. I do not have a problem with openssl or client connections. The only failure I'm seeing is with Perl.
With TLSProtocolMin 3.2 set in the directory I receive the following fatal error when connecting with Perl. When I set TLSProtocolMin 3.1 thinsg works as expected.
use strict; use warnings; use diagnostics;
use Net::LDAP;
my $ldap_master = Net::LDAP->new("ldap1.wglott.lott",
port => '389',
version => 3);
$ldap_master->start_tls();
my $msg = $ldap_master->search(base => "dc=wglott,dc=lott",
filter => "(&(objectclass=posixaccount)(uid=*))",
scope => "sub");
foreach my $entry ($msg->all_entries) {
my $dn= $entry->dn;
print($dn . "\n");
}
New TCP connection #1: ldap1(42174) <-> ldap1(389)
1 1 0.0215 (0.0215) C>S Handshake
ClientHello
Version 3.1
cipher suites
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA
TLS_ECDH_anon_WITH_AES_256_CBC_SHA
TLS_DH_anon_WITH_AES_256_CBC_SHA
TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
TLS_DHE_RSA_WITH_SEED_CBC_SHA
TLS_DHE_DSS_WITH_SEED_CBC_SHA
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_anon_WITH_AES_128_CBC_SHA
TLS_DH_anon_WITH_AES_128_CBC_SHA
TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA
TLS_DH_anon_WITH_SEED_CBC_SHA
TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA
TLS_DH_anon_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_SEED_CBC_SHA
TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_IDEA_CBC_SHA
TLS_ECDHE_RSA_WITH_RC4_128_SHA
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
TLS_ECDH_anon_WITH_RC4_128_SHA
TLS_DH_anon_WITH_RC4_128_MD5
TLS_ECDH_RSA_WITH_RC4_128_SHA
TLS_ECDH_ECDSA_WITH_RC4_128_SHA
TLS_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_RC4_128_MD5
TLS_DHE_RSA_WITH_DES_CBC_SHA
TLS_DHE_DSS_WITH_DES_CBC_SHA
TLS_DH_anon_WITH_DES_CBC_SHA
TLS_RSA_WITH_DES_CBC_SHA
TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA
TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
TLS_DH_anon_EXPORT_WITH_RC4_40_MD5
TLS_RSA_EXPORT_WITH_RC4_40_MD5
TLS_EMPTY_RENEGOTIATION_INFO_SCSV
compression methods
NULL
1 2 0.0217 (0.0002) S>C Alert
level fatal
value protocol_version
1 3 0.0218 (0.0000) C>S Alert
level fatal
value protocol_version
1 0.0218 (0.0000) S>C TCP FIN
1 0.0219 (0.0000) C>S TCP RST
These are my package versions. [root@ldap1 ~]# rpm -q perl-Net-SSLeay perl-IO-Socket-SSL openssl nss openldap perl-Net-SSLeay-1.35-10.el6_8.1.x86_64 perl-IO-Socket-SSL-1.31-3.el6_8.2.noarch openssl-1.0.1e-48.el6_8.1.x86_64 nss-3.28.4-4.el6_9.x86_64 openldap-2.4.40-16.el6.x86_64 Also perl-LDAP-0.40-3.el6.noarch Your problem lies in the perl-LDAP, not in the perl-IO-Socket-SSL.
Net::LDAP documentation at start_tls() method reads:
sslversion => ’sslv2’ | ’sslv3’ | ’sslv2/3’ | ’tlsv1’
This defines the version of the SSL/TLS protocol to use. Defaults to tlsv1’.
And IO::Socket::SSL explains: "’TLSv1’ [...] restrict handshake and protocol to the specified version." Thus your Net::LDAP client forces TLS 1.0 while your server forces TLS 1.1. Therefore the TLS handshake fails.
If add some failure checks into your client:
#!/usr/bin/perl
use strict; use warnings; use diagnostics;
use Net::LDAP;
my $ldap_master = Net::LDAP->new('localhost',
port => '389',
version => 3,
);
$ldap_master->start_tls()
or die "start_tls() failed: $@\n";
my $msg = $ldap_master->search(base => "dc=wglott,dc=lott",
filter => "(&(objectclass=posixaccount)(uid=*))",
scope => "sub")
or die "search() failed: $@\n";
You can see client reports:
$ /tmp/test
syswrite() on closed filehandle GEN0 at
/usr/share/perl5/vendor_perl/Net/LDAP.pm line 806, <DATA> line 522 (#1)
(W closed) The filehandle you're writing to got itself closed sometime
before now. Check your control flow.
and the server reports:
5a252608 connection_get(12)
TLS: error: accept - force handshake failure: errno 11 - moznss error -12279
TLS: can't accept: TLS error -12279:Peer using unsupported version of security protocol..
5a252608 connection_closing: readying conn=1003 sd=12 for close
Passing 'sslversion' => 'TLSv1_1' start_tls() helps:
ldap_master->start_tls(sslversion => 'TLSv1_1')
or die "start_tls() failed: $@\n";
If you want your client to support TLS 1.1 or 1.2, you can use 'TLSv1_1:TLSv1_2'. Or you can disable SSL and keep TLS enabled with 'SSLv23:!SSLv2:!SSLv3'.
As I wrote this a documented behavior. Although I understand this is not a desired one nowadays, the change would qualify as a feature request and RHEL-6 is in a phase when new features are not accepted anymore.
You can use the work around with setting sslversion explicitly to overcome this issue.
If you insist on fixing this in the perl-LDAP package, please contact Red Hat support to help you escalate your request properly.
I already have a case open. 01964146 I believe the support engineer filed this Bugzilla on my behalf. We have a great deal of RHEL6 servers in our environments and it's not feasible to upgrade to RHEL7 anytime soon. We need this fixed. Then it's up to the support engineer to explain the urgency to the product management that can approve an exception. I, for the development side, am not against adding this change into RHEL-6. But the decision not up to me. Hello, //Business Justification from Customer// 1. Why does the customer need this? (List the business requirements here). We have a very large RHEL6 infrastructure and TLSv 1.0 is no longer acceptable for PCI compliance. 2. Is there already an existing RFE upstream or in Red Hat Bugzilla? NO 3. Does the customer have any specific timeline dependencies? ASAP 4. Is the sales team involved in this request and do they have any additional input? NO 5. List any affected packages or components? As far as I can see through testing it appears perl-LDAP and possibly some versions of openLDAP are both affected. 6. Would the customer be able to assist in testing this functionality if implemented? Absolutely. Thanks Created attachment 1363548 [details]
1st upstream fix ported to 0.40
Created attachment 1363550 [details]
2nd upstream fix ported to 0.40
An unsupported fixed package for test purposes is available on <http://people.redhat.com/~ppisar/perl-LDAP-0.40-4.el6/>. Testing instructions are in bug #1520364 comment #4. Hello Petr, This is response from Customer: The negotiation looks good. Thank you for the quick turnaround. I have confirmed the perl-LDAP test package you have provided works with TLSProtocolMin 3.2 and TLSProtocolMin 3.3 set in openLDAP. Thanks Amit This request was evaluated by Red Hat Engineering for inclusion in a Red Hat Enterprise Linux maintenance release. Red Hat does not currently plan to provide this change in a Red Hat Enterprise Linux 6 update release for currently deployed products. In Perl's LDAP module, the selection of the client SSL/TLS protocol version can be set at runtime as outlined in comment 10. We updated this code in Red Hat Enterprise Linux 7 to use the default protocol selection from IO::Socket::SSL in the following erratum: https://access.redhat.com/errata/RHEA-2018:3038 Since changing the default protocol selection can present backwards compatibility risk for existing systems, we are not planning to backport this change to Red Hat Enterprise Linux 6. With the goal of minimizing risk of change for deployed systems, and in response to customer and partner requirements, Red Hat takes a conservative approach when evaluating enhancements for inclusion in maintenance updates for currently deployed products. The primary objectives of update releases are to enable new hardware platform support and to resolve critical defects. |
Description of problem: RHEL-6.3 LDAP-server # vim slapd.conf TLSProtocolMin = 3.2 or 3.3 //TLS1.2 1.3. While 3.1(TLS1.0) works fine # smbldap-passwd user-name Cannot start TLS on LDAP connection: ldap://<>:389: SSL connect attempt failed with unknown error error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number # rpm -q perl-Net-SSLeay perl-IO-Socket-SSL perl-Net-SSLeay-1.35-10.el6_8.1.x86_64 perl-IO-Socket-SSL-1.31-3.el6_8.2.noarch Following settings in Customer LDAP configuration, perl fails to make a negotiation. TLSProtocolMin 3.2 compression methods NULL 1 2 0.0217 (0.0002) S>C Alert level fatal value protocol_version 1 3 0.0218 (0.0000) C>S Alert level fatal value protocol_version 1 0.0218 (0.0000) S>C TCP FIN 1 0.0219 (0.0001) C>S TCP RST Note: perl-IO-Socket-SSL-1.94-6.e17(RHEL-7) have no issues with TLS 3.2,3.3 Version-Release number of selected component (if applicable): perl-IO-Socket-SSL-1.31-3.el6_8.2.noarch How reproducible: All time in Customer Env Steps to Reproduce: 1. Configure TLSProtocolMin 3.2 or 3.3 in slapd.conf 2. Run smbldap-passwd user-name 3. See the Error: Cannot start TLS on LDAP connection: ldap://<>:389: SSL connect attempt failed with unknown error error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number Actual results: TLS1.1, 1.2 cannot complete SSL handshake and connection establishment. Expected results: TLS1.1, 1.2 should work fine Additional info: