Please Donate to Bitcoin Address : [[address]]

Donation of [[value]] BTC Received. Thank You.
[[error]]

OpenLDAP’da Gruplamalar

Merhabalar.

Uzun zaman sonra tekrar bir blog yazısı yazma fırsatı buldum. Bu yazıda geyiği kısa kesip (kesemedi…) direkt konuya atlayacağım.

OpenLDAP bildiğiniz gibi özgür dünyaların lightweight directory access protocol yazılımı. Bir sürü özel-kamu vb. kurum
içersinde bu protokolü bir şekilde kullanmaktalar. Ne için peki?

Cevap en az problem kadar basit : kullanıcıların merkezi olarak yönetimi. Yönetmek? Bir kullanıcının nesini yöneteceksiniz ki
diye düşünürseniz özellikle kamuda IT ops özelinde en süslü fantezilerin bu servis etrafında yoğunlaştığını tecrübe ettim.

Özellikle TÜBİTAK’da işe başladığımdan beri neredeyse en çok uğraştığım problemler bu servis özelinde oldu anlam veremediğim
bir şekilde.

Şöyle istekler duydu, gördü bu bünye :

“biz on bin küsür tane kullanıcımızı bir şekilde gruplayıp, sonicbilmem-ne  (a.k.a özgür yazılım olmayan)
firewall’undan bu gruplara özel youtube yasağı koymak istiyoruz” ya da,
“Microsoft Active Directory’den (kamu ağzıyla “aktif dizin” (her ne demekse artık))  bir kaç bin kullanıcıyı linux client’lardan
doğrulatalım ama herkes de login olamasın bir gruplamaya göre bunu yönetelim” lere kadar uzanan bir sürü istek.

Tembel bünyem çok çalışmak zorunda kaldığından size OpenLDAP üzerinde nasıl gruplamalar yapabilirsiniz bunlardan bahsetmek istedim.

Hazırsanız başlıyorum, (hazırdan kasıt slapd servisi kurun işte herhangi bir işletim sistemi üzerine (centos kurun olm)), müzik gelsin.

Yöntem 1 : Standart posixGroup ile Gruplama

Nezdimdeki en net gruplama yöntemi, eğer fancy istekler ve Active Directory işin içinde yoksa standart ve geleneksel posix’e göre
kullanıcıları gruplayın. Linux client’lar OpenLDAP’tan doğrulama yapıyorlarsa kullanıcıları bu gruplara göre yönetmek
işletim sistemi düzeyinde çok çok kolay.

Şöyle bir OpenLDAP ağacında çalıştığınızı varsayın :

dc=aydintd,dc=net (rootDN)
|_ou=groups,dc=aydintd,dc=net (organizationalUnit)
|__|__ ou=ankara,ou=groups,dc=aydintd,dc=net (organizationalUnit)
|__|___|__cn=techops,ou=ankara,ou=groups,dc=aydintd,dc=net (posixGroup)
|__|___ou=istanbul,dc=aydintd,dc=net (organizationalUnit)
|_ou=personal,dc=aydintd,dc=net (organizationalUnit)
|__|__uid=aydin.doyak,ou=personel,dc=aydintd,dc=net (inetOrgPerson + posixAccount)
|__|__...

Bunu LDIF e döksek şöyle oluyor :


dn: dc=aydintd,dc=net objectClass: top objectClass: dcObject objectClass: organization o: aydintd.net dc: aydintd dn: ou=groups,dc=aydintd,dc=net ou: groups objectClass: organizationalUnit objectClass: top dn: ou=ankara,ou=groups,dc=aydintd,dc=net ou: ankara objectClass: organizationalUnit objectClass: top dn: cn=techops,ou=ankara,ou=groups,dc=aydintd,dc=net gidNumber: 2000 cn: techops objectClass: posixGroup objectClass: top dn: ou=personal,dc=aydintd,dc=net ou: personal objectClass: organizationalUnit objectClass: top dn: uid=aydin.doyak,ou=personal,dc=aydintd,dc=net uid: aydin.doyak gidNumber: 2000 sn: Doyak cn: aydin.doyak homeDirectory: /home/adoyak objectClass: posixAccount objectClass: top objectClass: shadowAccount objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: person uidNumber: 3000 userPassword: 12345falan employeeType: techops ...

