LDAP: Defenses for the Directory Services Environment


The Need For Defenses

Directory Servers, as with any service provider, can be neutralized and their ability to provide directory services as specified in their Service Level Agreements (SLAs) compromised by client applications that consume large amounts of server resources. Server and operating system resources are finite and when clients make large numbers of simultaneous requests, hold their connections open without making any requests, monopolizing connections by making large numbers of requests per time period, and making requests that consume Directory Server resources, those resources are not available to other clients and connections. Clients whose requests consume large amounts of Directory Server and operating system resources reduce the resources available for other clients. This condition has a negative impact on directory server’s ability to satisfy Service Level Agreements.

Administrators should consider deploying Directory Services in such a way that critical, time-sensitive, and security-sensitive requests are managed appropriate to the level of criticality involved. For example, long running requests (requests that consume large amounts of server and operating resources), unindexed searches, and requests that result in searches that return entries with large numbers of or large-valued attributes should be isolated from main-line Directory Services where possible. Backup services should be executed from Directory Servers that are deployed out of the main-line operation path.

Client Connection Policies

Client connection policies are used to:

  1. limit LDAP client access to the directory information tree
  2. limit aspects of LDAP client performance

Client connection policies are assigned to each LDAP client connection based on the following criteria:

  1. Client IP address
  2. security
  3. authentication state
  4. authentication identity
  5. evaluation index (an ascending order integer priority)

Collectively, these properties and others associated with an LDAP client connection are known as “Connection Criteria”. All LDAP client connections are unauthenticated when the connection is first established, therefore, to enforce restrictions on all LDAP client connections to the server, it is necessary to create a client connection policy whose connection criteria include unauthenticated connections. If no client connection policy matches a connection, the connection is terminated (a default, lenient client connection policy is configured out-of-the-box).

Use the dsconfig tool to list the client connection policies. This example shows how to list the client connection policies with the server offline. The password is stored in the file ~/.pwdFile:

dsconfig --offline list-client-connection-policies \
   -j ~/.pwdFile --no-prompt --applyChangeTo single-server
Client Connection Policy : Type    : enabled : evaluation-order-index
-------------------------:---------:---------:-----------------------
default                  : generic : true    : 9999

This server is in its out-of-the-box configuration with only the default client connection policy. The client connection policy properties show that the default client connection policy is extremely lenient:

dsconfig --offline get-client-connection-policy-prop \
  --policy-name 'default' -j ~/.pwdFile --no-prompt \
  --applyChangeTo single-server
Property                                                : Value(s)
--------------------------------------------------------:------------------
policy-id                                               : default
description                                             : -
enabled                                                 : true
evaluation-order-index                                  : 9999
connection-criteria                                     : -
terminate-connection                                    : false
maximum-concurrent-connections                          : 0
maximum-connection-duration                             : 0 ms
maximum-idle-connection-duration                        : 0 ms
maximum-operation-count-per-connection                  : 0
maximum-concurrent-operations-per-connection            : 0
maximum-concurrent-operation-wait-time-before-rejecting : 0 ms
maximum-connection-operation-rate                       : -
connection-operation-rate-exceeded-behavior             : reject-busy
maximum-policy-operation-rate                           : -
policy-operation-rate-exceeded-behavior                 : reject-busy
allowed-operation                                       : abandon
allowed-operation                                       : add
allowed-operation                                       : bind
allowed-operation                                       : compare
allowed-operation                                       : delete
allowed-operation                                       : extended
allowed-operation                                       : modify
allowed-operation                                       : modify-dn
allowed-operation                                       : search
allowed-request-control                                 : -
denied-request-control                                  : -
allowed-extended-operation                              : -
denied-extended-operation                               : -
allowed-auth-type                                       : sasl
allowed-auth-type                                       : simple
allowed-sasl-mechanism                                  : -
denied-sasl-mechanism                                   : -
allowed-filter-type                                     : and
allowed-filter-type                                     : approximate-match
allowed-filter-type                                     : equality
allowed-filter-type                                     : extensible-match
allowed-filter-type                                     : greater-or-equal
allowed-filter-type                                     : less-or-equal
allowed-filter-type                                     : not
allowed-filter-type                                     : or
allowed-filter-type                                     : present
allowed-filter-type                                     : sub-any
allowed-filter-type                                     : sub-final
allowed-filter-type                                     : sub-initial
required-operation-request-criteria                     : -
prohibited-operation-request-criteria                   : -
allow-unindexed-searches                                : true
sensitive-attribute                                     : -
exclude-global-sensitive-attribute                      : -
minimum-substring-length                                : 1
maximum-search-size-limit                               : 0
maximum-search-time-limit                               : 0 s
maximum-search-lookthrough-limit                        : 0
included-backend-base-dn                                : -
excluded-backend-base-dn                                : -
result-code-map                                         : -

