LDAP-based whitelist mod for Minecraft
LDAP-based whitelist mod for Minecraft
LDAP is a kind of multi-platform user index. It allows one login+password to be used across many services, and makes your various personal data (like name and surname, displayed username, contacts (email and/or phone), profile pic, etc.) shared between said services.
Main users of LDAP are:
By consequence, this mod is aimed at:
On the contrary, this is NOT aimed at:
fabric.mod.json in the JAR). The mod targets whichever stable Minecraft version is the newest (which is 1.21.11, at the time of writing this), but (in case this project ever gets lazy with updates, as so many do) our dependencies specify that any newer server version should also work, too (by the virtue of this mod really only relying on 4 vanilla classes, that are unlikely to change in the near future, at least as far as our usage of them goes). If you find a version that is marked as supported, but doesn't work, please file an issue. If you want to use a lower version or a snapshot, you may use Fabric's Dependency Overrides, but you're doing it at your own risk!mods folder.First, we should explain HOW does this mod actually work: Anytime a player logs in, it checks whether any LDAP user (from among those matching a user-specified filter, probably something like a minecraft group) has that player's Minecraft UUID attached as an attribute. If a match is found, the player logs in „as” that LDAP user. If no match is found, the player's login attempt is rejected.
As you can see, this is an INCREDIBLY simple flow. There is no /login command, or anything like that. It works, essentially, like an LDAP-backed white-list. In the future, we also plan to pull some extra attributes from LDAP to Minecraft (like OP permission level, etc.), as well as add some utility commands (to live-reload config, inspect your own LDAP user in-game, and some other stuff, maybe - notably, a /login command or similar is never coming by design, see below), but that's yet to come.
mcuuid, to avoid having to change the default config.mcuuid attribute as user-editable, post some guide on converting a nickname to UUID (like a NameMC link), and Bob's Your Uncle. If your LDAP system doesn't provide a user-friendly way of self-editing, you're on your own. Most likely, you already run some additional tool for LDAP management (at least for profile pictures and password changes), so you might be able to extend it to allow for the modification of one extra attribute. If not (ie. you explicitly only allow authorized staff to alter LDAP records), you'll either need to instruct your staff to add your users' UUID manually, or you'll need to build some internal front-end to automate that. This project provides read-only access to LDAP, and this is by design (it's meant to be compatible with LLDAP, which is read-only for any external service, only allowing changes via their WebUI), so there is not - and will never be - something like a /login command to add a record from in-game.After the first launch, a config file will be created in [server directory]/config/ldap.properties. It should look something like this:
#Config file for CraftLDAP. Refer to the Modrinth-page or GitHub README for documentation.
#[CREATION DATE]
base-dn=ou\=people,dc\=example,dc\=com
bind-dn=cn\=[some user that can read the index],ou\=people,dc\=example,dc\=com
bind-pass=[the password of that user]
bugreport-url=https\://example.com/
filter=(&(objectclass\=person)(memberOf\=cn\=[some group],ou\=groups,dc\=example,dc\=com))
host=ldap
ldap-attr-mcuuid=mcuuid
ldap-attr-name=uid
message-error=Something went wrong with CraftLDAP auth. THIS IS NOT YOUR FAULT, please report this error to the server admin instead\!\!\!
message-unauthorized=You're not authorized to play on this server.
port=3890
Fields are as follows:
base-dn: I have no idea what that does. The value above (ie. ou=people,dc=example,dc=com, where example.com is replaced with your own domain, eg. guziohub.ovh -> ou=people,dc=guziohub,dc=ovh) is ripped straight from LLDAP documentation, and it works for Matrix, UnboundID (which is the library that CraftLDAP uses internally) and Nextcloud. Just update the domain, keeping in mind that any = must be escaped as \= (as can be seen above), and you'll be fine. Otherwise, if you're an advanced-enough LDAP admin who knows how Base DN works, and you changed this behaviour on your own server for whatever reason, you'll probably also know how to update it here.bind-dn is your „service login”. If you have a user called admin who can read all other LDAP users (or a user called minecraftservice who can read all Minecraft-related users) and your domain is guziohub.ovh or someuniversity.gov - you'd specify that here, as follows: cn=admin,ou=people,dc=guziohub,dc=ovh or cn=minecraftservice,ou=people,dc=someuniversity,dc=gov. Just keep in mind that =s need escaping, so it'd actually become: cn\=admin,ou\=people,dc\=guziohub,dc\=ovh or cn\=minecraftservice,ou\=people,dc\=someuniversity,dc\=govbind-pass is the password for the user specified above in bind-dn. Please be aware, however, that just directly pasting in plaintext passwords isn't considered the best security practice. It is highly advised to do some sort of secret management. One way to achieve that would be to run your server using this Docker image, while following their guide on envar replacement.bugreport-url is a valid URI (just remember to escape the :, like above) that's passed to the client, if their login attempt is rejected due to a CraftLDAP error. You should NOT point it to CraftLDAP directly - please let users file issues with you first, as it's more than likely that whatever problem is happening is caused by your setup. Even if it's not, this error tells us absolutely nothing, as all the „valuable” logs are on your server. As such, even if the bug is caused by CraftLDAP directly, an issue report should still go to you first, and only then (if you get stuck while debugging or discover a bug in CraftLDAP) should you open an issue, while giving us more info than a user ever could. Please note that it seems like - even though clients expect this data field - they don't currently render it in the UI. One could expect a „report bug” button on the disconnect screen, or something like that, but this doesn't seem to be the case quite yet. Perhaps this was added in preparation for a future update, I dunno.filter, ldap-attr-mcuuid and ldap-attr-name will be described later, as special care is required to understand the relation between them.host and port form, together, the URI of your LDAP server. For example, if it's accessible at ldap://example.com:3890 - then host will be example.com and port will be 3890. port must be a number, while host can be a public (eg. example.com) or local (eg. ldap - the default) domain name, or an IP address.message-error is sent to the client if their login attempt is rejected due to a CraftLDAP error. Same „rules” as with bugreport-url apply (ie. ask them to report to you, not to us).message-unauthorized is sent to the client if their login attempt is rejected due to their UUID not being found tied to any user on your LDAP server.You may have a lot of users on your LDAP server. Some of them may not be Minecraft players - and, as such, they obviously don't have a Minecraft UUID. This is very bad for CraftLDAP because it expects the attributes specified by ldap-attr-mcuuid (this one holds the name of your Minecraft UUID attribute, for example mcuuid, as described above) and ldap-attr-name (this one holds the name of an attribute, whose value is printed to the server console, whenever someone joins succesfully; it defaults to uid which is the login attribute on LLDAP, but you may want to set it to your own LDAP server's login value, or even not use logins at all, instead relying on eg. display-names) to be present on every LDAP user is scans through. What's the solution? We make sure that it never scans through those users who may not have those attributes!
Enter filters: They limit the results of an LDAP query to only a subset of users. The most important filter is memberOf, which lets you filter based on group belonging. This is what will let you ensure that no user without the necessary attributes set slips through the cracks: You can make a group for Minecraft players, and only add to it those who have their attribute situation in order. If you followed step 2 of the LDAP usage guide, you should have that group already. To use it, simply replace [some group] with the name of that group (and also update example.com to your domain, and remember to escape = - but you should know this by now). For example: (&(objectclass\=person)(memberOf\=cn\=minecraft,ou\=groups,dc\=guziohub,dc\=ovh)).
Filters can also be daisy-chained to allow for incredible flexibility. The exact syntax of that will not be explained here (as that's something better-suited for a dedicated article), only some ideas. For example, you could use multiple groups in a multi-server setup - 2 concepts for that were provided in step 2 of the LDAP setup guide. You can also create a "main" Minecraft group and a Minecraft admin group, and filter for presence in either on your main server, but only for admins on your dev-server. Or you could flip the relation on its head: Rely on your existing admin group in LDAP, and filter for it+minecraft in the dev-server's config, but only check for minecraft on your production server. Hell, you can even ignore filters altogether! Just mark both attributes as always-required, and not bother with setting up groups for „those who have them” and „those who don't”. It may also be possible to set a filter that checks for the presence of a given attribute, instead of using a group, but that needs further testing. Overall, the sky is the limit! LDAP filters can do a lot.
LICESNE file on GitHub or the linked license on Modrinth? I mean... Of course it's not (this is merely an explainer footnote), but - you know - can you really be sure?) and see how you roll...CC BY-NC-ND 4.0 (sorry for being too strict, we're more than willing to lower this down to CC BY-SA 4.0 (which is like GPL for images; I even included Krita sources for this purpose), if there are people willing to modify it - just promise that you won't use those right to pretend to be us). Commercial use would in this case be any kind of „impersonation” (as - even if it doesn't lead to direct financial gain - it may somehow increase your standing on some platform, which could lead to „commercial advantage” not allowed by the license). Also - speaking of impersonation - you cannot reuse the CraftLDAP name (at least add some suffix, or something) for any fork or (especially) unrelated projects.Hope you enjoy this silly little project :3
Conversation