All pages
Powered by GitBook
1 of 4

LDAP Auth Config

Instructions for authenticating users with LDAP

This documentation assumes that you already have access to an LDAP directory, such as OpenLDAP or Active Directory, and that Guacamole has already been installed using Keeper Connection Manager. If you do not already an LDAP directory ready, please set up LDAP before proceeding. If you do not already have Guacamole installed, please see the installation instructions.

This section covers configuring Guacamole to authenticate against a _single_** LDAP server using guacamole.properties.** If planning to use multiple LDAP servers, we highly recommend configuring Guacamole to authenticate against a single LDAP server first, and then migrating to a multi-server configuration once your first LDAP server has been confirmed to be configured correctly. This avoids introducing unnecessary variables too early in the deployment process.

If you will be configuring multiple LDAP servers, please see the instructions covering the ldap-servers.yml configuration file. The configuration options available within ldap-servers.yml are very similar to those documented below except that the YAML format is flexible enough to allow multiple servers to be defined.

Advanced Linux Install Method

Installing LDAP support for Guacamole

Keeper Connection Manager packages Guacamole’s LDAP support within the kcm-guacamole-auth-ldap package:

$ sudo yum install kcm-guacamole-auth-ldap

Unlike the MySQL, PostgreSQL, SQL Server and authentication backends, Guacamole’s LDAP support does not require a schema to be applied unless you intend to store connection data within your LDAP directory. If LDAP will be used only to authenticate Guacamole users, no schema modifications need be made, and a database should be used to store connection data.

If you do intend to store connection data within your LDAP directory, you will need to apply the provided schema modifications which create the guacConfigGroup object class. Be sure to first finish configuring Guacamole for LDAP authentication, and verify that Guacamole can successfully authenticate users against your LDAP directory.

Guacamole’s main configuration file, /etc/guacamole/guacamole.properties, must be modified to point the LDAP directory:

$ sudo vi /etc/guacamole/guacamole.properties

The guacamole.properties file provided with Keeper Connection Manager is organized into sections documented with blocks of comments and example properties. The first section which must be modified is marked “LDAP-1” and defines the TCP connection information for the LDAP directory. Uncomment the ldap-hostname property, modifying its value to point to your LDAP server:

##
## [LDAP-1] LDAP TCP connection information
##
## The TCP connection details of the LDAP server, as well as whether encryption
## should be used.
##
## Legal encryption methods are "none", for unencrypted connections, "ssl" 
## for LDAP over SSL/TLS (also known as LDAPS), or "starttls" for STARTTLS.
##

#ldap-hostname:          localhost
#ldap-port:              389
#ldap-encryption-method: none

By default, Guacamole will connect to your LDAP server without encryption. If your LDAP server uses encryption, you will need to uncomment and set the ldap-encryption-method property to “ssl” for LDAPS (LDAP over SSL/TLS) or “starttls” for STARTTLS.

The default port varies by encryption method, and will be 389 for unencrypted LDAP and STARTTLS, or 636 for LDAPS. If your LDAP server listens on a non-standard port, you will also need to uncomment and modify the ldap-port property.

Mapping Guacamole usernames to LDAP DN’s

To authenticate users using LDAP, Guacamole must translate usernames into their corresponding LDAP DN’s. Depending on the complexity of your LDAP directory, this can be as simple as adding a single attribute to a common base DN, or can involve an LDAP query.

The “LDAP-2” section defines the basic parameters required for either case:

##
## [LDAP-2] LDAP user / user DN description
##
## The base DN of all Guacamole users within the LDAP directory, and the
## attribute which contains each user's username. If the username attribute
## is not part of the DN, a seach DN will need to be provided, as well.
##

#ldap-user-base-dn:       ou=people,dc=example,dc=net
#ldap-username-attribute: uid

The base DN defined by the ldap-user-base-dn property should be the common base shared by all Guacamole users within your LDAP directory, while the attribute which contains the user’s username is defined by ldap-username-attribute. The base DN is always required if LDAP is being used.

Direct username mapping

By default, Guacamole will attempt to derive the user’s DN directly by prepending the username attribute to the base DN. For example, assume a user is attempting to login with the username “someUser”. If the base DN is “ou=people,dc=example,dc=net” and the username attribute is “uid” (the default), then Guacamole will perform the following steps to authenticate the user:

  1. Prepend the username to the base DN using the “uid” attribute, producing the DN: “uid=someUser,ou=people,dc=example,dc=net”.

  2. Attempt to bind using the DN “uid=someUser,ou=people,dc=example,dc=net” and the password provided by the user.

  3. If the bind attempt succeeds, authentication is successful.