posixGroup gruplamasında önemi büyük, dikkat edilmesi iki durum var.
Bunlardan ilki :

Gruplar için posixGroup oluşturduktan sonra gidNumber atanması.
Burada size önereceğim şey, her bir group için eşsiz bir gidNumber ataması yapmanız.
Eğer gruplamanın gerçekten gruplama olması istiyorsanız her bir grubun unique bir gid’si olmalı.

Kullanıcılar oluşturulurken ise eğer bu kullanıcı posixAccount objectClass’ıyla oluşturulmuşsa
her bir kullanıcı için gidNumber ataması da yapmanız gerekecek. Bir yukarıdaki örnekte aydin.doyak
kullanıcısı için atanan gidNumber ile posixGroup olarak oluşturulan techops grubunun gidNumber’ını kıyaslayın.
Aynı olduğunu göreceksiniz. Linux clientlardan bu kullanıcı doğrulama yaptığında, bu kullanıcının
unix grubu olarak techops’u, gidNumber olarak da 2000 olduğunu ve bu kullanıcının bu gruba mensup olduğunu
göreceksiniz pam ayarlarınız doğru yapılandırılmışsa. Dolayısıyla işletim sistemi düzeyinde unix gruplarıyla
nasıl atraksiyonlara girebiliyorsanız artık bunu yapabilir hale geldiniz.

İkinci dikkat edilmesi gereken durum ise :

Tek bir kullanıcı için bu anlattığım çok basit, yapılabilir gözükse de örneğin 10000 kullanıcı için bir betik yazmak zorundasınız, ilgili
posixGruplara gid’ler atayıp, daha sonra hangi kullanıcıların hangi gruplarda yer almasını istiyorsanız bu kullanıcıları bir pattern’e
göre bu gid -> gid eşlemesi üzerinden yönetmek durumundasınız. Ağrılı olabilir. Ancak başka bir yolu yok malesef.

Dikkat etmeniz gereken en önemli şey ise bu grupları oluştururken tercihen 2000’den başlatarak gid ataması yapmanız, hem uid
hem gid ataması yaparken eğer 500’den başlatırsanız örneğin Linux tabanlı işletim sistemi koşturan client’lardaki servis ve yerel kullanıcıların
bu LDAP kullanıcılarıyla çakışma yaşaması %100. Bu çakışmanın önüne geçmezseniz çok daha ağrılı süreçler sizi bekliyor demektir.
uid’leri 3000’den grupları 2000’den başlatmak genellikle işi çözüyor. Yapıyı bir kez kurarsanız bir daha ellemenize de gerek yok ancak zorlu.
Kamu’daki sistem yöneticilerine bunu anlatamıyorsunuz da işin kötüsü.
Ben göremiyorum kim hangi gruba ait, gruba policy basabiliyo olsam bile kim hangi grupta gid’sine bakmak istemiyorum her defasında diyor.

Bu yüzden en çok istediğim halde hiç uygulayamadığım gruplama çözümü de bu.

Yöntem 2 : groupOfNames ile Gruplama

Bu yöntem kamu’ya en çok giden güzel bir yöntem, şöyle bir LDIF dosyasıyla bir groupOfNames grubu oluşturalım örneğin :

dn: cn=devops,ou=ankara,dc=aydintd,dc=net
objectClass: top
objectClass: groupOfNames
cn: devops
member: uid=ali.veli,ou=personal,dc=aydintd,dc=net
member: uid=cihan.dogan,ou=personal,dc=aydintd,dc=net

