security.sdf 15.2 KB
Newer Older
Gavin Henry's avatar
Gavin Henry committed
1
# $OpenLDAP$
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
2
# Copyright 1999-2021 The OpenLDAP Foundation, All Rights Reserved.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
3
# Portions Copyright 2008 Andrew Findlay.
4
5
6
7
8
9
# COPYING RESTRICTIONS APPLY, see COPYRIGHT.

H1: Security Considerations

OpenLDAP Software is designed to run in a wide variety of computing
environments from tightly-controlled closed networks to the global
Kurt Zeilenga's avatar
Kurt Zeilenga committed
10
Internet.  Hence, OpenLDAP Software supports many different security
11
12
mechanisms.  This chapter describes these mechanisms and discusses
security considerations for using OpenLDAP Software.
13

14
15
H2: Network Security

Kurt Zeilenga's avatar
Kurt Zeilenga committed
16
H3: Selective Listening
17
18
19
20

By default, {{slapd}}(8) will listen on both the IPv4 and IPv6 "any"
addresses.  It is often desirable to have {{slapd}} listen on select
address/port pairs.  For example, listening only on the IPv4 address
Kurt Zeilenga's avatar
Kurt Zeilenga committed
21
22
23
24
{{EX:127.0.0.1}} will disallow remote access to the directory server.
E.g.:

>	slapd -h ldap://127.0.0.1
25
26
27
28

While the server can be configured to listen on a particular interface
address, this doesn't necessarily restrict access to the server to
only those networks accessible via that interface.   To selective
29
30
restrict remote access, it is recommend that an {{SECT:IP Firewall}}
be used to restrict access.
31
32
33
34
35
36
37

See {{SECT:Command-line Options}} and {{slapd}}(8) for more
information.


H3: IP Firewall

Kurt Zeilenga's avatar
Kurt Zeilenga committed
38
39
40
{{TERM:IP}} firewall capabilities of the server system can be used
to restrict access based upon the client's IP address and/or network
interface used to communicate with the client.
41

