# How To Install and Configure an LDAP Proxy-Cache Server

## Background

To reduce network traffic overhead and avoid problems either logging in or performing user searches while sharing, it’s an excellent idea to implement an LDAP proxy cache.

An LDAP proxy cache server, similar to other kinds of caching servers, is a special type of LDAP replica. It can cache a range of LDAP records, often resulting in improved LDAP server performance.

Specifically, the records which need to be cached, for improved ownCloud performance, are:

- Users that are allowed to log in
- Groups (limited to the allowed users)
- Search fields (e.g., `sAMAccountName`, `cn`, `sn`, `givenName`, and `displayName`)

## How To Setup the Server

There’s not that much to it, just the following five steps:

1. Install OpenLDAP
2. Configure the server
3. Edit the default configuration directory
4. Perform a test search
5. Check the logs
6. Configure ownCloud LDAP app

Let’s begin.

## 1. Install OpenLDAP

There are a number of LDAP server implementations available. The one used in this guide is OpenLDAP.

Note

While OpenLDAP does work on any operating system, for the purposes of this guide, we’ll be using a Debian-based Linux distribution.

Firstly, log in as root, and update your system, to ensure that you’re using the latest packages.:

    apt-get update && apt-get upgrade -y

Next, install OpenLDAP and its associated packages.:

    apt-get install slapd ldap-utils -y

## 2. Configure the Server

With OpenLDAP installed and running, you now need to configure the server. One way of doing so, is to create a configuration file. So, create `/etc/ldap/slapd.conf` with your text editor of choice, and add the following configuration to it.

    # This an example of a config file:

    # See slapd.conf(5)

    # Global Directives:

    # Schema and objectClass definitions

    include         /etc/ldap/schema/core.schema
    include         /etc/ldap/schema/cosine.schema
    include         /etc/ldap/schema/nis.schema
    include         /etc/ldap/schema/inetorgperson.schema

    # Where the pid file is put. The init.d script
    # will not stop the server if you change this.

    pidfile         /var/run/slapd/slapd.pid

    # List of arguments that were passed to the server

    argsfile        /var/run/slapd/slapd.args

    # Read slapd.conf(5) for possible values
    # Change loglevel to "any" if you want to see everything.

    loglevel        none

    # Where the dynamically loaded modules are stored

    modulepath      /usr/lib/ldap

    # Here are the recommended modules:

    # module for the target ldap-server

    moduleload	back_ldap.la

    # module for your local database

    moduleload	back_hdb.la

    # module for rewriting attributes

    moduleload	rwm

    # caching module

    moduleload	pcache.la

    # module to enable memberof in LDAP

    moduleload memberof.la

    # The maximum number of entries that is returned for a search operation

    sizelimit 500

    # The tool-threads parameter sets the actual amount of cpu's that is used
    # for indexing.

    tool-threads 1

    # Type of backend, for example "ldap"

    backend         ldap

    # If you only have read acces, set this to "yes"

    readonly        yes

    # Set which protocol to use, we suggest "3"

    protocol-version  3

    # remember bind credentials

    rebind-as-user

    # If you want to save time and don't want to list all the refferals, set "yes"

    norefs  yes

    # Same as above

    chase-referrals no

    # Specify the URL of your ldap server and the port.
    # For unencrypted acces use the port 389, for encrypted 636
    # If you have to use 636, you will also probably have to import
    # the certificate of your target server. restart your webserver after you do.

    uri "ldap://192.168.178.2:389"

    # The base of your directory in database, for example "dc=ldap01,dc=com"
    suffix          "dc=ldap01,dc=com"

    # rootdn directive for specifying a superuser on the database.
    # If you don't have acces to the admin user, use the one you have.

    rootdn          "cn=admin,dc=ldap01,dc=com"

    # Now we start initialising the modules
    # First the rewrite module

    overlay         rwm

    # Now we rewrite the attributes

    rwm-map         attribute uid sAMAccountName
    rwm-map         attribute dn distinguishedName

    # Next one is optional, if you want memberof, for the groups,
    # you have to load it.

    overlay         memberof

    # Now we load the caching module

    overlay pcache

    # The directive enables proxy caching
    # See slapo-pcache

    # pcache <database> <max_entries> <numattrsets> <entry_limit> <cc_period>
    # Parameters:
    #
    # <database> for cached entries.
    # <max_entries> when reached - cache replacement is invoked
    # <numattrsets> = pcacheAttrset
    # <entry_limit> limit to the number of entries returned
    # <cc_period> Consistency check time to wait

    pcache hdb 100000 3 1000 100

    # pcachePersist { TRUE | FALSE }
    # Write cached results into the database
    # Results remain in database after restart

    pcachePersist TRUE

    # Where the database file are physically stored for database #1

    directory       "/var/lib/ldap"

    # Caching templates for general search

    # pcacheAttrset <index> <attrs...>
    # First set the index number
    # Then set the attribute to cache

    pcacheAttrset   0 1.1

    # pcacheTemplate <template_string> <attrset_index> <ttl>
    # First define the querry sting to cache
    # Then reference the Attrset
    # Last set the time-to-live

    pcacheTemplate  (&(|(objectClass=))) 0 3600

    pcacheTemplate (objectClass=*) 0 3600

    # User Name Field (Advanced Tab)

    pcacheAttrset   1 displayname
    pcacheTemplate (objectClass=*) 1 3600

    # Group Field

    pcacheAttrset   2 memberOf
    pcacheTemplate (objectClass=*) 2 3600