Connection Criteria

Connection Criteria are used to classify LDAP client connections. An LDAP client connection is initially unauthenticated and has at least the following properties:

  1. client IP address
  2. protocol
  3. security level

Connection Criteria can be created to match LDAP client IP address, connection handler, protocol, and communication security. After the authentication state for the connection is established by the BIND request, Connection Criteria can be used to match:

  1. authentication type (internal, SASL, or simple)
  2. authentication security level (any, secure-only, or insecure-only)
  3. SASL mechanism (ANONYMOUS, PLAIN, CRAM-MD5, DIGEST-MD5, EXTERNAL, or GSSAPI)
  4. authentication state distinguished name
  5. group membership
  6. a search filter that matches the entry of the authenticated user
  7. the name of a privilege held by the authenticated user

Use dsconfig to list the properties of the out-of-the-box Connection Criteria “Requests by Root Users”:

dsconfig get-connection-criteria-prop \
  --criteria-name 'Requests by Root Users' \
  --offline --applyChangeTo single-server \
  --no-prompt -j ~/.pwdFile
Property                        : Value(s)
--------------------------------:------------------------
description                     : -
included-client-address         : -
excluded-client-address         : -
included-connection-handler     : -
excluded-connection-handler     : -
included-protocol               : -
excluded-protocol               : -
communication-security-level    : any
user-auth-type                  : internal
user-auth-type                  : sasl
user-auth-type                  : simple
authentication-security-level   : any
included-user-sasl-mechanism    : -
excluded-user-sasl-mechanism    : -
included-user-base-dn           : "cn=Root DNs,cn=config"
excluded-user-base-dn           : -
all-included-user-group-dn      : -
any-included-user-group-dn      : -
not-all-included-user-group-dn  : -
none-included-user-group-dn     : -
all-included-user-filter        : -
any-included-user-filter        : -
not-all-included-user-filter    : -
none-included-user-filter       : -
all-included-user-privilege     : -
any-included-user-privilege     : -
not-all-included-user-privilege : -
none-included-user-privilege    : -

The Connection Criteria “Requests by Root Users” matches:

  1. any IP address
  2. any connection handler (LDAP, LDAPS)
  3. any protocol
  4. any security level
  5. authentication types internal, SASL, or simple
  6. any SASL mechanism
  7. authenticated user "cn=Root DNs,cn=config"

And so forth. Essentially, this connection criteria will match an LDAP client connection by a root user, or the root DN, of which there could be many entries. The default, out-of-the-box root user is "cn=Directory Manager".

Request Criteria

Use dsconfig to list the properties of the out-of-the-box Request Criteria "Search Requests":

dsconfig get-request-criteria-prop \
  --criteria-name 'Search Requests' \
  --offline --applyChangeTo single-server \
  --no-prompt -j ~/.pwdFile
Property                                   : Value(s)
-------------------------------------------:---------
description                                : -
operation-type                             : search
operation-origin                           : -
connection-criteria                        : -
all-included-request-control               : -
any-included-request-control               : -
not-all-included-request-control           : -
none-included-request-control              : -
included-target-entry-dn                   : -
excluded-target-entry-dn                   : -
all-included-target-entry-filter           : -
any-included-target-entry-filter           : -
not-all-included-target-entry-filter       : -
none-included-target-entry-filter          : -
all-included-target-entry-group-dn         : -
any-included-target-entry-group-dn         : -
not-all-included-target-entry-group-dn     : -
none-included-target-entry-group-dn        : -
target-bind-type                           : -
included-target-sasl-mechanism             : -
excluded-target-sasl-mechanism             : -
included-target-attribute                  : -
excluded-target-attribute                  : -
included-extended-operation-oid            : -
excluded-extended-operation-oid            : -
using-administrative-session-worker-thread : any

The Request Criteria "Search Requests" matches any search request.

Create Connection Criteria and Client Connection Policy

This connection criteria matches the authenticated user ‘uid=user.0,ou=people,dc=example,dc=com’ when that user authenticates using simple authentication. The description of the connection criteria is kept in the file ~/connection-criteria-description.txt:

dsconfig --applyChangeTo server-group \
  --hostname localhost --port 1389 \
  --bindDn 'cn=directory manager' --bindPasswordFile ~/.pwdFile \
  --useStartTls --trustAll --no-prompt create-connection-criteria \
  --criteria-name 'User.0 Connection Criteria'  \
  --set description:"$(< ~/connection-criteria-description.txt)"\
  --set included-user-base-dn:uid=user.0,ou=people,dc=example,dc=com \
  --set user-auth-type:simple  --type simple


The Simple Connection Criteria was created successfully

Retrieve the properties of the newly-created connection criteria:

dsconfig  --hostname localhost --port 1389 \
  --bindDn 'cn=directory manager' --bindPasswordFile ~/.pwdFile \
  --useStartTls --trustAll --no-prompt 
  get-connection-criteria-prop \
  --criteria-name 'User.0 Connection Criteria'
Property                        : Value(s)
--------------------------------:------------------------------------------------------------------------------------------------------------------------------
description                     : "This connection criteria matches the authenticated user 'uid=user.0,ou=people,dc=example,dc=com' when that user
                                : authenticates using simple authentication."
included-client-address         : -
excluded-client-address         : -
included-connection-handler     : -
excluded-connection-handler     : -
included-protocol               : -
excluded-protocol               : -
communication-security-level    : any
user-auth-type                  : simple
authentication-security-level   : any
included-user-sasl-mechanism    : -
excluded-user-sasl-mechanism    : -
included-user-base-dn           : "uid=user.0,ou=people,dc=example,dc=com"
excluded-user-base-dn           : -
all-included-user-group-dn      : -
any-included-user-group-dn      : -
not-all-included-user-group-dn  : -
none-included-user-group-dn     : -
all-included-user-filter        : -
any-included-user-filter        : -
not-all-included-user-filter    : -
none-included-user-filter       : -
all-included-user-privilege     : -
any-included-user-privilege     : -
not-all-included-user-privilege : -

This article will describe how to use connection criteria, request criteria, and client connection policies to establish a defensive mechanism for directory server. First, create a client connection policy called "Restrictive Client Connection Policy". The client connection policy will have all default values, have an evaluation-oder-index of 1000, and will be enabled. The description of the policy is kept in the file ~/client-connection-policy-description.txt.

The following command creates the client connection policy:

dsconfig --applyChangeTo server-group  \
  --hostname localhost --port 1389 --bindDn 'cn=directory manager' \
  --bindPasswordFile ~/.pwdFile --useStartTls --trustAll \
  --no-prompt create-client-connection-policy \
  --policy-name 'Restrictive Client Connection Policy'  \
  --set enabled:true --set evaluation-order-index:1000 \
  --set connection-criteria:'User.0 Connection Criteria' \
  --set description:"$(< ~/client-connection-policy-description.txt)"

The Client Connection Policy was created successfully

Retrieve the properties of the newly-created client connection policy:

dsconfig --applyChangeTo server-group \
  --hostname localhost --port 1389 \
  --bindDn 'cn=directory manager' --bindPasswordFile ~/.pwdFile \
  --useStartTls --trustAll --no-prompt get-client-connection-policy-prop \
  --policy-name 'Restrictive Client Connection Policy' 
