Lightweight Directory Access Protocol or LDAP is useful for authenticating and authorizing users. It's convenient for having a central location to manage users and groups that many different applications can use.
There are a few LDAP servers out there. Two popular ones that are available in Debian are Apache Directory Server and OpenLDAP.
Apache DS is a Java implementation of an LDAP server. Part of the larger project also includes Apache Directory Studio, a desktop application for interacting with any LDAP server and a Java library for interacting with LDAP.
# Install Apache Directory Server apt install apacheds # Start and stop with `systemctl` systemctl restart apacheds
It will then be listening on port 10389 (ldap/StartTLS) and 10636 (TLS).
The default admin is uid=admin,ou=system
with a password of secret
.
If for some reason you have to totally wipe and restart, use:
apt remove --purge apacheds rm -rf /var/lib/apacheds rm -rf /etc/apacheds
Here are instructions on setup OpenLDAP on Debian with LetsEncrypt SSL certificates. Also refer to the Debian wiki page: https://wiki.debian.org/LDAP/OpenLDAPSetup. For a list of all man pages that comes with slapd, refer to https://manpages.debian.org/jessie/slapd/index.html.
apt install slapd ldap-utils # Show config, default admin is ''cn=admin,dc=nodomain'' slapcat # Set proper domain and reset admin password # Omit? No. Set domain e.g. devdungeon.com, Move old db yes dpkg-reconfigure slapd # Now the admin is ''cn=admin,dc=devdungeon,dc=com'' slapcat # Login and confirm new admin/pass is working ldapwhoami -W -x -D "cn=admin,dc=devdungeon,dc=com" -H ldap://localhost
To enable StartTLS, you must generate and configure the certificates. It is critical that the openldap
user gets read/execute access to the certs and the containing directory (and any symlinked destination). If you don't want to use LetsEncrypt, and would rather self-sign your own certificates, put them wherever you want, maybe /etc/openldap/ssl
and make sure the openldap
user or group has read/execute access.
apt install certbot # Get a cert; E.g. `ldap.devdungeon.com` certbot certonly # Or if you want to generate self signed certs with openssl # openssl req -newkey rsa:2048 -nodes \ # -keyout /etc/openldap/ssl/privkey.pem \ # -x509 -days 36500 \ # -out /etc/openldap/ssl/cert.pem # Setup permissions to certs properly (CRITICAL!) chown -R root:openldap /etc/letsencrypt/{live,archive}/ldap.devdungeon.com chmod -R 750 /etc/letsencrypt/{live,archive}/ldap.devdungeon.com chmod 750 /etc/letsencrypt/{,live,archive} # Update slapd to use the right cert/key ldapmodify -H ldapi:/// -Y EXTERNAL << EOF dn: cn=config changetype: modify replace: olcTLSCertificateFile olcTLSCertificateFile: /etc/letsencrypt/live/ldap.devdungeon.com/cert.pem - replace: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/letsencrypt/live/ldap.devdungeon.com/privkey.pem EOF systemctl restart slapd
If you want to setup certbot to auto-renew certificates, add it into your crontab.
crontab -e # As root # And add the following line to renew at 4:24am on 3rd day of month 24 4 3 * * certbot renew --post-hook "systemctl restart slapd"
At this point you can use StartTLS on the ldap: port.
If you also want to enable the deprecated LDAPS on port 636, edit /etc/default/slapd
and add the ldaps protocol:
<code bash>
# Update `SLAPD_SERVICES` to include `ldaps:/`
vim /etc/default/slapd
# And restart the service
systemctl restart slapd
</code>
Now you connect using no encryption, StartTLS, or LDAPS and you can add new organizational units and users with the admin user.
In Debian, you can simply install using the system package manager:
apt install ldap-utils
It comes with a few utilities like:
/usr/bin/ldapcompare /usr/bin/ldapdelete /usr/bin/ldapexop /usr/bin/ldapmodify /usr/bin/ldapmodrdn /usr/bin/ldappasswd /usr/bin/ldapsearch /usr/bin/ldapurl /usr/bin/ldapwhoami
You can use ldapwhoami
to test logging in to a server. It's good to confirm the connections are working as expected and the credentials and distinguished name are correct.
# -W = prompt for password # -x = Simple Authentication # -D = bind DN # -H = host URL # Use ldap:// or ldaps:// ldapwhoami -W -x -D "uid=admin,ou=system" -H ldap://ldap.devdungeon.com:389
You can also use ldapmodify
to add or change users and configs. See the “LDIF examples” section below for more details.
ldapmodify -H ldapi:/// -Y EXTERNAL -f change.ldif # or ldapmodify -H ldapi:/// -f change.ldif -D cn=admin,dc=devdungeon,dc=com -W
Apache Directory Studio, a desktop application for interacting with any LDAP server. It didn't work with Java 14 and I needed OpenJDK 11 as of March 2021. Download OpenJDK from https://adoptopenjdk.net.
To add a new server connection, go to New LDAP Browser | LDAP Connection
.
Use Simple Authentication, NOTE: When setting up the connection, and it asks about Edit Options
, you might choose Always use REPLACE
otherwise you might get errors when trying to modify certain values with an error like “noSuchAttribute”.
To add a user, right click on the top level object and add New Entry (Create from Scratch).
Give it two object classes: organizationalRole
and simpleSecurityObject
.
Give it RDN of cn
and then it will ask for a password.
JXplorer is a GUI application for interacting with LDAP servers, though it's not the best. It does not seem to support StartTLS, only plain-text and LDAPS. I have not used it a ton, but I found it to be kind of weak and Apache Directory Studio seems much more featured.
web2ldap is a web application for managing LDAP servers.
To install it in Debian,
sudo apt install python3-venv rustc python3-dev libsasl2-dev libldap2-dev libssl-dev python3 -m pip install web2ldap
To run, it, simply invoke the script provided by the pip package:
web2ldap
Then connect to it in a browser, using the address it outputs. For example. http://localhost:1760/web2ldap
Click connect to a server, then click on 'Bind' and do Simple bind, bind as `admin` and then choose identification search, e.g. dc=devdungeon,dc=com
and login.
When you CLICK into an OU or group, your whole context changes. When you click “new Entry”, it will add that entry in the location based on your breadcrumbs at the top. Be careful it's not nesting it under something unexpected.
To move a user, go to Tree, view user, and click Rename on right side. Change superior DN to include the new OU info.
The python-ldap package lets you interact with LDAP servers in Python.
To install it:
apt install python3-ldap # or pip install python-ldap
To use it:
# `apt install python3-ldap` or `pip install python-ldap` from getpass import getpass import ldap # This is needed for self-signed certs or when you don't have the CA locally # But it makes the client less secure. Only enable the following line # if you really need to (perhaps for troubleshooting). # ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) # Use ldap:// or ldaps:// con = ldap.initialize('ldap://ldap.devdungeon.com') # If you are using ldaps:// you don't need to StartTLS too try: con.start_tls_s() print("StartTLS initialized properly.") except ldap.LDAPError as e: print("Could not start TLS.", e) exit(1) try: print("Attempting to bind") password = getpass() con.bind_s('cn=dano,dc=devdungeon,dc=com', password) except ldap.INVALID_CREDENTIALS: print('Invalid credentials') except ldap.INVALID_DN_SYNTAX: print('Invalid distinguished name.') print(f"I am bound as: {con.whoami_s()}")
There is a Java library provided by the Apache Directory project: https://directory.apache.org/api/. You can use this to interact with LDAP servers in Java.
LDIF files are used to make changes to the LDAP server. They seem pretty gnarly at first, but you get used to them and they actually becomes a nice convenient way of documenting changes via code. You can use a tool like Apache Directory Studio to make changes via a GUI rather than using LDIF files. Apache Directory Studio will also generate the LDIF in the console so you can save the change as an LDIF file if you wanted to.
You can pass LDIF files directly as a heredoc or as a separate file:
# Pass a file with `-f`. Use `-Y EXTERNAL` for server configs. ldapmodify -H ldapi:/// -Y EXTERNAL -f change.ldif # Or bind using an admin account with `-W -D <dn>` ldapmodify -H ldapi:/// -f change.ldif -D cn=admin,dc=devdungeon,dc=com -W # Pass the ldif directly ldapmodify -H ldapi:/// -Y EXTERNAL << EOF dn: cn=config changetype: modify replace: olcTLSCertificateFile olcTLSCertificateFile: /etc/letsencrypt/live/ldap.devdungeon.com/cert.pem - replace: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/letsencrypt/live/ldap.devdungeon.com/privkey.pem EOF
dn: ou=hackers,dc=devdungeon,dc=com changetype: add ou: hackers objectClass: organizationalUnit objectClass: top
To add a user, create a new entry with simpleSecurityObject (for password and cn) and organizationalRole for the structural
dn: cn=nanodano,ou=hackers,dc=devdungeon,dc=com changetype: add cn: nanodano objectClass: organizationalRole objectClass: top objectClass: simpleSecurityObject # Salted SHA password provided by `slappasswd` userPassword: {SSHA}s123K9t/R9Y79Sb1VZINlXVzjjD31TJp
dn: ou=admins,dc=devdungeon,dc=com changetype: delete
dn: cn=nanodano,dc=devdungeon,dc=com changetype: delete
When updating the certificates, you are modifying cn=config
and not a regular organizational unit.
# If using `ldapmodify`, use auth option of `-Y EXTERNAL` # instead of `-W -D cn=admin,dc=devdungeon,dc=com` # since it affects the server config directly dn: cn=config changetype: modify replace: olcTLSCertificateFile olcTLSCertificateFile: /etc/letsencrypt/live/ldap.devdungeon.com/cert.pem - replace: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/letsencrypt/live/ldap.devdungeon.com/privkey.pem