mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-28 02:29:34 -05:00
(ITS#5524) Additions to the Security section of the Admin Guide
This commit is contained in:
parent
62904cf50d
commit
23efb86d09
1 changed files with 230 additions and 2 deletions
|
|
@ -164,6 +164,234 @@ an {{anonymous}} authorization association.
|
|||
|
||||
H3: SASL method
|
||||
|
||||
The LDAP {{TERM:SASL}} method allows use of any SASL authentication
|
||||
mechanism. The {{SECT:Using SASL}} discusses use of SASL.
|
||||
The LDAP {{TERM:SASL}} method allows the use of any SASL authentication
|
||||
mechanism. The {{SECT:Using SASL}} section discusses the use of SASL.
|
||||
|
||||
H2: Password Storage
|
||||
|
||||
LDAP passwords are normally stored in the {{userPassword}} attribute.
|
||||
RFC4519 specifies that passwords are not stored in encrypted form,
|
||||
but this can create an unwanted security exposure so {{slapd}} provides
|
||||
several options for the administrator to choose from.
|
||||
|
||||
The {{userPassword}} attribute is allowed to have more than one value,
|
||||
and it is possible for each value to be stored in a different form.
|
||||
During authentication, {{slapd}} will iterate through the values
|
||||
until it finds one that matches the offered password or until it
|
||||
runs out of values to inspect. The storage scheme is stored as a prefix
|
||||
on the value, so a Unix {{crypt}}-style password might look like this:
|
||||
|
||||
> userPassword: {CRYPT}.7D8U/PCF00Hw
|
||||
|
||||
In general is is safest to store passwords in a salted hashed format
|
||||
like SSHA. This makes it very hard for an attacker to derive passwords
|
||||
from stolen backups or by obtaining access to the on-disk {{slapd}}
|
||||
database.
|
||||
|
||||
The disadvantage of hashed storage is that it prevents the use of some
|
||||
authentication mechanisms such as {{EX:DIGEST-MD5}}.
|
||||
|
||||
H3: CLEARTEXT password storage scheme
|
||||
|
||||
Cleartext passwords can be stored directly in the {{userPassword}}
|
||||
attribute, or can have the '{CLEARTEXT}' prefix. These two values are
|
||||
equivalent:
|
||||
|
||||
> userPassword: secret
|
||||
> userPassword: {CLEARTEXT}secret
|
||||
|
||||
H3: CRYPT password storage scheme
|
||||
|
||||
This scheme uses the operating system's {{crypt(3)}} hash function.
|
||||
It normally produces the traditional Unix-style 13 character hash, but
|
||||
on systems with {{EX:glibc2}} it can also generate the more secure
|
||||
34-byte MD5 hash.
|
||||
|
||||
> userPassword: {CRYPT}aUihad99hmev6
|
||||
> userPassword: {CRYPT}$1$czBJdDqS$TmkzUAb836oMxg/BmIwN.1
|
||||
|
||||
The advantage of the CRYPT scheme is that passwords can be
|
||||
transferred to or from an existing Unix password file without having
|
||||
to know the cleartext form. Both forms of {{crypt}} include salt so
|
||||
they have some resistance to dictionary attacks.
|
||||
|
||||
H3: MD5 password storage scheme
|
||||
|
||||
This scheme simply takes the MD5 hash of the password and stores it in
|
||||
base64 encoded form:
|
||||
|
||||
> userPassword: {MD5}Xr4ilOzQ4PCOq3aQ0qbuaQ==
|
||||
|
||||
Although safer than cleartext storage, this is not a very secure
|
||||
scheme. The MD5 algorithm is fast, and because there is no salt the
|
||||
scheme is vulnerable to a dictionary attack.
|
||||
|
||||
H3: SMD5 password storage scheme
|
||||
|
||||
This improves on the basic MD5 scheme by adding salt (random data
|
||||
which means that there are many possible representations of a given
|
||||
plaintext password). For example, both of these values represent the
|
||||
same password:
|
||||
|
||||
> userPassword: {SMD5}4QWGWZpj9GCmfuqEvm8HtZhZS6E=
|
||||
> userPassword: {SMD5}g2/J/7D5EO6+oPdklp5p8YtNFk4=
|
||||
|
||||
H3: SHA password storage scheme
|
||||
|
||||
Like the MD5 scheme, this simply feeds the password through an SHA
|
||||
hash process. SHA is thought to be more secure than MD5, but the lack
|
||||
of salt leaves the scheme exposed to dictionary attacks.
|
||||
|
||||
> userPassword: {SHA}5en6G6MezRroT3XKqkdPOmY/BfQ=
|
||||
|
||||
H3: SSHA password storage scheme
|
||||
|
||||
This is the salted version of the SHA scheme. It is believed to be the
|
||||
most secure password storage sheme supported by {{slapd}}.
|
||||
|
||||
These values represent the same password:
|
||||
|
||||
> userPassword: {SSHA}DkMTwBl+a/3DQTxCYEApdUtNXGgdUac3
|
||||
> userPassword: {SSHA}d0Q0626PSH9VUld7yWpR0k6BlpQmtczb
|
||||
|
||||
H3: SASL password storage scheme
|
||||
|
||||
This is not really a password storage scheme at all. It uses the
|
||||
value of the {{userPassword}} attribute to delegate password
|
||||
verification to another process. See below for more information.
|
||||
|
||||
Note that this is not the same as using SASL to authenticate the LDAP
|
||||
session.
|
||||
|
||||
H3: KERBEROS password storage scheme
|
||||
|
||||
This is not really a password storage scheme at all. It uses the
|
||||
value of the {{userPassword}} attribute to delegate password
|
||||
verification to Kerberos. Note that this is not the same as using
|
||||
Kerberos authentication of the LDAP session. This scheme could be said
|
||||
to defeat the advantages of Kerberos by causing the Kerberos password
|
||||
to be exposed to the {{slapd}} server (and possibly on the network as
|
||||
well).
|
||||
|
||||
H2: Pass-Through authentication
|
||||
|
||||
Since OpenLDAP 2.0 {{slapd}} has had the ability to delegate password
|
||||
verification to a separate process. This uses the {{sasl_checkpass(3)}}
|
||||
function so it can use any back-end server that Cyrus SASL supports for
|
||||
checking passwords. The choice is very wide, as one option is to use
|
||||
{{saslauthd(8)}} which in turn can use local files, Kerberos, an IMAP
|
||||
server, another LDAP server, or anything supported by the PAM mechanism.
|
||||
|
||||
The server must be built with the {{EX:--enable-spasswd}}
|
||||
configuration option to enable pass-through authentication.
|
||||
|
||||
Note that this is not the same as using a SASL mechanism to
|
||||
authenticate the LDAP session. Pass-Through authentication works only
|
||||
with plaintext passwords, as used in the "simple bind" and "SASL
|
||||
PLAIN" authentication mechanisms.
|
||||
|
||||
Pass-Through authentication is selective: it only affects users whose
|
||||
{{userPassword}} attribute has a value marked with the "{SASL}"
|
||||
scheme. The format of the attribute is:
|
||||
|
||||
> userPassword: {SASL}username@realm
|
||||
|
||||
The {{username}} and {{realm}} are passed to the SASL authentication
|
||||
mechanism and are used to identify the account whose password is to be
|
||||
verified. This allows arbitrary mapping between entries in OpenLDAP
|
||||
and accounts known to the backend authentication service.
|
||||
|
||||
Note that there is no support for changing passwords in the backend
|
||||
via {{slapd}}. It would be wise to use access control to prevent users
|
||||
from changing their passwords through LDAP where they have
|
||||
pass-through authentication enabled.
|
||||
|
||||
|
||||
H3: Configuring slapd to use an authentication provider
|
||||
|
||||
Where an entry has a "{SASL}" password value, OpenLDAP delegates the
|
||||
whole process of validating that entry's password to Cyrus SASL. All
|
||||
the configuration is therefore done in SASL config files.
|
||||
|
||||
The first
|
||||
file to be considered is confusingly named {{slapd.conf}} and is
|
||||
typically found in the SASL library directory, often
|
||||
{{EX:/usr/lib/sasl2/slapd.conf}} This file governs the use of SASL
|
||||
when talking LDAP to {{slapd}} as well as the use of SASL backends for
|
||||
pass-through authentication. See {{EX:options.html}} in the Cyrus SASL
|
||||
docs for full details. Here is a simple example for a server that will
|
||||
use {{saslauthd}} to verify passwords:
|
||||
|
||||
> mech_list: plain
|
||||
> pwcheck_method: saslauthd
|
||||
> saslauthd_path: /var/run/sasl2/mux
|
||||
|
||||
H3: Configuring saslauthd
|
||||
|
||||
{{saslauthd}} is capable of using many different authentication
|
||||
services: see {{saslauthd(8)}} for details. A common requirement is to
|
||||
delegate some or all authentication to another LDAP server. Here is a
|
||||
sample {{EX:saslauthd.conf}} that uses AD:
|
||||
|
||||
> ldap_servers: ldap://dc1.example.com/ ldap://dc2.example.com/
|
||||
>
|
||||
> ldap_search_base: cn=Users,DC=ad,DC=example,DC=com
|
||||
> ldap_filter: (userPrincipalName=%u)
|
||||
>
|
||||
> ldap_bind_dn: cn=saslauthd,cn=Users,DC=ad,DC=example,DC=com
|
||||
> ldap_password: secret
|
||||
|
||||
In this case, {{saslauthd}} is run with the {{EX:ldap}} authentication
|
||||
mechanism and is set to combine the SASL realm with the login name:
|
||||
|
||||
> saslauthd -a ldap -r
|
||||
|
||||
This means that the "username@realm" string from the {{userPassword}}
|
||||
attribute ends up being used to search AD for
|
||||
"userPrincipalName=username@realm" - the password is then verified by
|
||||
attempting to bind to AD using the entry found by the search and the
|
||||
password supplied by the LDAP client.
|
||||
|
||||
H3: Testing pass-through authentication
|
||||
|
||||
It is usually best to start with the back-end authentication provider
|
||||
and work through {{saslauthd}} and {{slapd}} towards the LDAP client.
|
||||
|
||||
In the AD example above, first check that the DN and password that
|
||||
{{saslauthd}} will use when it connects to AD are valid:
|
||||
|
||||
> ldapsearch -x -H ldap://dc1.example.com/ \
|
||||
> -D cn=saslauthd,cn=Users,DC=ad,DC=example,DC=com \
|
||||
> -w secret \
|
||||
> -b '' \
|
||||
> -s base
|
||||
|
||||
Next check that a sample AD user can be found:
|
||||
|
||||
> ldapsearch -x -H ldap://dc1.example.com/ \
|
||||
> -D cn=saslauthd,cn=Users,DC=ad,DC=example,DC=com \
|
||||
> -w secret \
|
||||
> -b cn=Users,DC=ad,DC=example,DC=com \
|
||||
> "(userPrincipalName=user@ad.example.com)"
|
||||
|
||||
Check that the user can bind to AD:
|
||||
|
||||
> ldapsearch -x -H ldap://dc1.example.com/ \
|
||||
> -D cn=user,cn=Users,DC=ad,DC=example,DC=com \
|
||||
> -w userpassword \
|
||||
> -b cn=user,cn=Users,DC=ad,DC=example,DC=com \
|
||||
> -s base \
|
||||
> "(objectclass=*)"
|
||||
|
||||
If all that works then {{saslauthd}} should be able to do the same:
|
||||
|
||||
> testsaslauthd -u user@ad.example.com -p userpassword
|
||||
> testsaslauthd -u user@ad.example.com -p wrongpassword
|
||||
|
||||
Now put the magic token into an entry in OpenLDAP:
|
||||
|
||||
> userPassword: {SASL}user@ad.example.com
|
||||
|
||||
It should now be possible to bind to OpenLDAP using the DN of that
|
||||
entry and the password of the AD user.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue