diff --git a/ldap.conf b/ldap.conf new file mode 100644 index 0000000..01c3429 --- /dev/null +++ b/ldap.conf @@ -0,0 +1,15 @@ +# +# LDAP Defaults +# + +# See ldap.conf(5) for details +# This file should be world readable but not world writable. + +#BASE dc=example,dc=com +#URI ldap://ldap.example.com ldap://ldap-master.example.com:666 + +#SIZELIMIT 12 +#TIMELIMIT 15 +#DEREF never + +TLS_CACERTDIR /etc/openldap/certs diff --git a/libexec-create-certdb.sh b/libexec-create-certdb.sh new file mode 100755 index 0000000..2377fdd --- /dev/null +++ b/libexec-create-certdb.sh @@ -0,0 +1,70 @@ +#!/bin/bash +# Author: Jan Vcelak + +set -e + +# default options + +CERTDB_DIR=/etc/openldap/certs + +# internals + +MODULE_CKBI="$(rpm --eval %{_libdir})/libnssckbi.so" +RANDOM_SOURCE=/dev/urandom +PASSWORD_BYTES=32 + +# parse arguments + +usage() { + printf "usage: create-certdb.sh [-d certdb]\n" >&2 + exit 1 +} + +while getopts "d:" opt; do + case "$opt" in + d) + CERTDB_DIR="$OPTARG" + ;; + \?) + usage + ;; + esac +done + +[ "$OPTIND" -le "$#" ] && usage + +# verify target location + +if [ ! -d "$CERTDB_DIR" ]; then + printf "Directory '%s' does not exist.\n" "$CERTDB_DIR" >&2 + exit 1 +fi + +if [ ! "$(find "$CERTDB_DIR" -maxdepth 0 -empty | wc -l)" -eq 1 ]; then + printf "Directory '%s' is not empty.\n" "$CERTDB_DIR" >&2 + exit 1 +fi + +# create the database + +printf "Creating certificate database in '%s'.\n" "$CERTDB_DIR" >&2 + +PASSWORD_FILE="$CERTDB_DIR/password" +OLD_UMASK="$(umask)" +umask 0377 +dd if=$RANDOM_SOURCE bs=$PASSWORD_BYTES count=1 2>/dev/null | base64 > "$PASSWORD_FILE" +umask "$OLD_UMASK" + +certutil -d "$CERTDB_DIR" -N -f "$PASSWORD_FILE" &>/dev/null + +# load module with builtin CA certificates + +echo | modutil -dbdir "$CERTDB_DIR" -add "Root Certs" -libfile "$MODULE_CKBI" &>/dev/null + +# tune permissions + +for dbfile in "$CERTDB_DIR"/*.db; do + chmod 0644 "$dbfile" +done + +exit 0 diff --git a/libexec-generate-server-cert.sh b/libexec-generate-server-cert.sh new file mode 100755 index 0000000..d77e3b8 --- /dev/null +++ b/libexec-generate-server-cert.sh @@ -0,0 +1,118 @@ +#!/bin/bash +# Author: Jan Vcelak + +set -e + +# default options + +CERTDB_DIR=/etc/openldap/certs +CERT_NAME="OpenLDAP Server" +PASSWORD_FILE= +HOSTNAME_FQDN="$(hostname --fqdn)" +ALT_NAMES= +ONCE=0 + +# internals + +RANDOM_SOURCE=/dev/urandom +CERT_RANDOM_BYTES=256 +CERT_KEY_TYPE=rsa +CERT_KEY_SIZE=1024 +CERT_VALID_MONTHS=12 + +# parse arguments + +usage() { + printf "usage: generate-server-cert.sh [-d certdb-dir] [-n cert-name]\n" >&2 + printf " [-p password-file] [-h hostnames]\n" >&2 + pritnf " [-a dns-alt-names] [-o]\n" >&2 + exit 1 +} + +while getopts "d:n:p:h:a:o" opt; do + case "$opt" in + d) + CERTDB_DIR="$OPTARG" + ;; + n) + CERT_NAME="$OPTARG" + ;; + p) + PASSWORD_FILE="$OPTARG" + ;; + h) + HOSTNAME_FQDN="$OPTARG" + ;; + a) + ALT_NAMES="$OPTARG" + ;; + o) + ONCE=1 + ;; + \?) + usage + ;; + esac +done + +[ "$OPTIND" -le "$#" ] && usage + +# generated options + +ONCE_FILE="$CERTDB_DIR/.slapd-leave" +PASSWORD_FILE="${PASSWORD_FILE:-${CERTDB_DIR}/password}" +ALT_NAMES="${ALT_NAMES:-${HOSTNAME_FQDN},localhost,localhost.localdomain}" + +# verify target location + +if [ "$ONCE" -eq 1 -a -f "$ONCE_FILE" ]; then + printf "Skipping certificate generating, '%s' exists.\n" "$ONCE_FILE" >&2 + exit 0 +fi + +if ! certutil -d "$CERTDB_DIR" -U &>/dev/null; then + printf "Directory '%s' is not a valid certificate database.\n" "$CERTDB_DIR" >&2 + exit 1 +fi + +printf "Creating new server certificate in '%s'.\n" "$CERTDB_DIR" >&2 + +if [ ! -r "$PASSWORD_FILE" ]; then + printf "Password file '%s' is not readable.\n" "$PASSWORD_FILE" >&2 + exit 1 +fi + +if certutil -d "$CERTDB_DIR" -L -a -n "$CERT_NAME" &>/dev/null; then + printf "Certificate '%s' already exists in the certificate database.\n" "$CERT_NAME" >&2 + exit 1 +fi + +# generate server certificate (self signed) + + +CERT_RANDOM=$(mktemp) +dd if=$RANDOM_SOURCE bs=$CERT_RANDOM_BYTES count=1 of=$CERT_RANDOM &>/dev/null + +certutil -d "$CERTDB_DIR" -f "$PASSWORD_FILE" -z "$CERT_RANDOM" \ + -S -x -n "$CERT_NAME" \ + -s "CN=$HOSTNAME_FQDN" \ + -t TC,, \ + -k $CERT_KEY_TYPE -g $CERT_KEY_SIZE \ + -v $CERT_VALID_MONTHS \ + -8 "$ALT_NAMES" \ + &>/dev/null + +rm -f $RANDOM_DATA + +# tune permissions + +if [ "$(id -u)" -eq 0 ]; then + chgrp ldap "$PASSWORD_FILE" + chmod g+r "$PASSWORD_FILE" +else + printf "WARNING: The server requires read permissions on the password file in order to\n" >&2 + printf " load it's private key from the certificate database.\n" >&2 +fi + +touch "$ONCE_FILE" +exit 0 diff --git a/openldap.spec b/openldap.spec index adf953f..0cac08b 100644 --- a/openldap.spec +++ b/openldap.spec @@ -17,10 +17,13 @@ Source2: slapd.sysconfig Source3: slapd.tmpfiles Source4: slapd.conf.obsolete Source5: slapd.ldif -Source50: slapd-libexec-functions -Source51: slapd-libexec-convert-config.sh -Source52: slapd-libexec-check-config.sh -Source53: slapd-libexec-upgrade-db.sh +Source6: ldap.conf +Source50: libexec-functions +Source51: libexec-convert-config.sh +Source52: libexec-check-config.sh +Source53: libexec-upgrade-db.sh +Source54: libexec-create-certdb.sh +Source55: libexec-generate-server-cert.sh Source100: README.evolution # patches for 2.4 @@ -73,7 +76,7 @@ customized LDAP clients. %package servers Summary: LDAP server License: OpenLDAP -Requires: openldap%{?_isa} = %{version}-%{release}, libdb-utils, nss-utils +Requires: openldap%{?_isa} = %{version}-%{release}, libdb-utils, nss-tools Requires(pre): shadow-utils Requires(post): systemd-units, systemd-sysv, chkconfig Requires(preun): systemd-units @@ -308,8 +311,7 @@ make install DESTDIR=%{buildroot} \ popd # setup directories for TLS certificates -mkdir -p %{buildroot}%{_sysconfdir}/openldap/cacerts -mkdir -p %{buildroot}%{_sysconfdir}/pki/tls/certs +mkdir -p %{buildroot}%{_sysconfdir}/openldap/certs # setup data and runtime directories mkdir -p %{buildroot}%{_sharedstatedir} @@ -321,6 +323,10 @@ install -m 0755 -d %{buildroot}%{_localstatedir}/run/openldap mkdir -p %{buildroot}%{_sysconfdir}/tmpfiles.d install -m 0644 %SOURCE3 %{buildroot}%{_sysconfdir}/tmpfiles.d/slapd.conf +# install default ldap.conf (customized) +rm -f %{buildroot}%{_sysconfdir}/openldap/ldap.conf +install -m 0644 %SOURCE5 %{buildroot}%{_sysconfdir}/openldap/ldap.conf + # setup maintainance scripts mkdir -p %{buildroot}%{_libexecdir} install -m 0755 -d %{buildroot}%{_libexecdir}/openldap @@ -328,6 +334,8 @@ install -m 0644 %SOURCE50 %{buildroot}%{_libexecdir}/openldap/functions install -m 0755 %SOURCE51 %{buildroot}%{_libexecdir}/openldap/convert-config.sh install -m 0755 %SOURCE52 %{buildroot}%{_libexecdir}/openldap/check-config.sh install -m 0755 %SOURCE53 %{buildroot}%{_libexecdir}/openldap/upgrade-db.sh +install -m 0755 %SOURCE54 %{buildroot}%{_libexecdir}/openldap/create-certdb.sh +install -m 0755 %SOURCE55 %{buildroot}%{_libexecdir}/openldap/generate-server-cert.sh # remove build root from config files and manual pages perl -pi -e "s|%{buildroot}||g" %{buildroot}%{_sysconfdir}/openldap/*.conf @@ -383,7 +391,12 @@ rm -f %{buildroot}%{_libdir}/openldap/*.so rm -f %{buildroot}%{_localstatedir}/openldap-data/DB_CONFIG.example rmdir %{buildroot}%{_localstatedir}/openldap-data -%post -p /sbin/ldconfig +%post + +/sbin/ldconfig + +# create certificate database +%{_libexecdir}/openldap/create-certdb.sh >&/dev/null || : %postun -p /sbin/ldconfig @@ -417,23 +430,8 @@ if [ $1 -eq 1 ]; then /bin/systemctl daemon-reload &>/dev/null || : fi -# generate sample TLS certificates -if [ ! -f %{_sysconfdir}/pki/tls/certs/slapd.pem ] ; then -pushd %{_sysconfdir}/pki/tls/certs > /dev/null 2>&1 -umask 077 -cat << EOF | make slapd.pem > /dev/null 2>&1 --- -SomeState -SomeCity -SomeOrganization -SomeOrganizationalUnit -localhost.localdomain -root@localhost.localdomain -EOF -chown root:ldap slapd.pem -chmod 640 slapd.pem -popd -fi +# generate sample TLS certificate for server (will not replace) +%{_libexecdir}/openldap/generate-server-cert.sh -o &>/dev/null || : # generate/upgrade configuration if [ ! -f %{_sysconfdir}/openldap/slapd.d/cn=config.ldif ]; then @@ -569,9 +567,10 @@ exit 0 %doc openldap-%{version}/LICENSE %doc openldap-%{version}/README %dir %{_sysconfdir}/openldap -%dir %{_sysconfdir}/openldap/cacerts +%dir %{_sysconfdir}/openldap/certs %config(noreplace) %{_sysconfdir}/openldap/ldap.conf %dir %{_libexecdir}/openldap/ +%{_libexecdir}/openldap/create-certdb.sh %{_libdir}/liblber-2.4*.so.* %{_libdir}/libldap-2.4*.so.* %{_libdir}/libldap_r-2.4*.so.* @@ -587,7 +586,6 @@ exit 0 %config(noreplace) %{_sysconfdir}/openldap/schema %config(noreplace) %{_sysconfdir}/sysconfig/slapd %config(noreplace) %{_sysconfdir}/tmpfiles.d/slapd.conf -%config(noreplace) %ghost %attr(0640,root,ldap) %{_sysconfdir}/pki/tls/certs/slapd.pem %dir %attr(0700,ldap,ldap) %{_sharedstatedir}/ldap %dir %attr(-,ldap,ldap) %{_localstatedir}/run/openldap %{_unitdir}/slapd.service @@ -626,6 +624,7 @@ exit 0 %{_libexecdir}/openldap/convert-config.sh %{_libexecdir}/openldap/check-config.sh %{_libexecdir}/openldap/upgrade-db.sh +%{_libexecdir}/openldap/generate-server-cert.sh %{_sbindir}/sl* %{_mandir}/man8/* %{_mandir}/man5/slapd*.5* @@ -658,6 +657,10 @@ exit 0 + server: buxfixes in mdb backend + server: buxfixes in overlays (syncrepl, meta, monitor, perl, sql, dds, rwm) - openldap-servers now provide ldib2ldbm (#437104) +- certificates management improvements + + create empty Mozilla NSS certificate database during installation + + enable builtin Root CA in generated database (#789088) + + generate server certificate using Mozilla NSS tools instead of OpenSSL tools * Tue Jan 31 2012 Jan Vcelak 2.4.28-3 - fix: replication (syncrepl) with TLS causes segfault (#783431) diff --git a/slapd.ldif b/slapd.ldif index a016384..9ce13ea 100644 --- a/slapd.ldif +++ b/slapd.ldif @@ -11,9 +11,9 @@ olcPidFile: /var/run/openldap/slapd.pid # # TLS settings # -#olcTLSCACertificateFile: /etc/pki/tls/certs/ca-bundle.crt -#olcTLSCertificateFile: /etc/pki/tls/certs/slapd.pem -#olcTLSCertificateKeyFile: /etc/pki/tls/certs/slapd.pem +olcTLSCACertificatePath: /etc/openldap/certs +olcTLSCertificateFile: "OpenLDAP Server" +olcTLSCertificateKeyFile: /etc/openldap/certs/password # # Do not enable referrals until AFTER you have a working directory # service AND an understanding of referrals.