groupOfNames gidNumber yerine member adında multiple bir attribute alabiliyor, bu ağaç yapısına göre personel dalı altında tüm
kullanıcıları tutuyorken, ağacın başka bir yerinde başka bir dalında groupOfNames grubu altında da bu kullanıcıları member attribute’u
altında ağacın personel dalı altından seçebildiğiniz kullanıcılarla gruba üye yapabiliyorsunuz.

Başka ekstra bir işlem yapmanıza da gerek yok. Ancak benim gördüğüm bunun dışındaki tek handikapıysa
tabii ki tüm kullanıcıları member olarak elle tanımlamanız (ya da betikle parse etmeniz) gerekmekte yine posixGroup’da olduğu gibi.

Tüm bu problemler ve tembelliğim beni bu gruplamaların belirli attribute’lara göre dinamik yapılıp yapılamayacağına araştırmaya itti zaman içersinde.

Gelelim bu blog yazısını yazma sebebim olan benim bildiğim son yönteme.

Yöntem 3 : Dyngroup ve Dynlist ile Dinamik Gruplama

dyngroup OpenLDAP’ta öntanımlı yüklü gelmeyen bir schema. Ancak slapd’nin schema dizini
içersinde her an yüklenebilir halde gelmekte.

Aşağıdaki şekilde OpenLDAP’a bu schema’yı import edin :


# ldapadd -H ldap://localhost -D "cn=admin,cn=config" -x -W -f /etc/ldap/schema/dyngroup.ldif Enter LDAP Password: adding new entry "cn=dyngroup,cn=schema,cn=config"

Debian’da schema’nın öntanımlı yeri burası, CentOS’da dyngroup schema’sının ldifi farklı bir dizin altında olabilir.

Şimdi sıra dinamik gruplamayı yapabilmemize yarayan gruopofURLs objectClass’ıyla tanımlı grupları oluşturmaya geldi :
Aşağıdaki içerikle bir groups.ldif LDIF dosyasıyla grupları groupofURLs ile yaratalım :

dn: cn=devops,ou=ankara,ou=groups,dc=aydintd,dc=net
objectclass: top
objectclass: groupofURLs
cn: devops
description: Ankara ili devops'larimiz
memberURL: ldap:///ou=personal,dc=aydintd,dc=net?uid?sub?(employeeType=*devops*)

dn: cn=techops,ou=ankara,ou=groups,dc=aydintd,dc=net
objectclass: top
objectclass: groupofURLs
cn: techops
description: Ankara ili techops'larimiz
memberURL: ldap:///ou=personal,dc=aydintd,dc=net?uid?sub?(employeeType=*techops*)

Buradaki memberURL attribute’u çok önemli. LDAP ağacı üzerinde herhangi bir yerdeki kullanıcıları
kullanıcıların istediğiniz bir attribute’una göre gruplama yapabilmenizi sağlıyor. Burayı açacak olursak
ağacın ou=personal,dc=aydintd,dc=net dalı altındaki tüm entryler içersinde employeeType attribute’u içersinde
value olarak ne tanımlandıysa (devops ya da techops (* bu işi yapıyor)) geçiyorsa bu kullanıcı bu grubun üyesidir
olarak kabul edilir diyorsunuz.

Ancak bunu yaptığınızda bir değişme olduğunu göremeyeceksiniz. Çünkü listeleme işinin de dinamik yapılmasını
istiyoruz. Bunun için bir dynlist overlay’ini OpenLDAP üzerinde tanımlamamız gerekmekte. dynlist bir modül, önce
bu modülü sisteme eklememiz gerekiyor.

Aşağıdaki şekilde bir dynlist.ldif dosyası oluşturun ve dynlist modülünü sisteme import edin :

dynlistmodule.ldif :

dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulePath: /usr/lib/ldap
olcModuleLoad: dynlist.la

Not:  Debian’da OpenLDAP modulleri /usr/lib/ldap altında. CentOS türevi işletim sistemlerinde
farklı bir dizin altında olabilir.

bu module’u sisteme import edin :

# ldapadd -Y EXTERNAL -H ldapi:/// -f dynlistmodule.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=module,cn=config"