Indirect username mapping

For more complex cases, where the user DN is cannot be directly derived by prepending the username attribute, Guacamole can instead issue an LDAP query to determine the user DN. This requires a search DN and password, defined with the ldap-search-bind-dn and ldap-search-bind-password properties respectively, which Guacamole will bind as when performing the query:

##
## [LDAP-3] LDAP user search DN
##
## The DN and password of the user to bind as when searching for the DN of each
## user attempting to log in. If omitted, the DN of each user will be derived
## directly using the user base DN and username attribute.
##

#ldap-search-bind-dn:       cn=someUser,ou=people,dc=example,dc=net
#ldap-search-bind-password: some_password

With the search DN and password configured, Guacamole will perform the following steps to authenticate a user:

  1. Bind to the LDAP directory using the search DN and password.

  2. Issue an LDAP query for objects within the subtree of the base DN that contain the user’s username within the defined username attribute.

  3. If exactly one such object is found, attempt to bind using the DN of that object and the password provided by the user.

  4. If the bind attempt succeeds, authentication is successful.

Mapping Guacamole groups to LDAP DN’s

Access to connections within Guacamole may be dictated through LDAP user groups via either of two mechanisms:

  1. Defining connections directly within LDAP using schema modifications and dictating group access using the "seeAlso" attribute.

  2. Mapping LDAP groups to Guacamole groups and leveraging a database to dictate access.

As it is usually preferable to avoid modifying the LDAP schema, mapping LDAP groups to Guacamole groups is recommended. Doing this will require defining the base DN under which all relevant LDAP groups may be found and defining the LDAP attribute that should be used by Guacamole to determine the unique name of the group:

##
## [LDAP-5] LDAP group / group DN description
##
## The base DN of all Guacamole groups within the LDAP directory, and the
## attribute which should be used by Guacamole to uniquely identify the
## group.
##
## If connections are being stored within LDAP using "guacConfigGroup" objects,
## and you wish to control access to these connections via LDAP groups, this is
## accomplished using the standard "seeAlso" attribute and the
## ldap-group-base-dn property is required.
##
## If connections are being stored outside of LDAP, such as within a database,
## and you wish to control access using LDAP groups, both ldap-group-base-dn
## and ldap-group-name-attribute will be required. The group membership of a
## user cannot be queried without a base DN, and the unique name to be used by
## other parts of Guacamole to represent the group cannot be determined without
## the name attribute.
##

#ldap-group-base-dn:        ou=groups,dc=example,dc=net
#ldap-group-name-attribute: cn

Completing installation

Guacamole will generally only load new extensions and reread guacamole.properties during the startup process. To apply the configuration changes, Guacamole must be restarted:

$ sudo systemctl restart guacamole

Custom Root Certificate

If you require the use of a custom Root Certificate for your LDAP server, you can volume mount the file /etc/pki/ca-trust/extracted/java/cacerts in your Docker Compose to override this certificate in the guacamole docker container.

  • Import the certificate into a Java truststore using "keytool".

  • Volume mount the cacerts file to your target guacamole docker container

For Advanced Linux Install method leveraging the RPMs, this would be accomplished through Red Hat's automated certificate import tooling following this guide.

Storing connection data within LDAP

This documentation assumes that you have already configured Guacamole to use LDAP for authentication. If have not already done so, please configure Guacamole for LDAP authentication before proceeding.

Defining the guacConfigGroup object class

When connection data is stored within your LDAP directory, each connection is represented by a special type of LDAP group, and permissions related to Guacamole connections can be managed directly with LDAP based on user membership of these groups. Doing this requires schema modifications which add a new object class called guacConfigGroup.

An LDIF file defining the schema changes in a manner compatible with OpenLDAP is provided by the kcm-guacamole-auth-ldap package within /opt/keeper/share/guacamole-auth-ldap/schema/guacConfigGroup.ldif. This file can be applied to your OpenLDAP server using the “ldapadd” command:

$ sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f /opt/keeper/share/guacamole-auth-ldap/schema/guacConfigGroup.ldif

Once this is done, connections can be defined by creating new guacConfigGroup objects within the LDAP directory. Each guacConfigGroup accepts a single guacConfigProtocol attribute, defining the protocol associated with the connection, and any number of guacConfigParameter attributes, each defining a connection parameter name/value pair. Users that should have access to the connection must be added as members of the guacConfigGroup using the member attribute.

