]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add docs on bootstrapping an OpenLDAP test instance
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 20 Oct 2019 19:59:28 +0000 (15:59 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 20 Oct 2019 19:59:34 +0000 (15:59 -0400)
doc/antora/modules/howto/nav.adoc
doc/antora/modules/howto/pages/modules/ldap/bootstrap_openldap.adoc [new file with mode: 0644]
doc/antora/modules/howto/pages/modules/ldap/docker.adoc [deleted file]

index 581c4dbc908377cb7b57cc115c4e3e1e58261871..2eda16a80a43f1cc979b767e183f523f1647192a 100644 (file)
@@ -6,12 +6,12 @@
 *** xref:modules/expiration/index.adoc[Expiration]
 *** xref:modules/krb5/index.adoc[Krb5]
 *** xref:modules/ldap/index.adoc[LDAP]
+**** xref:modules/ldap/bootstrap_openldap.adoc[Bootstrap OpenLDAP]
 **** xref:modules/ldap/ldapsearch.adoc[Directory mapping and testing with ldapsearch]
 **** xref:modules/ldap/configuration.adoc[Configuration]
 **** xref:modules/ldap/authorization.adoc[Authorization]
 **** xref:modules/ldap/authentication.adoc[Authentication]
 **** xref:modules/ldap/accounting.adoc[Accounting]
-**** xref:modules/ldap/docker.adoc[Docker]
 *** xref:modules/mschap/index.adoc[MS-CHAP]
 *** xref:modules/pam/index.adoc[PAM]
 *** xref:modules/passwd/index.adoc[Passwd]
diff --git a/doc/antora/modules/howto/pages/modules/ldap/bootstrap_openldap.adoc b/doc/antora/modules/howto/pages/modules/ldap/bootstrap_openldap.adoc
new file mode 100644 (file)
index 0000000..9aaa3b6
--- /dev/null
@@ -0,0 +1,363 @@
+= Bootstrapping OpenLDAP
+
+This page describes two methods (
+<<bootstrap_with_docker,Docker>> and via <<bootstrap_with_packages,Packages>>) of creating an
+OpenLDAP instance for testing purposes.
+
+If you're looking to create a temporary instance of OpenLDAP and spin
+it up as quickly as possible, you should consider using the
+https://docs.docker.com/install/[Docker containerisation service].
+
+This will allow you to create a self-contained, and pre-configured
+OpenLDAP instance with a minimum amount of effort.
+
+If you're looking to create a more permanent installation of OpenLDAP or
+are not comfortable using docker, then you may wish to install OpenLDAP from packages.
+
+OpenLDAP is available pre-packaged for many distributions.  We recommend
+using the OpenLDAP LTB packages available under the
+"Packaging and OpenLDAP extensions" heading https://ltb-project.org/documentation[here].
+
+[#bootstrap_with_docker]
+== Using OpenLDAP in a docker container
+=== Bootstrap
+
+https://github.com/osixia[Osixia!] provides a
+https://github.com/osixia/docker-openldap[fully functionally OpenLDAP container]
+which can be instantiated using the docker invocation below.
+
+This docker invocation also sets up a readonly user, and loads the custom
+FreeRADIUS schemas required for RADIUS to LDAP attribute mapping, dynamic client
+definitions, and attribute profiles.
+
+==== Define site specific variables
+Change the values here to match local paths and your site specific
+configuration.
+
+[source,shell]
+----
+# Where to store a temporary shallow clone of the FreeRADIUS source
+# Or the path to an existing copy of the FreeRADIUS source
+FREERADIUS_SRC="/tmp/freeradius-src"
+
+# Base DN
+LDAP_BASE_DN="dc=example,dc=com"
+
+# Domain
+LDAP_DOMAIN="example.com"
+
+# DN Suffix
+LDAP_BASE_DN="dc=example,dc=com"
+
+# Password for the administrative user
+LDAP_ADMIN_PASSWORD="secret"
+
+# Password for the read only user
+LDAP_READONLY_PASSWORD="readonly"
+----
+
+==== Instantiate an OpenLDAP docker container
+
+[source,shell]
+----
+if [ ! -d "${FREERADIUS_SRC}" ]; then
+       git clone --depth 1 https://github.com/FreeRADIUS/freeradius-server.git "${FREERADIUS_SRC}"
+fi
+docker run -it --rm -p 389:389 \
+       --env LDAP_DOMAIN=${LDAP_DOMAIN} \
+       --env LDAP_ADMIN_PASSWORD=${LDAP_ADMIN_PASSWORD} \
+       --env LDAP_READONLY_USER=true \
+       --env LDAP_READONLY_USER_PASSWORD=${LDAP_READONLY_PASSWORD} \
+       --volume "${FREERADIUS_SRC}/doc/schemas/ldap/openldap/freeradius.schema:/container/service/slapd/assets/config/bootstrap/schema/mmc/radius.schema:ro" \
+       --volume "${FREERADIUS_SRC}/doc/schemas/ldap/openldap/freeradius-clients.schema:/container/service/slapd/assets/config/bootstrap/schema/mmc/freeradius-clients.schema:ro" \
+       osixia/openldap:1.2.5 --copy-service
+----
+
+=== Test data
+Once docker is running, there should now be an LDAP server running on
+`localhost`, it can now be populated with test data.
+
+For test data we will be using the object definitions from the LDAP
+module's CIT (Continuous Integration Testing) script.
+
+These object definitions have been designed to exercise all features
+of the FreeRADIUS LDAP module.
+
+[source,shell]
+----
+sed -e '1,/^description:/ d' "${FREERADIUS_SRC}/src/tests/modules/ldap/example.com.ldif" \
+    | ldapadd -H ldap://localhost -x -D cn=admin,${LDAP_BASE_DN} -w admin
+----
+
+There should be no errors, and the console with the running LDAP
+server should show requests being handled.
+
+If the LDAP server server is stopped, as with `CTRL-C`, then the database
+contents will be lost.  All of the steps above will have to be re-done the next
+time the server is started.
+
+In order to make the LDAP database persistent, see the
+https://github.com/osixia/docker-openldap[osixia/openldap
+instructions].
+
+As a final step you should <<verifying_openldap_setup,verify OpenLDAP is
+setup correctly>>.
+
+[#bootstrap_with_packages]
+== Installing OpenLDAP from packages
+=== Bootstrap
+==== Switch to privileged user
+[source,shell]
+----
+sudo -s
+----
+
+LDAP URIs that begin with `ldapi://` (as in the examples below) refer to a Unix
+Socket. Unix sockets use `peercred` authorization where the primary UID and GID
+of the user running the LDAP client, determines which resources they can access.
+
+For convenience we will configure the OLC database to be modifiable only by the
+root user (`UID=0`, `GID=0`).  When configuring OpenLDAP via OLC the `ldapadd`
+utility will be run as root so our changes are authorised.
+
+==== Define site specific variables
+Change the values here to match local paths and your site specific
+configuration.
+
+[source,shell]
+----
+# The base directory for OpenLDAP
+OPENLDAP_PATH="/usr/local/openldap"
+
+# Where to store a temporary shallow clone of the FreeRADIUS source
+# Or the path to an existing copy of the FreeRADIUS source
+FREERADIUS_SRC="/tmp/freeradius-src"
+
+# DN Suffix
+LDAP_BASE_DN="dc=example,dc=com"
+
+# Password for the administrative user
+LDAP_ADMIN_PASSWORD="secret"
+
+# Password for the read only user
+LDAP_READONLY_PASSWORD="readonly"
+----
+
+==== Switch OpenLDAP from using state configuration files to OLC
+After installing OpenLDAP, `slapd` (the main OpenLDAP daemon) needs to be
+switched to using OLC (on-line configuration).
+
+OLC provides an LDAP based interface for dynamically changing OpenLDAP's
+configuration at runtime. OLC also allows more programatic manipulation of
+OpenLDAP's configuration, which is the primary reason for using it in this
+example.
+
+[source,shell]
+----
+# Hash input passwords as SSHA
+LDAP_ADMIN_PASSWORD_HASH=$(slappasswd -s "${LDAP_ADMIN_PASSWORD}")
+LDAP_READONLY_PASSWORD_HASH=$(slappasswd -s "${LDAP_READONLY_PASSWORD}")
+
+# Stop OpenLDAP
+systemctl stop slapd
+
+# A very basic "bootstrap configuration"
+cat <<EOF > /tmp/slapd_bootstrap.conf
+# We always need the core schema loaded, otherwise things fail with obscure errors
+include         ${OPENLDAP_PATH}/etc/openldap/schema/core.schema
+pidfile         ${OPENLDAP_PATH}/var/run/slapd.pid
+argsfile        ${OPENLDAP_PATH}/var/run/slapd.args
+
+# Provide a defintion for the OLC database
+database config
+# Allow access to the root user only
+access to * by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
+EOF
+
+# Make config dir, convert slapd.d to OLC format, then fixup permissions
+LDAP_SLAP_D_DIR="${OPENLDAP_PATH}/etc/openldap/slapd.d"
+mkdir "${LDAP_SLAP_D_DIR}"
+slaptest -f /tmp/slapd_bootstrap.conf -F "${LDAP_SLAP_D_DIR}"
+chown -R ldap:ldap "${LDAP_SLAP_D_DIR}"
+chmod -R 0750 "${LDAP_SLAP_D_DIR}"
+
+# Remove our temporary bootstrap file
+rm -f /tmp/slapd_bootstrap.conf
+
+# Alter the OpenLDAP LTB startup script to use OLC instead of slapd.conf
+sed -ie 's#^SLAPD_CONF=.*#SLAPD_CONF=""#;s#^SLAPD_CONF_DIR=.*#SLAPD_CONF_DIR="$SLAPD_PATH/etc/openldap/slapd.d"#' "${OPENLDAP_PATH}/etc/openldap/slapd-cli.conf"
+
+# Start slapd with an OLC definition only
+systemctl start slapd
+----
+
+==== Define a database and set appropriate ACLs
+
+[source,shell]
+----
+# Create MDB database
+cat <<EOF | ldapadd -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd%2Fldapi
+dn: olcDatabase=mdb,cn=config
+objectClass: olcDatabaseConfig
+objectClass: olcMdbConfig
+olcDatabase: {1}mdb
+olcSuffix: ${LDAP_BASE_DN}
+olcDbDirectory: ${OPENLDAP_PATH}/var/openldap-data/
+olcRootDN: cn=admin,${LDAP_BASE_DN}
+olcRootPW: ${LDAP_ADMIN_PASSWORD_HASH}
+olcDbIndex: objectClass eq
+olcLastMod: TRUE
+olcDbCheckpoint: 512 30
+olcAccess: to attrs=userPassword by dn="cn=admin,${LDAP_BASE_DN}" write by anonymous auth by self write by * none
+olcAccess: to * by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage by dn="cn=admin,${LDAP_BASE_DN}" manage by users read by * none
+olcAccess: to dn.base="" by * read
+EOF
+----
+
+.Decoding OpenLDAP ACLs
+****
+
+The OpenLDAP ACL syntax can be difficult to understand for new users. To help
+with implementing site-specific ACLs, the humanly readable translation of the
+base ACLs in the above example is included below.
+
+* `to attrs=userPassword by dn="cn=admin,${LDAP_BASE_DN}" write by anonymous auth by self write by * none`
+** The administrative user can change the userPassword attribute.
+** Anonymous users can use the userPassword attribute contents for the purposes of authentication.
+** OpenLDAP itself can write to userPassword attributes.
+** Other than the above users no one can access the userPassword attribute.
+* `to * by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage by dn="cn=admin,${LDAP_BASE_DN}" manage by users read by * none`
+** The root user and admin users have full access to the data portion of the directory.
+** Any other authenticated user has read only access to the data portion of the directory.
+* `to dn.base="" by * read`
+** Any user may access the metadata at the top of the directory.  The is useful for the
+   autodiscovery functionality in LDAP browsers.
+
+****
+
+==== Populate the top level object, and add credentials for the readonly user
+
+[source,shell]
+----
+# Create the top level object and a read only user
+cat <<EOF | ldapadd -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd%2Fldapi
+dn: ${LDAP_BASE_DN}
+objectClass: top
+objectClass: dcObject
+objectclass: organization
+o: Example Organization
+dc: Example
+description: LDAP Example
+
+dn: cn=readonly,${LDAP_BASE_DN}
+objectClass: organizationalRole
+objectClass: simpleSecurityObject
+userPassword: ${LDAP_READONLY_PASSWORD_HASH}
+description: LDAP read only user
+EOF
+----
+
+=== Loading schemas
+
+For our tests we need to load some basic bundled OpenLDAP schemas and some
+FreeRADIUS specific schemas for defining profiles, RADIUS to LDAP mappings and
+clients.
+
+[source,shell]
+----
+if [ ! -d "${FREERADIUS_SRC}" ]; then
+       git clone --depth 1 https://github.com/FreeRADIUS/freeradius-server.git "${FREERADIUS_SRC}"
+fi
+
+SCHEMA_DIR="${OPENLDAP_PATH}/etc/openldap/schema"
+for i in cosine.ldif inetorgperson.ldif nis.ldif openldap.ldif; do
+       ldapadd -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd%2Fldapi -f ${SCHEMA_DIR}/$i
+done
+
+SCHEMA_DIR="${FREERADIUS_SRC}/doc/schemas/ldap/openldap"
+for i in freeradius.ldif freeradius-clients.ldif; do
+       ldapadd -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd%2Fldapi -f ${SCHEMA_DIR}/$i
+done
+----
+
+=== Test data
+Once slapd is running and appropriately configured with database definitions an
+admin user, a readonly user, and the prerequisite schemas, it can now be
+populated with test data.
+
+For test data we will be using the object definitions from the LDAP module's CIT
+(Continuous Integration Testing) script.
+
+These object definitions have been designed to exercise all features of the
+FreeRADIUS LDAP module.
+
+[source,shell]
+----
+sed -e '1,/^description:/ d' ${FREERADIUS_SRC}/src/tests/modules/ldap/example.com.ldif \
+    | ldapadd -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd%2Fldapi
+----
+
+=== Switch to an unprivileged user
+[source,shell]
+----
+exit
+----
+
+Now the setup of the directory is complete, we can communicate with it
+over a standard TCP socket and no longer need a root session.
+
+If, however, you need to make further changes to OpenLDAP's configuration, you
+should note that the `ldapadd`, `ldapmodify` commands must be called as root
+with the `-Y EXTERNAL` argument.
+
+[#verifying_openldap_setup]
+== Verifying OpenLDAP setup
+
+As a final step you should verify that test data has been loaded correctly.
+This can be done using the `ldapsearch` utility using the LDAP read only user.
+
+The command below will retrieve the entry for one of the test `radiusClient`
+entries. You should see a single search result returned if everything worked
+correctly.
+
+[source,shell]
+----
+ldapsearch -LLL -H ldap://localhost -x -D cn=readonly,<base_dn> -w <readonly_password> -b <base_dn> '(&(objectClass=radiusClient)(radiusClientShortname=client2))'
+----
+
+.Searching for a RADIUS Client
+====
+[source,shell]
+----
+ldapsearch -LLL -H ldap://localhost -x -D cn=readonly,dc=example,dc=com -w readonly -b dc=example,dc=com '(&(objectClass=radiusClient)(radiusClientShortname=client2))'
+----
+
+.Expected output
+[source,ldiff]
+----
+# extended LDIF
+#
+# LDAPv3
+# base <dc=example,dc=com> with scope subtree
+# filter: (&(objectClass=radiusClient)(radiusClientShortname=client2))
+# requesting: ALL
+#
+
+# 2.2.2.2, clients, example.com
+dn: radiusClientIdentifier=2.2.2.2,ou=clients,dc=example,dc=com
+objectClass: radiusClient
+radiusClientIdentifier: 2.2.2.2
+radiusClientSecret: 123secret
+radiusClientShortname: client2
+radiusClientType: cisco
+radiusClientRequireMa: TRUE
+radiusClientComment: Another test client
+
+# search result
+search: 2
+result: 0 Success
+
+# numResponses: 2
+# numEntries: 1
+----
+====
diff --git a/doc/antora/modules/howto/pages/modules/ldap/docker.adoc b/doc/antora/modules/howto/pages/modules/ldap/docker.adoc
deleted file mode 100644 (file)
index 6a5d21d..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-= Using LDAP in Docker
-
-It is possible to experiment with a local LDAP server under
-https://docs.docker.com/install/[Docker].  There is a
-https://github.com/osixia/docker-openldap[fully functionally OpenLDAP
-container] available via the following commands:
-
-[source,shell]
-----
-docker run -it --rm -p 389:389 --env LDAP_DOMAIN=example.com --env LDAP_READONLY_USER=true --volume $(pwd)/doc/schemas/ldap/openldap/freeradius.schema:/container/service/slapd/assets/config/bootstrap/schema/mmc/radius.schema:ro --volume $(pwd)/doc/schemas/ldap/openldap/freeradius-clients.schema:/container/service/slapd/assets/config/bootstrap/schema/mmc/freeradius-clients.schema:ro osixia/openldap:1.2.5 --copy-service
-----
-
-Once docker is running, there should now be an LDAP server running on
-`localhost`.  This LDAP server needs to be populated with some initial
-user data using the LDAP admin user and an
-http://www.zytrax.com/books/ldap/ch8/[LDIF file]:
-
-[source,shell]
-----
-sed -e '1,/^description:/ d' src/tests/modules/ldap/example.com.ldif \
-    | ldapadd -H ldap://localhost -x -D cn=admin,dc=example,dc=com -w admin
-----
-
-There should be no errors, and the console with the running LDAP
-server should show requests being handled.  Next, check that data is
-there by using the LDAP read only user:
-
-[source,shell]
-----
-ldapsearch -LLL -H ldap://localhost -x -D cn=readonly,dc=example,dc=com -w readonly -b dc=example,dc=com '(&(objectClass=radiusClient)(radiusClientShortname=client2))'
-----
-
-You should see a single result returned if everything worked
-correctly.
-
-If the LDAP server server is stopped, as with `CTRL-C`, then the
-databas will be lost.  All of the steps above will have to be re-done
-the next time the server is started.
-
-In order to make the LDAP database persistent, see the
-https://github.com/osixia/docker-openldap[osixia/openldap
-instructions].
-
-Lastly, remember that this testing server may or may not resemble the
-production environment.  Therefore, any FreeRADIUS configuration that
-works in a test environment will need updating and testing in order to
-work in production.