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 set_lk_max_locks 8000 set_lk_max_objects 8000
- 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 ldap2.unimore.it base dc=unimore,dc=it pagesize 100000 ldap_version 3 bind_policy soft ssl start_tls tls_cacert /etc/pki/tls/certs/tcs-chain.pem
- 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 export SLAPD_SERVICES="ldapi:/// ldap:/// ldaps:///" export SLAPD_OPTIONS="-l LOCAL6" #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 '^directoryspace:+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
- Per farlo loggare su /var/log/ldap.log, bisogna aggiungere la seguente riga a /etc/syslog.conf :
LOCAL6.* -/var/log/ldap.log
- 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"