197 lines
No EOL
7.1 KiB
Text
197 lines
No EOL
7.1 KiB
Text
=head1 NAME
|
|
|
|
Net::LDAP::Security - Security issues with LDAP connections
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
none
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
This document discusses various security issues relating to using LDAP
|
|
and connecting to LDAP servers, notably how to manage these potential
|
|
vulnerabilities:
|
|
|
|
=over 4
|
|
|
|
=item *
|
|
|
|
do you know that you are connected to the right server
|
|
|
|
=item *
|
|
|
|
can someone sniff your passwords/userids from the directory connection
|
|
|
|
=item *
|
|
|
|
can someone sniff other confidential information from the directory
|
|
connection
|
|
|
|
=back
|
|
|
|
B<Net::LDAP> provides ways to address these vulnerabilities: through the
|
|
use of LDAPS, or LDAPv3 and TLS, and/or the use of SASL. Each of these
|
|
will be explained below.
|
|
|
|
=head2 How does an LDAP connection work
|
|
|
|
A normal LDAPv2 or LDAPv3 connection works by the client connecting
|
|
directly to port 389 (by default), and then issuing various LDAP
|
|
requests like search, add, etc.
|
|
|
|
There is no way to guarantee that an LDAP client is connected to the
|
|
right LDAP server. Hackers could have poisoned your DNS, so
|
|
'ldap.example.com' could be made to point to 'ldap.hacker.com'. Or
|
|
they could have installed their own server on the correct machine.
|
|
|
|
It is in the nature of the LDAP protocol that all information goes
|
|
between the client and the server in 'plain text'. This is a term used
|
|
by cryptographers to describe unencrypted and recoverable data, so
|
|
even though LDAP can transfer binary values like JPEG photographs,
|
|
audio clips and X.509 certificates, everything is still considered
|
|
'plain text'.
|
|
|
|
If these vulnerabilities are an issue to, then you should consider the
|
|
other possibilities described below, namely LDAPS, LDAPv3 and TLS, and
|
|
SASL.
|
|
|
|
=head2 How does an LDAPS connection work
|
|
|
|
LDAPS is an unofficial protocol. It is to LDAP what HTTPS is to HTTP,
|
|
namely the exact same protocol (but in this case LDAPv2 or LDAPv3)
|
|
running over a I<secured> SSL ("Secure Socket Layer") connection to
|
|
port 636 (by default).
|
|
|
|
Not all servers will be configured to listen for LDAPS connections,
|
|
but if they do, it will commonly be on a different port from the normal
|
|
plain text LDAP port.
|
|
|
|
Using LDAPS can I<potentially> solve the vulnerabilities described
|
|
above, but you should be aware that simply "using" SSL is not a magic
|
|
bullet that automatically makes your system "secure".
|
|
|
|
First of all, LDAPS can solve the problem of verifying that you are
|
|
connected to the correct server. When the client and server connect,
|
|
they perform a special SSL 'handshake', part of which involves the
|
|
server and client exchanging cryptographic keys, which are described
|
|
using X.509 certificates. If the client wishes to confirm that it is
|
|
connected to the correct server, all it needs to do is verify the
|
|
server's certificate which is sent in the handshake. This is done in
|
|
two ways:
|
|
|
|
=over 4
|
|
|
|
=item 1
|
|
|
|
check that the certificate is signed (trusted) by someone that you
|
|
trust, and that the certificate hasn't been revoked. For instance, the
|
|
server's certificate may have been signed by Verisign
|
|
(www.verisign.com), and you decide that you want to trust Verisign to
|
|
sign legitimate certificates.
|
|
|
|
=item 2
|
|
|
|
check that the least-significant cn RDN in the server's
|
|
certificate's DN is the fully-qualified hostname of the hostname that
|
|
you connected to when creating the LDAPS object. For example if the
|
|
server is <cn=ldap.example.com,ou=My department,o=My company>, then
|
|
the RDN to check is cn=ldap.example.com.
|
|
|
|
=back
|
|
|
|
You can do this by using the cafile and capath options when creating a
|
|
B<Net::LDAPS> object, I<and> by setting the verify option to 'require'.
|
|
|
|
To prevent hackers 'sniffing' passwords and other information on your
|
|
connection, you also have to make sure the encryption algorithm used
|
|
by the SSL connection is good enough. This is also something that gets
|
|
decided by the SSL handshake - if the client and server cannot agree
|
|
on an acceptable algorithm the connection is not made.
|
|
|
|
B<Net::LDAPS> will by default use all the algorithms built into your copy
|
|
of OpenSSL, except for ones considered to use "low" strength
|
|
encryption, and those using export strength encryption. You can
|
|
override this when you create the B<Net::LDAPS> object using the
|
|
'ciphers' option.
|
|
|
|
Once you've made the secure connection, you should also check that the
|
|
encryption algorithm that is actually being used is one that you find
|
|
acceptable. Broken servers have been observed in the field which 'fail
|
|
over' and give you an unencrypted connection, so you ought to check
|
|
for that.
|
|
|
|
=head2 How does LDAP and TLS work
|
|
|
|
SSL is a good solution to many network security problems, but it is
|
|
not a standard. The IETF corrected some defects in the SSL mechanism
|
|
and published a standard called RFC 2246 which describes TLS
|
|
("Transport Layer Security"), which is simply a cleaned up and
|
|
standardized version of SSL.
|
|
|
|
You can only use TLS with an LDAPv3 server. That is because the
|
|
standard (RFC 2830) for LDAP and TLS requires that the I<normal> LDAP
|
|
connection (ie., on port 389) can be switched on demand from plain text
|
|
into a TLS connection. The switching mechanism uses a special extended
|
|
LDAP operation, and since these are not legal in LDAPv2, you can only
|
|
switch to TLS on an LDAPv3 connection.
|
|
|
|
So the way you use TLS with LDAPv3 is that you create your normal
|
|
LDAPv3 connection using C<Net::LDAP::new()>, and then you perform the
|
|
switch using C<Net::LDAP::start_tls()>. The C<start_tls()> method takes
|
|
pretty much the same arguments as C<Net::LDAPS::new()>, so check above for
|
|
details.
|
|
|
|
=head2 How does SASL work
|
|
|
|
SASL is an authentication framework that can be used by a number of
|
|
different Internet services, including LDAPv3. Because it is only a
|
|
framework, it doesn't provide any way to authenticate by itself; to
|
|
actually authenticate to a service you need to use a specific SASL
|
|
I<mechanism>. A number of mechanisms are defined, such as CRAM-MD5.
|
|
|
|
The use of a mechanism like CRAM-MD5 provides a solution to the
|
|
password sniffing vulnerability, because these mechanisms typically do
|
|
not require the user to send across a secret (eg., a password) in the
|
|
clear across the network. Instead, authentication is carried out in a
|
|
clever way which avoids this, and so prevents passwords from being
|
|
sniffed.
|
|
|
|
B<Net::LDAP> supports SASL using the B<Authen::SASL> class. Currently the
|
|
only B<Authen::SASL> subclasses (ie., SASL mechanism) available are
|
|
CRAM-MD5 and EXTERNAL.
|
|
|
|
Some SASL mechanisms provide a general solution to the sniffing of all
|
|
data on the network vulnerability, as they can negotiate confidential
|
|
(ie., encrypted) network connections. Note that this is over and above
|
|
any SSL or TLS encryption! Unfortunately, perl's B<Authen::SASL> code
|
|
cannot negotiate this.
|
|
|
|
=head1 SEE ALSO
|
|
|
|
L<Net::LDAP>,
|
|
L<Net::LDAPS>,
|
|
L<Authen::SASL>
|
|
|
|
=head1 ACKNOWLEDGEMENTS
|
|
|
|
Jim Dutton <jimd@dutton3.it.siu.edu> provided lots of useful feedback
|
|
on the early drafts.
|
|
|
|
=head1 AUTHOR
|
|
|
|
Chris Ridd <chris.ridd@messagingdirect.com>
|
|
|
|
Please report any bugs, or post any suggestions, to the perl-ldap mailing list
|
|
<perl-ldap-dev@lists.sourceforge.net>
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
Copyright (c) 2001 Chris Ridd. All rights reserved. This program is
|
|
free software; you can redistribute it and/or modify it under the same
|
|
terms as Perl itself.
|
|
|
|
=for html <hr>
|
|
|
|
I<$Id$>
|
|
|
|
=cut |