====== LDAP ====== [[https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol|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. ===== Servers ===== There are a few LDAP servers out there. Two popular ones that are available in Debian are Apache Directory Server and OpenLDAP. ==== Apache Directory Server ==== [[https://directory.apache.org/apacheds/|Apache DS]] is a Java implementation of an LDAP server. Part of the larger project also includes [[https://directory.apache.org/studio/|Apache Directory Studio]], a desktop application for interacting with any LDAP server and a [[https://directory.apache.org/api/|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 ==== OpenLDAP ==== 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: # Update `SLAPD_SERVICES` to include `ldaps:///` vim /etc/default/slapd # And restart the service systemctl restart slapd Now you connect using no encryption, StartTLS, or LDAPS and you can add new organizational units and users with the admin user. ===== Tools ===== ==== ldap-utils ==== 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 ==== [[https://directory.apache.org/studio/|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 ==== [[http://jxplorer.org|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 ==== [[https://www.web2ldap.de|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. ==== Python Library ==== The [[https://www.python-ldap.org/|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()}") ==== Java Library ==== 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 examples ===== 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 ` 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 ==== Add an OU ==== dn: ou=hackers,dc=devdungeon,dc=com changetype: add ou: hackers objectClass: organizationalUnit objectClass: top ==== Add a user ==== 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 ==== Delete an OU ==== dn: ou=admins,dc=devdungeon,dc=com changetype: delete ==== Delete a user ==== dn: cn=nanodano,dc=devdungeon,dc=com changetype: delete ==== Update TLS certificates ==== 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