mirror of
https://github.com/Cacti/documentation.git
synced 2026-10-23 03:26:44 +09:00
* docs(auth): document LDAP OTP/MFA single-bind behavior and configuration Adds a One-Time Passwords (OTP / MFA) note to the LDAP authentication page explaining that Cacti binds the user's password only once, that the DN lookup never uses the user's password, and that OTP/MFA deployments should use Specific Searching with a service account and a single server. * docs(auth): recommend resilient DNS load balancer for LDAP OTP; qualify single-bind for failover; clarify No Searching
424 lines
18 KiB
Markdown
424 lines
18 KiB
Markdown
# LDAP Authentication
|
|
|
|
Cacti supports using LDAP authentication to access the Cacti GUI.
|
|
There are several different ways to use LDAP, which will be described in the
|
|
following sections.
|
|
|
|
## Be Aware
|
|
|
|
New authentication settings may not take effect immediately. We recommend to
|
|
open a **new** private browser window to test configuration changes.
|
|
|
|
## Defining some terms
|
|
|
|
Before proceeding, please ensure you are familiar with the following terms:
|
|
|
|
1. _LDAP_ - A communication language, or protocol. It is a defined structure
|
|
of how to ask questions of, and receive responses from, a directory.
|
|
It also defines what questions there exist to be asked, and what responses
|
|
there exist to be returned. LDAP is not a directory; it is a way to query
|
|
a directory.
|
|
|
|
2. _Directory_ - A database of objects, accompanied with other attributes.
|
|
Commonly, these objects are user identities, accompanied with passwords.
|
|
Sometimes, the objects are groups, accompanied by a list of members.
|
|
Usually the objects are stored in some type of hierarchical structure
|
|
for organizational and management purposes.
|
|
|
|
3. _DN_ - Short for _distinguished name_, a string that represents a
|
|
unique object in the directory. There can not be two DNs alike
|
|
in a directory. In Microsoft's _Active Directory_, this is a string
|
|
like 'CN=Joseph,OU=Accounting,OU=Users,DC=corp,DC=example,DC=com'.
|
|
|
|
4. _Search_ - A type of LDAP request, in which the client sends
|
|
some criteria to the server in an attempt to receive back a
|
|
list of directory objects that meet the search criteria.
|
|
|
|
5. _Bind_ - A type of LDAP request, in which the client sends the server a
|
|
username and a password in an attempt to confirm whether the password is
|
|
correct for that user.
|
|
|
|
6. _sAMAccountName_ - An attribute found in Microsoft's _Active Directory_
|
|
directory, and is what we casually know as a _username_. The _sAMAccountName_
|
|
does not uniquely represent an object in the Active Directory,
|
|
whereas the _DN_ does.
|
|
|
|
## Configuring LDAP
|
|
|
|
### LDAP General Settings
|
|
|
|

