Creazione di una replica Ldap per zimbra
Installazione su un server CentOS
La replica verrà installata su un server CentOS.
Prima di tutto assicurarsi che il server ldap1.unimore.it sia raggiungibile alla porta 389 tcp e a quella 636 tcp (c'è anche un firewall sulla macchina stessa). Poi bisogna aver già generato un account "cn=adminzimbra,dc=unimore,dc=it" con una password e permessi di lettura sull'albero people di ldap1.
- Installare ex novo dai sorgenti ldap e berkeley db:
Scaricare il file db-4.8.24.tar.gz e scompattarlo. Andare sotto la directory ed eseguire
cd build_unix ../dist/configure –libdir=/usr/local/BerkeleyDB.4.8/lib/ make make install
a questo punto scomprimere il file openldap-stable-20090411.tgz, andare nella directory ed eseguire
export LDFLAGS="-L/usr/local/BerkeleyDB.4.8/lib" export CPPFLAGS="-I/usr/local/BerkeleyDB.4.8/include" export LD_LIBRARY_PATH=/usr/local/BerkeleyDB.4.8/lib/ ./configure make depend make make install
- Il file /usr/local/etc/openldap/slapd.conf è
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /usr/local/etc/openldap/schema/core.schema
include /usr/local/etc/openldap/schema/cosine.schema
include /usr/local/etc/openldap/schema/inetorgperson.schema
include /usr/local/etc/openldap/schema/nis.schema
include /usr/local/etc/openldap/schema/dyngroup.schema
include /usr/local/etc/openldap/schema/unimore-studenti.schema
include /usr/local/etc/openldap/schema/unimore-dipendenti.schema
include /usr/local/etc/openldap/schema/nabla2.schema
include /usr/local/etc/openldap/schema/qmail.schema
include /usr/local/etc/openldap/schema/sendmail.schema
include /usr/local/etc/openldap/schema/samba.schema
include /usr/local/etc/openldap/schema/samba3.schema
include /usr/local/etc/openldap/schema/hdb.schema
include /usr/local/etc/openldap/schema/eduperson.schema
# Allow LDAPv2 client connections. This is NOT the default.
#allow bind_v2
# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral ldap://root.openldap.org
pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args
sizelimit 100000
timelimit 86400
idletimeout 180
loglevel 16384
# Load dynamic backend modules:
modulepath /usr/lib/openldap
#moduleload back_hdb
# modules available in openldap-servers-overlays RPM package:
# moduleload accesslog.la
# moduleload auditlog.la
# moduleload denyop.la
# moduleload dyngroup.la
# moduleload dynlist.la
# moduleload lastmod.la
# moduleload pcache.la
# moduleload ppolicy.la
# moduleload refint.la
# moduleload retcode.la
# moduleload rwm.la
# moduleload smbk5pwd.la
# moduleload syncprov.la
# moduleload translucent.la
# moduleload unique.la
# moduleload valsort.la
# modules available in openldap-servers-sql RPM package:
# moduleload back_sql.la
# The next three lines allow use of TLS for encrypting connections using a
# dummy test certificate which you can generate by changing to
# /etc/pki/tls/certs, running "make slapd.pem", and fixing permissions on
# slapd.pem so that the ldap user or group can read it. Your client software
# may balk at self-signed certificates, however.
TLSCACertificateFile /etc/pki/tls/certs/europki-ca-chain.pem
TLSCertificateFile /etc/pki/tls/certs/ldap-posta.pem
TLSCertificateKeyFile /etc/pki/tls/certs/ldap-posta-key-sprotetta.pem
# Sample security restrictions
# Require integrity protection (prevent hijacking)
# Require 112-bit (3DES or better) encryption for updates
# Require 63-bit encryption for simple bind
# security ssf=1 update_ssf=112 simple_bind=64
# Sample access control policy:
# Root DSE: allow anyone to read it
# Subschema (sub)entry DSE: allow anyone to read it
# Other DSEs:
# Allow self write access
# Allow authenticated users read access
# Allow anonymous users to authenticate
# Directives needed to implement policy:
# access to dn.base="" by * read
# access to dn.base="cn=Subschema" by * read
# access to *
# by self write
# by users read
# by anonymous auth
#
# if no access controls are present, the default policy
# allows anyone and everyone to read anything but restricts
# updates to rootdn. (e.g., "access to * by * read")
#
# rootdn can always read and write EVERYTHING!
access to dn.base="" by * read
access to attrs=userPassword,sambaNTPassword,sambaLMPassword
by dn="cn=adminlocal,dc=unimore,dc=it" write
by anonymous auth
by self write
by * none
access to attrs=cn,sn,gecos,givenname,telephonenumber,memberURL,memberUid,facsimiletelephonenumber,
\description,objectclass,mail,unimoreriferimento,uid,uidNumber,gidNumber,
\homeDirectory,loginShell,ou,unimoreDipOrg1,unimoreDipOrg2,unimoreDipOrg3,unimoreDipOrg4
by dn="cn=adminlocal,dc=unimore,dc=it" write
by * read
access to attrs=mail,objectClass,uid,unimorestudannocorso,unimorestudcodiceindirizzo,unimorestudcognome,
\unimorestudcorso,unimorestuddataannullamento,unimoreStudDataRilascio,unimorestuddatarilasciotessera,
\unimorestuddescrcorso,unimorestuddescrfacolta,unimorestuddescrindirizzo,unimorestuddescrsede,
\unimorestudduratacorso,unimorestudfacolta,unimorestudmatricola,unimorestudnome,
\unimorestudnumerotessera,unimorestudpassword,unimorestudsede,unimorestudtipoiscrizione,
\unimorestudultimoannoaccademico,unimorestudvaliditatessera
by dn="cn=adminlocal,dc=unimore,dc=it" read
by * none
access to attrs=accountStatus,c,mailAlternateAddress,mailForwardingAddress,mailHost,mailMessageStore,
\mailQuota,mailQuotaCount,mailQuotaSize,mailReplyText,mailSizeMax,nabla2Accesso,
\nabla2AccountStatus,nabla2AccountType,nabla2auth,nabla2CodiceSettore,nabla2Funzione,nabla2Note,
\nabla2Orario,nabla2Password,nabla2personafisica,nabla2Revision,nabla2scadenza,nabla2Settore,
\nabla2Tipoutente,nabla2UfficioOServizio,nabla2UltimaRevisione,nabla2UltimoRevisore,
\nabla2VersioneRubrica,sambaAcctFlags,sambaAlgorithmicRidBase,sambaBadPasswordCount,
\sambaBadPasswordTime,sambaBoolOption,sambaDomainName,sambaGroupType,sambaHomeDrive,
\sambaHomePath,sambaIntegerOption,sambaKickoffTime,sambaLMPassword,sambaLogoffTime,
\sambaLogonHours,sambaLogonScript,sambaLogonTime,sambaMungedDial,sambaNextGroupRid,
\sambaNextRid,sambaNextUserRid,sambaNTPassword,sambaOptionName,sambaPasswordHistory,
\sambaPrimaryGroupSID,sambaProfilePath,sambaPwdCanChange,sambaPwdLastSet,sambaPwdMustChange,
\sambaShareName,sambaSID,sambaSIDList,sambaStringListOption,sambaStringOption,sambaTrustFlags,
\sambaUserWorkstations,seeAlso,serialNumber,shadowExpire,shadowFlag,shadowInactive,
\shadowLastChange,shadowMax,shadowMin,shadowWarning
by dn="cn=adminlocal,dc=unimore,dc=it" read
by * none
access to attrs=st,street,title,unimorecodicefiscale,unimorecorscodfac,unimorecorscodicecorso,
\unimorecorscodicefacolta,unimorecorscodiceindirizzo,unimorecorscodiceordinamento,
\unimorecorscodicestato,unimorecorscodicetipocorso,unimorecorsdescrizionecorso,
\unimorecorsdescrizioneindirizzo,unimorecorsdescrizioneordinamento,unimorecorsdurataanni,
\unimorecorsfacolta,unimorecorsnomeindirizzo,unimorecorsnomeorientamento,unimorecorssede,
\unimorecorsstatopercorso,unimorecorstipocorso,unimoreDipAttivita,unimoreDipCF,
\unimoreDipCodiceAttivita,unimoreDipCodiceDidattica,unimoreDipCodiceProfilo,unimoreDipCognome,
\unimoreDipDataFineattivita,unimoreDipDataInizioAttivita,unimoreDipDataUltimoInquadramento,
\unimoreDipDescrizioneInquadramento,unimoreDipInquadramento,unimoreDipMatricola,unimoreDipNome,
\unimoreDipProfilo,unimoreDipCodiceRuolo,unimoreDipRuoloCod,unimoreDipRuoloDesc,unimoreDipTessera,
\unimoredsitdatamodifica,unimorenote,unimoreutentediriferimento,uniqueIdentifier
by dn="cn=adminlocal,dc=unimore,dc=it" read
by * none
access to attrs=objectclass,ou
by self read
by * read
access to *
by dn="cn=adminlocal,dc=unimore,dc=it" write
by * read
# The maximum number of entries that is returned for a search operation
sizelimit unlimited
# The tool-threads parameter sets the actual amount of cpu's that is used
# for indexing.
tool-threads 1
#######################################################################
ldbm and/or bdb database definitions
#######################################################################
database hdb
suffix "ou=People,dc=unimore,dc=it"
rootdn "cn=adminpeople,ou=People,dc=unimore,dc=it"
# Cleartext passwords, especially for the rootdn, should
# be avoided. See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw {SSHA}EDt9b/JlKNgdUao9mxiUyThstmXT4v54
# rootpw {crypt}ijFYNcSNctBYg
subordinate
cachesize 50000
#idlcachesize 200000
checkpoint 2048 5
syncrepl rid=2
provider=ldap://ldap1.unimo.it:389
type=refreshAndPersist
interval=00:00:10:00
searchbase="ou=People,dc=unimore,dc=it"
filter="(&(objectClass=*)(!(ou=accounts)))"
scope=sub
starttls=yes
schemachecking=on
sizelimit=50000
timelimit=7200
bindmethod=simple
binddn="cn=adminzimbra,dc=unimore,dc=it"
credentials="QYn.mqYP"
# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
directory "/var/lib/ldap-people"
# Indices to maintain for this database
#index objectClass eq,pres
#index ou,cn,mail,surname,givenname eq,pres,sub
#index uidNumber,gidNumber,loginShell eq,pres
#index uid,memberUid eq,pres,sub
#index nisMapName,nisMapEntry eq,pres,sub
index entryUUID pres,eq
index objectclass pres,eq
index cn,sn,givenname,uid pres,eq,sub
index uidnumber,gidnumber pres,eq
index sambaSID sub
index memberUid pres,eq
index uniquemember pres,eq
#index sambaGroupMapping,sambaSIDList,sambaGroupType pres,eq
dbconfig set_cachesize 0 5097152 0
#######################################################################
# Specific Directives for database #1, of type bdb:
# Database specific directives apply to this databasse until another
# 'database' directive occurs
database hdb
# The base of your directory in database #1
suffix "dc=unimore,dc=it"
# Where the database file are physically stored for database #1
directory "/var/lib/ldap"
# For the Debian package we use 2MB as default but be sure to update this
# value if you have plenty of RAM
dbconfig set_cachesize 0 2097152 0
rootdn "cn=adminlocal,dc=unimore,dc=it"
rootpw {SSHA}1tebUJ9RqeeTcl2nLKbbhRQYLoKSa2YI
# Number of objects that can be locked at the same time.
dbconfig set_lk_max_objects 1500
# Number of locks (both requested and granted)
dbconfig set_lk_max_locks 1500
# Number of lockers
dbconfig set_lk_max_lockers 1500
index entryUUID pres,eq
index objectclass pres,eq
index cn,sn,givenname,uid pres,eq,sub
index uidnumber,gidnumber pres,eq
index sambaSID sub
index memberUid pres,eq
index uniquemember pres,eq
#index sambaGroupMapping,sambaSIDList,sambaGroupType pres,eq
Dove:
La password criptata per l'utente adminlocal deve essere creata con il comando
/usr/local/sbin/slappasswd -s <password>
e il risultato copiato e incollato nella riga
rootpw {SSHA}....
- La richiesta di certificato va generata con il seguente comando:
wget http://certificatidigitali.unimore.it/unimore-ssl.cnf openssl req -new -out ldap-posta.csr -keyout ldap-posta-key.pem -config unimore-ssl.cnf
e mandata a chi gestisce le richieste. Il file del certificato, che sarà scaricato dal sito della CA Unimore:
https://pki.dmz-int.unimo.it/cgi-bin/pub/pki?cmd=getStaticPage&name=index
va scaricato in formato PEM e messo in
/etc/pki/tls/certs/ldap-posta.pem
Va a questo punto scaricato il file di chain
wget http://apps.lettere.unimo.it/samba-ldap/certs/europki-ca-chain.pem
e copiato nella directory /etc/pki/tls/certs con i permessi giusti:
cp europki-ca-chain.pem /etc/pki/tls/certs chown ldap:ldap /etc/pki/tls/certs/europki-ca-chain.pem
Per sproteggere il file di chiave, bisogna eseguire:
openssl rsa -in ldap-posta-key.pem -out ldap-posta-key-sprotetta.pem cp ldap-posta-key-sprotetta.pem /etc/pki/tls/certs
- Devono esistere le directory
/var/lib/ldap /var/lib/ldap-people
con i permessi
chown -R ldap:ldap /var/lib/ldap*
e i files DB_CONFIG al loro interno devono essere
set_cachesize 0 536870912 1 set_lg_regionmax 1048576 set_lg_bsize 2097152 set_lg_max 10485760 set_flags DB_LOG_AUTOREMOVE
- Il file /usr/local/etc/openldap/ldap.conf deve essere:
# # 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 host ldap1.unimore.it base dc=unimore,dc=it pagesize 100000 ldap_version 3 bind_policy soft ssl start_tls tls_cacert /etc/pki/tls/certs/europki-ca-chain.pem
- Il file /etc/default/slapd.conf deve essere:
SLAPD_SERVICES="ldapi:/// ldap:/// ldaps:///" SLAPD_OPTIONS="-l LOCAL6"
- Eseguire, (a ldap spento) il comando:
slapadd -v -l Wiki-ldap.ldif
dove Wiki-ldap.ldif è quello scaricato dal sito con il comando:
wget http://wiki.unimore.it/mediawiki/upload/7/78/Wiki-ldap.ldif
- Il file /etc/init.d/ldap deve essere:
#!/bin/bash
#
# ldap This shell script takes care of starting and stopping
# ldap servers (slapd and slurpd).
#
# chkconfig: - 27 73
# description: LDAP stands for Lightweight Directory Access Protocol, used \
# for implementing the industry standard directory services.
# processname: slapd
# config: /usr/local/etc/openldap/slapd.conf
# pidfile: /var/run/openldap/slapd.pid
# Source function library.
. /etc/init.d/functions
# Source networking configuration and check that networking is up.
if [ -r /etc/sysconfig/network ] ; then
. /etc/sysconfig/network
[ ${NETWORKING} = "no" ] && exit 1
fi
# Source an auxiliary options file if we have one, and pick up OPTIONS,
# SLAPD_OPTIONS, SLURPD_OPTIONS, SLAPD_LDAPS, SLAPD_LDAPI, and maybe
# KRB5_KTNAME and SLURPD_KRB5CCNAME.
if [ -r /etc/sysconfig/ldap ] ; then
. /etc/sysconfig/ldap
fi
#slapd=/usr/sbin/slapd
slapd=/usr/local/libexec/slapd
slurpd=/usr/sbin/slurpd
export LD_LIBRARY_PATH=/usr/local/BerkeleyDB.4.8/lib/
#slaptest=/usr/sbin/slaptest
slaptest=/usr/local/sbin/slaptest
[ -x ${slapd} ] || exit 1
[ -x ${slurpd} ] || exit 1
RETVAL=0
#
# Pass commands given in $2 and later to "test" run as user given in $1.
#
function testasuser() {
local user= cmd=
user="$1"
shift
cmd="$@"
if test x"$user" != x ; then
if test x"$cmd" != x ; then
/sbin/runuser -f -m -s /bin/sh -c "test $cmd" -- "$user"
else
false
fi
else
false
fi
}
#
# Check for read-access errors for the user given in $1 for a service named $2.
# If $3 is specified, the command is run if "klist" can't be found.
#
function checkkeytab() {
local user= service= klist= default=
user="$1"
service="$2"
default="${3:-false}"
if test -x /usr/kerberos/bin/klist ; then
klist=/usr/kerberos/bin/klist
elif test -x /usr/bin/klist ; then
klist=/usr/bin/klist
fi
KRB5_KTNAME="${KRB5_KTNAME:-/etc/krb5.keytab}"
export KRB5_KTNAME
if test -s "$KRB5_KTNAME" ; then
if test x"$klist" != x ; then
if LANG=C $klist -k "$KRB5_KTNAME" | tail -n 4 | awk '{print $2}' | grep -q ^"$service"/ ; then
if ! testasuser "$user" -r ${KRB5_KTNAME:-/etc/krb5.keytab} ; then
true
else
false
fi
else
false
fi
else
$default
fi
else
false
fi
}
function configtest() {
local user= ldapuid= dbdir= file=
# Check for simple-but-common errors.
user=ldap
prog=`basename ${slapd}`
ldapuid=`id -u $user`
# Unaccessible database files.
slaptestflags=
for dbdir in `LANG=C egrep '^directory\space:+print:+$' /usr/local/etc/openldap/slapd.conf
\ | sed s,^directory,,` ; do
dbdirfind=`echo ${dbdir} | sed 's/\"//g'`;
for file in `find ${dbdirfind}/ -not -uid $ldapuid -and \( -name "*.dbb" -or -name "*.gdbm"
\ -or -name "*.bdb" -or -name "__db.*" \)` ; do
echo -n $"$file is not owned by \"$user\"" ; warning ; echo
done
if ! test -s ${dbdir}/id2entry.dbb ; then
if ! test -s ${dbdir}/id2entry.gdbm ; then
if ! test -s ${dbdir}/id2entry.bdb ; then
slaptestflags=-u
fi
fi
fi
done
# Unaccessible keytab with an "ldap" key.
if checkkeytab $user ldap ; then
file=${KRB5_KTNAME:-/etc/krb5.keytab}
echo -n $"$file is not readable by \"$user\"" ; warning ; echo
fi
# Unaccessible TLS configuration files.
tlsconfigs=`LANG=C egrep '^(TLS_CACERT|TLSCACertificateFile|TLSCertificateFile|TLSCertificateKeyFile)space:'
\ /usr/local/etc/openldap/slapd.conf /etc/openldap/ldap.conf | awk '{print $2}'`
for file in $tlsconfigs ; do
if ! testasuser $user -r $file ; then
echo -n $"$file is not readable by \"$user\"" ; warning ; echo
fi
done
# Check the configuration file.
if ! action $"Checking configuration files for $prog: " /sbin/runuser -m -s "$slaptest" -- "$user" $slaptestflags; then
if /sbin/runuser -m -s "$slaptest" -- "$user" "-u" > /dev/null 2> /dev/null ; then
dirs=`LANG=C egrep '^directoryspace:+print:+$'
\ /usr/local/etc/openldap/slapd.conf | awk '{print $2}'`
for directory in $dirs ; do
if test -r $directory/__db.001 ; then
echo -n $"stale lock files may be present in $directory" ; warning ; echo
fi
done
fi
exit 1
fi
}
function start() {
configtest
# Define a couple of local variables which we'll need. Maybe.
user=ldap
prog=`basename ${slapd}`
# Build a wrapper script to exec slapd with the right arguments, to
# avoid being tripped out by changes or weirdness in how daemon()
# handles quoted arguments.
wrapper=`mktemp ${TMP:-/tmp}/start-slapd.XXXXXX`
harg="ldap:///"
if grep -q ^TLS /usr/local/etc/openldap/slapd.conf || test x$SLAPD_LDAPS = xyes ; then
harg="$harg ldaps:///"
fi
if test x$SLAPD_LDAPI = xyes ; then
harg="$harg ldapi:///"
fi
if test -z "$wrapper" ; then
return 1
fi
cat >> $wrapper <<- EOF
exec ${slapd} -h "$harg" -u ${user} $OPTIONS $SLAPD_OPTIONS
EOF
chmod u+x $wrapper
trap "rm -f $wrapper" EXIT
# Start daemons.
echo -n $"Starting $prog: "
daemon --check=$prog $wrapper
RETVAL=$?
echo
if [ $RETVAL -eq 0 ]; then
if grep -q "^replogfile" /usr/local/etc/openldap/slapd.conf; then
prog=`basename ${slurpd}`
echo -n $"Starting $prog: "
if [ -n "$SLURPD_KRB5CCNAME" ]; then
export KRB5CCNAME="$SLURPD_KRB5CCNAME";
fi
daemon ${slurpd} $OPTIONS $SLURPD_OPTIONS
RETVAL=$?
echo
fi
fi
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/ldap
return $RETVAL
}
function stop() {
# Stop daemons.
prog=`basename ${slapd}`
echo -n $"Stopping $prog: "
killproc ${slapd}
RETVAL=$?
echo
if [ $RETVAL -eq 0 ]; then
if grep -q "^replogfile" /usr/local/etc/openldap/slapd.conf; then
prog=`basename ${slurpd}`
echo -n $"Stopping $prog: "
killproc ${slurpd}
RETVAL=$?
echo
fi
fi
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/ldap /var/run/slapd.args
return $RETVAL
}
# See how we were called.
case "$1" in
configtest)
configtest
;;
start)
start
RETVAL=$?
;;
stop)
stop
RETVAL=$?
;;
status)
status ${slapd}
RETVAL=$?
if grep -q "^replogfile" /usr/local/etc/openldap/slapd.conf ; then
status ${slurpd}
RET=$?
if [ $RET -ne 0 ] ; then
RETVAL=$RET;
fi
fi
;;
restart)
stop
start
;;
condrestart)
if [ -f /var/lock/subsys/ldap ] ; then
stop
start
RETVAL=$?
fi
;;
*)
echo $"Usage: $0 {start|stop|restart|status|condrestart}"
RETVAL=1
esac
exit $RETVAL
- A questo punto, basta far partire ldap:
/etc/init.d/ldap start
anche al boot
chkconfig --level 2345 ldap on
e per testarlo basta eseguire una query
ldapsearch -x -h localhost -b "dc=unimore,dc=it"