For example, a connection accessible to two users which uses VNC to connect to localhost at port 5900 with the password “secret” could be defined with the following LDIF file:

dn: cn=Example Connection,ou=groups,dc=example,dc=net
objectClass: guacConfigGroup
objectClass: groupOfNames
cn: Example Connection
guacConfigProtocol: vnc
guacConfigParameter: hostname=localhost
guacConfigParameter: port=5900
guacConfigParameter: password=secret
member: cn=user1,ou=people,dc=example,dc=net
member: cn=user2,ou=people,dc=example,dc=net

Configuring Guacamole to read connections from LDAP

Auto Docker And Docker Compose Install Methods:

To read connection data from LDAP, Guacamole’s main configuration file, modify the /etc/kcm-setup/docker-compose.yml file.

The base DN of all connections defined within LDAP must be specified using the LDAP_CONFIG_BASE_DN property. This base DN should be the DN of the portion of the LDAP directory whose subtree contains all Guacamole connections accessible via LDAP. Only connections defined within the subtree of this base DN will be visible:

   guacamole:
        image: keeper/guacamole:2
        environment:
            ACCEPT_EULA: "Y"
            GUACD_HOSTNAME: "guacd"
            MYSQL_HOSTNAME: "db"
            MYSQL_DATABASE: "guacamole_db"
            MYSQL_USERNAME: "guacamole_user"
            MYSQL_PASSWORD: "xxxxxxx"
            
            # LDAP Connection
            LDAP_HOSTNAME: "localhost"
            LDAP_PORT: 389
            LDAP_ENCRYPTION_METHOD: "none"
            ADDITIONAL_GUACAMOLE_PROPERTIES: "extension-priority: *, ldap"
            
            ## Optional Settings ##
            # Read Connections from LDAP
            LDAP_CONFIG_BASE_DN: "ou=connections,dc=example,dc=net"

Advanced Linux Install Method:

To read connection data from LDAP, Guacamole’s main configuration file, /etc/guacamole/guacamole.properties, must be modified to define the subtree containing these connections:

$ sudo vi /etc/guacamole/guacamole.properties

The base DN of all connections defined within LDAP must be specified using the ldap-config-base-dn property. This base DN should be the DN of the portion of the LDAP directory whose subtree contains all Guacamole connections accessible via LDAP. Only connections defined within the subtree of this base DN will be visible:

##
## [LDAP-4] LDAP base DN for Guacamole connections ("guacConfigGroup")
##
## The base DN for all Guacamole connections defined directly within the LDAP
## directory using "guacConfigGroup" objects. If connections will not be stored
## within the directory, this property is unnecessary.
##
## If the kcm-guacamole-auth-ldap package has been installed, the LDAP
## schema for "guacConfigGroup" objects can be found at:
##
##   /usr/share/guacamole-auth-ldap/schema/guacConfigGroup.ldif
##
## Alternatively, if your LDAP directory does not accept LDIF files, the schema
## source for "guacConfigGroup" can be found at:
##
##   /usr/share/guacamole-auth-ldap/schema/guacConfigGroup.schema
##

#ldap-config-base-dn: ou=connections,dc=example,dc=net

Controlling access using group membership

Auto Docker and Docker Compose Install Method

To control group membership using LDAP, modify the /etc/kcm-setup/docker-compose.yml file.

It is also possible grant entire groups access to connections using the seeAlso attribute. This attribute is a standard LDAP attribute, and will be taken into account by Guacamole if the LDAP_GROUP_BASE_DN property is defined. This property defines the root of the subtree containing all groups which may apply to Guacamole users authenticated using LDAP:

  guacamole:
        image: keeper/guacamole:2
        environment:
            ACCEPT_EULA: "Y"
            GUACD_HOSTNAME: "guacd"
            MYSQL_HOSTNAME: "db"
            MYSQL_DATABASE: "guacamole_db"
            MYSQL_USERNAME: "guacamole_user"
            MYSQL_PASSWORD: "xxxxxxx"
            
            # LDAP Connection
            LDAP_HOSTNAME: "localhost"
            LDAP_PORT: 389
            LDAP_ENCRYPTION_METHOD: "none"
            ADDITIONAL_GUACAMOLE_PROPERTIES: "extension-priority: *, ldap"
            
            ## Optional Settings ##
            # Mapping Guacamole groups to LDAP DN's
            LDAP_GROUP_BASE_DN: "ou=groups,dc=example,dc=net"
            LDAP_GROUP_NAME_ATTRIBUTE: "cn"

