LDAP (Lightweight Directory Access Protocol) es un protocolo estándar abierto para acceder a servicios de directorio X.500. Un directorio es una base de datos específicamente diseñada para la búsqueda y navegación de información. De manera similar a una guía telefónica, más que como una carpeta en un sistema de archivos. Al igual que una guía telefónica o libreta de direcciones/contactos, el directorio almacena información acerca de un ítem, como un doctor: primero se encuentra la guía telefónica, luego se buscan doctores, a continuación se busca la especialidad deseada, y finalmente se decide qué doctor examinar (obtener sus datos como dirección, número de teléfono, horarios, etc.)

Los servicios de directorio juegan un rol importante en el desarrollo de aplicaciones sobre Internet y redes privadas (intranets) permitiendo compartir información de recursos (usuarios, sistemas, redes, servicios y aplicaciones) a través de la red. Como ejemplo, un servicio de directorio puede proveer un conjunto organizado de registros, generalmente respetando una estructura jerárquica, tal como una libreta de direcciones de correo electrónico dentro de una red corporativa. También son utilizados muy frecuentemente para proveer servicios de autenticación y autorización centralizados (y a su vez distribuidos entre varios servidores) en redes corporativas, tal como es el caso de Active Directory, el popular servicio de directorio implementado por Microsoft.

El protocolo LDAP opera sobre los protocolos de transporte de Internet (TCP/IP). LDAP es una alternativa liviana al protocolo DAP (Directory Access Protocol) del estándar X.500 para uso en Internet. Liviana porque se basa en la pila TCP/IP en lugar de en la compleja pila OSI. Además tiene simplificaciones como la representación de la mayoría de los valores de atributos e ítems del protocolo como texto plano, lo cual está diseñado para simplificar la implementación de clientes.

Por defecto, OpenLDAP utiliza una base de datos Bekerley DB como backend. Sin embargo, de acuerdo a experiencias previas con otras aplicaciones, esta librería es propensa a errores, corrupción de datos y es ineficiente en comparación a otras tecnologías similares (por ejemplo SQLite). Por ende, este artículo documenta la instalación de un servidor LDAP con Postgres como backend (un motor de bases de datos muchísimo más eficiente y robusto) lo cual requiere la instalación de un driver ODBC.



OpenLDAP no soporta PostgreSQL como backend de manera nativa, aunque soporta cualquier servidor de bases de datos SQL a través de ODBC.

Compilar e instalar PostgreSQL

En artículos anteriores expliqué detalladamente los procesos de compilación de Postgres, creación de instancias y configuración del servidor:

  1. Compilar e instalar Postgres desde los fuentes
  2. Cómo crear una instancia de PostgreSQL
  3. Configuración básica de un servidor PostgreSQL

Compilar e instalar unixODBC

ODBC es una especificación abierta para proveer a desarrolladores de aplicaciones una API predecible a través de la cual acceder a diferentes Data Sources. Entre los posibles Data Sources se incluyen la mayoría de los servidores SQL (Oracle, MySQL, Microsoft SQL, Postgres, IBM DB2, IBM Informix, entre otros), y cualquier otra tecnología que posea un driver ODBC (por ejemplo Microsoft Visual FoxPro, Microsoft Access, Microsoft Excel, Symantec Backup Exec, etc.)

Esta capa de abstracción permite a los desarrolladores independizarse de la tecnología de datos subyacente.

El proyecto unixODBC intenta ser el estándar definitivo para ODBC en plataformas no Windows, e incluye soporte GUI tanto para GNOME como KDE.

Descargar, compilar e instalar la última versión estable de unixODBC:

# cd /usr/local/src/
# wget http://www.unixodbc.org/unixODBC-2.3.4.tar.gz
# tar xzf unixODBC-2.3.4.tar.gz 
# cd unixODBC-2.3.4/
# ./configure
# make
# make install

Al finalizar la instalación, es necesario agregar el directorio de instalación bin/ de Postgres a la variable de entorno PATH, y configurar correctamente la variable de entorno LD_LIBRARY_PATH:

# nano /etc/profile.d/path.sh

La variable LD_LIBRARY_PATH puede ser exportada previamente, revisar cuidadosamente la siguiente configuración:

PATH="${PATH}:/usr/local/pgsql/bin"
export PATH
LD_LIBRARY_PATH="/usr/local/lib:/usr/local/pgsql/lib"
export LD_LIBRARY_PATH

Actualizar el perfil Bash ejecutando:

# source /etc/profile.d/path.sh

Compilar e instalar el driver ODBC para PostgreSQL

psqlODBC es el driver ODBC oficial de PostgreSQL. Es posible descargarlo desde el siguiente enlace:

https://www.postgresql.org/ftp/odbc/versions/src/

