Site Index
 Wiki

External Links
 Public Directory

Search Site


 

Puffy Security


OpenBSD ldapd YP LDAP Domain with default Login Class Support and Blowfish Hashes

This Wiki page will walk through the setup of an OpenBSD ldapd server and YP Domains via ypldap, which are supported by the default login class and uses a Blowfish password hash.

Systems will use BSD Auth to authenticate domain users against a local YP Domain and ypldap will periodically sync the YP Domain with the LDAP server. This is more efficient, reliable, and secure then direct LDAP interaction.

If the LDAP server becomes unreachable, each servers local YP Domain will continue to work. They just will not be able to sync with LDAP. All user information requests are fulfilled locally, so it is fast even at remote sites. Additionally, user passwords only need to be sent over the network as Blowfish hashes for ypldap sync operations, because YP is used to check plain-text passwords instead of LDAP. However, LDAP Binds will need to send the plain-text password to the central LDAP server for {BSDAUTH}.

This configuration will result in:

  • Central OpenBSD ldapd LDAP server hosting all Domain users and groups
  • Every server running it's own local YP Domain
    • ypldap will synchronize the local YP Domain with the central LDAP server
  • Users will be authenticated by OpenBSD's BSD Auth
    • The default login class will be used
    • The default passwd authentication style will be used
    • Passwords checked against an Blowfish hash stored in LDAP
  • LDAP Binds will be preformed against {BSDAUTH}
    • {BSDAUTH} will check the users password against Blowfish hash

Table of Contents

  1. OpenBSD YP LDAP Server
    1. Setup OpenBSD ldapd
      1. Custom LDAP Schema files
        1. Download and Install
      2. Configure ldapd
        1. /etc/ldapd.conf
      3. Configure OpenBSD PF Firewall
        1. /etc/pf.conf
        2. Load the PF Rules
      4. Start OpenBSD ldapd
    2. Populate and Modify LDAP with LDIF Files
      1. Install Required Packages
      2. Migration Script: OpenBSD Local Users to LDAP
        1. Download Migration Script
        2. Run ypldap-migration and Add LIDFs to LDAP
        3. Optimize LDAP Database
      3. How To Change a LDAP User's Password
        1. Create New Blowfish Password Hash
        2. Create Password Change LDIF
          1. Example Password Change LDIF
        3. Update LDAP Password with LDIF
      4. Manually Create LDIF
        1. Example Complete LDIF
  2. OpenBSD YP LDAP Client
    1. Install Required Packages
    2. Add YP Marker to Local Account Files
      1. Add YP Marker to /etc/master.passwd
      2. Add YP Marker to /etc/group
      3. Check Files for YP Marker
    3. Create YP Domain
      1. Set the YP Domain Name
      2. Initialize YP Domain
    4. Configure ypldap
      1. /etc/ypldap.conf
    5. Start and Test ypldap
      1. Start portmap, ypldap, ypbind
      2. Test the ypldap Domain

1 OpenBSD YP LDAP Server

This section describes the setup of the OpenBSD ldapd LDAP Server. This configuration only needs to be done on the Central LDAP server. However, this central server also needs to be configured as an OpenBSD YP LDAP Client, so LDAP Binds against {BSDAUTH} will work.


1.1 Setup OpenBSD ldapd

1.1.1 Custom LDAP Schema files

I have modified the nis.schema which ships with OpenBSD-5.7 in order for the posixAccount to support the attributes shadowPassword, shadowExpire, modifyTimestamp, and userClass. You must use these ldap schema files in order to use this ypldap system. You could also the /etc/ypldap.conf passwd filter, but you'll probaly be changing the schema anyway. So, I change one thing instead of two.

1.1.1.1 Download and Install

The files are hosted on my github page.