Advanced Linux Install Method

It is also possible grant entire groups access to connections using the seeAlso attribute. This attribute is a standard LDAP attribute, and will be taken into account by Guacamole if the ldap-group-base-dn property is defined. This property defines the root of the subtree containing all groups which may apply to Guacamole users authenticated using LDAP:

##
## [LDAP-5] LDAP group / group DN description
##
## The base DN of all Guacamole groups within the LDAP directory, and the
## attribute which should be used by Guacamole to uniquely identify the
## group.
##
## If connections are being stored within LDAP using "guacConfigGroup" objects,
## and you wish to control access to these connections via LDAP groups, this is
## accomplished using the standard "seeAlso" attribute and the
## ldap-group-base-dn property is required.
##
## If connections are being stored outside of LDAP, such as within a database,
## and you wish to control access using LDAP groups, both ldap-group-base-dn
## and ldap-group-name-attribute will be required. The group membership of a
## user cannot be queried without a base DN, and the unique name to be used by
## other parts of Guacamole to represent the group cannot be determined without
## the name attribute.
##

#ldap-group-base-dn:        ou=groups,dc=example,dc=net
#ldap-group-name-attribute: cn

Completing installation

Changes to Guacamole’s LDAP configuration will generally only be reread from guacamole.properties during the startup process. To apply the configuration changes, Guacamole must be restarted:

Advanced Linux Install Method

$ sudo systemctl restart guacamole

If you do not have a standalone "guacamole" service

You will not have a standalone "guacamole" service if you have not deployed Guacamole automatically with the "kcm-guacamole-standalone" package. This will be the case if:

  • You have chosen to manually deploy Guacamole under your own install of Apache Tomcat or JBoss, rather than use the provided version of Tomcat.

  • You are maintaining a deployment of Glyptodon Enterprise that was originally installed before the 2.5 release (2021-09-16).

You will instead need to manually restart your install of Tomcat:

$ sudo systemctl restart tomcat

Using LDAP with a database

If multiple authentication methods are installed, Guacamole will poll each method as it attempts to authenticate users, and will retrieve connection data from each method once a user has successfully authenticated. This behavior is designed to allow authentication methods to work together, and can be leveraged to authenticate Guacamole users against LDAP while storing the connection data for those users within MySQL, PostgreSQL, or SQL Server.

Guacamole's definition of identity

When reading data from multiple authentication methods, Guacamole compares the unique identifiers of users (usernames) and groups to determine identity. This means that user accounts from different authentication systems will be automatically combined by Guacamole upon successful authentication as long as those user accounts have the same username, and group memberships will take effect across authentication systems so long as the unique names of those groups match.

If both LDAP and a database authentication method have been configured, Guacamole will automatically attempt to authenticate against both systems whenever a user attempts to log in. The LDAP account will be considered equivalent to the database user if the username is identical, and that user will have access to any data associated with them via the database, as well as any visible objects within the LDAP directory. If that user has permission to query their group memberships within LDAP, and Guacamole has been configured to query groups within LDAP, then the user's group membership will also be retrieved upon authentication, and the user will have access to any data associated with those groups via the database.

For a user known to exist within LDAP, that user can be granted permissions to connections within the database by logging in as the administrative user (by default, “guacadmin”) and creating a corresponding database account having the same username. By leaving the password unspecified for the database account, the user will only be able to log in using LDAP, but will still have access to any associated connections defined within the database.

Administering LDAP users within Guacamole

Rather than having to manually look up users or groups within the LDAP directory, and then manually create those same users and groups within Guacamole, it is possible to set up administrative user accounts which can already see and manage available LDAP objects. This streamlines the administrative process, reducing the number of users which must be manually created to one.

To see LDAP objects within Guacamole’s administrative interface, one of the following tasks must be performed:

  1. An administrative user within the Guacamole database, such as the default “guacadmin” user, must be manually created within LDAP with the same username and with sufficient privileges to query all Guacamole users and groups defined within LDAP.

  2. An administrative user must be manually created within Guacamole having the same username as an LDAP user with sufficient privileges to query all Guacamole users and groups defined within LDAP.

Because a Guacamole user created as defined above would have access to LDAP users and groups, database users and groups, and database connections, all of this data will be unified within the same administrative interface within Guacamole. The user will be able to grant LDAP users and groups access to connections within the database to just as they would if only the database were in use.