Para descargar, compilar e instalar la versión 10.00.0000 de psqlODBC, repetir los siguientes pasos:

# cd /usr/local/src/
# wget https://ftp.postgresql.org/pub/odbc/versions/src/psqlodbc-10.00.0000.tar.gz
# tar xzf psqlodbc-10.00.0000.tar.gz 
# cd psqlodbc-10.00.0000/
# ./configure --help
# ./configure --with-unixodbc
# make
# make install

Instalar OpenLDAP

OpenLDAP es la comunidad que desarrolla el software LDAP open source. El paquete openldap provee tanto el demonio slapd (servidor LDAP) como las librerías que implementan el protocolo LDAP, junto con utilitarios, herramientas y clientes.

Descargar y extraer el paquete:

# cd /usr/local/src/
# wget http://gpl.savoirfairelinux.net/pub/mirrors/openldap/openldap-release/openldap-2.4.45.tgz
# tar xzf openldap-2.4.45.tgz
# chown -R root:staff openldap-2.4.45
# cd openldap-2.4.45/

La guía de instalación se encuentra en el archivo INSTALL:

# less INSTALL

Revisar cuidadosa y detenidamente todas y cada una de las opciones de configuración:

# ./configure --help

En este caso (a fin de deshabilitar Berkeley DB y reemplazarlo por Postgres), utilizo las siguientes opciones de configuración del paquete:

--enable-crypt        Permitir contraseñas generadas con crypt
--enable-modules      Permitir soporte para módulos dinámicos
--enable-rlookups     Habilitar lookups reversos de nombres de hosts de clientes
--enable-sql=yes      Habilitar un backend SQL
--with-tls=openssl    Utilizar OpenSSL para proveer TLS
--without-cyrus-sasl  Deshabilitar Cyrus SASL
--disable-bdb         Deshabilitar Berkeley DB
--disable-hdb         Deshabilitar Berkeley DB
--disable-ipv6        Deshabilitar IPv6

A tal fin, es necesario instalar algunas dependencias previo a la configuración:

# apt-get install libtool libssl-dev

Configurar el paquete con las opciones indicadas:

# ./configure --enable-crypt --enable-modules --enable-rlookups --enable-sql=yes --with-tls=openssl --without-cyrus-sasl --disable-bdb --disable-hdb --disable-ipv6

Las opciones --without-cyrus-sasl, disable-bdb, --disable-hdb y --disable-ipv6 se utilizan para eliminar el soporte para el mecanismo de autenticación Cyrus SASL, Berkeley DB e IPv6. Por otro lado, --enable-crypt permite utilizar contraseñas generadas con crypt, se habilita el soporte para módulos con --enable-modules y TLS con la opción --with-tls=openssl.

La opción clave para lograr utilizar Postgres como backend es --enable-sql=yes.

Si la configuración falla con un error de tipo sql.h not found, se debe a que el soporte para ODBC debe ser provisto previamente.

Finalmente, compilar e instalar:

# make depend
# make
# make install

Configurar ODBC

Una vez instalados todos los componentes, comienza el proceso de configuración. El primer paso consiste en configurar la conexión LDAP/Postgres a través de ODBC. Editar el archivo de configuración de ODBC odbc.ini:

# nano /usr/local/etc/odbc.ini 

Establecer correctamente los valores para el usuario, contraseña y base de datos (aún no han sido creados):

;
;  odbc.ini
;
[ODBC Data Sources]
PgSQL=PostgreSQL

[PgSQL]
; WARNING: The old psql odbc driver psqlodbc.so is now renamed psqlodbcw.so
; in version 08.x. Note that the library can also be installed under an other
; path than /usr/local/lib/ following your installation.
Driver=/usr/local/lib/psqlodbcw.so
Description=Connection to LDAP/POSTGRESQL
Servername=localhost
Port=5432
Protocol=6.4
FetchBufferSize=99
Username=ldap
Password=1234
Database=pg_ldap
ReadOnly=no
Debug=1
CommLog=1

[ODBC]
InstallDir=/usr/local/lib

La conexión se define a través del nombre de data source. En este caso se llama "PgSQL" y utiliza el driver "Postgres".

Habiendo configurado el data source "PgSQL", resta configurar el driver ODBC "Postgres". Editar el archivo odbcinst.ini:

# nano /usr/local/etc/odbcinst.ini

Revisar que la ruta para el driver (psqlodbcw.so) sea correcta:

;
;  odbcinst.ini
;
[PostgreSQL]
Description=ODBC for PostgreSQL
; WARNING: The old psql odbc driver psqlodbc.so is now renamed psqlodbcw.so
; in version 08.x. Note that the library can also be installed under an other
; path than /usr/local/lib/ following your installation.
Driver=/usr/local/lib/psqlodbcw.so

[ODBC]
Trace=1
Debug=1
Pooling=No

Configurar OpenLDAP

El paquete openldap incluye una configuración de ejemplo para el acceso a un backend SQL:

# cd /usr/local/etc/openldap/
# cp /usr/local/src/openldap-2.4.45/servers/slapd/back-sql/rdbms_depend/pgsql/slapd.conf .

Editar el archivo de configuración y modificar las variables suffix, rootdn, dbname, dbuser y dbpassword con los siguientes valores:

database        sql
suffix          "dc=example,dc=com"
rootdn          "cn=root,dc=example,dc=com"
rootpw          secret
dbname          PgSQL
dbuser          ldap
dbpasswd        1234

Estos valores corresponden a los datos de ejemplo que se instalarán luego en la base de datos Postgres. Las variables suffix y rootdn se modifican para que coincidan con los mismos. Notar que el nombre de la base de datos no es el nombre dentro del motor Postgres ("pg_ldap"), sino el nombre asignado al data source en la configuración del driver ODBC ("PgSQL").

Instalar la base de datos PostgreSQL

Cambiar al usuario "postgres":

root@debian8:~# su - postgres
postgres@debian8:~$

Crear un usuario y base de datos en la instancia recién inicializada de acuerdo a los valores configurados en el data source ODBC:

$ createdb pg_ldap
$ createuser -D -R -S -W ldap
Password:

A continuación se debe crear la estructura de base de datos para LDAP. Esta estructura es necesaria para que LDAP funcione con SQL como backend.

Cambiar al directorio servers/slapd/back-sql/rdbms_depend/pgsql/ dentro del paquete:

$ cd /usr/local/src/openldap-2.4.45/servers/slapd/back-sql/rdbms_depend/pgsql/

Crear la meta-estructura de LDAP ejecutando el script SQL backsql_create.sql:

$ psql -d pg_ldap < backsql_create.sql

A fin de verificar el funcionamiento de la instalación, es posible crear datos de prueba. A tal fin, crear la base de datos de prueba:

$ psql -d pg_ldap < testdb_create.sql 

Los errores arrojados por ambos scripts se deben a que intentan eliminar tablas que aún no existen (están pensados para limpiar una instalación preexistente). Simplemente ignorar estos errores.

Luego se generan todos los enlaces entre el backend SQL y los objetos almacenados en la base de datos de prueba. Esta meta-información es la que traduce las consultas LDAP en consultas SQL. También se generan todas las funciones SQL utilizadas por la definición de metadatos para crear los objetos de directorios de prueba y sus atributos.

$ psql -d pg_ldap < testdb_metadata.sql 

Finalmente se insertan algunos datos de prueba:

$ psql -d pg_ldap < testdb_data.sql 

El último paso consiste en otorgar permisos al usuario recién creado para que sea capaz de ejecutar consultas sobre la base de datos de prueba. Conectarse a la base de datos "pg_ldap":

$ psql -d pg_ldap
psql (10.0)
Type "help" for help.

pg_ldap=#

Otorgar permisos sobre las siguientes tablas:

pg_ldap=# grant all on ldap_attr_mappings,ldap_entries,ldap_entry_objclasses,ldap_oc_mappings,referrals,certs to ldap;
GRANT
pg_ldap=# grant all on ldap_attr_mappings_id_seq,ldap_entries_id_seq,ldap_oc_mappings_id_seq,referrals_id_seq to ldap;
GRANT
pg_ldap=# grant all on authors_docs,documents,institutes,persons,phones to ldap;
GRANT
pg_ldap=# grant all on documents_id_seq,institutes_id_seq,persons_id_seq,phones_id_seq to ldap;
GRANT

Verificar el funcionamiento de unixODBC

Comprobar que los datos de ejemplo hayan sido instalados correctamente en la base de datos Postgres:

root@debian8:~# su - postgres
postgres@debian8:~$ psql
psql (10.0)
Type "help" for help.

postgres=# \c pg_ldap
You are now connected to database "pg_ldap" as user "postgres".
pg_ldap=# \dt+
                              List of relations
 Schema |         Name          | Type  |  Owner   |    Size    | Description 
--------+-----------------------+-------+----------+------------+-------------
 public | authors_docs          | table | postgres | 8192 bytes | 
 public | certs                 | table | postgres | 16 kB      | 
 public | documents             | table | postgres | 16 kB      | 
 public | institutes            | table | postgres | 8192 bytes | 
 public | ldap_attr_mappings    | table | postgres | 16 kB      | 
 public | ldap_entries          | table | postgres | 8192 bytes | 
 public | ldap_entry_objclasses | table | postgres | 8192 bytes | 
 public | ldap_oc_mappings      | table | postgres | 16 kB      | 
 public | persons               | table | postgres | 16 kB      | 
 public | phones                | table | postgres | 8192 bytes | 
 public | referrals             | table | postgres | 16 kB      | 
