@cepharum/simple-ldap

0.1.1 • Public • Published

simple-ldap

simple LDAP server exposing user accounts defined in local JSON file

License

MIT

About

This package implements LDAP server suitable for authentication. The supported user base is defined in a local JSON file read once on start. Name of JSON file is provided in first argument provided on starting service, in environment variable SIMPLE_LDAP_DB_FILE or in file ./ldap-db.json.

Data Format

The simulated LDAP tree is flat, fixed and simple by design. All entries are children of root DN o=foo with foo being customizable via environment variable SIMPLE_LDAP_ORGANIZATION.

The JSON read from file must be an array of objects each describing another LDAP entry eventually subordinated to o=foo. Either object's properties are describing attributes of resulting entry. A property named cn must be provided and is used to generate entry's DN:

cn=<value of property cn>,o=foo

This DN is meant to uniquely select the entry in resulting LDAP tree. Thus, it is hashed to create the entry's unique ID exposed in attribute entryUUID. You shouldn't change the cn of an entry to keep its DN as well as its entryUUID unchanged for either one might be used for associating data with the related entry.

All properties are basically adopted as attributes. However, by adding a period and the name of a hashing algorithm to a property's name the provided value is hashed and assigned to resulting attribute instead.

Example

[
	{
		"cn": "John Doe",
		"sn": "Doe",
		"givenName": "John",
		"userPassword.ssha": "secret",
		"customPIN.ssha256": "12345"
	}
]

This JSON input results in the following LDAP entry:

dn: cn=John Doe,o=foo
objectclass: top
objectclass: inetorgperson
cn: John Doe
givenName: John
sn: Doe
userPassword: {SSHA}tG0H2qnuiLBSb/Z085nHKxaiDYHUk/x1xAtaYueyb4DQ/LPF
customPIN: {SSHA256}yvWoHbrHR5Q4TWUf1JwHPlYTm6X7qtM8uENOqxreZiVWUinR0iarp93rtWkecX1R
entryUUID: c5de1dca-a879-29df-83db-1552edcfb6fb

The values of userPassword and customPIN are salted hashes of values provided in JSON. In either case a random salt has been applied.

Querying

The LDAP server works with commonly available clients.

/ # ldapsearch -x -H ldap://host.docker.internal -b o=foo
# extended LDIF
#
# LDAPv3
# base <o=foo> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# foo
dn: o=foo
o: foo
objectclass: organization
objectclass: top

# John Doe, foo
dn: cn=John Doe,o=foo
objectclass: top
objectclass: inetorgperson
cn: John Doe
sn: Doe
givenName: John
userPassword:: e1NTSEF9dEcwSDJxbnVpTEJTYi9aMDg1bkhLeGFpRFlIVWsveDF4QXRhWXVleWI
 0RFEvTFBG
customPIN: {SSHA256}yvWoHbrHR5Q4TWUf1JwHPlYTm6X7qtM8uENOqxreZiVWUinR0iarp
 93rtWkecX1R
entryUUID: c5de1dca-a879-29df-83db-1552edcfb6fb

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 2

This example is querying all entries in thread o=foo. Filters are mostly obeyed:

~ > ldapsearch -LLL -x -H ldap://host.docker.internal -b o=foo "(sn=Doe)"
dn: cn=John Doe,o=foo
objectclass: top
objectclass: inetorgperson
cn: John Doe
sn: Doe
givenName: John
userPassword:: e1NTSEF9dEcwSDJxbnVpTEJTYi9aMDg1bkhLeGFpRFlIVWsveDF4QXRhWXVleWI
 0RFEvTFBG
inpasCustomPIN: {SSHA256}yvWoHbrHR5Q4TWUf1JwHPlYTm6X7qtM8uENOqxreZiVWUinR0iarp
 93rtWkecX1R
entryUUID: c5de1dca-a879-29df-83db-1552edcfb6fb

Using a more specific base DN is supported, too:

~ > ldapsearch -LLL -x -H ldap://host.docker.internal -b "cn=John Doe,o=foo"
dn: cn=John Doe,o=foo
objectclass: top
objectclass: inetorgperson
cn: John Doe
sn: Doe
givenName: John
userPassword:: e1NTSEF9dEcwSDJxbnVpTEJTYi9aMDg1bkhLeGFpRFlIVWsveDF4QXRhWXVleWI
 0RFEvTFBG
inpasCustomPIN: {SSHA256}yvWoHbrHR5Q4TWUf1JwHPlYTm6X7qtM8uENOqxreZiVWUinR0iarp
 93rtWkecX1R
entryUUID: c5de1dca-a879-29df-83db-1552edcfb6fb

Limitations

Currently, the LDAP server is handling unencrypted traffic on port 389, only. There is support for search queries, only. You can't actually bind against this service. In addition, it is always exposing every attribute per entry. So contrary to common behaviour of existing LDAP servers hashed passwords are provided in response to public queries, too.

Use Cases

Limitations listed above render this service inappropriate for public production environments. You should use it for testing purposes or in a stack or pod of containers that communicate over encrypted connections, only.

Usage

This package is deployed as a docker image:

docker run -v $HOME/config:/config:ro -p 389:389 \
       registry.gitlab.com/cepharum-foss/simple-ldap

On start, it is looking for a file named ldap-db.json, simple-ldap-entries.json or entries.json in folder /config which is addressing bound host folder here. First existing file is used. Service is exposed on port 389.

In context of Docker Swarm you can use a docker secret named simple-ldap.config.tgz for easy distribution of data. This secret must contain a compressed tar archive. It is extracted into folder /config at start of container.

Dependencies (1)

Dev Dependencies (0)

    Package Sidebar

    Install

    npm i @cepharum/simple-ldap

    Weekly Downloads

    0

    Version

    0.1.1

    License

    MIT

    Unpacked Size

    14.4 kB

    Total Files

    3

    Last publish

    Collaborators

    • simon.friedo
    • soletan