@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.

    Keywords

    none

    Install

    npm i @cepharum/simple-ldap

    DownloadsWeekly Downloads

    2

    Version

    0.1.1

    License

    MIT

    Unpacked Size

    14.4 kB

    Total Files

    3

    Last publish

    Collaborators

    • simon.friedo
    • soletan