LemonLDAP::NG is designed to be very performant. Indeed, it uses Apache2 threads capabilities. So to increase performances, prefer using <ahref="http://httpd.apache.org/docs/2.2/misc/perf-tuning.html#compiletime"class="urlextern"title="http://httpd.apache.org/docs/2.2/misc/perf-tuning.html#compiletime"rel="nofollow">mpm-worker</a>.
By default, Linux does not use <abbrtitle="Domain Name System">DNS</abbr> cache and LemonLDAP::NG portal request <abbrtitle="Domain Name System">DNS</abbr> for each connexions on LDAP or DB. Under heavy loads, that can generated hundred of <abbrtitle="Domain Name System">DNS</abbr> queries and many errors on LDAP connexions (timed out) from IO::Socket.
<liclass="level1"><divclass="li"> Use <abbrtitle="Internet Protocol">IP</abbr> in configuration to avoid <abbrtitle="Domain Name System">DNS</abbr> resolution</div>
</li>
<liclass="level1"><divclass="li"> Install a <abbrtitle="Domain Name System">DNS</abbr> cache like nscd, netmask or bind</div>
For Nginx, you can use another auth server instead of llng-fastcgi-server. See: <ahref="psgi.html"class="wikilink1"title="documentation:2.0:psgi">Advanced PSGI usage</a>.
Handlers check rights and calculate headers for each HTTP hit. So to improve performances, avoid too complex rules by using macros, groups or local macros.
<h3class="sectionedit4"id="macros_and_groups">Macros and groups</h3>
<divclass="level3">
<p>
Macros and groups are calculated during authentication process by the portal:
</p>
<ul>
<liclass="level1"><divclass="li"> macros are used to extend (or rewrite) <ahref="exportedvars.html"class="wikilink1"title="documentation:2.0:exportedvars">exported variables</a>. A macro is stored as attributes: it can contain boolean results or any string</div>
<liclass="level1"><divclass="li"> macros can also be used to import environment variables <em>(these variables are in CGI format)</em>. Example: <code>$ENV{HTTP_COOKIE}</code></div>
<liclass="level1"><divclass="li"> groups are stored as space-separated strings in the special attribute “groups”: it contains the names of groups whose rules were returned true for the current user</div>
</li>
<liclass="level1"><divclass="li"> You can also get groups in <code>$hGroups</code> which is a Hash Reference of this form:</div>
<divclass="noteclassic">Groups are computed after macros, so a group rule may involve a macro value.
</div><divclass="noteimportant">Macros and groups are computed in alphanumeric order, that is, in the order they are displayed in the manager. For example, macro “macro1” will be computed before macro “macro2”: so, expression of macro2 may involve value of macro1. As same for groups: a group rule may involve another, previously computed group.
Macros and groups are stored in session database. Local macros is a special feature of handler that permit one to have macros useable localy only. Those macros are calculated only at the first usage and stored in the local session cache (only for this server) and only if the user access to the related applications. This avoid to have to many datas stored.
The portal is the biggest component of Lemonldap::NG. Since version 2.0, portal runs under FastCGI and has been rewritten using plugins, so performance is increased in comparison to earlier versions. You just have to disable unused plugins:
By default it uses local storage to store its tokens. If you have more than 1 portal and if your load-balancer doesn't keep state, you have to disable this to use the global session storage <em>(General parameters » portal Parameters » Advanced Parameters » Forms)</em>. Note that this will decrease performances.
<divclass="notetip">In production environment for network performance, prefer using minified versions of javascript and css libs: use <code>make install <strong>PROD=yes</strong></code>. This is done by default in RPM/DEB packages.
Lemonldap::NG handlers use a local cache to store sessions (for 10 minutes). So Apache::Session module is not a problem for handlers. It can be a brake for the portal:
</p>
<ol>
<liclass="level1"><divclass="li"> When you use the multiple sessions restriction parameters, sessions are parsed for each authentication unless you use an <ahref="https://metacpan.org/module/Apache::Session::Browseable"class="urlextern"title="https://metacpan.org/module/Apache::Session::Browseable"rel="nofollow">Apache::Session::Browseable</a> module.</div>
</li>
<liclass="level1"><divclass="li"> Since MySQL does not have always transaction feature, Apache::Session::MySQL has been designed to use MySQL locks. Since MySQL performances are very bad using this, if you want to store sessions in a MySQL database, prefer one of the following</div>
<divclass="notetip">Since 1.9.6, LLNG portal and handler check if session is valid at each access, so purgeCentralCache cron no longer needs to be launched every 10 minutes: one or two times per day is enough.
<h4id="replace_mysql_by_apachesessionflex">Replace MySQL by Apache::Session::Flex</h4>
<divclass="level4">
<p>
In “Apache::Session module” field, set “<ahref="https://metacpan.org/module/Apache::Session::Flex"class="urlextern"title="https://metacpan.org/module/Apache::Session::Flex"rel="nofollow">Apache::Session::Flex</a>” and use the following parameters:
</p>
<preclass="code">Store -> MySQL
Lock -> Null
Generate -> MD5
Serialize -> Storable
DataSource -> dbi:mysql:sessions;host=...
UserName -> ...
Password -> ...</pre>
<divclass="notetip">Since version 1.90 of Apache::Session, you can use Apache::Session::MySQL::NoLock instead
<ahref="https://metacpan.org/module/Apache::Session::Browseable"class="urlextern"title="https://metacpan.org/module/Apache::Session::Browseable"rel="nofollow">Apache::Session::Browseable</a> is a wrapper for other Apache::Session modules that add the capability to manage indexes. Prefer versions ≥ 1.2.5 for better performances in DB cleaning. To use it (with PostgreSQL for example), choose “Apache::Session::Browseable::Postgres” as “Apache::Session module” and use the following parameters:
Look at <ahref="browseablesessionbackend.html"class="wikilink1"title="documentation:2.0:browseablesessionbackend">Browseable session backend</a> to known which index to choose.
</p>
<divclass="noteimportant">Some Apache::Session module are not fully usable by Lemonldap::NG such as Apache::Session::Memcached since these modules do not offer capability to browse sessions. They does not allow one to use sessions explorer neither manage one-off sessions.
<divclass="notetip">A <ahref="https://metacpan.org/module/Apache::Session::Browseable::Redis"class="urlextern"title="https://metacpan.org/module/Apache::Session::Browseable::Redis"rel="nofollow">Apache::Session::Browseable::Redis</a> has been created, it is the fastest (except for session explorer, defeated by Apache::Session::Browseable::<ahref="https://metacpan.org/module/Apache::Session::Browseable"class="urlextern"title="https://metacpan.org/module/Apache::Session::Browseable"rel="nofollow">DBI</a>/<ahref="https://metacpan.org/module/Apache::Session::Browseable::LDAP"class="urlextern"title="https://metacpan.org/module/Apache::Session::Browseable::LDAP"rel="nofollow">LDAP</a>])
<liclass="level1"><divclass="li"><em><strong>(1) :</strong> “purge” test is done with Apache::Session::Browseable-1.2.5 and LLG-2.0. Earlier results are not so good.</em></div>
</li>
<liclass="level1"><divclass="li"><em><strong>(2) :</strong> “purge” test is done with Apache::Session::Browseable-1.2.6 and LLG-2.0.</em></div>
<liclass="level1"><divclass="li"> LDAP servers are “write-once-read-many”, so write performances are very bad. Don't use this on heavy load if “Session activity timeout” is enabled <em>(if set, handler “write” sessions)</em></div>
</li>
<liclass="level1"><divclass="li"> MySQL/MariaDB is better to read than to write. Prefer PostgreSQL if you use “Session activity timeout”</div>
</li>
<liclass="level1"><divclass="li"> Logged tables decrease a lot insert performances with PostgreSQL, so use unlogged tables for sessions except for persistent sessions</div>
</li>
<liclass="level1"><divclass="li"> Redis is the best for main usage</div>
</li>
<liclass="level1"><divclass="li"> Browseable::Postgres/PgHstore/PgJSON are the best SQL solutions on average</div>
So instead of using LDAP groups recovery, you just have to store “memberOf” field in your exported variables. With OpenLDAP, you can use the <ahref="http://www.openldap.org/doc/admin24/overlays.html#Reverse%20Group%20Membership%20Maintenance"class="urlextern"title="http://www.openldap.org/doc/admin24/overlays.html#Reverse%20Group%20Membership%20Maintenance"rel="nofollow">memberof overlay</a> to do it automatically.
In lemonldap-ng.ini, set only modules that you will use. By default, configuration, sessions explorer, notifications explorer and second factor are enabled. Example:
Once Manager is installed, browse enabled modules (configuration, sessions, notifications) and save the web pages respectively under <code>manager.html</code>, <code>sessions.html</code> and <code>notifications.html</code> in the <code>DocumentRoot</code> directory. Then replace this in Manager file of Apache configuration: