LDAP authentication

Currently, Vitess supports two ways to authenticate to vtgate via the MySQL protocol:

  • Static : You provide a static configuration file to vtgate with user names and plaintext passwords or mysql_native_password password hashes. This file can be reloaded without restarting vtgate. Further details can be found here.
  • LDAP : You provide the necessary details of an upstream LDAP server, along with credentials and configuration, to query it. Using this information, the LDAP passwords for a user can then be used to authenticate the same user against vtgate. You can also integrate with LDAP groups to allow ACLs to be managed using information from the LDAP server.

In this guide, we will examine the capabilities of the vtgate LDAP integration and how to configure them.

Requirements #

There are a few requirements that are necessary for the vtgate LDAP integration to work:

  • The communication between vtgate and the LDAP server has to be encrypted.
  • Encrypted communication to LDAP has to be via LDAP over TLS (STARTTLS) and not via LDAP over SSL (LDAPS). The latter is not a standardized protocol and is not supported by Vitess. Ensure that your LDAP server and the LDAP URI (hostname/port) that you provide supports STARTTLS.
  • The application MySQL protocol connections to vtgate that use LDAP usernames/passwords need to use TLS. This is required because of the next point, but can be bypassed. We strongly DO NOT recommend doing this.
  • The application needs to be able to, and configured to, pass its password authentication using the cleartext MySQL authentication protocol. This is why it is required that the MySQL connection to vtgate be encrypted first. This is required because LDAP servers do not standardize their password hashes and, as a result, a cleartext password is required by vtgate to bind (i.e. authenticate) against the LDAP server to verify the user's password. Note that some applications might not support passing cleartext MySQL passwords without alteration or configuration. An example is recent versions of the MySQL CLI client mysql need the additional --enable-cleartext-plugin option to allow the passing of cleartext passwords.

Configuration #

To configure vtgate to integrate with LDAP you will have to perform various tasks:

  • Generate/obtain TLS certificate(s) for the vtgate server(s), and configure vtgate to use them. Further details can be found here.
  • Obtain or add the necessary LDAP user/groups for integration with vtgate. In general, you will need:
    • LDAP user entries for each of the MySQL users you want to use at the vtgate level. An example might be a readonly user, a readwrite user, and an admin/DBA user.
    • Ensure these users are part of one or more LDAP groups. This is not strictly required by Vitess, but is leveraged to obtain group membership that can then be used in Vitess (vttablet)ACLs. At the moment if you use an LDAP user that is not a member of an LDAP group, the MySQL client authentication to vtgate will fail, even if the password is correct.
  • As mentioned above, you also need to have:
    • Your LDAP server setup for STARTTLS
    • Obtained the LDAP URI to connect to the LDAP server
    • The CA certificate, that your LDAP server TLS certificate is signed by, in PEM format
    • Make sure that you are accessing the LDAP server via a hostname or IP SAN that is defined in your LDAP server TLS certificate. If not, you will not be able to use your LDAP server as-is from vtgate.

Once you have your prerequisites above ready, you can now construct your JSON configuration file for vtgate using the command line parameter -mysql_ldap_auth_config_file. The content of this file is a JSON format object with string key/value members as follows:

{
    "LdapServer": "ldapserver.example.org:389",
    "LdapCert": "path/to/ldap-client-cert.pem",
    "LdapKey": "path/to/ldap-client-key.pem",
    "LdapCA": "path/to/ldap-server-ca.pem",
    "User": "cn=admin,dc=example,dc=org",
    "Password": "adminpassword!",
    "GroupQuery": "ou=groups,ou=people,dc=example,dc=org",
    "UserDnPattern": "uid=%s,ou=users,ou=people,dc=example,dc=org",
    "RefreshSeconds": 300
}

Not all these options are necessary in all configurations. Here are what each key/value option represents:

  • LdapServer : Hostname/IP and port to access the LDAP server via using STARTTLS. Note that as mentioned above, this needs to match the server TLS certificate presented by the LDAP server. This is required.
  • LdapCert : Path to the local file that contains the PEM format TLS client certificate that you want to present to the LDAP server. This is optional unless you use client-certificates with the LDAP server. If you are using this option, LdapKey is also required.
  • LdapKey : Path to the local file that contains the PEM format TLS private key for the client certificate you want to present to the LDAP server. This is optional unless you use client-certificates with the LDAP server. If you are using this option, LdapCert is also required.
  • LdapCA : Path to the local file that contains the PEM format TLS CA certificate to verify against the TLS server certificate presented by the LDAP server. This is required.
  • User : DN of the LDAP user you will be authenticating to the LDAP server to read information such as group membership. Required, unless you are using LDAP client certificates to authenticate to the LDAP server. If you are using this option, Password option is also required.
  • Password : Cleartext password for the LDAP user specified above in User. This is required, unless you are using LDAP client certificates to authenticate to the LDAP server. If you are using this option, User option is also required.
  • GroupQuery : LDAP base DN from which to start the group membership query to establish the group of which the User specified (or implied via the client certificate) is a member. The group membership query itself is hardcoded to the LDAP query filter of (memberUid=%s) where %s is the authenticating username. This is required.
  • UserDnPattern : LDAP DN pattern to autofill with MySQL username passed during MySQL client authentication to vtgate. This DN is then used, along with the password provided to vtgate, to attempt to bind with the LDAP server. If the bind is successful, you know that the password provided to vtgate was valid. This is required.
  • RefreshSeconds : Number of seconds that you should cache individual LDAP credentials for in-memory at the vtgate. This is used to reduce load on the LDAP for high traffic MySQL servers. As well as to avoid short LDAP server outages from causing Vitess/vtgate authentication outages. Default value is 0, which means do not cache. For production it is recommended to set this value to something reasonably high, for example at least a few minutes. This is optional.

Note that vtgate only does very basic validation of the values passed here and that incorrect configurations may just fail at runtime. If you are lucky, relevant errors may be logged by vtgate, but in many cases incorrect configuration will just result in a vtgate instance that you cannot log into via the MySQL protocol.

For debugging this, it is useful to have access to the logs from your LDAP server that you are pointing to. The logs would preferably be at trace or debug level, so that you can see each LDAP bind and search operation against the LDAP server as you are testing.

Once you have constructed the above file, you will need to remove any options that references static authentication from your vtgate command line such as:

  • -mysql_auth_server_static_file
  • -mysql_auth_server_static_string
  • -mysql_auth_static_reload_interval
  • -mysql_auth_server_impl static

and add the following new options:

-mysql_auth_server_impl ldap -mysql_ldap_auth_config_file /path/to/ldapconfig.json

LDAP authentication