Kurt Zeilenga's avatar
Kurt Zeilenga committed
42
43
44
Generally, {{slapd}}(8) listens on port 389/tcp for {{F:ldap://}}
sessions and port 636/tcp for {{F:ldaps://}}) sessions.  {{slapd}}(8)
may be configured to listen on other ports.
45
46
47
48
49
50
51
52

As specifics of how to configure IP firewall are dependent on the
particular kind of IP firewall used, no examples are provided here.
See the document associated with your IP firewall.


H3: TCP Wrappers

Kurt Zeilenga's avatar
Kurt Zeilenga committed
53
54
55
{{slapd}}(8) supports {{TERM:TCP}} Wrappers.  TCP Wrappers provide
a rule-based access control system for controlling TCP/IP access
to the server.  For example, the {{host_options}}(5) rule:
56
57
58
59

>	slapd: 10.0.0.0/255.0.0.0 127.0.0.1 : ALLOW
>	slapd: ALL : DENY

Kurt Zeilenga's avatar
Kurt Zeilenga committed
60
61
allows only incoming connections from the private network {{F:10.0.0.0}}
and localhost ({{F:127.0.0.1}}) to access the directory service.
62
63

Note: IP addresses are used as {{slapd}}(8) is not normally
64
configured to perform reverse lookups.
65
66
67

It is noted that TCP wrappers require the connection to be accepted.
As significant processing is required just to deny a connection,
Kurt Zeilenga's avatar
Kurt Zeilenga committed
68
69
it is generally advised that IP firewall protection be used instead
of TCP wrappers.
70
71

See {{hosts_access}}(5) for more information on TCP wrapper rules.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
72
73


Kurt Zeilenga's avatar
Kurt Zeilenga committed
74
H2: Data Integrity and Confidentiality Protection
Kurt Zeilenga's avatar
Kurt Zeilenga committed
75

Kurt Zeilenga's avatar
Kurt Zeilenga committed
76
77
78
79
80
{{TERM[expand]TLS}} (TLS) can be used to provide data integrity and
confidentiality protection.  OpenLDAP supports negotiation of
{{TERM:TLS}} ({{TERM:SSL}}) via both StartTLS and {{F:ldaps://}}.
See the {{SECT:Using TLS}} chapter for more information.  StartTLS
is the standard track mechanism.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
81

Kurt Zeilenga's avatar
Kurt Zeilenga committed
82
83
84
85
A number of {{TERM[expand]SASL}} (SASL) mechanisms, such as
{{TERM:DIGEST-MD5}} and {{TERM:GSSAPI}}, also provide data integrity
and confidentiality protection.  See the {{SECT:Using SASL}} chapter
for more information.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
86

Kurt Zeilenga's avatar
Kurt Zeilenga committed
87
88
89

H3: Security Strength Factors

Kurt Zeilenga's avatar
Kurt Zeilenga committed
90
91
92
93
94
95
The server uses {{TERM[expand]SSF}}s (SSF) to indicate the relative
strength of protection.  A SSF of zero (0) indicates no protections
are in place.  A SSF of one (1) indicates integrity protection are
in place.  A SSF greater than one (>1) roughly correlates to the
effective encryption key length.  For example, {{TERM:DES}} is 56,
{{TERM:3DES}} is 112, and {{TERM:AES}} 128, 192, or 256.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
96
97
98
99
100
101
102
103
104
105

A number of administrative controls rely on SSFs associated with
TLS and SASL protection in place on an LDAP session.

{{EX:security}} controls disallow operations when appropriate
protections are not in place.  For example:

>	security ssf=1 update_ssf=112

requires integrity protection for all operations and encryption
Kurt Zeilenga's avatar
Kurt Zeilenga committed
106
107
108
protection, 3DES equivalent, for update operations (e.g. add, delete,
modify, etc.).  See {{slapd.conf}}(5) for details.

109
For fine-grained control, SSFs may be used in access controls.
Gavin Henry's avatar
Gavin Henry committed
110
See the {{SECT:Access Control}} section for more information.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
111
112
113
114
115
116
117
118
119
120
121
122


H2: Authentication Methods

H3: "simple" method

The LDAP "simple" method has three modes of operation:

* anonymous,
* unauthenticated, and
* user/password authenticated.

Kurt Zeilenga's avatar
Kurt Zeilenga committed
123
124
125
126
Anonymous access is requested by providing no name and no password
to the "simple" bind operation.  Unauthenticated access is requested
by providing a name but no password.  Authenticated access is
requested by providing a valid name and password.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
127

Kurt Zeilenga's avatar
Kurt Zeilenga committed
128
129
130
An anonymous bind results in an {{anonymous}} authorization
association.  Anonymous bind mechanism is enabled by default, but
can be disabled by specifying "{{EX:disallow bind_anon}}" in
131
132
133
134
135
{{slapd.conf}}(5).  

Note: Disabling the anonymous bind mechanism does not prevent 
anonymous access to the directory. To require authentication to 
access the directory, one should instead specify "{{EX:require authc}}".
Kurt Zeilenga's avatar
Kurt Zeilenga committed
136

Kurt Zeilenga's avatar
Kurt Zeilenga committed
137
138
139
140
141
142
143
An unauthenticated bind also results in an {{anonymous}} authorization
association.  Unauthenticated bind mechanism is disabled by default,
but can be enabled by specifying "{{EX:allow bind_anon_cred}}" in
{{slapd.conf}}(5).  As a number of LDAP applications mistakenly
generate unauthenticated bind request when authenticated access was
intended (that is, they do not ensure a password was provided),
this mechanism should generally remain disabled.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
144

Kurt Zeilenga's avatar
Kurt Zeilenga committed
145
146
147
A successful user/password authenticated bind results in a user
authorization identity, the provided name, being associated with
the session.  User/password authenticated bind is enabled by default.
Gavin Henry's avatar
Gavin Henry committed
148
However, as this mechanism itself offers no eavesdropping protection
Kurt Zeilenga's avatar
Kurt Zeilenga committed
149
150
(e.g., the password is set in the clear), it is recommended that
it be used only in tightly controlled systems or when the LDAP
Kurt Zeilenga's avatar
Kurt Zeilenga committed
151
session is protected by other means (e.g., TLS, {{TERM:IPsec}}).
Kurt Zeilenga's avatar
Kurt Zeilenga committed
152
153
Where the administrator relies on TLS to protect the password, it
is recommended that unprotected authentication be disabled.  This
154
155
is done using the {{EX:security}} directive's {{EX:simple_bind}}
option, which provides fine grain control over the level of confidential
Kurt Zeilenga's avatar
Kurt Zeilenga committed
156
protection to require for {{simple}} user/password authentication.
157
158
E.g., using {{EX:security simple_bind=56}} would require {{simple}}
binds to use encryption of DES equivalent or better.
159

Kurt Zeilenga's avatar
Kurt Zeilenga committed
160
161
The user/password authenticated bind mechanism can be completely
disabled by setting "{{EX:disallow bind_simple}}".
Kurt Zeilenga's avatar
Kurt Zeilenga committed
162

163
Note: An unsuccessful bind always results in the session having
Kurt Zeilenga's avatar
Kurt Zeilenga committed
164
an {{anonymous}} authorization association.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
165
166
167


H3: SASL method
Kurt Zeilenga's avatar
Kurt Zeilenga committed
168

169
The LDAP {{TERM:SASL}} method allows the use of any SASL authentication
170
mechanism. The {{SECT:Using SASL}} section discusses the use of SASL.
171
172
173
174

H2: Password Storage

LDAP passwords are normally stored in the {{userPassword}} attribute.
175
176
177
178
179
180
181
182
183
184
185
186
187
{{REF:RFC4519}} specifies that passwords are not stored in encrypted
(or hashed) form.  This allows a wide range of password-based
authentication mechanisms, such as {{EX:DIGEST-MD5}} to be used.
This is also the most interoperable storage scheme.

However, it may be desirable to store a hash of password instead.
{{slapd}}(8) supports a variety of storage schemes for the administrator
to choose from.

Note: Values of password attributes, regardless of storage scheme
used, should be protected as if they were clear text.  Hashed
passwords are subject to {{dictionary attacks}} and {{brute-force
attacks}}.
188
189
190
191
192

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
193
194
195
runs out of values to inspect.  The storage scheme is stored as a prefix
on the value, so a hashed password using the Salted SHA1 ({{EX:SSHA}})
scheme looks like:
196

197
> userPassword: {SSHA}DkMTwBl+a/3DQTxCYEApdUtNXGgdUac3
198

Gavin Henry's avatar
Gavin Henry committed
199
The advantage of hashed passwords is that an attacker which
200
discovers the hash does not have direct access to the actual password.
Gavin Henry's avatar
Gavin Henry committed
201
Unfortunately, as dictionary and brute force attacks are generally
202
quite easy for attackers to successfully mount, this advantage is
Gavin Henry's avatar
Gavin Henry committed
203
204
marginal at best (this is why all modern Unix systems use shadow
password files).
205

Gavin Henry's avatar
Gavin Henry committed
206
207
The disadvantages of hashed storage is that they are non-standard, may
cause interoperability problem, and generally preclude the use
208
of stronger than Simple (or SASL/PLAIN) password-based authentication
Gavin Henry's avatar
Gavin Henry committed
209
mechanisms such as {{EX:DIGEST-MD5}}.
210

211
H3: SSHA password storage scheme
212

213
214
This is the salted version of the SHA scheme. It is believed to be the
most secure password storage scheme supported by {{slapd}}.
215

216
217
218
219
These values represent the same password:

> userPassword: {SSHA}DkMTwBl+a/3DQTxCYEApdUtNXGgdUac3
> userPassword: {SSHA}d0Q0626PSH9VUld7yWpR0k6BlpQmtczb
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235

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.

Gavin Henry's avatar
Gavin Henry committed
236
237
Note: Since this scheme uses the operating system's {{crypt(3)}}
hash function, it is therefore operating system specific.
238

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
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: 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.

274
Note: This is not the same as using SASL to authenticate the LDAP
275
276
277
278
279
280
281
282
283
284
285
286
287
288
session.

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.

289
290
291
292
Note: This is not the same as using a SASL mechanism to
authenticate the LDAP session.

Pass-Through authentication works only with plaintext passwords, as 
293
used in the "simple bind" and "SASL PLAIN" authentication mechanisms.
294
295
296
297
298
299
300
301
302
303
304
305

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.

306
307
308
It would be wise to use access control to prevent users from changing 
their passwords through LDAP where they have pass-through authentication 
enabled.
309
310
311
312
313
314
315
316
317
318
319
320
321


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
322
pass-through authentication. See {{EX:options.html}} in the {{PRD:Cyrus SASL}}
323
324
325
326
327
328
329
330
331
332
333
334
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
335
sample {{EX:saslauthd.conf}} that uses Microsoft Active Directory (AD):
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397

> 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.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
398