====== osnova skoleni ======
- Co si odnesete
- Co je ldap
- Instalace na linuxu
- Pridavani zaznamu
- Vyhledavani
- PhpLDAPadmin
- Pridavani strukturalnich zaznamu
- Pokrocile vyhledavani
- Ukazka php
- Zabezpeceni, zalohovani a indexy
====== Co si odnesete ======
* znalosti
* obsah skoleni v pdf, ktere v prubehu skoleni budu doplnovat
* 2GB image s testovacim ldapem -> pak staci ve vmware zmackout jen play
====== Co je LDAP =======
LDAP je protokol. Neurcuje nic jineho, ani zpusob ulozeni dat.
Mame zaznam (napriklad ja uid=dalibor,ou=people,dc=starlab), ten se sklada z nekolika objectClass a ta ma v sobe atributy a ty maji v sobe hodnoty. Cele to pripomina adresar, skoro jako DNS. Tak a ted vite o LDAPu skoro vse.
Narozdil od ostatnich systemu (napr. sql) maji klice/atributy preddefinovana jmena a jsou prednstaveny vybranou objectClass pro dany zaznam.
LDAP pripomina spise dresar, kde je jmeno prijmeni, adresa, telefon a dnes jeste email a heslo, nic vic z toho nedelejte.
//Poznamka pro me: Vyjasnit terminologii, DIT, schemata, classy, atributy, strukturalni, povinne a nepovinne. Nakousnout podivnou prefixovou notaci dotazu.//
An entry is basically a collection of attributes under a name used to describe something.
objectclass ( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top STRUCTURAL
MUST ( sn $ cn )
MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )
attributetype ( 2.5.4.41 NAME 'name' DESC 'RFC4519: common supertype of name attributes'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
Unlike traditional relational databases, schemas in LDAP are simply collections of related objectClasses and attributes
In its definition, an objectClass can identify a par ent objectClass from which to inherit its attributes. This is done using SUP followed by the objectClass to inherit from. For instance, the organizationalPerson objectClass begins like this: objectclass ( 2.5.6.7 NAME 'organizationalPerson' SUP person STRUCTURAL
. .
''inetOrgPerson -> organizationalPerson -> person -> top''
Skoro vsechny dedicnosti objectClass ve stromu konci specielni objectClassou zvanou "top". Prakticky jen proto, "aby tam neco bylo".
====== Instalace na Linux ========
# apt-get install slapd ldap-utils
Poznamka pro me: zminit fail2ban a omezit jen na vasi sit, kde je DB
Existuji jeste krome BDB take HDB a MDB. Mene konfigurace, rychlejsi. BDB je naopak vyzkousena min. 20 let a opravitelna.
Uchylarna s DB_CONFIG
# WARNING: Before tuning the following parameters, _PLEASE READ_
# /usr/share/doc/slapd/README.DB_CONFIG.gz
# Set the database in memory cache size.
#
# set_cachesize
# Sets the database in memory cache size.
# Database entries and indexes will be stored in this cache to
# avoid disk access during database read and write operations.
# Tuning this value can greatly effect your database performance.
# The parameters are:
# : The number of gigabytes of memory to allocate to the cache.
# : The number of bytes of memory to allocate to the cache.
# : The number of cache segments to use. If this value is set to
# 0 or 1 then Berkeley DB will try to allocate one contiguous section
# of memory for the cache. If this value is greater than 1, the cache
# will be split into that number of segments.
#set_cachesize 0 52428800 0
# For the Debian package we use 2MB as default but be sure to update this
# value if you have plenty of RAM
set_cachesize 0 2097152 0
# Sets the database startup flags.
#
# set_flags
# There are various flag options that may be set. The DB_TXN_NOSYNC flag
# tells the database not to immediately flush transaction buffers to disk.
# Setting this flag can help speed up database access during periods of
# database write activity BUT at expense of data safety. Enable it only
# to load data with slapadd, while slapd is not running.
#set_flags DB_TXN_NOSYNC
# Set the maximum in memory cache in for database file name caching.
#
# set_lg_regionmax
# This value should be increased as the number of database files increases
# (tables and indexes).
#set_lg_regionmax 1048576
# Set the maximum size of log files in .
#
# set_lg_max
# Logs will be rotated when amount of data have been written to
# one log file. This value should be at least four times the size of
# set_lg_bsize.
#set_lg_max 10485760
# Set the in memory cache for log information.
#
# set_lg_bsize
# When amount of logging information have been written to this
# cache it will be flushed to disk.
#set_lg_bsize 2097152
# For the Debian package we use 512kByte which should suffice for typical
# directory usage (read often, write seldom)
set_lg_bsize 524288
# Set the log file directory to .
#
# set_lg_dir /usr/local/var/openldap-logs
# Log files should preferably be on a different disk than the
# database files. This both improves reliability (for disastrous
# recovery) and speed of the database.
#set_lg_dir
# Sven Hartge reported that he had to set this value incredibly high
# to get slapd running at all. See http://bugs.debian.org/303057
# for more information.
# Number of objects that can be locked at the same time.
set_lk_max_objects 5000
# Number of locks (both requested and granted)
set_lk_max_locks 5000
# Number of lockers
set_lk_max_lockers 5000
Filipika proti slapd.d a pouziti slapd.conf.
Soubor vytvorime pomoci
cat >slapd.conf
vkladani staci copy&paste, prostredni tlacitko mysi a ukoncime stiskem ctrl+d.
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/inetorgperson.schema
# Allow LDAPv2 client connections. This is NOT the default.
allow bind_v2
#disallow bind_anon
#schemacheck on
pidfile /var/run/slapd/slapd.pid
argsfile /var/run/slapd/slapd.args
loglevel 50
# DB
modulepath /usr/lib/ldap
moduleload back_bdb
backend bdb
#checkpoint 51230
database bdb
suffix "dc=pb"
rootdn "cn=admin,dc=pb"
rootpw deLTa2019
cachesize 10000
# multi master
moduleload syncprov.la
moduleload accesslog.la
serverID 2
checkpoint 10240 720
directory "/var/lib/ldap"
index objectClass eq
lastmod on
access to dn.base="" by * read
access to *
by dn="cn=admin,dc=example,dc=net" write
by * read
#!/bin/sh
DIR=/etc/ldap/slapd.d
rm $DIR -rf
mkdir $DIR
slaptest -f slapd.conf -F $DIR
chown openldap.openldap -R $DIR
cp bin/DB_CONFIG /var/lib/ldap
chown openldap.openldap -R /var/lib/ldap
Nezapomenout na gymnastiku s
chown openldap.openldap /var/lib/ldap -R
chown openldap.openldap /etc/ldap/slapd.d -R
pri vytvareni databaze a provadeni slaptest -f -F.
Test, zda-li slapd posloucha na portu 389
netstat -nlpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:9102 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:5666 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:389 0.0.0.0:* LISTEN
tcp6 0 0 :::111 :::* LISTEN
tcp6 0 0 :::22 :::* LISTEN
tcp6 0 0 :::25 :::* LISTEN
tcp6 0 0 :::5666 :::* LISTEN
tcp6 0 0 :::389 :::* LISTEN
====== Pridavani zaznamu =======
Nejdrive si vytvorime soubor a pak ho pridame pomoc ldapadd
version: 1
## version not strictly necessary (and some implementations reject it) but generally good practice
## DEFINE DIT ROOT/BASE/SUFFIX ####
## uses RFC 2377 (domain name) format
## dcObject is an AUXILIARY objectclass and MUST
## have a STRUCTURAL objectclass (organization in this case)
# this is an ENTRY sequence and is preceded by a BLANK line
dn: dc=pb
dc: pb
description: Praguebest
objectClass: dcObject
objectClass: organization
o: Praguebest s.r.o.
## FIRST Level hierarchy - people
# this is an ENTRY sequence and is preceded by a BLANK line
dn: ou=people, dc=pb
ou: people
description: All people in organisation
objectClass: organizationalUnit
## SECOND Level hierarchy - people entries
# this is an ENTRY sequence and is preceded by a BLANK line
dn: cn=Radek Saturka,ou=people,dc=pb
objectclass: inetOrgPerson
cn: Radek Saturka
cn: Radek
sn: Saturka
uid: saturka
mail: radek.saturka@praguebest.com
ou: manager
## SECOND Level hierarchy - people entries
# this is an ENTRY sequence and is preceded by a BLANK line
dn: cn=Bill Novak,ou=people,dc=pb
objectclass: inetOrgPerson
cn: Bill Novak
cn: William
sn: Novak
uid: bnovak
mail: bill@example.com
ou: project
## SECOND Level hierarchy - people entries
# this is an ENTRY sequence and is preceded by a BLANK line
dn: cn=John Novak,ou=people,dc=pb
objectclass: inetOrgPerson
cn: John Novak
sn: novak
uid: jnovak
mail: jim@example.com
ou: prog
dn: cn=Robert Novak,ou=people,dc=pb
objectclass: inetOrgPerson
cn: Robert Novak
cn: Robert
sn: Novak
uid: rnovak
mail: robert@example.com
ou: project
dn: ou=groups, dc=pb
ou: groups
description: generic groups for GDPR
objectClass: organizationalUnit
dn: cn=projekt_a,ou=groups,dc=pb
cn: projekt_a
description: grupa ktera smi jen na projekt_a
objectClass: groupOfNames
member: cn=Bill Novak,ou=people,dc=pb
dn: cn=projekt_b,ou=groups,dc=pb
cn: projekt_b
description: grupa ktera smi jen na projekt_b
objectClass: groupOfNames
member: cn=John Novak,ou=people,dc=pb
ldapadd -x -D "cn=admin,dc=pb" -w heslo -f pb_add1.ldif
Ted sami pridejte
* sebe jako person
* dve skupiny
dn: uid=cervenka,ou=people,dc=pb
objectclass: inetOrgPerson
cn: David Cervenka
sn: Cervenka
uid: cervenka
mail: cervenka@praguebest.com
dn: uid=coufal,ou=people,dc=pb
objectclass: inetOrgPerson
cn: Martin Coufal
sn: Coufal
uid: coufal
mail: coufal@praguebest.com
dn: uid=cajkovsky,ou=people,dc=pb
objectclass: inetOrgPerson
cn: Igor Cajkovsky
sn: Cajkovsky
uid: cajkovsky
mail: cajkovsky@praguebest.com
====== Vyhledavani ======
Mnoho prikladu
ldapsearch -x -b 'uid=novak,ou=people,dc=pb'
ldapsearch -x -b 'cn=Radek Saturka,ou=people,dc=pb'
ldapsearch -x -b 'ou=people,dc=pb' uid=saturka
ldapsearch -x -b 'ou=people,dc=pb' uid=jnovak
ldapsearch -x -b 'dc=pb' uid=saturka
ldapsearch -x -b 'dc=pb' uid=jnovak
A pozor, porad jedeme anonymne bez hesla, jinak bude search vypadat takto:
ldapsearch -x -b 'ou=people,dc=pb' -D uid=cajkovsky,ou=people,dc=pb -w blooood '(&(objectClass=inetOrgPerson)(uid=cajkovsky)(memberOf=cn=projekt_b,ou=groups,dc=pb))'
====== Instalace PhpLDAPadmin =======
Pozor, je potreba pouzit php5, protoze nema opravene par chyb. Napr. create_function je v php7 obsolete
$CACHE[$sortby] = create_function('$a, $b',$code);
Nam bude pro ukazku bohate stacit apache2 s php5 modulem. Pokud mate debian 9 stretch, pak je treba pro vyukove ucely pridat do /etc/apt/sources.list
deb http://debian.superhosting.cz/debian/ jessie main contrib non-free
Provedte update db a pak instalaci
apt update
apt install libapache2-mod-php5 php5.0-xml
Par uprav v konfiguraci a muzeme jet
$servers->setValue('server','host','127.0.0.1');
/* The port your LDAP server listens on (no quotes). 389 is standard. */
// $servers->setValue('server','port',389);
/* Array of base DNs of your LDAP server. Leave this blank to have phpLDAPadmin
auto-detect it for you. */
$servers->setValue('server','base',array('dc=pb'));
/* Five options for auth_type:
1. 'cookie': you will login via a web form, and a client-side cookie will
store your login dn and password.
2. 'session': same as cookie but your login dn and password are stored on the
web server in a persistent session variable.
3. 'http': same as session but your login dn and password are retrieved via
HTTP authentication.
4. 'config': specify your login dn and password here in this config file. No
login will be required to use phpLDAPadmin for this server.
5. 'sasl': login will be taken from the webserver's kerberos authentication.
Currently only GSSAPI has been tested (using mod_auth_kerb).
Choose wisely to protect your authentication information appropriately for
your situation. If you choose 'cookie', your cookie contents will be
encrypted using blowfish and the secret your specify above as
session['blowfish']. */
$servers->setValue('login','auth_type','session');
/* The DN of the user for phpLDAPadmin to bind with. For anonymous binds or
'cookie','session' or 'sasl' auth_types, LEAVE THE LOGIN_DN AND LOGIN_PASS
BLANK. If you specify a login_attr in conjunction with a cookie or session
auth_type, then you can also specify the bind_id/bind_pass here for searching
the directory for users (ie, if your LDAP server does not allow anonymous
binds. */
$servers->setValue('login','bind_id','cn=admin,dc=pb');
Racte namirit vas browser na cerstve nainstalovany ldapadmin
[[http://127.0.0.1/phpldapadmin]]
====== Pridavani strukturalnich zaznamu ======
# ldapadd -x -D "cn=admin,dc=pb" -W -f memberof_config.ldif
Enter LDAP Password:
adding new entry "cn=module,cn=config"
ldap_add: Insufficient access (50)
# ldapadd -x -D "cn=admin,dc=pb" -W -f memberof_config.ldif
Enter LDAP Password:
ldap_bind: Invalid credentials (49)
Pri pridavani strukturalni zmeny hluboko do strev ldapu - memberOf.
Obvykla metoda ldapadd selhala na nedostatku prav pozdeji na chybnem prihlaseni
Klasický BindDN uživatel (admin), který je největší kápo celého ldapu neměl dost oprávnění.
Nevim, jestli je to specialitka Debianu, ale vytvoří vám admina jen pro váš celý DIT. Jenže DIT není vše, existuje ještě "ldap v ldapu". Ne, nezbláznil jsem se, ale měkké mozky vymysleli, že nově se bude konfigurace LDAPu ukládat do adresářové struktury ''slap.d/cn=config/foo=bar'' atd. Při pečlivějším zkoumání zjistíte, že máte databáze dvě, jedna se jmenuje bla=bla{0} a druhe foo=bar{1}. A právě ta ''{0}'' je strukturální mimo celý váš DIT.
Soubor můžete plaintext editovat
/etc/ldap/slapd.d/cn=config/olcDatabase\=\{0\}config.ldif
a změnit admina a v debianu přidat heslo. Bacha na koncovku cn=config, bez ní to nejde. Jen pro úplnost uvádím jaká chyba vznikne
(
olcRootPW: value #0: can only be set when rootdn is under suffix
)
olcRootDN: cn=admin,cn=config
olcRootPW: superheslo
Je nutné restartovat ldap:
service slapd restart
a vyzkoušet funkčnost pomocí
ldapwhoami -x -D "cn=admin,cn=config" -x -w superheslo
dn:cn=admin,cn=config
Pokud vše funguje můžete vesele přidat memberOf pošetilost
ldapadd -x -D "cn=admin,cn=config" -W -f memberof_config.ldif
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList
olcModuleLoad: memberof
olcModulePath: /usr/lib/ldap
dn: olcOverlay={0}memberof,olcDatabase={1}bdb,cn=config
objectClass: olcConfig
objectClass: olcMemberOf
objectClass: olcOverlayConfig
objectClass: top
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf
Proc nepouzivat "muzevsude" a jine powergroupy? -> protoze tam z lenosti pak skonci vsichni.
====== Pokrocile vyhledavani ======
Syntaxe je prefixova, kterou vymyslel chory mozek, aby byl LDAP jeste vice hustej nezli je
ldapsearch -x -b 'ou=people,dc=pb' '(&(objectClass=inetOrgPerson)(uid=cajkovsky)(memberOf=cn=projekt_b,ou=groups,dc=pb))'
NAME=ldapsearch -x -h 127.0.0.1 "(&(objectClass=person)(|(telephoneNumber=${NUM})(mobile=${NUM})(homePhone=${NUM})(fax=${NUM})))" cn | sed -n 's/cn:\s\(.*\)/\1/p
ldapsearch -x -b "dc=pb" '(objectClass=inetOrgPerson)' uid
====== Ukazka kodu v PHP ======
Pozor na mala a velka pismena v poli memberOf -> memberof
Dotaz na clenstvi ve skupine je diky schizofrennimu memberof jednoduche
====== Zabezpeceni, zalohovani a indexy ======
disallow bind_anon
A nasledne opet pregenerovat slapd.d. Pozor zmizi vam memberof a to si uzijeme. Musite proste znovu pridat olcRootDN i PW jinak se vam bude ldap chovat dost zvlastne a bohuzel nebude ani hazet chyby. Lze upravovat i online pres modifikaci pomoci ldapadd:
*zalohovani*
Zde jen prakticky slapcat, vzhledem k obvykle velikosti v radu jednotek MB se muze zalohovat vesele i nekolikrat denne a zasadne gzipovat, protoze se jedna o krasny plaintext.
*indexy*
index objectClass uid eq
ldapsearch -xLLL -b cn=config -D cn=admin,cn=config -W olcDatabase={1}bdb olcDbIndex
Enter LDAP Password:
dn: olcDatabase={1}bdb,cn=config
olcDbIndex: objectClass eq
ldapmodify -x -D cn=admin,cn=config -W
Enter LDAP Password:
dn: olcDatabase={1}bdb,cn=config
add: olcDbIndex
olcDbIndex: cn eq
olcDbIndex: uid eq
modifying entry "olcDatabase={1}bdb,cn=config"
# ldapsearch -xLLL -b cn=config -D cn=admin,cn=config -W olcDatabase={1}bdb olcDbIndex
Enter LDAP Password:
dn: olcDatabase={1}bdb,cn=config
olcDbIndex: objectClass eq
olcDbIndex: cn eq
olcDbIndex: uid eq