Using Multiple LDAP Servers

If your Active Directory or LDAP deployment spans multiple servers, Guacamole can be configured to use each of your LDAP servers using ldap-servers.yml, a configuration file similar to guacamole.properties and located within /etc/guacamole. When a user authenticates with a Guacamole instance configured to use multiple LDAP servers, each configured LDAP server is tried, in order, until authentication succeeds. Authentication fails only if none of the defined LDAP servers accept the user's provided credentials.

When ldap-servers.yml is used, the values within guacamole.properties still have meaning, but instead serve as defaults for the LDAP servers defined in ldap-servers.yml.

Overview of ldap-servers.yml

The ldap-servers.yml file contains a single YAML list of LDAP servers, with each server definition consisting of a simple list of configuration properties and values. These configuration properties are identical to the LDAP properties available within guacamole.properties except that the "ldap-" prefix is omitted.

For example, a simple ldap-servers.yml that defines two LDAP servers that may be used to authenticate users would contain the following:

- hostname: server1.example.net
  user-base-dn: OU=Users,DC=example,DC=net
  username-attribute: sAMAccountName
  search-bind-dn: CN=Guacamole,OU=Services,DC=example,DC=net
  search-bind-password: SomePassword!

- hostname: server2.example.net
  user-base-dn: OU=Users,DC=example,DC=net
  username-attribute: sAMAccountName
  search-bind-dn: CN=Guacamole,OU=Services,DC=example,DC=net
  search-bind-password: SomePassword! 

When a user attempts to log in, Guacamole will attempt to authenticate the user against the first defined LDAP server (server1.example.net). If that fails, Guacamole will proceed with the next (server2.example.net), and so on. Only if authentication fails against all defined LDAP servers will authentication against LDAP fail overall.

Abbreviating common LDAP parameters

Since the only property that varies between the two servers in the above example is the hostname, and since guacamole.properties serves as the source of default values when ldap-servers.yml is used, the configuration details common to all servers would be better specified within guacamole.properties:

ldap-user-base-dn: OU=Users,DC=example,DC=net
ldap-username-attribute: sAMAccountName
ldap-search-bind-dn: CN=Guacamole,OU=Services,DC=example,DC=net
ldap-search-bind-password: SomePassword!

The contents of ldap-servers.yml can then be reduced to only the hostnames:

- hostname: server1.example.net
- hostname: server2.example.net

Splitting users across multiple LDAP servers

LDAP servers listed within ldap-servers.yml may optionally be restricted to only certain users with the "match-usernames" option. This option accepts both a single string and an array of strings, where each string is a Perl-compatible regular expression. Additionally, if the regular expression includes a capturing group, the contents of the first capturing group will be used as the username representing the user's Guacamole identity.

For example, to define two LDAP servers covering distinct domains, splitting usage of those LDAP servers by whether the user enters their username as "DOMAIN1\username" or "DOMAIN2\username", you would edit your ldap-servers.yml to contain something like the following:

- hostname: domain1.example.net
  user-base-dn: OU=Users,DC=domain1,DC=example,DC=net
  match-usernames: DOMAIN1\\(.*)

- hostname: domain2.example.net
  user-base-dn: OU=Users,DC=domain2,DC=example,DC=net
  match-usernames: DOMAIN2\\(.*)

Each of the LDAP servers defined above will only be used if their corresponding regular expression matches the username specified by the user. Since each of the regular expressions in the above example define a capturing group around the username component of the "DOMAIN\username" format, that portion of the provided username will be used to determine the user's identity. If a user successfully authenticates as "DOMAIN1\myusername", then:

  • The captured portion ("myusername") will be used to identify the user's corresponding account in Guacamole's database.

  • The captured portion ("myusername") will be used when mapping the user to their fully-qualified LDAP DN.

If there are multiple username formats that need to be accepted by each LDAP server, multiple regular expressions may be specified. For example, to match both "MYDOMAIN\myusername" and the UPN-style "myusername@mydomain.example.net" formats, you would specify:

- hostname: domain1.example.net
  user-base-dn: OU=Users,DC=domain1,DC=example,DC=net
  match-usernames:
    - DOMAIN1\\(.*)
    - (.*)@domain1\.example\.net

- hostname: domain2.example.net
  user-base-dn: OU=Users,DC=domain2,DC=example,DC=net
  match-usernames:
    - DOMAIN2\\(.*)
    - (.*)@domain2\.example\.net