Property                                                : Value(s)
--------------------------------------------------------:--------------------------------------------------------
policy-id                                               : Restrictive Client Connection Policy
description                                             : Restrictive Client Connection Policy (initial creation)
enabled                                                 : true
evaluation-order-index                                  : 1000
connection-criteria                                     : User.0 Connection Criteria
terminate-connection                                    : false
maximum-concurrent-connections                          : 0
maximum-connection-duration                             : 0 ms
maximum-idle-connection-duration                        : 0 ms
maximum-operation-count-per-connection                  : 0
maximum-concurrent-operations-per-connection            : 0
maximum-concurrent-operation-wait-time-before-rejecting : 0 ms
maximum-connection-operation-rate                       : -
connection-operation-rate-exceeded-behavior             : reject-busy
maximum-policy-operation-rate                           : -
policy-operation-rate-exceeded-behavior                 : reject-busy
allowed-operation                                       : abandon
allowed-operation                                       : add
allowed-operation                                       : bind
allowed-operation                                       : compare
allowed-operation                                       : delete
allowed-operation                                       : extended
allowed-operation                                       : modify
allowed-operation                                       : modify-dn
allowed-operation                                       : search
allowed-request-control                                 : -
denied-request-control                                  : -
allowed-extended-operation                              : -
denied-extended-operation                               : -
allowed-auth-type                                       : sasl
allowed-auth-type                                       : simple
allowed-sasl-mechanism                                  : -
denied-sasl-mechanism                                   : -
allowed-filter-type                                     : and
allowed-filter-type                                     : approximate-match
allowed-filter-type                                     : equality
allowed-filter-type                                     : extensible-match
allowed-filter-type                                     : greater-or-equal
allowed-filter-type                                     : less-or-equal
allowed-filter-type                                     : not
allowed-filter-type                                     : or
allowed-filter-type                                     : present
allowed-filter-type                                     : sub-any
allowed-filter-type                                     : sub-final
allowed-filter-type                                     : sub-initial
required-operation-request-criteria                     : -
prohibited-operation-request-criteria                   : -
allow-unindexed-searches                                : true
sensitive-attribute                                     : -
exclude-global-sensitive-attribute                      : -
minimum-substring-length                                : 1
maximum-search-size-limit                               : 0
maximum-search-time-limit                               : 0 s
maximum-search-lookthrough-limit                        : 0
included-backend-base-dn                                : -
excluded-backend-base-dn                                : -
result-code-map                                         : -

Issue a search request wherein the connection is authenticated as uid=user.0,ou=people,dc=example,dc=com and examine the server’s access log file:

ldapsearch -j ~/.pwdFile -D 'uid=user.0,ou=people,dc=example,dc=com' \
  -h localhost -p 1389 -b 'uid=user.0,ou=people,dc=example,dc=com' \
  -s base '(&)' 1.1
dn: uid=user.0, ou=People, dc=example, dc=com

This search in the access log. Note the initial client connection policy of 'default', which is changed to 'Restrictive Client Connection Policy' after the authentication state changes (the BIND sets the authentication state).

[04/Nov/2011:12:47:10.849 -0400] CONNECT instanceName="Alcor.local:1389" 
  conn=103 from="127.0.0.1" to="127.0.0.1" protocol="LDAP" 
  clientConnectionPolicy="default"
[04/Nov/2011:12:47:10.913 -0400] BIND RESULT instanceName="Alcor.local:1389" 
  conn=103 op=0 msgID=1 requesterIP="127.0.0.1" version="3" 
  dn="uid=user.0,ou=people,dc=example,dc=com" authType="SIMPLE" resultCode=0 
  etime=31.972 authDN="uid=user.0,ou=People,dc=example,dc=com" 
  clientConnectionPolicy="Restrictive Client Connection Policy"
[04/Nov/2011:12:47:10.924 -0400] SEARCH RESULT instanceName="Alcor.local:1389" 
  conn=103 op=1 msgID=2 requesterIP="127.0.0.1" requesterDN="uid=user.0,ou=People,dc=example,dc=com" 
  base="uid=user.0,ou=people,dc=example,dc=com" scope=0 filter="(&)" 
  attrs="1.1" resultCode=0 etime=3.131 entriesReturned=1
[04/Nov/2011:12:47:10.949 -0400] DISCONNECT instanceName="Alcor.local:1389"
   conn=103 reason="Client Unbind"

The above client connection policy will be modified to be more restrictive based on the discussion below.

Types of Attacks

On the Advisability of Restricting Connections

In the matter of restricting numbers of connections, length of idle connections, and number of operations per connection, administrators should consider whether allowing connections to remain open is more expensive from a resource allocation perspective than forcing clients to re-establish connections. It might be that it is more expensive to establish TCP/IP connections is than allowing clients to maintain connections to directory server. Administrators should have a complete understanding of the client application landscape before any changes to Directory Server configuration are made. Tests should be conducted with SLAMD, searchrate, addrate, modrate, or similar utilities to make a determination as to the advisability of making changes to Directory Server configuration.

Excessive Simultaneous Connections

