Securing LDAP Connections
When using your project with a production LDAP server, you should always use a secure connection. The LDAP connections probably will include sensitive information from your domain, like the credentials of the service account that is begin used by your Django Project, user information of the users on your site and any other custom uses of LDAP in your code.
Securing the connection to your LDAP is somewhat easy, yet still requires some prerequisites and configurations. Here you will be informed of some practices you can do to better secure your LDAP connections.
Note
Using SSL/TLS
SSL/TLS use certificates to establish a secure connection between you and the LDAP service before any data is exchanged. This practice is called LDAPs, and refers for LDAP over TLS or LDAP over SSL.
To use LDAPs, it needs to be enabled on the LDAP service side. Each LDAP service has a different setup required to enable LDAPs, you can search docs for your case.
For Active Directory administrators, here is a great guide to enable it for testing: https://techexpert.tips/windows/enabling-the-active-directory-ldap-over-ssl-feature/
Once you have enabled LDAPs on the server, you just need to configure the LDAP Setting USE_SSL
to True.
WAUTH_DOMAINS = {
"EXAMPLE": LDAPSettings(
SERVER="example.local",
SEARCH_BASE="DC=example,DC=local",
USERNAME="EXAMPLE\\bind_account",
PASSWORD="<super secret>",
USE_SSL=True,
),
}
Warning
This module uses LDAPs by default to provide an easier setup.
In case your LDAP servers are not capable of LDAPs, you should configure the LDAP setting USE_SSL
to False.
Using NTLM Authentication
NTLM is a protocol used to securely exchange credential information between the client and the server. It is done by hashing the password with a random generated number provided by the server before sending.
NTLM was originally created by Microsoft to be used in the Windows ecosystem. It is still in use today, yet it is considered outdated, and has been mainly replaced with Kerberos.
To enable NTLM authentication, you can specify connection’s authentication
options in the CONNECTION_OPTIONS
LDAP setting.
WAUTH_DOMAINS = {
"EXAMPLE": LDAPSettings(
SERVER="example.local",
SEARCH_BASE="DC=example,DC=local",
USERNAME="EXAMPLE\\bind_account",
PASSWORD="<super secret>",
USE_SSL=True,
CONNECTION_OPTIONS={
"authentication": ldap3.NTLM,
},
),
}
See also
NTLM authentication on ldap3 docs https://ldap3.readthedocs.io/en/latest/bind.html#ntlm
Using Kerberos (SASL)
Kerberos is an authentication and authorization protocol designed by MIT in the late ’80s. Today, kerberos is the gold standard authentication and authorization protocol used throughout Windows and other OSs. It uses tickets to represent the authenticated user and to authorize it to access desired services.
See also
Learn more about Kerberos at https://www.simplilearn.com/what-is-kerberos-article
When using kerberos authentication, the credentials given to the LDAP server is the account’s kerberos token accessed from the MIT Token Manager. Therefore, the account running your Django Project will be used when accessing LDAP servers, and no username or password needs to be provided.
In order to use the ldap3 SASL
authentication with the KERBEROS
mechanism, you will need to install the gssapi
package.
To install it you first need to install the MIT Kerberos on the server.
Go to https://web.mit.edu/KERBEROS/dist/ and download the latest MIT Kerberos for Windows as 64-bit MSI Installer, and install it on the server. Restart will be required after installation is done.
After the restart, edit the C:\ProgramData\MIT\Kerberos5\krb5.ini
and provide the default_realm
setting.
For example:
[libdefaults]
default_realm = EXAMPLE.LOCAL
See also
More about the krb5.ini
config file https://web.mit.edu/kerberos/www/krb5-latest/doc/admin/conf_files/krb5_conf.html
Then, install the gssapi
package in your virtualenv:
$ pip install gssapi
Then configure your LDAP connections to use the SASL
authentication with KERBEROS
mechanism like so:
WAUTH_DOMAINS = {
"EXAMPLE": LDAPSettings(
SERVER="example.local",
SEARCH_BASE="DC=example,DC=local",
USERNAME="",
PASSWORD="",
USE_SSL=True,
CONNECTION_OPTIONS={
"authentication": ldap3.SASL,
"sasl_mechanism": ldap3.KERBEROS,
}
),
}
Now you need to get the ticket for that account configured though MIT Token Manager.
Note
Notice the username and password kept as empty strings as they are not necessary in this setup.
Optimize your code
Securing the LDAP connection in at the protocol level is good, but do not let it deceive you. It is very important to restrict any unintended operation on the LDAP server, especially write operations.
Minimize the permissions and delegations of the bind account to the bare minimum possible. You can never know how and what could be done through vulnerabilities in your code.
Never ever write user password or other credentials explicitly inside your code. Use instead another way to store your secrets in a protected place. See the tutorial about Managing Secrets
Use ``Reader`` and ``Writer`` cursors from ldap3’s abstraction module. Using them can help you to avoid unwanted behaviors by simplifying the interface.
Restrict access to views performing LDAP operations. Allow only authenticated users, and implement permission check to avoid compromising your views.
Use read-only connection when possible. By default, LDAP connections are made read-only. It restricts the execution of write operations at the client level.
In case you need to perform write operations, you will need to explicitly disable read-only.
When doing so, consider creating a dedicated connection for writing, with a different bind account with the minimal permissions.
This can be done by adding another domain to WAUTH_DOMAINS
setting for the same domain, but with different account and read-only disabled.