Modül aktif olduysa şöyle bir dosya oluşmuş olmalı :

# cat  /etc/ldap/slapd.d/cn\=config/cn\=module\{1\}.ldif

## AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
##  CRC32 f8fcc3de
dn: cn=module{1}
objectClass: olcModuleList
cn: module{1}
olcModulePath: /usr/lib/ldap
olcModuleLoad: {0}dynlist.la
structuralObjectClass: olcModuleList
entryUUID: 83603cde-94fa-1035-9027-5d341689e601
creatorsName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
createTimestamp: 20160412130210Z
entryCSN: 20160412130210.752190Z#000000#000#000000
modifiersName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
modifyTimestamp: 20160412130210Z

olc yapısında incremental bir yapı söz konusu. Her yeni yaptığınız ayar = bir önceki ayar + 1 olarak
yorumlanıyor. (module{0} -> module{1})

Ve son olarak bu modülün groupofURLs grupları üzerinde aktif olması için dynlist overlay’i tanımlayalım :

dynlistoverlay.ldif dosyası aşağıdaki içerikle oluşturun :

dn: olcOverlay=dynlist,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcDynamicList
olcOverlay: dynlist
olcDlAttrSet: groupOfURLs memberURL

ve aşağıdaki şekilde sisteme import edin :

# ldapadd -Y EXTERNAL -H ldapi:/// -f dynlistoverlay.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "olcOverlay=dynlist,olcDatabase={1}mdb,cn=config"

Hepsi bu kadar. Dinamik gruplamanın çalıştığını test etmek için aşağıdaki gibi kullanıcıları veya grupları sorgulayabilirsiniz :

# ldapsearch -H ldap://localhost -x -D "uid=aydin.doyak,ou=personal,dc=aydintd,dc=net" -W -b "dc=aydintd,dc=net"

# devops, ankara, groups, aydintd.net
dn: cn=devops,ou=ankara,ou=groups,dc=aydintd,dc=net
objectClass: top
objectClass: groupOfURLs
cn: devops
description: Ankara ili devops'larimiz
memberURL: ldap:///ou=personal,dc=aydintd,dc=net?uid?sub?(employeeType=*devops*)
uid: ozge.sefer
uid: cihan.dogan

# techops, ankara, groups, aydintd.net
dn: cn=techops,ou=ankara,ou=groups,dc=aydintd,dc=net
objectClass: top
objectClass: groupOfURLs
cn: techops
description: Ankara ili techops'larimiz
memberURL: ldap:///ou=personal,dc=aydintd,dc=net?uid?sub?(employeeType=*techops*)
uid: aydin.doyak

Bütün kullanıcılar sizin belirlediğiniz bir attributeType’a göre istediğiniz bir grup içersinde
en önemlisi de dinamik olarak otomatik bir şekilde gruplandı.  (uid satırları dinamik oluştu)

Apache Directory Studio üzerinde de bu şekilde görünüyor (anlaşılması için koyuyorum) :

ldaps1

ldaps2

Son bir uyarı yapmam gerekirse, bu groupOfURLs gruplarını bazı OpenLDAP üzerinde çalışması için tasarlanan uygulamalar grup olarak algılayamıyor.
Dolayısıyla bu otomatik generate edilen uid satırlarıyla ilgili grubun membership ilişkisini kuramıyor.
Her OpenLDAP’a bağlanıp bu gruplar üzeirnde işlemler yapacak uygulama bu yeteneğe sahip olmayabilir.
Bu bir implemetasyon meselesi aslında. Bu yüzden “use at your own risk” demekten başka bir çarem yok bunu yaşayabilecek arkadaşlara.

Diyeceklerimin hepsi bunlar, şarkı da bitmiş zaten.

Bir Cevap Yazın

I'm not a freaking robot : Time limit is exhausted. Please reload CAPTCHA.

12 Nisan 2016

Posted In: Sistem, Teknik

Etiketler:, , , , ,

Leave a Comment