Administrators should consider placing a limit on the number of connections that can be opened simultaneously. Failure to limit the number of simultaneous connections allows an application to monopolize Directory Server and operating system resources, which might result in a failure to meet SLAs due to resource contention. Determining the correct setting for the maximum number of simultaneous connections depends on understanding client requirements and taking into consideration the resources available. For example, there is nothing to be gained from allowing clients to establish 10,000 connections to Directory Server when an upstream load balancer only allows 5,000 connections per server. As a general rule, the number of simultaneous connections to Directory Server should be limited by causing a connection to be subject a client connection policy. SLAMD optimizing jobs can be used to great effect to determine the amount of traffic a given configuration can service successfully.

Restrict connections where the authenticated user is uid=user.0,ou=people,dc=example,dc=com to two (2) simultaneous connections:

dsconfig --applyChangeTo server-group  --hostname localhost \
  --port 1389 --bindDn 'cn=directory manager' \
  --bindPasswordFile ~/.pwdFile --useStartTls --trustAll \
  --no-prompt set-client-connection-policy-prop \
  --policy-name 'Restrictive Client Connection Policy' \
  --set maximum-concurrent-connections:2

The Client Connection Policy was modified successfully
#
# Retrieve the value of the 'maximum-concurrent-connections' property:
#
dsconfig --applyChangeTo server-group  --hostname localhost \
  --port 1389 --bindDn 'cn=directory manager' --bindPasswordFile ~/.pwdFile \
  --useStartTls --trustAll --no-prompt get-client-connection-policy-prop \
  --policy-name 'Restrictive Client Connection Policy' \
  --property maximum-concurrent-connections
Property                       : Value(s)
-------------------------------:---------
maximum-concurrent-connections : 2

The Directory Server will now allow a maximum of two simultaneous connections for connections whose authenticated user is uid=user.0,ou=people,dc=example,dc=com. Note that the maximum number of simultaneous connections is actually 2 times the number of servers, since the property is per server. If there are 20 servers in the topology, the maximum number of simultaneous connections for this user is 40.

To test whether a client can connect to directory server using more than two concurrent connections, use the following search rate command which authenticates as the user specified in the Connection Criteria as attempts to execute search requests on three connections ('--numThreads 3'):

# Example search rate using three threads:
searchrate -D 'uid=user.0,ou=people,dc=example,dc=com' \
   -w password -h localhost -p 1389 --filter '(uid=user.0)' \
   --scope base -b 'uid=user.0,ou=people,dc=example,dc=com' \
   --numThreads 3

After the command executes, examine the server access log:

# Connection #1
[05/Nov/2011:05:21:47.012 -0400] CONNECT instanceName="Alcor.local:1389" 
   conn=730 from="127.0.0.1" to="127.0.0.1" protocol="LDAP" clientConnectionPolicy="default"
[05/Nov/2011:05:21:47.084 -0400] BIND RESULT instanceName="Alcor.local:1389" 
   conn=730 op=0 msgID=1 requesterIP="127.0.0.1" 
   version="3" dn="uid=user.0,ou=people,dc=example,dc=com" 
   authType="SIMPLE" resultCode=0 etime=3.492 authDN="uid=user.0,ou=People,dc=example,dc=com" 
   clientConnectionPolicy="Restrictive Client Connection Policy"
# Connection #2
[05/Nov/2011:05:21:47.120 -0400] CONNECT instanceName="Alcor.local:1389" 
   conn=731 from="127.0.0.1" to="127.0.0.1" 
   protocol="LDAP" clientConnectionPolicy="default"
[05/Nov/2011:05:21:47.122 -0400] BIND RESULT instanceName="Alcor.local:1389" 
   conn=731 op=0 msgID=1 requesterIP="127.0.0.1" 
   version="3" dn="uid=user.0,ou=people,dc=example,dc=com"
    authType="SIMPLE" resultCode=0 etime=2.501 authDN="uid=user.0,ou=People,dc=example,dc=com" 
   clientConnectionPolicy="Restrictive Client Connection Policy"
# Connection #3
[05/Nov/2011:05:21:47.124 -0400] CONNECT instanceName="Alcor.local:1389" 
   conn=732 from="127.0.0.1" to="127.0.0.1" protocol="LDAP" clientConnectionPolicy="default"