|
|
|
|
#### Mode
|
|
|
|
There are three basic routines that Cacti can execute when handling an
|
|
LDAP authentication.
|
|
|
|
1. _No Searching_ - In this routine, Cacti simply binds to the LDAP server
|
|
using the credentials that were entered during login. Cacti performs a
|
|
transformation upon the username before binding, that which is specified
|
|
in the _Distinguished Name (DN)_ field. This transformation is useful,
|
|
for example, to add a fully-qualified domain name suffix, or to add a NetBIOS
|
|
domain name prefix. For example:
|
|
|
|
```<username>@example.com```
|
|
|
|
or
|
|
|
|
```domain\<username>```
|
|
|
|
2._Anonymous Searching_ - In this routine, Cacti connects to LDAP with no
|
|
authentication and attempts to perform a search for the _username_, in an
|
|
attempt to retrieve the specific DN associated with the username. Once
|
|
the specific DN of the username is found, Cacti binds to LDAP using the DN of
|
|
the user and the password that was entered during login. Please note, by
|
|
default, Microsoft's Active Directory does not permit anonymous searches, and
|
|
will refuse the search request.
|
|
|
|
3.Specific Searching_- In this routine, Cacti binds to LDAP using a service
|
|
account that was provided beforehand, then performs a search for the
|
|
_username_, in an attempt to retrieve the specific DN associated with the
|
|
username. Once the specific DN of the username is found, Cacti binds to LDAP
|
|
using the DN of the user and the password that was entered during login.
|
|
|
|
#### Encryption
|
|
|
|
1. _None_ - This is plain-text, normally on port tcp/389. Passwords are
|
|
transmitted over the network in clear text between Cacti and the directory.
|
|
|
|
2. _SSL_ - Commonly known as LDAPS, this is just like LDAP, but encrypted. This
|
|
normally runs on port tcp/636. Please note, this is not enabled by default for
|
|
Microsoft's Active Directory because it requires an encryption key and
|
|
certificate to be installed on the AD controller(s).
|
|
|
|
3. _TLS_ - This is plain LDAP, but a START_TLS command is sent by the client to
|
|
the server to initiate encryption. Normally runs on port tcp/389 and can be
|
|
entered into during a regular LDAP session.
|
|
|
|
Please note that some directories will limit the request types to which they
|
|
respond when there is no encryption on the LDAP communication.
|
|
|
|
#### Referrals
|
|
|
|
An LDAP Referral is a field returned in an LDAP response message. The referral
|
|
provides a list of alternate sources from which directory information can be
|
|
obtained. In the case of a replicated directory such as Microsoft's Active
|
|
Directory, the referral may contain an LDAP URL which could resolve to any
|
|
participating LDAP server, whether correctly configured or not.
|
|
|
|
### LDAP Group Settings
|
|
|
|
Cacti can enforce that a user be a member of a specific directory group to be
|
|
granted access to Cacti. This is useful when your directory contains a mix of
|
|
users who should and should not be granted access to Cacti. For Cacti to
|
|
require that the user be apart of a group, Cacti will send a _compare_ request
|
|
to the directory server asking the server if a specific group has any
|
|
parameters that contain a specific username. As an example, a compare requests
|
|
asks the following type of question:
|
|
|
|
Does there exist a group named
|
|
`CN=cacti-admins,OU=Admin_Groups,OU=Groups,DC=corp,DC=company,DC=com`, attached
|
|
to which there is an attribute named `member`, where the value of the attribute
|
|
is `CN=Joseph,OU=Admins,DC=example,DC=com`?
|
|
|
|
The following three settings determine the content of the compare request.
|
|
|
|
1. _Group Distinguished Name (DN)_ - The DN of the group into which the
|
|
directory server should search for attributes. For example:
|
|
|
|
```html
|
|
CN=cacti-admins,OU=Admin_Groups,OU=Groups,DC=corp,DC=company,DC=com
|
|
```
|
|
|
|
2.Group Member Attribute_ - The name of the attribute into which the
|
|
directory server should search for the user. For example:
|
|
|
|
```bash
|
|
member
|
|
```
|
|
|
|
3.Group Member Type_ - The format of the text string which should represent
|
|
the user.
|
|
|
|
### Specific Search Settings
|
|
|
|
1. _Search Base_ - The portion of the directory hierarchy inside which the
|
|
server should perform the search. When the directory contains many objects,
|
|
the time and resources required to search the directory are greater. The
|
|
_search base_ setting is useful to reduce the portion of the directory that is
|
|
searched, thus increasing speed and reducing processor load on the directory
|
|
server. This setting is also useful if you want to restrict access to Cacti to
|
|
users who exist in a particular location in the director heierarchy.
|
|
|
|
2. _Search Filter_ - The criteria for which the directory server should search.
|
|
Any parameters that the server is capable of understanding are permitted here.
|
|
Cacti will perform a substitution for the phrase `<username>` in the search
|
|
filter, and will replace it with the username. This field must be in
|
|
acceptable LDAP syntax. A useful example of a search filter would be:
|
|
|
|
```bash
|
|
(sAMAccountName=<username>)
|
|
```
|
|
|
|
But more complex filers are also permitted, such as:
|
|
|
|
```bash
|
|
(&(sAMAccountName=<username>)(memberOf=CN=cacti-admins,OU=Admin_Groups,OU=Groups
|
|
,DC=corp,DC=company,DC=com))
|
|
```
|
|
|
|
3.Search Distinguished Name (DN)_ - The username of the service account with
|
|
which Cacti will bind to the directory.
|
|
|
|
4.Search Password_ - The password of the service account with which Cacti
|
|
will bind to the directory.
|
|
|
|
### LDAP CN Settings
|
|
|
|
#### Mapping an LDAP user to a Cacti user
|
|
|
|
Cacti stores many personal preferences and settings into its database that make
|
|
it easier to use Cacti. For example, the GUI Theme, the Default View Mode, and
|
|
the User Language are a few of these user settings. These settings are not
|
|
stored in the LDAP directory, so they are not returned in the LDAP response.
|
|
Therefore, Cacti will create a local user identity for each LDAP user who logs
|
|
in. When Cacti creates a local user, it can automatically populate the
|
|
following two parameters from the LDAP directory. If Cacti sees a local user
|
|
already exists, it will not attempt to update the user with values from the
|
|
directory.
|
|
|
|
1. _Full Name_ - The LDAP attribute name which contains a user's full name.
|
|
Some common examples are 'displayname' or 'cn'.
|
|
|
|
2. _Email_ - The LDAP attribute name which contains a user's email address.
|
|
One common example is 'mail'.
|
|
|
|
**Always user lower case**. No matter if the directory's attribute name contains
|
|
uppercase characters (e.g. `fullName`), the respective field must be filled
|
|
out in lower-case (`fullname`).
|
|
|
|
## A few notes
|
|
|
|
### One-Time Passwords (OTP / MFA)
|
|
|
|
Cacti supports directories where users authenticate with a One-Time Password
|
|
(OTP) or another Multi-Factor Authentication (MFA) token, but the LDAP _Mode_
|
|
must be chosen so that the user's single-use credential is presented to the
|
|
directory only once.
|
|
|
|
On a single-server authentication path, Cacti binds the user's password exactly
|
|
once, during the final authentication step. The Distinguished Name (DN) lookup
|
|
that precedes it never uses the user's password (see the note on multi-server
|
|
failover below):
|
|
|
|
- _No Searching_ performs no bind during the lookup (the DN is built from the
|
|
template), then binds once as the user.
|
|
- _Anonymous Searching_ binds anonymously to locate the DN, then binds once as
|
|
the user.
|
|
- _Specific Searching_ binds with the service account to locate the DN, then
|
|
binds once as the user.
|
|
|
|
Group membership checks, when enabled, reuse the connection that was already
|
|
bound with the user's credential and do not perform a second bind.
|
|
|
|
Because Active Directory refuses anonymous searches by default, an OTP/MFA
|
|
deployment on AD should use _Specific Searching_ with a dedicated service
|
|
account. The service account performs the directory search so that the user's
|
|
one-time code is preserved for the single authentication bind. _No Searching_
|
|
is also safe for OTP when the DN template alone identifies the user, since it
|
|
performs no directory lookup; choose _Specific_ or _Anonymous Searching_ only
|
|
when a lookup is actually required to resolve the DN.
|
|
|
|
Finally, for OTP/MFA do not use the _Server(s)_ space-delimited multi-server
|
|
list. That field fails over from left to right, so if the first server consumes
|
|
the one-time password and then returns an error, Cacti re-attempts the bind
|
|
against the next server with an already-spent code, which will fail. Instead,
|
|
point the _Server(s)_ field at a single, resilient DNS name fronted by a DNS
|
|
load balancer (VIP). Treat that DNS/load-balancer layer as the resilient,
|
|
highly-available entry point: it handles backend failover transparently, so
|
|
Cacti only ever performs one authentication bind per login and the single-use
|
|
code is never replayed.
|
|
|
|
### Certificate verification
|
|
|
|
When using LDAPS or STARTTLS, the Cacti server (as an LDAP client) must trust
|
|
the certificate presented by the directory server. PHP's LDAP functions use the
|
|
system OpenLDAP library, which reads its certificate configuration from
|
|
`/etc/ldap/ldap.conf` (Debian/Ubuntu) or `/etc/openldap/ldap.conf`
|
|
(RHEL/Rocky/AlmaLinux).
|
|
|
|
#### Adding a CA certificate on Linux
|
|
|
|
If the directory server uses a certificate signed by an internal CA or a
|
|
self-signed certificate, install the CA certificate on the Cacti server and
|
|
configure the OpenLDAP client library to trust it.
|
|
|
|
**Debian/Ubuntu:**
|
|
|
|
```shell
|
|
# Copy the CA certificate
|
|
cp /path/to/internal-ca.crt /usr/local/share/ca-certificates/internal-ca.crt
|
|
|
|
# Update the system trust store
|
|
update-ca-certificates
|
|
|
|
```
|
|
|
|
Add the following line to `/etc/ldap/ldap.conf` if not already present:
|
|
|
|
```console
|
|
TLS_CACERT /etc/ssl/certs/ca-certificates.crt
|
|
```
|
|
|
|
**RHEL/Rocky/AlmaLinux:**
|
|
|
|
```shell
|
|
# Copy the CA certificate
|
|
cp /path/to/internal-ca.crt /etc/pki/ca-trust/source/anchors/internal-ca.crt
|
|
|
|
# Update the system trust store
|
|
update-ca-trust extract
|
|
|
|
```
|
|
|
|
Add the following line to `/etc/openldap/ldap.conf` if not already present:
|
|
|
|
```console
|
|
TLS_CACERT /etc/pki/tls/cert.pem
|
|
```
|
|
|
|
#### Controlling certificate verification strictness
|
|
|
|
By default, the OpenLDAP library requires a valid, trusted certificate
|
|
(`TLS_REQCERT demand`). You can relax this for testing, but do not disable
|
|
verification in production; it exposes the LDAP bind to interception.
|
|
|
|
```console
|
|
# /etc/ldap/ldap.conf or /etc/openldap/ldap.conf
|
|
|
|
# Require a valid certificate (default, recommended for production)
|
|
TLS_REQCERT demand
|
|
|
|
# Accept certificates signed by the configured CA even if the hostname
|
|
# does not match (useful if the LDAP server has an internal hostname)
|
|
TLS_REQCERT allow
|
|
|
|
# Disable certificate verification entirely — DO NOT use in production
|
|
TLS_REQCERT never
|
|
```
|
|
|
|
#### Verifying the configuration
|
|
|
|
Test the LDAP TLS connection from the Cacti server before enabling it in Cacti:
|
|
|
|
```shell
|
|
# Test LDAPS (port 636)
|
|
openssl s_client -connect ldap.example.com:636 -CAfile /path/to/ca.crt
|
|
|
|
# Test STARTTLS (port 389)
|
|
openssl s_client -connect ldap.example.com:389 -starttls ldap -CAfile /path/to/ca.crt
|
|
```
|
|
|
|
> **Note**: `openssl s_client` verifies the certificate chain but does not
|
|
> check the server hostname. Use `ldapsearch` or a dedicated TLS testing tool
|
|
> (e.g. `testssl.sh`) to confirm hostname validation.
|
|
|
|
```shell
|
|
# Full LDAP query over TLS using ldapsearch (-W prompts for password)
|
|
ldapsearch -H ldaps://ldap.example.com -b "dc=example,dc=com" \
|
|
-D "cn=service,dc=example,dc=com" -W "(cn=testuser)"
|
|
```
|
|
|
|
A successful `CONNECTED` and `Verify return code: 0 (ok)` in the `openssl`
|
|
output confirms the Cacti server trusts the certificate.
|
|
|
|
#### Adding a CA certificate on Windows (IIS)
|
|
|
|
On Windows, PHP's LDAP extension uses the Windows Certificate Store. Import the
|
|
CA certificate using the Microsoft Management Console:
|
|
|
|
1. Open `mmc.exe`, go to **File > Add/Remove Snap-in**, add
|
|
**Certificates** for the **Computer account**.
|
|
2. Expand **Trusted Root Certification Authorities > Certificates**.
|
|
3. Right-click, select **All Tasks > Import**, and follow the wizard to import
|
|
the CA certificate (`.crt` or `.cer` file).
|
|
4. Restart the IIS service (`net stop w3svc && net start w3svc`) for the
|
|
change to take effect.
|
|
|
|
### Search Result Reference (Referrals)
|
|
|
|
In Microsoft's Active Directory, LDAP response messages may contain a referral
|
|
to other directory servers. If you are using LDAPS and have installed a
|
|
certificate on some LDAP servers and not others, LDAP lookups will fail
|
|
intermittently because LDAPS negotiations will succeed with some directory
|
|
servers while failing with other directory servers. If you are experiencing
|
|
intermittent LDAP failures, ensure that the Cacti server has network access to
|
|
all directory servers, and that all directory servers are properly configured.
|
|
|
|
## Common Scenarios
|
|
|
|
These following scenarios are designed to help you see the different ways to
|
|
harness the power of LDAP and build a working LDAP configuration in your
|
|
environment.
|
|
|
|
### A small office where everyone has access to Cacti
|
|
|
|
In this scenario, a small LDAP directory contains users who are all granted
|
|
access to Cacti (there are no users denied from Cacti). Some may be
|
|
administrators, while others are read-only users.
|
|
|
|
To handle this scenario, start by creating a new local user in Cacti with
|
|
read-only permissions. Name the user 'MyLdapTemplate'. Next, in Cacti's
|
|
Authentication settings, set the `User Template` field to 'MyLdapTemplate'.
|
|
Set the `Mode` to 'No Searching'. Set the `Distinguished Name (DN)` field to
|
|
```<username>@example.com'```, where 'example.com' is the name of your domain.
|
|
When any user logs in to Cacti, their password will be checked against the LDAP
|
|
directory and they'll be granted access to Cacti with read-only access (from
|
|
the LDAP template user). Once a new user logs in, Cacti will create a local
|
|
user where the user's `Realm` is 'LDAP'. You may then optionally promote that
|
|
user to an administrator by visiting the `Users` page, locating the account for
|
|
the LDAP user, and granting additional permissions to that user.
|
|
|
|
### A large office where you only want a subset of users to access Cacti
|
|
|
|
In this scenario, a large LDAP directory contains a mix of users who should,
|
|
and should not, be granted access to Cacti.
|
|
|
|
There are two ways to handle this scenario. You may either manually authorize
|
|
users within Cacti, or you may use a group in the directory to define the
|
|
authorized users.
|
|
|
|
To handle this scenario by manually authorizing users within Cacti, navigate to
|
|
the Authentication settings, and set the `User Template` field to 'No User'.
|
|
Set the `Mode` to 'No Searching'. Set the `Distinguished Name (DN)` field t
|
|
```<username>@example.com```, where 'example.com' is the name of your domain.
|
|
Next, navigate to the `Users` page and create a new user where the username
|
|
matches the username in the directory. Set the user's `Realm` to 'LDAP'.
|
|
Grant your desired permissions to the user. When that user logs in to Cacti,
|
|
their password will be checked against the LDAP directory and they'll be
|
|
granted access to Cacti based upon their local account.
|
|
|
|
To handle the large office scenario by using group membership, start by
|
|
creating a user in the directory that can be used for searching the directory
|
|
(this is sometimes referred to as a Service Account). Under normal
|
|
circumstances, this directory user does not need elevated permissions. Next,
|
|
create a group in the directory that contains all the users who should be
|
|
granted access to Cacti. Next, in Cacti, create a new local user named
|
|
'MyLdapTemplate', with administrator permissions. In Cacti's Authentication
|
|
settings, set the `User Template` field to 'MyLdapTemplate'. Set the `Mode` to
|
|
'Specific Searching'. Leave the `Distinguished Name (DN)` field blank. Set
|
|
the `Require Group Membership` field to enabled. Set the `Group Distinguished
|
|
Name (DN)` to the name of the group. Set `Group Member Attribute` to 'member'.
|
|
Set `Group Member Type` to 'Distinguished Name'. Set `Search Base` to the DN
|
|
of the hierarchical structure in the directory which contains all the users,
|
|
such as 'OU=Users,DC=example,DC=com'. Set `Search Filter` to
|
|
```'sAMAccountName=<username>'```. Set `Search Distinguished Name (DN)` to the
|
|
username of the service account you created in the directory. Set `Search
|
|
Password` to the password for the service account. Optionally, set `Full Name`
|
|
to the directory attribute that contains the user's name, such as 'cn', and
|
|
also set `Email` to the directory attribute that contains the user's email
|
|
address, such as 'mail'.
|
|
|
|
---
|
|
Copyright (c) 2004-2026 The Cacti Group
|