Permisos y Grupos en Openldap¶
- Permisos y Grupos en Openldap
Documnetación de openldap: http://www.openldap.org/doc/admin24/
En el encuentro 2014 se habló de una raíz dc=interior,dc=udelar,dc=edu,dc=uy, pero finalmente conviene poner la raíz en dc=udelar,dc=edu,dc=uy
La estructura del árbol es la que se manejó desde el inicio:
dc=udelar,dc=edu,dc=uy --- Recursos -- --- Gente -- --- Grupos ------ admins (Superadministradores) -- ------ cup (un grupo para cada regional) ----------admins (un grupo para los administradores de cada regional) -- ------ redmine (un grupo para cada servicio) -------- login (una cuenta para que el servicio se conecte al ldap) --
Exploración inicial de ACL's¶
En las nuevas versiones de OpenLDAP el control de acceso ya no se maneja desde el fichero slapd.conf sinó desde la on-line configuration (OLC) que permite agregar nuevas reglas sin parar el servicio.
Para agregar estas reglas primero se deben especificar creando un fichero ldif:
# nano olcAccess.ldif dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcAccess olcAccess: to dn.subtree="ou=cure,dc=interior,dc=udelar,dc=edu,dc=uy" by group.exact="cn=admins,ou=grupos,ou=cure,dc=interior,dc=udelar,dc=edu,dc=uy" write by self write by * read
Para este caso los miembros del grupo "admins" del CURE pueden escribir en el subdirectorio, un usuario puede modificar sus propias entradas y el resto leerlas.
Para aplicar la nueva regla hay que ejecutar la linea
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f ./olcAccess.ldif
NOTA: Es importante repetar el formato definido anteriormente, incluyendo los espacios de separación, de lo contrario no se puede crear la regla mostrándose un error del tipo:
ldap_modify: Other (e.g., implementation specific) error (80) additional info: <olcAccess> handler exited with 1
Para listar las reglas activas hay que ejecutar:
ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config '(olcAccess=*)' olcAccess olcSuffix
Mostrándose
olcAccess: {3}to dn.subtree="ou=cure,dc=interior,dc=udelar,dc=edu,dc=uy" by gr oup.exact="cn=admins,ou=grupos,ou=cure,dc=interior,dc=udelar,dc=edu,dc=uy" wr ite by self write by * read
En este caso es la 3ra regla que se creó, el orden se puede especificar a la hora de crearla incluyendo "olcAccess: {3}..." en la definición.
Para eliminar una regla, se crea un .ldif donde se puede especificar la regla a eliminar o el indice de esta:
dn: olcDatabase={1}hdb,cn=config changetype: modify delete: olcAccess olcAccess: {3}
...o...
dn: olcDatabase={1}hdb,cn=config changetype: modify delete: olcAccess olcAccess: to dn.subtree="ou=cure,dc=interior,dc=udelar,dc=edu,dc=uy" by group.exact="cn=admins,ou=grupos,ou=cure,dc=interior,dc=udelar,dc=edu,dc=uy" write by self write by * read
Funciones del LDAP:¶
1) Crear/eliminar usuarios.
2) Crear/eliminar grupos (grupos y servicios).
3) Agregar/quitar usuarios a grupos.
4) Definir superadministradores, y administradores de cada CENUR.
5) Definir ACL's (agregar/quitar permisos de usuario/grupos a ramas/grupos/usuarios).
Por ahora toda función administrativa se puede realizar con ApacheDS con un usuario superadministrador, o desde el servidor utilizando archivos ldif (con las herramientas ldap-utils).
Crear/eliminar usuarios.¶
Para crear un usuario se utiliza PWM, todos los usuarios van a ser hijos del grupo gente.
objectClass=inetOrgPerson. cn=username sn=Apellido givenName=Nombre mail=correo userPassword=SSHA hashed password
Para eliminar un usuario, un superadministrador o un administrador (si corresponde) borra la entrada del usuario.
Crear/eliminar grupos (servicios).¶
Para crear grupos:
objectClass=groupOfNames cn=nombreGrupo member=entrada de usuario miembro member=entrada de usuario miembro member=entrada de usuario miembro ......
Servicios:
Si el grupo es un servicio, crear una cuenta autenticador, para que el servicio se conecte con ese usuario (y no con el admin del ldap).
Para eliminar grupos se borra la entrada del grupo.
Agregar/quitar usuarios a grupos.¶
Para agregar un usuario a un grupo se crea un atributo member=cn=usuario,..., en el grupo.
Para quitar un usuario de un grupo se borra el atributo member=cn=usuario,..., del grupo.
Definir superadministradores, y administradores de cada CENUR.¶
Crear un grupo admins (de superadministradores) y agregar usuarios al grupo.
Crear un grupo para cada Cenur, y dentro un grupo administradores para cada Cenur.
Definir ACL's (agregar/quitar permisos de usuario/grupos a ramas/recursos).¶
**Esto habría que ver, que permisos se da a cada usuario o grupo.
Miembros de un grupo¶
Como todos los usuarios estan dentro del grupo Gente, hay que dar permisos a miembros de un grupo y no a subárboles o ramas.
Para dar permiso sobre los usuarios miembros de un grupo es necesario habilitar y configurar el modulo memberof, con 2 archivos:
memberof_add.ldif
dn: cn=module,cn=config objectClass: olcModuleList cn: module olcModulePath: /usr/lib/ldap olcModuleLoad: memberof
memberof_config.ldif
dn: olcOverlay=memberof,olcDatabase={1}hdb,cn=config objectClass: olcMemberOf objectClass: olcOverlayConfig objectClass: olcConfig objectClass: top olcOverlay: memberof olcMemberOfDangling: ignore olcMemberOfRefInt: TRUE olcMemberOfGroupOC: groupOfNames olcMemberOfMemberAD: member olcMemberOfMemberOfAD: memberOf
Los agregamos al openldap
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f memberof_add.ldif sudo ldapadd -Y EXTERNAL -H ldapi:/// -f memberof_config.ldif
Este módulo hace que cuando se agrega un usuario al grupo, se cree un atributo memberOf en el usuario con el valor del grupo, de forma automática.
Link: http://www.cbjck.de/2012/05/08/enabling-the-memberof-overlay-for-openldap/
Cree otro archivo para que cuando se agregue un atributo memberOf en el usuario con el grupo, en el grupo se cree un atributo member con el usuario, de forma automática.
memberof_a_member.ldif
dn: olcOverlay=memberof,olcDatabase={1}hdb,cn=config objectClass: olcMemberOf objectClass: olcOverlayConfig objectClass: olcConfig objectClass: top olcOverlay: memberof olcMemberOfDangling: ignore olcMemberOfRefInt: TRUE olcMemberOfGroupOC: inetOrgPerson olcMemberOfMemberAD: memberOf olcMemberOfMemberOfAD: member
Los agregamos al openldap
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f memberof_a_member.ldif
Agregar una ACL¶
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f olcAccess.ldif
Ver la lista de ACL's para decidir que poner en ocAccess.ldif
Ver la lista de los ACL configurados:
ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config '(olcAccess=*)' olcAccess olcSuffix
ACL para que el usuario admin y los administadores puedan administrar las ACL's
dn: olcDatabase={0}config,cn=config changetype: modify add: olcAccess olcAccess: {1}to * by dn="cn=admin,dc=interior,dc=udelar,dc=edu,dc=uy" write by group.exact="cn=admins,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" write by * break
Implementación final de ACL's¶
Para ver como fueron implementadas las ACL's en el servidor, consultar el link ACL's Curie
Los siguientes son ejemplos de las ACL que implemento Tupac en su servidor de prueba:
olcAccess: {0}to attrs=userPassword,shadowLastChange filter=(&(objectclass=per son)(memberof=cn=cup,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy)) by self w rite by dn="cn=admin,dc=interior,dc=udelar,dc=edu,dc=uy" write by group.exact ="cn=admins,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" write by group.exac t="cn=admins,cn=cup,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" write by * auth olcAccess: {1}to attrs=userPassword,shadowLastChange by self write by dn="cn=a dmin,dc=interior,dc=udelar,dc=edu,dc=uy" write by group.exact="cn=admins,ou=g rupos,dc=interior,dc=udelar,dc=edu,dc=uy" write by * auth olcAccess: {2}to filter=(&(objectclass=person)(memberof=cn=cup,ou=grupos,dc=in terior,dc=udelar,dc=edu,dc=uy)) by group.exact="cn=admins,cn=cup,ou=grupos,dc =interior,dc=udelar,dc=edu,dc=uy" write by dn="cn=admin,dc=interior,dc=udelar ,dc=edu,dc=uy" write by group.exact="cn=admins,ou=grupos,dc=interior,dc=udela r,dc=edu,dc=uy" write by * break olcAccess: {3}to dn.base="cn=cup,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" attrs="member" by self write by dn="cn=admin,dc=interior,dc=udelar,dc=edu,dc =uy" write by group.exact="cn=admins,ou=grupos,dc=interior,dc=udelar,dc=edu,d c=uy" write by group.exact="cn=admins,cn=cup,ou=grupos,dc=interior,dc=udelar, dc=edu,dc=uy" write by * auth olcAccess: {4}to filter=(&(objectclass=person)(!(memberof=cn=redmine,ou=grupos ,dc=interior,dc=udelar,dc=edu,dc=uy))) by dn="cn=login,cn=redmine,ou=grupos,d c=interior,dc=udelar,dc=edu,dc=uy" none by dn="cn=admin,dc=interior,dc=udelar ,dc=edu,dc=uy" write by group.exact="cn=admins,ou=grupos,dc=interior,dc=udela r,dc=edu,dc=uy" write by * read olcAccess: {5}to dn.base="" by * read olcAccess: {6}to * by dn="cn=admin,dc=interior,dc=udelar,dc=edu,dc=uy" write b y group.exact="cn=admins,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" write by anonymous none by * read
{0} La contraseña de los usuarios miembros del grupo cup, cada uno puede cambiar su contraseña, la pueden cambiar los miembros del grupo cn=admins,cn=cup,ou=grupos...., el usuario admin y los miembros del grupo admins, los demas nada
password_admin_cup.ldif
dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcAccess olcAccess: to attrs=userPassword,shadowLastChange filter=(&(objectclass=person)(memberof=cn=cup,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy)) by self write by dn="cn=admin,dc=interior,dc=udelar,dc=edu,dc=uy" write by group.exact="cn=admins,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" write by group.exact="cn=admins,cn=cup,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" write by * auth
{1} La contraseña de todos los usuarios, cada uno puede cambiar su contraseña, la pueden cambiar el usuario admin y los miembros del grupo admins, los demas nada
password.ldif
dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcAccess olcAccess: to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=interior,dc=udelar,dc=edu,dc=uy" write by group.exact="cn=admins,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" write by * auth
{2} Los usarios del grupo cup, pueden ser modificados por los miembros del grupo cn=admins,cn=cup,ou=grupos...., el usuario admin y los miembros del grupo admins, los demas nada
admin_cup.ldif
dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcAccess olcAccess: {1}to filter=(&(objectclass=person)(memberof=cn=cup,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy)) by group.exact="cn=admins,cn=cup,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" write by dn="cn=admin,dc=interior,dc=udelar,dc=edu,dc=uy" write by group.exact="cn=admins,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" write by * break
{3} Los administradores del cup, pueden agregar miembros al grupo cup
member_cup.ldif
dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcAccess olcAccess: {3}to dn.base="cn=cup,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" attrs="member" by self write by dn="cn=admin,dc=interior,dc=udelar,dc=edu,dc=uy" write by group.exact="cn=admins,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" write by group.exact="cn=admins,cn=cup,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" write by * auth
{3} Los administradores del cup, solo pueden ver los miembros de grupo cup, esta no iría pero queda como ejemplo por si se quiere hacer algo parecido
olcAccess: {3}to filter=(&(objectclass=person)(!(memberof=cn=cup,ou=grupos,dc= interior,dc=udelar,dc=edu,dc=uy))) by group.exact="cn=admins,cn=cup,ou=grupos ,dc=interior,dc=udelar,dc=edu,dc=uy" none by dn="cn=admin,dc=interior,dc=udel ar,dc=edu,dc=uy" write by group.exact="cn=admins,ou=grupos,dc=interior,dc=ude lar,dc=edu,dc=uy" write by * break
admin_cup_solo.ldif
dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcAccess olcAccess: to filter=(&(objectclass=person)(!(memberof=cn=cup,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy))) by group.exact="cn=admins,cn=cup,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" none by dn="cn=admin,dc=interior,dc=udelar,dc=edu,dc=uy" write by group.exact="cn=admins,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" write by * break
{4} El autenticador del servicio redmine solo puede ver a los miembros del grupo redmine
redmine.ldif
dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcAccess olcAccess: to filter=(&(objectclass=person)(!(memberof=cn=redmine,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy))) by dn="cn=login,cn=redmine,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" none by dn="cn=admin,dc=interior,dc=udelar,dc=edu,dc=uy" write by group.exact="cn=admins,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" write by * read
{5} Todos pueden leer la base del ldap
rdn_base.ldif
dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcAccess olcAccess: to dn.base="" by * read
{6} El usuario admin, y los miembros del grupo admins pueden escribir todo el arbol los demás lo pueden leer
total.ldif
dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcAccess olcAccess: to * by dn="cn=admin,dc=interior,dc=udelar,dc=edu,dc=uy" write by group.exact="cn=admins,ou=grupos,dc=interior,dc=udelar,dc=edu,dc=uy" write by * read