[05/Nov/2011:05:21:47.125 -0400] DISCONNECT instanceName="Alcor.local:1389"
   conn=732 reason="Administrative Limit Exceeded" 
   msg="The Directory Server already has the maximum number of client 
   connections established which 
   are associated with the client connection policy defined in 
   configuration entry 
   ds-cfg-policy-id=Restrictive Client Connection Policy,cn=Client Connection Policies,cn=config"

Connection 732 was disallowed because it was the third connection, and a maximum of two concurrent connections are allowed by the Client Connection Policy.

Connection Duration

Administrators can limit the length of time a connection is allowed to remain connected to directory server using the maximum-connection-duration property of the Client Connection Policy. If maximum-connection-duration property is non-zero, the connections which exceed the number of milliseconds specified in the maximum-connection-duration property are disconnected. The advantage of limiting the time a connection can remain established is that this can result in fewer resources being consumed on directory server. Note, however, that clients which are forcibly disconnected may reconnect, therefore, administrators should dialog with application developers to ensure that the application’s requirements and needs are met.

Use dsconfig to modify the Restrictive Client Connection Policy. Specify a value of 1000 milliseconds for the maximum-connection-duration property (obviously this is an extreme example, purely for demonstration purposes):

# Use dsconfig to set the maximum-connection-duration property:
dsconfig --applyChangeTo server-group  \
   --hostname localhost --port 1389 \
   --bindDn 'cn=directory manager' \
   --bindPasswordFile ~/.pwdFile \
   --useStartTls --trustAll --no-prompt \
   set-client-connection-policy-prop \
   --policy-name 'Restrictive Client Connection Policy' \
   --set maximum-connection-duration:'1 s'
#
# Retrieve the value of the 'maximum-connection-duration' property:
#
dsconfig --applyChangeTo server-group  \
   --hostname localhost --port 1389 \
   --bindDn 'cn=directory manager' --bindPasswordFile ~/.pwdFile \
   --useStartTls --trustAll --no-prompt \
   get-client-connection-policy-prop \
   --policy-name 'Restrictive Client Connection Policy' \
   --property maximum-connection-duration
Property                    : Value(s)
----------------------------:---------
maximum-connection-duration : 1 s

To test whether a connection can remain connected past the specified connection duration, use the following searchrate command (note that now the number of concurrent connections must be restricted):

searchrate -D 'uid=user.0,ou=people,dc=example,dc=com' \
   -w password -h localhost -p 1389 --filter '(uid=user.0)' \
   --scope base -b 'uid=user.0,ou=people,dc=example,dc=com'\
   --numThreads 1
#
# Examine the access log:
#
[05/Nov/2011:05:48:09.047 -0400] CONNECT ...
[05/Nov/2011:05:48:09.050 -0400] BIND RESULT ...
[05/Nov/2011:05:48:09.050 -0400] SEARCH RESULT ...
...
[05/Nov/2011:05:48:09.607 -0400] DISCONNECT i...

Unused Idle Connections

Administrators should consider limiting the length of time a connection can remain idle. Active connections that are not being used might result in resource contention and a failure to meet SLAs – a connection attempt from a client might fail if an idle connection which could have otherwise been closed is using the last available file descriptor, for example. On the other hand, forcing clients to connect for each set of LDAP requests might be even more expensive.

The name of the Client Connection Policy property which controls the length of time a connection can be idle is maximum-idle-duration-duration, and its default value is zero, meaning idle connections are never disconnected by the server while the server is running unless the server enters lockdown mode. The length of time a connection is ‘idle’ is the number of milliseconds since the last operation completed on the connection. Any operation resets the idle connection time to zero. Use dsconfig to set the maximum-idle-duration-duration property to 1000 milliseconds:

dsconfig --applyChangeTo server-group \
    --hostname localhost --port 1389 \
    --bindDn 'cn=directory manager' \
    --bindPasswordFile ~/.pwdFile  \
    --useStartTls --trustAll --no-prompt  \
    set-client-connection-policy-prop  \
    --policy-name 'Restrictive Client Connection Policy'  \
    --set maximum-idle-connection-duration:'1 s'