(11 rows)

pg_ldap=# \d persons
                                     Table "public.persons"
  Column  |          Type          | Collation | Nullable |               Default               
----------+------------------------+-----------+----------+-------------------------------------
 id       | integer                |           | not null | nextval('persons_id_seq'::regclass)
 name     | character varying(255) |           | not null | 
 surname  | character varying(255) |           | not null | 
 password | character varying(64)  |           |          | 
Indexes:
    "persons_pkey" PRIMARY KEY, btree (id)

pg_ldap=# select name from persons;
    name    
------------
 Mitya
 Torvlobnor
 Akakiy
(3 rows)

pg_ldap=# \q
postgres@debian8:~$ exit
logout
root@debian8:~#

Se observa que la base de datos de ejemplo tiene una tabla "persons" con una columna "name", la cual posee 3 filas.

El siguiente paso consiste en tratar de obtener la misma información a través de ODBC. Se puede recurrir al cliente ODBC isql. Es necesario pasar el DSN (Data Source Name) como parámetro (DSN=PsQSL):

root@debian8:~# isql -v PgSQL
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> select name from persons;
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| name                                                                                                                                                                                                                                                           |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Mitya                                                                                                                                                                                                                                                          |
| Torvlobnor                                                                                                                                                                                                                                                     |
| Akakiy                                                                                                                                                                                                                                                         |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
SQLRowCount returns 3
3 rows fetched
SQL> quit
root@debian8:~# 

La conexión ODBC con Postgres funciona correctamente.

Verificación el funcionamiento del servidor LDAP

El primer paso consiste en levantar el servidor LDAP. Simplemente se debe lanzar el demonio slapd:

root@debian8:~# /usr/local/libexec/slapd

El demonio debe quedar corriendo en background:

root@debian8:~# ps aux | grep '[s]lapd'
root      3064  0.0  0.7 267528  8032 ?        Ssl  oct31   0:03 /usr/local/libexec/slapd

Verificar que abra el puerto TCP/IP 389 (LDAP):

root@debian8:~# netstat -tulpn | grep slapd
tcp        0      0 0.0.0.0:389             0.0.0.0:*               LISTEN      3064/slapd

En caso de errores, revisar el log del sistema (syslog en Debian). Si el demonio falla al iniciar, la causa queda registrada en el mismo:

root@debian8:~# tail -n 2 /var/log/syslog
Oct 31 13:10:23 debian8 slapd[3063]: @(#) $OpenLDAP: slapd 2.4.45 (Oct 30 2017 10:34:41) $#012#011root@debian8:/usr/local/src/openldap-2.4.45/servers/slapd
Oct 31 13:10:27 debian8 slapd[3064]: slapd starting

Con el servidor LDAP corriendo, es posible hacer una consulta utilizando el cliente ldapsearch. Por ejemplo, para obtener todos los objetos en los datos de ejemplo cuyo cn (Common Name) contienen la palabra "Mitya", ejecutar:

root@debian8:~# ldapsearch -x -h localhost -b "dc=example,dc=com" "cn=*Mitya*"
# extended LDIF
#
# LDAPv3
# base <dc=example,dc=com> with scope subtree
# filter: cn=*Mitya*
# requesting: ALL
#

# Mitya Kovalev, example.com
dn: cn=Mitya Kovalev,dc=example,dc=com
objectClass: inetOrgPerson
cn: Mitya Kovalev
sn: Kovalev
seeAlso: documentTitle=book1,dc=example,dc=com
seeAlso: documentTitle=book2,dc=example,dc=com
givenName: Mitya
userPassword:: bWl0
telephoneNumber: 222-3234
telephoneNumber: 332-2334

# search reference
ref: ldap://localhost:9012/dc=example,dc=com??sub

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 1
# numReferences: 1

El servidor LDAP funciona correctamente y se conecta a Postgres a través de unixODBC sin inconvenientes.

Para ejecutar una batería de testeos más profunda, recomiendo revisar los ejemplos en el siguiente enlace:

Pasos restantes

Para finalizar la instalación quedan pendientes lo siguientes ítems:

  • Crear un script de inicio del servicio slapd.
  • Configurar el firewall y verificar el funcionamiento desde clientes remotos.
  • Borrar los datos de prueba.
  • Configurar el servidor slapd y crear un directorio para usar en el sitio (slapd-config).
  • Definir un esquema de backup para los datos del servidor LDAP.

Referencias


Tal vez pueda interesarte


Compartí este artículo