MySQL 8.0 Reference Manual Including MySQL NDB Cluster 8.0
LDAP pluggable authentication is an extension included in MySQL Enterprise Edition, a commercial product. To learn more about commercial products, see https://www.mysql.com/products/.
MySQL Enterprise Edition supports an authentication method that enables MySQL Server to use LDAP (Lightweight Directory Access Protocol) to authenticate MySQL users by accessing directory services such as X.500. MySQL uses LDAP to fetch user, credential, and group information.
LDAP pluggable authentication provides these capabilities:
External authentication: LDAP authentication enables MySQL Server to accept connections from users defined outside the MySQL grant tables in LDAP directories.
Proxy user support: LDAP authentication can return to MySQL
a user name different from the external user name passed by
the client program, based on the LDAP groups the external
user is a member of. This means that an LDAP plugin can
return the MySQL user that defines the privileges the
external LDAP-authenticated user should have. For example,
an LDAP user named joe
can connect and
have the privileges of a MySQL user named
developer
, if the LDAP group for
joe
is developer
.
Security: Using TLS, connections to the LDAP server can be secure.
The following tables show the plugin and library file names for
simple and SASL-based LDAP authentication. The file name suffix
might differ on your system. The files must be located in the
directory named by the
plugin_dir
system variable.
Table 6.18 Plugin and Library Names for Simple LDAP Authentication
Plugin or File | Plugin or File Name |
---|---|
Server-side plugin name | authentication_ldap_simple |
Client-side plugin name | mysql_clear_password |
Library file name | authentication_ldap_simple.so |
Table 6.19 Plugin and Library Names for SASL-Based LDAP Authentication
Plugin or File | Plugin or File Name |
---|---|
Server-side plugin name | authentication_ldap_sasl |
Client-side plugin name | authentication_ldap_sasl_client |
Library file names | authentication_ldap_sasl.so ,
authentication_ldap_sasl_client.so |
The library files include only the
authentication_ldap_
authentication plugins. The client-side
XXX
mysql_clear_password
plugin is built into the
libmysqlclient
client library.
Each server-side LDAP plugin works with a specific client-side plugin:
The server-side
authentication_ldap_simple
plugin
performs simple LDAP authentication. For connections by
accounts that use this plugin, client programs use the
client-side mysql_clear_password
plugin,
which sends the password to the server as cleartext. No
password hashing or encryption is used, so a secure
connection between the MySQL client and server is
recommended to prevent password exposure.
The server-side authentication_ldap_sasl
plugin performs SASL-based LDAP authentication. For
connections by accounts that use this plugin, client
programs use the client-side
authentication_ldap_sasl_client
plugin.
The client-side and server-side SASL LDAP plugins use SASL
messages for secure transmission of credentials within the
LDAP protocol, to avoid sending the cleartext password
between the MySQL client and server.
The following sections provide installation and usage information specific to LDAP pluggable authentication:
For general information about pluggable authentication in MySQL,
see Section 6.2.17, “Pluggable Authentication”. For information
about the mysql_clear_password
plugin, see
Section 6.4.1.4, “Client-Side Cleartext Pluggable Authentication”. For proxy
user information, see Section 6.2.18, “Proxy Users”.
If your system supports PAM and permits LDAP as a PAM
authentication method, another way to use LDAP for MySQL user
authentication is to use the server-side
authentication_pam
plugin. See
Section 6.4.1.5, “PAM Pluggable Authentication”.
To use LDAP pluggable authentication for MySQL, these prerequisites must be satisfied:
An LDAP server must be available for the LDAP authentication plugins to communicate with.
LDAP users to be authenticated by MySQL must be present in the directory managed by the LDAP server.
An LDAP client library must be available on systems where
the server-side
authentication_ldap_sasl
or
authentication_ldap_simple
plugin is
used. Currently, supported libraries are the Windows
native LDAP library, or the OpenLDAP library on
non-Windows systems.
To use SASL-based LDAP authentication:
The LDAP server must be configured to communicate with a SASL server.
A SASL client library must be available on systems
where the client-side
authentication_ldap_sasl_client
plugin is used. Currently, the only supported library
is the Cyrus SASL library.
To use a particular SASL authentication method, any other services required by that method must be available. For example, to use GSSAPI/Kerberos, a GSSAPI library and Kerberos services must be available.
This section provides a general overview of how MySQL and LDAP work together to authenticate MySQL users. For examples showing how to set up MySQL accounts to use specific LDAP authentication plugins, see Using LDAP Pluggable Authentication. For information about authentication methods available to the LDAP plugins, see LDAP Authentication Methods.
The client connects to the MySQL server, providing the MySQL client user name and a password:
For simple LDAP authentication, the client-side and server-side plugins communicate the password as cleartext. A secure connection between the MySQL client and server is recommended to prevent password exposure.
For SASL-based LDAP authentication, the client-side and server-side plugins avoid sending the cleartext password between the MySQL client and server. For example, the plugins might use SASL messages for secure transmission of credentials within the LDAP protocol. For the GSSAPI authentication method, the client-side and server-side plugins communicate securely using Kerberos without using LDAP messages directly.
If the client user name and host name match no MySQL account, the connection is rejected.
If there is a matching MySQL account, authentication against LDAP occurs. The LDAP server looks for an entry matching the user and authenticates the entry against the LDAP password:
If the MySQL account names an LDAP user distinguished name
(DN), LDAP authentication uses that value and the LDAP
password provided by the client. (To associate an LDAP
user DN with a MySQL account, include a
BY
clause that specifies an
authentication string in the CREATE
USER
statement that creates the account.)
If the MySQL account names no LDAP user DN, LDAP authentication uses the user name and LDAP password provided by the client. In this case, the authentication plugin first binds to the LDAP server using the root DN and password as credentials to find the user DN based on the client user name, then authenticates that user DN against the LDAP password. This bind using the root credentials fails if the root DN and password are set to incorrect values, or are empty (not set) and the LDAP server does not permit anonymous connections.
If the LDAP server finds no match or multiple matches, authentication fails and the client connection is rejected.
If the LDAP server finds a single match, LDAP authentication succeeds (assuming that the password is correct), the LDAP server returns the LDAP entry, and the authentication plugin determines the name of the authenticated user based on that entry:
If the LDAP entry has a group attribute (by default, the
cn
attribute), the plugin returns its
value as the authenticated user name.
If the LDAP entry has no group attribute, the authentication plugin returns the client user name as the authenticated user name.
The MySQL server compares the client user name with the authenticated user name to determine whether proxying occurs for the client session:
If the names are the same, no proxying occurs: The MySQL account matching the client user name is used for privilege checking.
If the names differ, proxying occurs: MySQL looks for an account matching the authenticated user name. That account becomes the proxied user, which is used for privilege checking. The MySQL account that matched the client user name is treated as the external proxy user.
This section describes how to install the LDAP authentication plugins. For general information about installing plugins, see Section 5.6.1, “Installing and Uninstalling Plugins”.
To be usable by the server, the plugin library files must be
located in the MySQL plugin directory (the directory named by
the plugin_dir
system
variable). If necessary, configure the plugin directory
location by setting the value of
plugin_dir
at server startup.
The server-side plugin library file base names are
authentication_ldap_simple
and
authentication_ldap_sasl
. The file name
suffix differs per platform (for example,
.so
for Unix and Unix-like systems,
.dll
for Windows).
To load the plugins at server startup, use
--plugin-load-add
options to
name the library files that contain them. With this
plugin-loading method, the options must be given each time the
server starts. Also, specify values for any plugin-provided
system variables you wish to configure.
Each server-side LDAP plugin exposes a set of system variables that enable its operation to be configured. Setting most of these is optional, but you must set the variables that specify the LDAP server host (so the plugin knows where to connect) and base distinguished name for LDAP bind operations (to limit the scope of searches and obtain faster searches). For details about all LDAP system variables, see Section 6.4.1.11, “Pluggable Authentication System Variables”.
To load the plugins and set the LDAP server host and base
distinguished name for LDAP bind operations, put lines such as
these in your my.cnf
file, adjusting the
.so
suffix for your platform as
necessary:
[mysqld] plugin-load-add=authentication_ldap_simple.so authentication_ldap_simple_server_host=127.0.0.1 authentication_ldap_simple_bind_base_dn="dc=example,dc=com" plugin-load-add=authentication_ldap_sasl.so authentication_ldap_sasl_server_host=127.0.0.1 authentication_ldap_sasl_bind_base_dn="dc=example,dc=com"
After modifying my.cnf
, restart the
server to cause the new settings to take effect.
Alternatively, to load the plugins at runtime, use these
statements, adjusting the .so
suffix for
your platform as necessary:
INSTALL PLUGIN authentication_ldap_simple SONAME 'authentication_ldap_simple.so'; INSTALL PLUGIN authentication_ldap_sasl SONAME 'authentication_ldap_sasl.so';
INSTALL PLUGIN
loads the plugin
immediately, and also registers it in the
mysql.plugins
system table to cause the
server to load it for each subsequent normal startup without
the need for --plugin-load-add
.
After installing the plugins at runtime, their system
variables become available and you can add settings for them
to your my.cnf
file to configure the
plugins for subsequent restarts. For example:
[mysqld] authentication_ldap_simple_server_host=127.0.0.1 authentication_ldap_simple_bind_base_dn="dc=example,dc=com" authentication_ldap_sasl_server_host=127.0.0.1 authentication_ldap_sasl_bind_base_dn="dc=example,dc=com"
After modifying my.cnf
, restart the
server to cause the new settings to take effect.
Alternatively, to set and persist the values at runtime, use these statements:
SET PERSIST authentication_ldap_simple_server_host='127.0.0.1'; SET PERSIST authentication_ldap_simple_bind_base_dn='dc=example,dc=com'; SET PERSIST authentication_ldap_sasl_server_host='127.0.0.1'; SET PERSIST authentication_ldap_sasl_bind_base_dn='dc=example,dc=com';
SET
PERSIST
sets the value for the running MySQL
instance. It also saves the value, causing it to carry over to
subsequent server restarts. To change a value for the running
MySQL instance without having it carry over to subsequent
restarts, use the GLOBAL
keyword rather
than PERSIST
. See
Section 13.7.6.1, “SET Syntax for Variable Assignment”.
To verify plugin installation, examine the
INFORMATION_SCHEMA.PLUGINS
table
or use the SHOW PLUGINS
statement (see
Section 5.6.2, “Obtaining Server Plugin Information”). For example:
mysql>SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE '%ldap%';
+----------------------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | +----------------------------+---------------+ | authentication_ldap_sasl | ACTIVE | | authentication_ldap_simple | ACTIVE | +----------------------------+---------------+
If a plugin fails to initialize, check the server error log for diagnostic messages.
To associate MySQL accounts with an LDAP plugin, see Using LDAP Pluggable Authentication.
On systems running EL6 or EL that have SELinux enabled, changes to the SELinux policy are required to enable the MySQL LDAP plugins to communicate with the LDAP service:
Create a file mysqlldap.te
with
these contents:
module mysqlldap 1.0; require { type ldap_port_t; type mysqld_t; class tcp_socket name_connect; } #============= mysqld_t ============== allow mysqld_t ldap_port_t:tcp_socket name_connect;
Compile the security policy module into a binary representation:
checkmodule -M -m mysqlldap.te -o mysqlldap.mod
Create an SELinux policy module package:
semodule_package -m mysqlldap.mod -o mysqlldap.pp
Install the module package:
semodule -i mysqlldap.pp
When the SELinux policy changes have been made, restart the MySQL server:
service mysqld restart
The method used to uninstall the LDAP authentication plugins depends on how you installed them:
If you installed the plugins at server startup using
--plugin-load-add
options,
restart the server without those options.
If you installed the plugins at runtime using
INSTALL PLUGIN
, they remain
installed across server restarts. To uninstall them, use
UNINSTALL PLUGIN
:
UNINSTALL PLUGIN authentication_ldap_simple; UNINSTALL PLUGIN authentication_ldap_sasl;
In addition, remove from your my.cnf
file
any startup options that set LDAP plugin-related system
variables. If you used
SET
PERSIST
to persist LDAP system variables, use
RESET PERSIST
to remove the
settings.
For installations that use OpenLDAP, the
ldap.conf
file provides global defaults
for LDAP clients. Options can be set in this file to affect
LDAP clients, including the LDAP authentication plugins.
OpenLDAP uses configuration options in this order of
precedence:
If the library defaults or ldap.conf
values do not yield appropriate option values, an LDAP
authentication plugin may be able to set related variables to
affect the LDAP configuration directly. For example, LDAP
plugins can override ldap.conf
for
parameters such as these:
TLS configuration: System variables are available to
enable TLS and control CA configuration, such as
authentication_ldap_simple_tls
and
authentication_ldap_simple_ca_path
for simple LDAP authentication, and
authentication_ldap_sasl_tls
and
authentication_ldap_sasl_ca_path
for SASL LDAP authentication.
LDAP referral. See LDAP Search Referral.
For more information about ldap.conf
consult the ldap.conf(5)
man page.
This section describes how to enable MySQL accounts to connect to the MySQL server using LDAP pluggable authentication. It is assumed that the server is running with the appropriate server-side plugins enabled, as described in Installing LDAP Pluggable Authentication, and that the appropriate client-side plugins are available on the client host.
This section does not describe LDAP configuration or administration. You are assumed to be familiar with those topics.
The two server-side LDAP plugins each work with a specific client-side plugin:
The server-side
authentication_ldap_simple
plugin
performs simple LDAP authentication. For connections by
accounts that use this plugin, client programs use the
client-side mysql_clear_password
plugin, which sends the password to the server as
cleartext. No password hashing or encryption is used, so a
secure connection between the MySQL client and server is
recommended to prevent password exposure.
The server-side
authentication_ldap_sasl
plugin
performs SASL-based LDAP authentication. For connections
by accounts that use this plugin, client programs use the
client-side
authentication_ldap_sasl_client
plugin.
The client-side and server-side SASL LDAP plugins use SASL
messages for secure transmission of credentials within the
LDAP protocol, to avoid sending the cleartext password
between the MySQL client and server.
Overall requirements for LDAP authentication of MySQL users:
There must be an LDAP directory entry for each user to be authenticated.
There must be a MySQL user account that specifies a
server-side LDAP authentication plugin and optionally
names the associated LDAP user distinguished name (DN).
(To associate an LDAP user DN with a MySQL account,
include a BY
clause in the
CREATE USER
statement that
creates the account.) If an account names no LDAP string,
LDAP authentication uses the user name specified by the
client to find the LDAP entry.
Client programs connect using the connection method
appropriate for the server-side authentication plugin the
MySQL account uses. For LDAP authentication, connections
require the MySQL user name and LDAP password. In
addition, for accounts that use the server-side
authentication_ldap_simple
plugin,
invoke client programs with the
--enable-cleartext-plugin
option to
enable the client-side
mysql_clear_password
plugin.
The instructions here assume the following scenario:
MySQL users betsy
and
boris
authenticate to the LDAP entries
for betsy_ldap
and
boris_ldap
, respectively. (It is not
necessary that the MySQL and LDAP user names differ. The
use of different names in this discussion helps clarify
whether an operation context is MySQL or LDAP.)
LDAP entries use the uid
attribute to
specify user names. This may vary depending on LDAP
server. Some LDAP servers use the cn
attribute for user names rather than
uid
. To change the attribute, modify
the
authentication_ldap_simple_user_search_attr
or
authentication_ldap_sasl_user_search_attr
system variable appropriately.
These LDAP entries are available in the directory managed by the LDAP server, to provide distinguished name values that uniquely identify each user:
uid=betsy_ldap,ou=People,dc=example,dc=com uid=boris_ldap,ou=People,dc=example,dc=com
CREATE USER
statements that
create MySQL accounts name an LDAP user in the
BY
clause, to indicate which LDAP entry
the MySQL account authenticates against.
The instructions for setting up an account that uses LDAP authentication depend on which server-side LDAP plugin is used. The following sections describe several usage scenarios.
To configure a MySQL account for simple LDAP authentication,
the CREATE USER
statement
specifies the authentication_ldap_simple
plugin, and optionally names the LDAP user distinguished name
(DN):
CREATE USERuser
IDENTIFIED WITH authentication_ldap_simple [BY 'LDAP user DN
'];
Suppose that MySQL user betsy
has this
entry in the LDAP directory:
uid=betsy_ldap,ou=People,dc=example,dc=com
Then the statement to create the MySQL account for
betsy
looks like this:
CREATE USER 'betsy'@'localhost' IDENTIFIED WITH authentication_ldap_simple AS 'uid=betsy_ldap,ou=People,dc=example,dc=com';
The authentication string specified in the
BY
clause does not include the LDAP
password. That must be provided by the client user at connect
time.
Clients connect to the MySQL server by providing the MySQL
user name and LDAP password, and by enabling the client-side
mysql_clear_password
plugin:
shell>mysql --user=betsy --password --enable-cleartext-plugin
Enter password:
betsy_password
(betsy_ldap LDAP password)
The client-side mysql_clear_password
authentication plugin leaves the password untouched, so
client programs send it to the MySQL server as cleartext.
This enables the password to be passed as is to the LDAP
server. A cleartext password is necessary to use the
server-side LDAP library without SASL, but may be a security
problem in some configurations. These measures minimize the
risk:
To make inadvertent use of the
mysql_clear_password
plugin less
likely, MySQL clients must explicitly enable it (for
example, with the
--enable-cleartext-plugin
option). See
Section 6.4.1.4, “Client-Side Cleartext Pluggable Authentication”.
To avoid password exposure with the
mysql_clear_password
plugin enabled,
MySQL clients should connect to the MySQL server using
an encrypted connection. See
Section 6.3.1, “Configuring MySQL to Use Encrypted Connections”.
The authentication process occurs as follows:
The client-side plugin sends betsy
and
betsy_password
as the client
user name and LDAP password to the MySQL server.
The connection attempt matches the
'betsy'@'localhost'
account. The
server-side LDAP plugin finds that this account has an
authentication string of
'uid=betsy_ldap,ou=People,dc=example,dc=com'
to name the LDAP user DN. The plugin sends this string and
the LDAP password to the LDAP server.
The LDAP server finds the LDAP entry for
betsy_ldap
and the password matches, so
LDAP authentication succeeds.
The LDAP entry has no group attribute, so the server-side
plugin returns the client user name
(betsy
) as the authenticated user. This
is the same user name supplied by the client, so no
proxying occurs and the client session uses the
'betsy'@'localhost'
account for
privilege checking.
Had the matching LDAP entry contained a group attribute, that
attribute value would have been the authenticated user name
and, if the value differed from betsy
,
proxying would have occurred. For examples that use the group
attribute, see
LDAP Authentication with Proxying.
Had the CREATE USER
statement
contained no BY
clause to specify the
betsy_ldap
LDAP distinguished name,
authentication attempts would use the user name provided by
the client (in this case, betsy
). In the
absence of an LDAP entry for betsy
,
authentication would fail.
To configure a MySQL account for SASL LDAP authentication, the
CREATE USER
statement specifies
the authentication_ldap_sasl
plugin, and
optionally names the LDAP user distinguished name (DN):
CREATE USERuser
IDENTIFIED WITH authentication_ldap_sasl [BY 'LDAP user DN
'];
Suppose that MySQL user boris
has this
entry in the LDAP directory:
uid=boris_ldap,ou=People,dc=example,dc=com
Then the statement to create the MySQL account for
boris
looks like this:
CREATE USER 'boris'@'localhost' IDENTIFIED WITH authentication_ldap_sasl AS 'uid=boris_ldap,ou=People,dc=example,dc=com';
The authentication string specified in the
BY
clause does not include the LDAP
password. That must be provided by the client user at connect
time.
Clients connect to the MySQL server by providing the MySQL user name and LDAP password:
shell>mysql --user=boris --password
Enter password:
boris_password
(boris_ldap LDAP password)
For the server-side
authentication_ldap_sasl
plugin, clients
use the client-side
authentication_ldap_sasl_client
plugin. If
a client program does not find the client-side plugin, specify
a --plugin-dir
option that names the
directory where the plugin library file is installed.
The authentication process for boris
is
similar to that previously described for
betsy
with simple LDAP authentication,
except that the client-side and server-side SASL LDAP plugins
use SASL messages for secure transmission of credentials
within the LDAP protocol, to avoid sending the cleartext
password between the MySQL client and server.
LDAP authentication plugins support proxying, enabling a user to connect to the MySQL server as one user but assume the privileges of a different user. This section describes basic LDAP plugin proxy support. The LDAP plugins also support specification of group preference and proxy user mapping; see LDAP Authentication Group Preference and Mapping Specification.
The proxying implementation described here is based on use of LDAP group attribute values to map connecting MySQL users who authenticate using LDAP onto other MySQL accounts that define different sets of privileges. Users do not connect directly through the accounts that define the privileges. Instead, they connect through a default proxy account authenticated with LDAP, such that all external logins are mapped to the proxied MySQL accounts that hold the privileges. Any user who connects using the proxy account is mapped to one of those proxied MySQL accounts, the privileges for which determine the database operations permitted to the external user.
The instructions here assume the following scenario:
LDAP entries use the uid
and
cn
attributes to specify user name and
group values, respectively. To use different user and
group attribute names, set the appropriate plugin-specific
system variables:
For the authentication_ldap_simple
plugin: Set
authentication_ldap_simple_user_search_attr
and
authentication_ldap_simple_group_search_attr
.
For the authentication_ldap_sasl
plugin: Set
authentication_ldap_sasl_user_search_attr
and
authentication_ldap_sasl_group_search_attr
.
These LDAP entries are available in the directory managed by the LDAP server, to provide distinguished name values that uniquely identify each user:
uid=basha,ou=People,dc=example,dc=com,cn=accounting uid=basil,ou=People,dc=example,dc=com,cn=front_office
At connect time, the group attribute values become the
authenticated user names, so they name the
accounting
and
front_office
proxied accounts.
The examples assume use of SASL LDAP authentication. Make the appropriate adjustments for simple LDAP authentication.
Create the default proxy MySQL account:
CREATE USER ''@'%' IDENTIFIED WITH authentication_ldap_sasl;
The proxy account definition has no AS
'
clause to
name an LDAP user DN. Thus:
auth_string
'
When a client connects, the client user name becomes the LDAP user name to search for.
The matching LDAP entry is expected to include a group attribute naming the proxied MySQL account that defines the privileges the client should have.
If your MySQL installation has anonymous users, they might conflict with the default proxy user. For more information about this issue, and ways of dealing with it, see Default Proxy User and Anonymous User Conflicts.
Create the proxied accounts and grant to each one the privileges it should have:
CREATE USER 'accounting'@'localhost' IDENTIFIED WITH mysql_no_login; CREATE USER 'front_office'@'localhost' IDENTIFIED WITH mysql_no_login; GRANT ALL PRIVILEGES ON accountingdb.* TO 'accounting'@'localhost'; GRANT ALL PRIVILEGES ON frontdb.* TO 'front_office'@'localhost';
The proxied accounts use the mysql_no_login
authentication plugin to prevent clients from using the
accounts to log in directly to the MySQL server. Instead,
users who authenticate using LDAP are expected to use the
default ''@'%'
proxy account. (This assumes
that the mysql_no_login
plugin is
installed. For instructions, see
Section 6.4.1.8, “No-Login Pluggable Authentication”.) For
alternative methods of protecting proxied accounts against
direct use, see
Preventing Direct Login to Proxied Accounts.
Grant to the proxy account the
PROXY
privilege for each
proxied account:
GRANT PROXY ON 'accounting'@'localhost' TO ''@'%'; GRANT PROXY ON 'front_office'@'localhost' TO ''@'%';
Use the mysql command-line client to
connect to the MySQL server as basha
.
shell>mysql --user=basha --password
Enter password:
basha_password
(basha LDAP password)
Authentication occurs as follows:
The server authenticates the connection using the default
''@'%'
proxy account, for client user
basha
.
The matching LDAP entry is:
uid=basha,ou=People,dc=example,dc=com,cn=accounting
The matching LDAP entry has group attribute
cn=accounting
, so
accounting
becomes the authenticated
proxied user.
The authenticated user differs from the client user name
basha
, with the result that
basha
is treated as a proxy for
accounting
, and
basha
assumes the privileges of the
proxied accounting
account. The
following query returns output as shown:
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
+-----------------+----------------------+--------------+
| USER() | CURRENT_USER() | @@proxy_user |
+-----------------+----------------------+--------------+
| basha@localhost | accounting@localhost | ''@'%' |
+-----------------+----------------------+--------------+
This demonstrates that basha
uses the
privileges granted to the proxied
accounting
MySQL account, and that proxying
occurs through the default proxy user account.
Now connect as basil
instead:
shell>mysql --user=basil --password
Enter password:
basil_password
(basil LDAP password)
The authentication process for basil
is
similar to that previously described for
basha
:
The server authenticates the connection using the default
''@'%'
proxy account, for client user
basil
.
The matching LDAP entry is:
uid=basil,ou=People,dc=example,dc=com,cn=front_office
The matching LDAP entry has group attribute
cn=front_office
, so
front_office
becomes the authenticated
proxied user.
The authenticated user differs from the client user name
basil
, with the result that
basil
is treated as a proxy for
front_office
, and
basil
assumes the privileges of the
proxied front_office
account. The
following query returns output as shown:
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
+-----------------+------------------------+--------------+
| USER() | CURRENT_USER() | @@proxy_user |
+-----------------+------------------------+--------------+
| basil@localhost | front_office@localhost | ''@'%' |
+-----------------+------------------------+--------------+
This demonstrates that basil
uses the
privileges granted to the proxied
front_office
MySQL account, and that
proxying occurs through the default proxy user account.
As described in LDAP Authentication with Proxying, basic LDAP authentication proxying works by the principle that the plugin uses the first group name returned by the LDAP server as the MySQL proxied user account name. This simple capability does not enable specifying any preference about which group name to use if the LDAP server returns multiple group names, or specifying any name other than the group name as the proxied user name.
As of MySQL 8.0.14, for MySQL accounts that use LDAP authentication, the authentication string can specify the following information to enable greater proxying flexibility:
A list of groups in preference order, such that the plugin uses the first group name in the list that matches a group returned by the LDAP server.
A mapping from group names to proxied user names, such that a group name when matched can provide a specified name to use as the proxied user. This provides an alternative to using the group name as the proxied user.
Consider the following MySQL proxy account definition:
CREATE USER ''@'%' IDENTIFIED WITH authentication_ldap_sasl AS '+ou=People,dc=example,dc=com#grp1=usera,grp2,grp3=userc';
The authentication string has a user DN suffix
ou=People,dc=example,dc=com
prefixed by the
+
character. Thus, as described in
LDAP Authentication User DN Suffixes,
the full user DN is constructed from the user DN suffix as
specified, plus the client user name as the
uid
attribute.
The remaining part of the authentication string begins with
#
, which signifies the beginning of group
preference and mapping information. This part of the
authentication string lists group names in the order
grp1
, grp2
,
grp3
. The LDAP plugin compares that list
with the set of group names returned by the LDAP server,
looking in list order for a match against the returned names.
The plugin uses the first match, or if there is no match,
authentication fails.
Suppose that the LDAP server returns groups
grp3
, grp2
, and
grp7
. The LDAP plugin uses
grp2
because it is the first group in the
authentication string that matches, even though it is not the
first group returned by the LDAP server. If the LDAP server
returns grp4
, grp2
, and
grp1
, the plugin uses
grp1
even though grp2
also matches. grp1
has a precedence higher
than grp2
because it is listed earlier in
the authentication string.
Assuming that the plugin finds a group name match, it performs mapping from that group name to the MySQL proxied user name, if there is one. For the example proxy account, mapping occurs as follows:
If the matching group name is grp1
or
grp3
, those are associated in the
authentication string with user names
usera
and userc
,
respectively. The plugin uses the corresponding associated
user name as the proxied user name.
If the matching group name is grp2
,
there is no associated user name in the authentication
string. The plugin uses grp2
as the
proxied user name.
If the LDAP server returns a group in DN format, the LDAP plugin parses the group DN to extract the group name from it.
To specify LDAP group preference and mapping information, these principles apply:
Begin the group preference and mapping part of the
authentication string with a #
prefix
character.
The group preference and mapping specification is a list
of one or more items, separated by commas. Each item has
the form
or group_name
=user_name
group_name
. Items should be
listed in group name preference order. For a group name
selected by the plugin as a match from set of group names
returned by the LDAP server, the two syntaxes differ in
effect as follows:
For an item specified as
(with a user name), the group name maps to the user
name, which is used as the MySQL proxied user name.
group_name
=user_name
For an item specified as
group_name
(with no user
name), the group name is used as the MySQL proxied
user name.
To quote a group or user name that contains special
characters such as space, surround it by double quote
("
) characters. For example, if an item
has group and user names of my group
name
and my user name
, it
must be written in a group mapping using quotes:
"my group name"="my user name"
If an item has group and user names of
my_group_name
and
my_user_name
(which contain no special
characters), it may but need not be written using quotes.
Any of the following are valid:
my_group_name=my_user_name my_group_name="my_user_name" "my_group_name"=my_user_name "my_group_name"="my_user_name"
To escape a character, precede it by a backslash
(\
). This is useful particularly to
include a literal double quote or backslash, which are
otherwise not included literally.
A user DN need not be present in the authentication
string, but if present, it must precede the group
preference and mapping part. A user DN can be given as a
full user DN, or as a user DN suffix with a
+
prefix character. (See
LDAP Authentication User DN Suffixes.)
LDAP authentication plugins permit the authentication string
that provides user DN information to begin with a
+
prefix character:
In the absence of a +
character, the
authentication string value is treated as is without
modification.
If the authentication string begins with
+
, the plugin constructs the full user
DN value from the user name sent by the client, together
with the DN specified in the authentication string (with
the +
removed). In the constructed DN,
the client user name becomes the value of the attribute
that specifies LDAP user names. This is
uid
by default; to change the
attribute, modify the appropriate system variable
(authentication_ldap_simple_user_search_attr
or
authentication_ldap_sasl_user_search_attr
).
The authentication string is stored as given in the
mysql.user
system table, with the full
user DN constructed on the fly before authentication.
This account authentication string does not have
+
at the beginning, so it is taken as the
full user DN:
CREATE USER 'baldwin' IDENTIFIED WITH authentication_ldap_simple AS 'uid=admin,ou=People,dc=example,dc=com';
The client connects with the user name specified in the
account (baldwin
). In this case, that name
is not used because the authentication string has no prefix
and thus fully specifies the user DN.
This account authentication string does have
+
at the beginning, so it is taken as just
part of the user DN:
CREATE USER 'accounting' IDENTIFIED WITH authentication_ldap_simple AS '+ou=People,dc=example,dc=com';
The client connects with the user name specified in the
account (accounting
), which in this case is
used as the uid
attribute together with the
authentication string to construct the user DN:
uid=accounting,ou=People,dc=example,dc=com
The accounts in the preceding examples have a nonempty user
name, so the client always connects to the MySQL server using
the same name as specified in the account definition. If an
account has an empty user name, such as the default anonymous
''@'%'
proxy account described in
LDAP Authentication with Proxying,
clients might connect to the MySQL server with varying user
names. But the principle is the same: If the authentication
string begins with +
, the plugin uses the
user name sent by the client together with the authentication
string to construct the user DN.
The LDAP authentication plugins use a configurable authentication method. The appropriate system variable and available method choices are plugin-specific:
For the authentication_ldap_simple
plugin: Set the
authentication_ldap_simple_auth_method_name
system variable to configure the method. The permitted
choices are SIMPLE
and
AD-FOREST
.
For the authentication_ldap_sasl
plugin: Set the
authentication_ldap_sasl_auth_method_name
system variable to configure the method. The permitted
choices are SCRAM-SHA-1
,
SCRAM-SHA-256
, and
GSSAPI
. (To determine which SASL LDAP
methods are actually available on the host system, check
the value of the
Authentication_ldap_sasl_supported_methods
status variable.)
See the system variable descriptions for information about each permitted method. Also, depending on the method, additional configuration may be needed, as described in the following sections.
Generic Security Service Application Program Interface (GSSAPI) is a security abstraction interface. Kerberos is an instance of a specific security protocol that can be used through that abstract interface. Using GSSAPI, applications authenticate to Kerberos to obtain service credentials, then use those credentials in turn to enable secure access to other services.
One such service is LDAP, which is used by the client-side and
server-side SASL LDAP authentication plugins. When the
authentication_ldap_sasl_auth_method_name
system variable is set to GSSAPI
, these
plugins use the GSSAPI/Kerberos authentication method. In this
case, the plugins communicate securely using Kerberos without
using LDAP messages directly. The server-side plugin then
communicates with the LDAP server to interpret LDAP
authentication messages and retrieve LDAP groups.
GSSAPI/Kerberos is supported as an authentication method for MySQL clients and servers only on Linux. It is useful in Linux environments where applications access LDAP using Microsoft Active Directory, which has Kerberos enabled by default.
The following discussion provides information about the configuration requirements for using the GSSAPI method. Familiarity is assumed with Kerberos concepts and operation, such as these common Kerberos terms:
Principal = A named entity, such as a user or service.
KDC = The Key Distribution Center, comprising the AS and TGS.
AS = The Authentication Server, part of the KDC. Provides the initial ticket needed to obtain a TGT.
TGS = The ticket-granting service, part of the KDC.
TGT = The ticket-granting ticket, presented to the TGS to obtain service tickets for service access.
Kerberos authentication requires both a KDC server and an LDAP server. This requirement can be satisfied in different ways:
Active Directory includes both servers, with Kerberos authentication enabled by default in the Active Directory LDAP server.
OpenLDAP provides an LDAP server, but a separate KDC server may be needed, with additional Kerberos setup required.
Kerberos must also be available on the client host. A client contacts the AS using a password to obtain a TGT. The client then uses the TGT to obtain access from the TGS to other services, such as LDAP.
The following sections discuss the configuration steps to use GSSAPI/Kerberos for SASL LDAP authentication in MySQL:
The following example shows how to test availability of Kerberos in Active Directory. The example makes these assumptions:
Active Directory is running on the host named
ldap_auth.example.com
with IP address
198.51.100.10
.
The MYSQL.LOCAL
domain is used for
MySQL-related Kerberos authentication and LDAP lookups.
A principal named bredon@MYSQL.LOCAL
is
registered with the KDC. (In later discussion, this
principal name is also used for the MySQL user that uses
GSSAPI/Kerberos to authenticate to the MySQL server.)
With those assumptions satisfied, follow this procedure:
Verify that the Kerberos library is installed and
configured correctly in the operating system. For example,
to configure a MYSQL.LOCAL
domain for
use during MySQL authentication, the Kerberos
configuration file, /etc/krb5.conf
,
should contain something like this:
[realms] MYSQL.LOCAL = { kdc = ldap_auth.example.com admin_server = ldap_auth.example.com default_domain = MYSQL.LOCAL }
You may need to add an entry to
/etc/hosts
for the server host:
198.51.100.10 ldap_auth ldap_auth.example.com
Check whether Kerberos authentication works correctly:
Use kinit to authenticate to Kerberos:
kinit bredon@MYSQL.LOCAL
The command authenticates for the Kerberos principal
named bredon@MYSQL.LOCAL
. Enter the
principal's password when the command prompts for it.
The KDC returns a TGT that is cached on the client
side for use by other Kerberos-aware applications.
Use klist to check whether the TGT was obtained correctly. The output should be similar to this:
Ticket cache: FILE:/tmp/krb5cc_244306 Default principal: bredon@MYSQL.LOCAL Valid starting Expires Service principal 03/23/2020 08:18:33 03/23/2020 18:18:33 krbtgt/MYSQL.LOCAL@MYSQL.LOCAL
Check whether ldapsearch works with the
Kerberos TGT using this command, which searches for users
in the MYSQL.LOCAL
domain:
ldapsearch -h 198.51.100.10 -Y GSSAPI -b "dc=MYSQL,dc=LOCAL"
Assuming that the LDAP server is accessible through Kerberos
as just described, configure the server-side SASL LDAP
authentication plugin to use the GSSAPI/Kerberos
authentication method. (For general LDAP plugin installation
information, see
Installing LDAP Pluggable Authentication.)
Here is an example of plugin-related settings the server
my.cnf
file might contain:
[mysqld]
plugin-load-add=authentication_ldap_sasl.so
authentication_ldap_sasl_auth_method_name="GSSAPI"
authentication_ldap_sasl_server_host=198.51.100.10
authentication_ldap_sasl_server_port=389
authentication_ldap_sasl_bind_root_dn="cn=admin,cn=users,dc=MYSQL,dc=LOCAL"
authentication_ldap_sasl_bind_root_pwd="password
"
authentication_ldap_sasl_bind_base_dn="cn=users,dc=MYSQL,dc=LOCAL"
authentication_ldap_sasl_user_search_attr="sAMAccountName"
Those option file settings configure the SASL LDAP plugin as follows:
The --plugin-load-add
option loads the plugin (adjust the
.so
suffix for your platform as
necessary). If you loaded the plugin previously using an
INSTALL PLUGIN
statement,
this option is unnecessary.
authentication_ldap_sasl_auth_method_name
must be set to GSSAPI
to use
GSSAPI/Kerberos as the SASL LDAP authentication method.
authentication_ldap_sasl_server_host
and
authentication_ldap_sasl_server_port
indicate the IP address and port number of the Active
Directory server host for authentication.
authentication_ldap_sasl_bind_root_dn
and
authentication_ldap_sasl_bind_root_pwd
configure the root DN and password for group search
capability. This capability is required, but users may not
have privileges to search. In such cases, it is necessary
to provide root DN information:
In the DN option value, admin
should be the name of an administrative LDAP account
that has privileges to perform user searches.
In the password option value,
password
should be the
admin
account password.
authentication_ldap_sasl_bind_base_dn
indicates the user DN base path, so that searches look for
users in the MYSQL.LOCAL
domain.
authentication_ldap_sasl_user_search_attr
specifies a standard Active Directory search attribute,
sAMAccountName
. This attribute is used
in searches to match logon names; attribute values are not
the same as the user DN values.
MySQL authentication using the SASL LDAP authentication plugin
with the GSSAPI/Kerberos method is based on a user that is a
Kerberos principal. The following discussion uses a principal
named bredon@MYSQL.LOCAL
as this user,
which must be registered in several places:
The Kerberos admininistrator should register the user name as a Kerberos principal. This name should include a domain name. The principal name and password are used by clients to authenticate with Kerberos and obtain a TGT.
The LDAP administrator should register the user name in an LDAP entry. For example:
uid=bredon,dc=MYSQL,dc=LOCAL
In Active Directory (which uses Kerberos as the default authentication method), creating a user creates both the Kerberos principal and the LDAP entry.
The MySQL DBA should create an account that has the Kerberos principal name as the user name, and that authenticates using the SASL LDAP plugin.
Assuming that the Kerberos principal and LDAP entry have been
registered by the appropriate service administrators, and that
the MySQL server has been started using the
my.cnf
settings previously described,
create a MySQL account that corresponds to the Kerberos
principal name, including the domain name.
The SASL LDAP plugin uses a constant user DN for Kerberos authentication and ignores any user DN configured from MySQL. This has certain implications:
For any MySQL account that uses GSSAPI/Kerberos
authentication, the authentication string in
CREATE USER
or
ALTER USER
statements
should contain no user DN because it has no effect.
Because the authentication string contains no user DN, it should contain group mapping information, to enable the user to be handled as a proxy user that is mapped onto the desired proxied user. For information about proxying with the LDAP authentication plugin, see LDAP Authentication with Proxying.
The following statements create a proxy user named
bredon@MYSQL.LOCAL
that assumes the
privileges of the proxied user named
proxied_krb_usr
. Other GSSAPI/Kerberos
users that should have the same privileges can similarly be
created as proxy users for the same proxied user.
-- create proxy account CREATE USER 'bredon@MYSQL.LOCAL' IDENTIFIED WITH authentication_ldap_sasl BY '#krb_grp=proxied_krb_user'; -- create proxied account and grant its privileges; -- use mysql_no_login plugin to prevent direct login CREATE USER 'proxied_krb_user' IDENTIFIED WITH mysql_no_login; GRANT ALL ON krb_user_db.* TO 'proxied_krb_user'; -- grant to proxy account the -- PROXY privilege for proxied account GRANT PROXY ON 'proxied_krb_user' TO 'bredon@MYSQL.LOCAL';
Observe closely the quoting for the proxy account name in the
first CREATE USER
statement and
the GRANT
PROXY
statement:
For most MySQL accounts, the user and host are separate
parts of the account name, and thus are quoted separately
as
'
.
user_name
'@'host_name
'
For Kerberos authentication, the user part of the account
name includes the principal domain, so
'bredon@MYSQL.LOCAL'
is quoted as a
single value. Because no host part is given, the full
MySQL account name uses the default of
'%'
as the host part:
'bredon@MYSQL.LOCAL'@'%'
The proxied account uses the mysql_no_login
authentication plugin to prevent clients from using the
account to log in directly to the MySQL server. Instead, it is
expected that users who authenticate using LDAP use the
bredon@MYSQL.LOCAL
proxy account. (This
assumes that the mysql_no_login
plugin is
installed. For instructions, see
Section 6.4.1.8, “No-Login Pluggable Authentication”.) For
alternative methods of protecting proxied accounts against
direct use, see
Preventing Direct Login to Proxied Accounts.
After a MySQL account that uses GSSAPI/Kerberos has been set up, clients can authenticate to Kerberos and use the account to connect to the MySQL server. Kerberos authentication can take place either prior to or at the time of MySQL client program invocation:
The client user can obtain a TGT independently of MySQL prior to invoking the MySQL client program. For example, the client user can use kinit to authenticate to Kerberos by providing a Kerberos principal name and the principal password. The TGT is cached and becomes available for use by other Kerberos-aware applications, such as the client-side SASL LDAP authentication plugin. In this case, the MySQL client program authenticates to the MySQL server using the TGT, so invoke the client without specifying a user name or password:
shell>kinit bredon@MYSQL.LOCAL
Password for bredon@MYSQL.LOCAL:(enter password here)
shell>mysql --default-auth=authentication_ldap_sasl_client
If the MySQL client command does include credentials, they are handled as follows:
If the command includes a user name, authentication fails if that name does not match the principal name in the TGT.
If the command includes a password, the password is ignored. Because authentication is based on the TGT, it can succeed even if the user-provided password is incorrect. For this reason, the plugin produces a warning if a valid TGT is found that causes a password to be ignored.
If there is no TGT, the client-side SASL LDAP authentication plugin itself can obtain the TGT from the KDC. In this case, to invoke the client, specify the name and password of the Kerberos principal associated with the MySQL account (enter the command on a single line, then enter the principal password at the prompt):
shell>mysql --default-auth=authentication_ldap_sasl_client
--user=bredon@MYSQL.LOCAL
--password
Enter password:(enter password here)
If the client command specifies no principal name as the user name and the client-side plugin finds the Kerberos cache empty because there is no TGT, authentication fails.
If you are uncertain whether a TGT exists, you can use klist to check.
Authentication occurs as follows:
The client uses the TGT to authenticate using Kerberos.
The server finds the LDAP entry for the principal and uses
it to authenticate the connection for the
bredon@MYSQL.LOCAL
MySQL proxy account.
The group mapping information in the proxy account
authentication string
('#krb_grp=proxied_krb_user'
) indicates
that the authenticated proxied user should be
proxied_krb_user
.
bredon@MYSQL.LOCAL
is treated as a
proxy for proxied_krb_user
, and the
following query returns output as shown:
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
+------------------------------+--------------------+--------------------------+
| USER() | CURRENT_USER() | @@proxy_user |
+------------------------------+--------------------+--------------------------+
| bredon@MYSQL.LOCAL@localhost | proxied_krb_user@% | 'bredon@MYSQL.LOCAL'@'%' |
+------------------------------+--------------------+--------------------------+
The USER()
value indicates
the user name used for the client command
(bredon@MYSQL.LOCAL
) and the host from
which the client connected (localhost
).
The CURRENT_USER()
value is
the full name of the proxied user account, which consists
of the proxied_krb_user
user part and
the %
host part.
The
@@proxy_user
value indicates the full name of the account used to make
the connection to the MySQL server, which consists of the
bredon@MYSQL.LOCAL
user part and the
%
host part.
This demonstrates that proxying occurs through the
bredon@MYSQL.LOCAL
proxy user account,
and that bredon@MYSQL.LOCAL
assumes the
privileges granted to the
proxied_krb_user
proxied user account.
A TGT once obtained is cached on the client side and can be used until it expires without specifying the password again. However the TGT is obtained, the client-side plugin uses it to acquire service tickets and communicate with the server-side plugin.
When the client-side plugin itself obtains the TGT, the client
user may not want the TGT to be reused. As described in
/etc/krb5.conf Client Configuration Parameters, the
local /etc/krb5.conf
file can be used to
cause the client-side plugin to destroy the TGT when done with
it.
The server-side plugin has no access to the TGT itself or the Kerberos password used to obtain it.
The LDAP authentication plugins have no control over the caching mechanism (storage in a local file, in memory, and so forth), but Kerberos utilities such as kswitch may be available for this purpose.
The client-side SASL LDAP plugin reads the local
/etc/krb5.conf
file. If this file is
missing or inaccessible, an error occurs. Assuming that the
file is accessible, the optional
[appdefaults]
group can be used to provide
information used by the plugin. Place such information within
the MySQL
section of the group. For
example:
[appdefaults] MySQL = { ldap_server_host = "ldap_host.example.com" ldap_destroy_tgt = true }
The client-side plugin recognizes these parameters in the
MySQL
section:
The ldap_server_host
value specifies
the LDAP server host and can be useful when that host
differs from the KDC server host specified in the
[realms]
group. By default, the plugin
uses the KDC server host as the LDAP server host.
The ldap_destroy_tgt
value indicates
whether the client-side plugin destroys the TGT after
obtaining and using it. By default,
ldap_destroy_tgt
is
false
, but can be set to
true
to avoid TGT reuse. (This setting
applies only to TGTs created by the client-side plugin,
not TGTs created externally to MySQL.)
An LDAP server can be configured to delegate LDAP searches to
another LDAP server, a functionality known as LDAP referral.
Suppose that the server a.example.com
holds
a "dc=example,dc=com"
root DN and wishes to
delegate searches to another server
b.example.com
. To enable this,
a.example.com
would be configured with a
named referral object having these attributes:
dn: dc=subtree,dc=example,dc=com objectClass: referral objectClass: extensibleObject dc: subtree ref: ldap://b.example.com/dc=subtree,dc=example,dc=com
An issue with enabling LDAP referral is that searches can fail
with LDAP operation errors when the search base DN is the root
DN, and referral objects are not set. A MySQL DBA might wish
to avoid such referral errors for the LDAP authentication
plugins, even though LDAP referral might be be set globally in
the ldap.conf
configuration file. To
configure on a plugin-specific basis whether the LDAP server
should use LDAP referral when communicating with each plugin,
set the
authentication_ldap_simple_referral
and
authentication_ldap_sasl_referral
system variables. Setting either variable to
ON
or OFF
causes the
corresponding LDAP authentication plugin to tell the LDAP
server whether to use referral during MySQL authentication.
Each variable has a plugin-specific effect and does not affect
other applications that communicate with the LDAP server. Both
variables are OFF
by default.