The Client Connection Policy was modified successfully
#
# Retrieve the value of the 'maximum-idle-connection-duration' property:
#
dsconfig --applyChangeTo server-group \
    --hostname localhost --port 1389  \
    --bindDn 'cn=directory manager'   \
    --bindPasswordFile ~/.pwdFile   \
    --useStartTls --trustAll --no-prompt    \
    get-client-connection-policy-prop \
    --policy-name 'Restrictive Client Connection Policy' \
    --property maximum-idle-connection-duration
Property                         : Value(s)
---------------------------------:---------
maximum-idle-connection-duration : 1 s

Unlimited Number of Operations Per Connection

Administrators should consider limiting the number of requests per connection that a client can make. On the other hand, forcing clients to disconnect and reconnect after the maximum number of LDAP requests has been issued might be even more expensive. The name of the property which restricts the number of requests a client can make on a connection is maximum-operation-count-per-connection.

Use dsconfig to restrict the number of operations per connection for uid=user.0,ou=people,dc=example,dc=com to 1000:

dsconfig --applyChangeTo server-group  \
  --hostname localhost --port 1389 \
  --bindDn 'cn=directory manager' --bindPasswordFile ~/.pwdFile \
  --useStartTls --trustAll --no-prompt set-client-connection-policy-prop\
  --policy-name 'Restrictive Client Connection Policy' \
  --set maximum-operation-count-per-connection:1000

The Client Connection Policy was modified successfully

Use dsconfig to display the value of maximum-operation-count-per-connection:

dsconfig --applyChangeTo server-group \
   --hostname localhost --port 1389 \
  --bindDn 'cn=directory manager' --bindPasswordFile ~/.pwdFile \
  --useStartTls --trustAll --no-prompt \
  get-client-connection-policy-prop \
  --policy-name 'Restrictive Client Connection Policy' \
  --property maximum-operation-count-per-connection
Property                               : Value(s)
---------------------------------------:---------
maximum-operation-count-per-connection : 1000

Use searchrate to generate connections with a connection authentication identity of uid=user.0,ou=people,dc=example,dc=com:

 searchrate --bindDn 'uid=user.0,ou=people,dc=example,dc=com' \
  --bindPasswordFile ~/.pwdFile --filter '(&)'\
   --baseDn 'uid=user.0,ou=people,dc=example,dc=com'\
   --hostname localhost --port 1389 --scope base
      Recent       Recent       Recent       Recent      Overall      Overall
Searches/Sec   Avg Dur ms Entries/Srch   Errors/Sec Searches/Sec   Avg Dur ms
------------ ------------ ------------ ------------ ------------ ------------
     985.228        0.995        0.999        0.800      985.227        0.995
	Error Results:
	server down:  4

The search rate never exceeds 1000 searches per second, and then fails as the server disconnects the client at the 1000 searches per second threshold. View the access log:

[09/Nov/2011:09:09:29.020 -0500] DISCONNECT instanceName="ldap:1389" 
 conn=57 reason="Administrative Limit Exceeded" 
 msg="Terminating the client connection because it has exceeded 
 the maximum number of operations that may be processed on that connection"

This mechanism provides a way to restrict client connections to a maximum number of operations per connection. Administrators can eliminate denial-of-service attacks using this mechanism. Security auditors can be assured that the server cannot be attacked by a client by overwhelming the server. This protects against malicious attacks and also against ‘attacks’ resulting from poorly constructed LDAP client code.

Unlimited Number of Requests Per Time Period

Administrators should consider using a client connection policy to limit the number of requests per time period that a client can make. Failure to limit the number of requests per time period allows a single connection or group of related connections to monopolize Directory Server and operating system resources which might result in a failure to meet SLAs due to resource contention. The setting for the maximum number of requests per time period should be chosen with great care, for example, peak request rates should be well known, and events that cause peak request rates to increase should be known in advance. For example, major sports events often cause the number of service requests to increase. Even though it may not be possible to determine how many requests will occur due to an event, the number of requests per time period should still be limited to the number of requests that can be serviced successfully (the number of requests that can be serviced successfully can be determined with SLAMD optimizing jobs). Administrators should consider whether rejecting requests when the Directory Server is heavily loaded is of more value than allowing clients to be responsible for timeouts – it is often simpler for developers to manage rejected requests by retrying after an interval than to handle timeouts, for example, where web pages are expecting service requests to finish before loading can be completed.

Types of Requests Allowed