You can just use OpenBSD's ftp to download them like so.

    mkdir /tmp/ldap
    cd /tmp/ldap
    ftp https://raw.githubusercontent.com/tdwyer/ypldap-migration/master/ldap/core.schema
    ftp https://raw.githubusercontent.com/tdwyer/ypldap-migration/master/ldap/inetorgperson.schema
    ftp https://raw.githubusercontent.com/tdwyer/ypldap-migration/master/ldap/nis.schema

    su - root
    cp /tmp/ldap/*schema /etc/ldap

1.1.2 Configure ldapd

Update the following configuration file to match your domain and install to /etc/ldapd.conf.

1.1.2.1 /etc/ldapd.conf

File Permissions: -rw------- 1 root wheel

    #   $OpenBSD: ldapd.conf,v 1.1 2014/07/11 21:20:10 deraadt Exp $

    schema  "/etc/ldap/core.schema"
    schema  "/etc/ldap/inetorgperson.schema"
    schema  "/etc/ldap/nis.schema"

    listen on "/var/run/ldapi"
    listen on lo0 secure
    listen on ldap.example.com ldaps
    #
    # ypldap cant use SSL or SASL...
    # You must allow unsecured authentication with the following line
    # Then setup OpenIKED VPN or use OpenSSH Socket or Port Forwording
    #
    listen on ldap.example.com secure

    namespace "dc=example,dc=com" {
        rootdn  "cn=admin,dc=example,dc=com"
        rootpw  "RootBindPasswordChangeMe"
        index   objectClass
        index   cn
        index   ou
        index   uid
        index   uidNumber
        index   gidNumber
        deny access to any by any
        allow bind access to children of "ou=People,dc=example,dc=com" by any
        allow read access to any by self
    }

1.1.3 Configure OpenBSD PF Firewall

You must allow the YP Domain servers to connect to the LDAP Server. ypldap can not do TLS or SASL Authentication. As a result, you must allow the unsecured LDAP port to be open. Better still, you can use the new UNIX Domain Socket forwarding in OpenSSH and not bother with the firewall. You could also setup an OpenIKED IPSec IKEv2 VPN between the servers.

1.1.3.1 /etc/pf.conf

File Permissions: -rw------- 1 root wheel

    set reassemble yes
    set block-policy return
    set loginterface egress
    set skip on lo

    match in all scrub (no-df random-id max-mss 1440)

    table <bruteforce> persist

    block in log
    block in quick from urpf-failed label uRPF
    block quick from <bruteforce>

    pass out all modulate state

    pass in quick inet proto icmp icmp-type { echoreq, unreach }

    pass in quick proto tcp from any \
        to (egress) port ssh \
        flags S/SA modulate state \
        (max-src-conn 15, max-src-conn-rate 15/5, overload <bruteforce> flush global)

    pass in quick proto tcp \
        from any to (egress) \
        port { ldap, ldaps } \
        label LDAP

1.1.3.2 Load the PF Rules

Now, load the PF configuration file into PF with pfctl

    pfctl -vf /etc/pf.conf

1.1.4 Start OpenBSD ldapd

First, check to make sure the configuration file /etc/ldapd.conf is okay. Then update /etc/rc.conf.local and start ldapd.

    ldapd -n
        configuration ok

    echo 'ldapd_flags=""' >> /etc/rc.conf.local

    /etc/rc.d/ldapd start

1.2 Populate and Modify LDAP with LDIF Files

1.2.1 Install Required Packages

While OpenBSD has a LDAP server ldapd in base, it dose not have a Client. So, install openldap-client to get the required utilities for managing LDAP.

    pkg_add openldap-client

1.2.2 Migration Script: OpenBSD Local Users to LDAP

I wrote a LDAP migration script in Awk. The script will read users and groups from /etc/master.passwd and /etc/group. At the top of the script you can configure the UID and GID range which will be coppied. By default it will only pull users and groups with a UID or GID in between 1000 and 3000.

It will create the following ldif files.

  • base.ldif = Contains the structure of the LDAP database
  • group.ldif = Contains the groups read from /etc/group
  • passwd.ldif = Contains the users read in from /etc/master.passwd

1.2.2.1 Download Migration Script

    ftp https://raw.githubusercontent.com/tdwyer/ypldap-migration/master/ypldap-migration
    chmod +x ypldap-migration

1.2.2.2 Run ypldap-migration and Add LIDFs to LDAP

    ./ypldap-migration
    ldapadd -H ldap://ldap.example.com -D 'cn=admin,dc=example,dc=com' -x -W -f base.ldif
    ldapadd -H ldap://ldap.example.com -D 'cn=admin,dc=example,dc=com' -x -W -f group.ldif
    ldapadd -H ldap://ldap.example.com -D 'cn=admin,dc=example,dc=com' -x -W -f passwd.ldif

1.2.2.3 Optimize LDAP Database

You will want to compact and index your LDAP database now.

    ldapctl compact
    ldapctl index

1.2.3 How To Change a LDAP User's Password

Unfortunately, OpenBSD's ypldap is not able to update the users password in the LDAP database. However, the user is allowed to Bind to their address and you can allow write access to any by self so the user can change the password hash.

1.2.3.1 Create New Blowfish Password Hash

First, you'll have to get the Blowfish hash of your new password with the encrypt command.

    encrypt -b 12 -p
        Enter string:
        $2b$12$roxYWRk/j/X2TXcG/tgu.OFnuMMqGRN58EMWyOCtdDdacY.GJIhLe

1.2.3.2 Create Password Change LDIF

Then you'll want to modify the Example Password Change LDIF. Change the username and set shadowPassword: to your new password hash.

1.2.3.2.1 Example Password Change LDIF

File Permissions: -rw-rw-r-- 1 root users

    dn: uid=alice,ou=People,dc=example,dc=com
    changetype: modify
    replace: shadowPassword
    shadowPassword: $2b$12$roxYWRk/j/X2TXcG/tgu.OFnuMMqGRN58EMWyOCtdDdacY.GJIhLe

1.2.3.3 Update LDAP Password with LDIF

Finally, you can update your password in LDAP with the ldapmodify command.

NOTE: To be on the safe side, the ldapd.conf in this Wiki will not allow a user write access, but you can just change it.

    ldapmodify -H ldap://ldap.example.com -D 'uid=alice,ou=People,dc=example,dc=com' -W -f pass-change.ldif
    # or you can Bind as the Domain Root User
    ldapmodify -H ldap://ldap.example.com -D 'cn=admin,dc=example,dc=com' -x -W -f pass-change.ldif

1.2.4 Manually Create LDIF

For completeness and for those who do not want to use my ypldap Migration Script. I have included a complete LDIF example below which shows the structure needed. You can simply add more groups and users just like how Alice and her groups are setup.

NOTE: For Groups, multiple group members are added with multiple... memberUid: username ...lines.

1.2.4.1 Example Complete LDIF

File Permissions: -rw-r--r-- 1 root wheel

    dn: dc=example,dc=com
    dc: example
    objectClass: top
    objectClass: domain

    dn: ou=People,dc=example,dc=com
    ou: People
    objectClass: top
    objectClass: organizationalUnit

    dn: ou=Group,dc=example,dc=com
    ou: Group
    objectClass: top
    objectClass: organizationalUnit

    dn: cn=users,ou=Group,dc=example,dc=com
    objectClass: posixGroup
    objectClass: top
    cn: users
    userPassword: {crypt}*
    gidNumber: 10
    memberUid: alice

    dn: cn=alice,ou=Group,dc=example,dc=com
    objectClass: posixGroup
    objectClass: top
    cn: alice
    userPassword: {crypt}*
    gidNumber: 1002

    dn: uid=alice,ou=People,dc=example,dc=com
    uid: alice
    cn: Alice Doe
    objectClass: account
    objectClass: posixAccount
    objectClass: top
    objectClass: shadowAccount
    userPassword: {BSDAUTH}alice
    shadowPassword: $2b$12$x6v.AoTQ1Qp2RScPThC2kepFUg3iAvaDpWDT9wKFLVwWbSQ4rNo36
    uidNumber: 1002
    gidNumber: 1002
    userClass: default
    modifyTimestamp: 0
    shadowExpire: 0
    gecos: Alice Doe
    homeDirectory: /home/alice
    loginShell: /bin/ksh

2 OpenBSD YP LDAP Client

Make sure to configure the LDAP Server as a YP LDAP Client as well. This is required so the {BSDAUTH}username SASL Bind will work.


2.1 Install Required Packages

While OpenBSD has a LDAP server ldapd in base, it dose not have a Client. So, install openldap-client to get the required utilities for managing LDAP.

    pkg_add openldap-client

2.2 Add YP Marker to Local Account Files

More information about setting up a YP client can be found in the OpenBSD FAQ 10 - System Management - Setting up a YP client section. However, all required commands are showed here.

2.2.1 Add YP Marker to /etc/master.passwd

Append the default YP marker to the master password file and rebuild the password database.

NOTE: the pwd_mkdb command should add a YP marker to /etc/passwd. If it dose not, try adding the YP marker to /etc/master.passwd with the command vipw

    echo '+:*::::::::' >> /etc/master.passwd
    pwd_mkdb -p /etc/master.passwd

2.2.2 Add YP Marker to /etc/group

Append the default YP marker to the group file.

    echo '+:*::' >> /etc/group

2.2.3 Check Files for YP Marker

Double check that everything went as expected by running the following command. The output should look just like what is shown here.

    tail -n 1 /etc/master.passwd /etc/passwd /etc/group

        ==> /etc/master.passwd <==
        +:*::::::::

        ==> /etc/passwd <==
        +:*:0:0:::

        ==> /etc/group <==
        +:*::

2.3 Create YP Domain

2.3.1 Set the YP Domain Name

    echo 'example.com' > /etc/defaultdomain
    domainname example.com

2.3.2 Initialize YP Domain

Run the following command to configure the base YP domain for ypldap to masquerade as.

NOTE: You do not need to edit /var/yp/example.com/Makefile and you should not run the make command. We are using LDAP as the database so those files are not used.

    ypinit -m example.com

        Server Type: MASTER Domain: example.com

        Creating an YP server will require that you answer a few questions.
        Questions will all be asked at the beginning of the procedure.

        Do you want this procedure to quit on non-fatal errors? [y/n: n] <Enter>

        Ok, please remember to go back and redo manually whatever fails.
        If you don't, something might not work.

        At this point, we have to construct a list of this domain's YP servers.
        ldap.example.com is already known as master server.
        Please continue to add any slave servers, one per line. When you are
        done with the list, type a <control D>.
                master server   :  ldap.example.com
                next host to add:  ^D
        The current list of NIS servers looks like this:

        ldap.example.com

        Is this correct?  [y/n: y] <Enter>
        Building /var/yp/example.com/ypservers...
        ldap.example.com has been setup as an YP master server.
        Edit /var/yp/example.com/Makefile to suit your needs.
        After that, run 'make' in /var/yp.

2.4 Configure ypldap

This /etc/ypldap.conf configuration file can be edited to meet your needs. Not all attributes must be used from LDAP. You can set them to be fixed for security reasons. If you allow users write access to their LDAP entry, you will probably want to set the users Login Class and Login Shell to be fixed for security reasons.

2.4.1 /etc/ypldap.conf

File Permissions: -rw------- 1 root wheel

    # $OpenBSD: ypldap.conf,v 1.1 2014/07/11 21:20:10 deraadt Exp $

    domain      "example.com"
    #   The interval in seconds at which ypldap will sync YP with LDAP
    interval    60
    provide map "passwd.byname"
    provide map "passwd.byuid"
    provide map "group.byname"
    provide map "group.bygid"
    provide map "netid.byname"

    directory "ldap.example.com" {
        # directory options
        binddn "cn=admin,dc=example,dc=com"
        bindcred "RootBindPasswordChangeMe"
        basedn "ou=People,dc=example,dc=com"
        # starting point for groups directory search, default to basedn
        groupdn "ou=Group,dc=example,dc=com"

        # passwd maps configuration (RFC 2307 posixAccount object class)
        passwd filter "(objectClass=posixAccount)"

        attribute name maps to "uid"
        attribute uid maps to "uidNumber"
        attribute gid maps to "gidNumber"
        attribute gecos maps to "gecos"
        attribute home maps to "homeDirectory"
        attribute shell maps to "loginShell"
        attribute class maps to "userClass"
        attribute passwd maps to "shadowPassword"
        attribute change maps to "modifyTimestamp"
        attribute expire maps to "shadowExpire"
        #   You can also make a value fixed instead of useing LDAP
        # fixed attribute class "default"
        # fixed attribute shell "/bin/ksh"

        # group maps configuration (RFC 2307 posixGroup object class)
        group filter "(objectClass=posixGroup)"

        attribute groupname maps to "cn"
        attribute grouppasswd maps to "userPassword"
        attribute groupgid maps to "gidNumber"
        # memberUid returns multiple group members
        list groupmembers maps to "memberUid"
    }

2.5 Start and Test ypldap

2.5.1 Start portmap, ypldap, ypbind

First, check to make sure the /etc/ypldap.conf file is okay. Then update /etc/rc.conf.local and start the services.

    ypldap -n
        configuration OK

    echo 'portmap_flags=YES' >> /etc/rc.conf.local
    echo 'ypldap_flags=""' >> /etc/rc.conf.local
    echo 'ypbind_flags=""' >> /etc/rc.conf.local

    /etc/rc.d/portmap start
    /etc/rc.d/ypldap start
    /etc/rc.d/ypbind start

2.5.2 Test the ypldap Domain

Okay, everything should be working now. To test it you can use the following getent command. It should return the entire contents of /etc/master.passwd ,as well as, all the users found in ypldap.

    getent passwd



Last Edited: Wed May 6 03:54:36 UTC 2015

# vim: set ts=4 sw=4 tw=80 et :

Powered By: OpenBSD, OpenNTPD, OpenIKED, OpenSSH, OpenSMTPD, LibreSSL, and mandoc
This site Copyright © 2015 Thomas Dwyer .