LemonLDAP::NG is designed to be very performant. Indeed, it uses Apache2 threads capabilities. So to increase performances, prefer using mpm-worker.
By default, Linux does not use DNS cache and LemonLDAP::NG portal request DNS for each connexions on LDAP or DB. Under heavy loads, that can generated hundred of DNS queries and many errors on LDAP connexions (timed out) from IO::Socket.
To bypass this, you can:
For Nginx, you can use another auth server instead of llng-fastcgi-server. See: Advanced PSGI usage.
To increase handler performance, you can disable “Sessions activity timeout” to prevent it from writing to the session database.
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.
Macros and groups are calculated during authentication process by the portal:
$ENV{HTTP_COOKIE}
$hGroups
which is a Hash Reference of this form:$hGroups = { 'group3' => { 'description' => [ 'Service 3', 'Service 3 TEST' ], 'cn' => [ 'group3' ], 'name' => 'group3' }, 'admin' => { 'name' => 'admin' } }
Example for macros:
# boolean macro isAdmin -> $uid eq 'foo' or $uid eq 'bar' # other macro displayName -> $givenName." ".$surName # Use a boolean macro in a rule ^/admin -> $isAdmin # Use a string macro in a HTTP header Display-Name -> $displayName
Example for groups:
# group admin -> $uid eq 'foo' or $uid eq 'bar' # Use a group in a rule ^/admin -> $groups =~ /\badmin\b/ # Or with hGroups ^/admin -> defined $hGroups->{'admin'}
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.
# rule admin -> $admin ||= ($uid eq 'foo' or $uid eq 'bar') # header Display-Name -> $displayName ||= $givenName." ".$surName
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 (General parameters » portal Parameters » Advanced Parameters » Forms). Note that this will decrease performances.
make install PROD=yes
. 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:
In “Apache::Session module” field, set “Apache::Session::Flex” and use the following parameters:
Store -> MySQL Lock -> Null Generate -> MD5 Serialize -> Storable DataSource -> dbi:mysql:sessions;host=... UserName -> ... Password -> ...
Apache::Session::Browseable 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:
DataSource -> dbi:Pg:database=sessions;host=... UserName -> user Password -> password Index -> ipAddr uid
Note that Apache::Session::Browseable::MySQL doesn't use MySQL locks.
Look at Browseable session backend to known which index to choose.
This test isn't an “only-backend” test but embedded some LLNG methods, so real differences between engines are mitigate here.
Backend | Portal and handlers | Session explorer and one-off sessions | |||||
---|---|---|---|---|---|---|---|
Name | Configuration | Insert 1000 | Search 1 | Purge 500 | Parse all | Search by substring | Search by UID |
Apache::Session::Browseable::LDAP | mdb | 159.66 | 0.0120 | 49.22 | 0.1110 | 0.0076 | 0.0050 |
Apache::Session::MySQL | No lock | 87.20 | 0.0039 | 23.14 | 0.0281 | 0.0252 | 0.0235 |
Apache::Session::Browseable::MySQL | 91.79 | 0.0039 | 0.139 (1) | 0.0272 | 0.0036 | 0.0026 | |
Apache::Session::Browseable::MySQLJSON | 86.06 | 0.0145 | 0.151 (2) | 0.0104 | 0.0137 | 0.0038 | |
Apache::Session::Postgres | 18.31 | 0.0095 | 13.40 | 0.0323 | 0.0277 | 0.0264 | |
Apache::Session::Postgres | Unlogged table | 9.16 | 0.0095 | 7.91 | 0.0318 | 0.0270 | 0.0254 |
Apache::Session::Browseable::Postgres | Unlogged table with indexes | 9.24 | 0.0094 | 0.103 (1) | 0.0301 | 0.0036 | 0.0028 |
Apache::Session::Browseable::PgJSON | Unlogged table, json field | 9.25 | 0.0091 | 0.108 (1) | 0.0247 | 0.0035 | 0.0029 |
Apache::Session::Browseable::PgJSON | Unlogged table, jsonb field | 9.25 | 0.0091 | 0.105 (1) | 0.0126 | 0.0034 | 0.0029 |
Apache::Session::Browseable::PgHstore | Unlogged table, hstore field | 9.62 | 0.0111 | 0.105 (1) | 0.0125 | 0.0033 | 0.0029 |
Apache::Session::Redis | 2.13 | 0.0033 | 1.158 | 0.0623 | 0.0570 | 0.0550 | |
Apache::Session::Browseable::Redis | 2.36 | 0.0033 | 1.154 | 0.0643 | 0.1048 | 0.0024 | |
The source of this test is available in sources: e2e-tests/sbperf.pl |
Analysis:
LDAP server can be a brake when you use LDAP groups recovery. You can avoid this by setting “memberOf” fields in your LDAP scheme:
dn: uid=foo,dmdName=people,dc=example,dc=com ... memberOf: cn=admin,dmdName=groups,dc=example,dc=com memberOf: cn=su,dmdName=groups,dc=example,dc=com
So instead of using LDAP groups recovery, you just have to store “memberOf” field in your exported variables. With OpenLDAP, you can use the memberof overlay to do it automatically.
ldapgroups -> memberOf
For now, ldapgroups contains “cn=admin,dmdName=groups,dc=example,dc=com cn=su,dmdName=groups,dc=example,dc=com”
ldapgroups -> join(" ",($ldapgroups =~ /cn=(.*?),/g))
Now ldapgroups contains “admin su”
In lemonldap-ng.ini, set only modules that you will use. By default, configuration, sessions explorer, notifications explorer and second factor are enabled. Example:
[manager] enabledModules = conf, sessions
Once Manager is installed, browse enabled modules (configuration, sessions, notifications) and save the web pages respectively under manager.html
, sessions.html
and notifications.html
in the DocumentRoot
directory. Then replace this in Manager file of Apache configuration:
RewriteRule "^/$" "/psgi/manager-server.fcgi" [PT] # DirectoryIndex manager.html # RewriteCond "%{REQUEST_FILENAME}" "!\.html$" RewriteCond "%{REQUEST_FILENAME}" "!^/(?:static|doc|lib).*" RewriteRule "^/(.+)$" "/psgi/manager-server.fcgi/$1" [PT]
by:
# RewriteRule "^/$" "/psgi/manager-server.fcgi" [PT] DirectoryIndex manager.html RewriteCond "%{REQUEST_FILENAME}" "!\.html$" RewriteCond "%{REQUEST_FILENAME}" "!^/(?:static|doc|lib).*" RewriteRule "^/(.+)$" "/psgi/manager-server.fcgi/$1" [PT]
So manager HTML templates will be no more generated by Perl but directly given by the web server.