Note

This configuration only caches queries from a single Active Directory server. To cache queries from multiple Active Directory servers, a configuration is available below.

After you’ve done that, save the file, test that there are no errors in the configuration by running:

    slaptest -f /etc/ldap/slapd.conf

Note

If you see warnings in the console output, they are not crucial.

## 3. Enable the configuration file

Next, we need to tell OpenLDAP to use our configuration. To do so, open `/etc/default/slapd` and add the following line to it:

    SLAPD_CONF=/etc/ldap/slapd.conf

With that done, restart OpenLDAP by running the following command:

    service slapd restart

## 4. Open the log

Open another terminal and see the systemlog with the following command.:

    tail -f /var/log/syslog | grep QUERY

Note

> If there is no such file, you need to install rsyslog with.:

apt install rsyslog

## 5. Perform a test search

Now that the server’s installed, configured, and running, we next need to perform a search. This will check that records are being correctly cached. To do so, update the command below with values from your Active Directory server configuration, and then run it.:

    ldapsearch -h localhost -x -LLL -D "cn=admin,cn=users,dc=example,dc=com" -b "cn=users,dc=example,dc=com" -w "Password" "(cn=Administrator)" name

or

> ldapsearch -H ldaps://localhost:636 -x -LLL -D “cn=admin,cn=users,dc=example,dc=com” -b “cn=users,dc=example,dc=com” -W “(cn=Administrator)” name

-h = host adress (Example: localhost or 192.168.1.1) -H = host adress (Example: ldap:// or ldaps:// hostname or ip and port :389 or :636 ) -x = simple authentication -b = Search Base, (Example: “cn=Users,dc=example,dc=com”) -D = User with permissions (Example: “cn=Admin,dc=example,dc=com”) -LLL = Show only results, no extra information -w = Password (“Password”) -W = Password, will ask for password and hide your input “(cn=Administrator)” = Filter the search name = Show only this attributes

If you see results including: `"Query cachable"` and `"Query answered (x) times"`, then the setup works.

## 6. Configure ownCloud LDAP App

Login as ownCloud admin in your ownCloud server.

Click on the dropdown menu in the top-left corner next to “Files”, then on Apps.

Click on “Not enabled”, and enable the “LDAP user and group backend” App.

Go to the admin dropdown menu in the top-right corner, select “Admin”.

In the administration section, click on the left side on “LDAP”.

Configure Server-Tab

First enter the server address, either IP or DN.

You can click on the button to detect your servers port or enter it manualy.

Next, enter the dn of the user, you want to log in with and in the next line enter the password.

Then you can click on “detect base dn” or enter it manualy. then click on “test base dn”.

If you fullfill all the requirements you should get a green light and “configuration ok” message.

Configure Users

Select the objectclass for the users, for example “user”.

Verify your settings; where you will see the number of users being found.

Configure Login Attributes

A configuration appears by default, adjusted it to your users configuration.

If required, adjust the login paramethers additional login attributes.

You can check users with any of the allowed login options. You can adjust them or leave them the way they are.

Configure Groups

Select all the objectclasses for your groups, for example “group”. Verify your settings.

Configure Advanced

Configuration Active shoud be selected.

Adjust the Cache TTL (time to live) value as required.

ownCloud usualy autoselects the best settings for each AD configuration.

Check if the Group-Member association is “Member (AD)”. That’s important for the users being shown in their respective groups.

Select “Nested groups”, if you have them.

Configure Expert

“Internal Username Attribute”

Here we need to set “cn” for the users being shown with their unique name. If you leave that field empty, each user will get a unique uid as a string of numbers and letters.

Clear the Username and Groupname Mapping and test your configuration by clicking on the buttons below.

Navigate to Admin -> Users and check if all your users are listed properly, and shown in the right groups.

Go to the homepage of your ownCloud server and try to share something with one of your users

If everything is set up correctly, you now have an LDAP proxy server to your active directory that will

reduce the network traffic by caching the searches your perform.

## Cache Multiple Active Directory Servers

If you have more than one that you want to cache, in `/etc/ldap/slapd.conf` add the following configuration instead, adjusting as necessary. The ownCloud LDAP app settings are the same as in section 6.

    # This an example of a config file:

    # See slapd.conf(5)

    # Global Directives:

    # Schema and objectClass definitions

    include         /etc/ldap/schema/core.schema
    include         /etc/ldap/schema/cosine.schema
    include         /etc/ldap/schema/nis.schema
    include         /etc/ldap/schema/inetorgperson.schema
    include 	/etc/ldap/schema/misc.schema

    # Where the pid file is put. The init.d script
    # will not stop the server if you change this.

    pidfile         /var/run/slapd/slapd.pid

    # List of arguments that were passed to the server

    argsfile        /var/run/slapd/slapd.args

    # Read slapd.conf(5) for possible values
    # Change loglevel to "any" if you want to see everything.

    loglevel        none

    # Where the dynamically loaded modules are stored

    modulepath      /usr/lib/ldap

    # Here are the recommended modules:

    # module for meta-database

    moduleload back_meta.la

    # module for the target ldap-server

    moduleload	back_ldap.la

    # module for your local database

    moduleload	back_hdb.la

    # module for rewriting attributes

    moduleload	rwm

    # caching module

    moduleload	pcache.la

    # module to enable memberof in ldap

    moduleload memberof.la

    # The maximum number of entries that is returned for a search operation

    sizelimit 500

    # The tool-threads parameter sets the actual amount of cpu's that is used
    # for indexing.

    tool-threads 1

    # If you want to save time and don't want to list all the refferals, set "yes"

    norefs  yes

    # Same as above

    chase-referrals no

    # See slapd-meta

    # database type, for multiple ADS "meta" is required

    database	meta

    # now we create a local ldap tree

    # in our tree we put the multiple ADS on different branches

    # we need a suffix, an admin, and a password

    suffix          "dc=owncloud,dc=com"

    rootdn		"cn=Administrator,cn=Users,dc=example,dc=com"

    rootpw "Password"

    # now we specify our ADs

    # First-AD

    # uri <protocol>://[<host>]/<naming context>

    uri             "ldap://first.ad.com:389/
    cn=users,dc=first,dc=example,dc=com"

    # here we need to set the virtual name to the real name

    # the virtual name is a branch in our new created ldap tree

    # suffixmassage <virtual naming context> <real naming context>

    suffixmassage   "cn=users,dc=first,dc=example,dc=com" "cn=users,dc=first,dc=ad,dc=com"

    # authentication parameters

    idassert-bind	bindmethod=simple
    		binddn="cn=user01,cn=users,dc=first,dc=owncloud,dc=com"
    credentials="Password01"

    # Second-AD
    uri             "ldaps://second.ad.com:636/cn=users,dc=second,dc=example,dc=com"
    suffixmassage   "cn=users,dc=second,dc=example,dc=com" "cn=users,dc=second,dc=ad,dc=com"
    idassert-bind   bindmethod=simple
                    binddn="cn=user02,cn=users,dc=second,dc=owncloud,dc=com"
                    credentials="Password02"

    # Now we start initialising the modules
    # First the rewrite module

    overlay         rwm

    # Now we rewrite the attributes

    rwm-map         attribute uid sAMAccountName
    rwm-map         attribute dn distinguishedName

    # Next one is optional, if you want memberof, for the groups,
    # you have to load it.

    overlay         memberof

    # Now we load the caching module

    overlay pcache

    # The directive enables proxy caching
    # See slapo-pcache

    # pcache <database> <max_entries> <numattrsets> <entry_limit> <cc_period>
    # Parameters:
    #
    # <database> for cached entries.
    # <max_entries> when reached - cache replacement is invoked
    # <numattrsets> = pcacheAttrset
    # <entry_limit> limit to the number of entries returned
    # <cc_period> Consistency check time to wait

    pcache hdb 100000 3 1000 100

    # pcachePersist { TRUE | FALSE }
    # Write cached results into the database
    # Results remain in database after restart

    pcachePersist TRUE

    # Where the database files are physically stored for database #1

    directory       "/var/lib/ldap"

    # Caching templates for general search

    # pcacheAttrset <index> <attrs...>
    # First set the index number
    # Then set the attribute to cache

    pcacheAttrset   0 1.1

    # pcacheTemplate <template_string> <attrset_index> <ttl>
    # First define the query sting to cache
    # Then reference the Attrset
    # Last set the time-to-live

    pcacheTemplate  (&(|(objectClass=))) 0 3600

    pcacheTemplate (objectClass=*) 0 3600

    # User Name Field (Advanced Tab)

    pcacheAttrset   1 displayname
    pcacheTemplate (objectClass=*) 1 3600

    # Group Field

    pcacheAttrset   2 memberOf
    pcacheTemplate (objectClass=*) 2 3600