Administrators should consider using a client connection policy to limit the types of requests that clients can make. For example, from a policy perspective, clients that are known to issue only search and compare requests should be limited to those types of requests. Developers should interface with Directory Service administrators when a change to an application might result in a change to the applications’ Directory Service access profile. Directory Service administrators should maintain positive control over Directory Service operations, that is, clients and applications that use the Directory Service should be well-known to administrators and access to the Directory Service should be strictly controlled.

Types of Request Controls Allowed

Administrators should consider using a client connection policy to limit the types of request controls that clients can send with requests. For example, clients that are known to add only AccountUsableRequestControls to search requests should be limited to that request control – establishing and maintaining policy aids in keeping positive control over the Directory Service environment. Developers should interface with Directory Service administrators when a change to an application might result in a change to the applications’ Directory Service access profile. Directory Server publishes supported Request Controls in the root DSE.

Types of Extended Operations Allowed

Administrators should consider using a client connection policy to limit the types of extended operations and LDAP extensions that clients can request. Developers should interface with Directory Service administrators when a change to an application might result in a change to the applications’ Directory Service access profile.

Types of Filters Allowed

Administrators should consider controlling the types of filters that LDAP clients can use when making a search request. Certain filters increase load on Directory Server. Encourage developers to consider using more efficient filters.

Unindexed Searches

Administrators should consider whether clients are allowed to issue requests that would result in unindexed searches. Unindexed searches can have a negative impact on Directory Server performance that is propagated to all connections that are currently active. If applications must perform unindexed searches, for example, for data mining purposes, administrators should consider routing known unindexed searches to a set of Directory Server installations that are tuned for the express purpose of allowing unindexed searches under controlled conditions, and are not in the main Directory Service LDAP operation path. Using a dedicated Directory Server (or a redundant set of Directory Servers) for data mining purposes where that Directory Server is isolated from the main LDAP operation path protects the servers ability to meet SLAs with client applications that are not issuing search requests that result in unindexed searches. Routing search requests that are known to be unindexed can be accomplished with Directory Proxy Server.

Number of Entries Returned

Administrators should consider using a client connection policy to limit the number of entries that can be returned to a client request. Failure to limit the number of entries that can be returned to a client search request can result in a single client connection using a large amount of Directory Server and operating system resources, which might cause a failure to meet SLAs due to resource contention. Resource contention can occur because of server and operating system performance capabilities and network bandwidth. Developers should consider including a size limit with LDAP operation requests.

Amount of Time Allowed Per Request

Administrators should consider using a client connection policy to place an upper bound on the amount of time directory server spends on individual requests. Failure to limit the amount of time Directory Server spends on a single request can result in a single client connection using a large amount of Directory Server and operating system resources, which might cause a failure to meet SLAs due to resource contention. Developers should consider including a time limit with LDAP operation requests.

Look-through Limit

Administrators should consider using a client connection policy to limit the number of entries that the directory server will examine when processing a search request on a per-client basis. Failure to limit the number of entries Directory Server examines on a single request can result in a single client connection using a large amount of Directory Server and operating system resources, which might cause a failure to meet SLAs due to resource contention.

Creating the Client Connection Policy

To create the Client Connection Policy in one dsconfig command:

dsconfig create-client-connection-policy \
  --policy-name "Restrictive Client Connection Policy" \
  --set "description:Restrictive Client Connection Policy" \
  --set enabled:true --set evaluation-order-index:1000 \
  --set "connection-criteria:User.0 Connection Criteria" \
  --set maximum-concurrent-connections:2 \
  --set "maximum-connection-duration:1 s" \
  --set "maximum-idle-connection-duration:1 s" \
  --set maximum-operation-count-per-connection:1000

Notes

Updates

  • 04-NOV-2011: Added dsconfig examples for maximum-concurrent-connections
  • 05-NOV-2011: Added dsconfig examples for maximum-connection-duration
  • 05-NOV-2011: Added dsconfig examples for maximum-idle-connection-duration
  • 09-NOV-2011: Added dsconfig examples for maximum-operation-count-per-connection

About Terry Gardner

Terry Gardner was a leading directory services architect with experience with many large scale directory services installations and messaging server installations, and was a Subject Matter Expert in the field of Directory Services and Solaris (operating system) performance. Mr. Gardner also participated in the open-source software community. Mr. Gardner passed away in December, 2013.
This entry was posted in computing, LDAP, performance, UnboundID and tagged , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s