2.3. Comprobaciones iniciales de la instalación

2.3.1. Ejecución del demonio

En este punto, ya se debería tener un servidor OpenLDAP instalado y ejecutándose, aunque no esté ajustado todavía a los objetivos que persigue este apartado. Para comprobar que efectivamente el demonio slapd se está ejecutando, realizaremos un par de consultas al sistema. La primera consiste en ver si el demonio slapd se encuentra en la lista de procesos que actualmente se estén ejecutando en el sistema:

Ejemplo 2.3. Comprobación de que slapd está en la lista de procesos actuales

# /bin/ps auxf | /bin/grep slapd
USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
root      4453  0.0  0.5 12144 3004 ?        S    12:52   0:00 /usr/sbin/slapd
root      4455  0.0  0.5 12144 3004 ?        S    12:52   0:00  \_ /usr/sbin/slapd
root      4456  0.0  0.5 12144 3004 ?        S    12:52   0:00      \_ /usr/sbin/slapd
[Note]Nota

En la captura de pantalla anterior se ha eliminado la línea que hacía referencia la instrucción tecleada (/bin/ps auxf | /bin/grep slapd) y se ha añadido la línea de información sobre cada parte de la captura, para mejorar la legibilidad.

La segunda comprobación ha realizar, para ver si el demonio se está realmente ejecutando, es verificar que está escuchando en la red[7]:

Ejemplo 2.4. Comprobación de que slapd escucha en la red

# /bin/netstat -puta
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 *:ldap                  *:*                     LISTEN     4453/slapd

2.3.2. Conectando con el servidor

Una vez comprobado que el demonio slapd se está ejecutando en el sistema, se verificará que la conexión con el mismo está permitida. Para ello, se realizará una búsqueda sencilla en el directorio. Si todo va bien, se debería mostrar algo similar a:

Ejemplo 2.5. Realización de una búsqueda simple con ldapsearch

$ /usr/bin/ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts
# extended LDIF
#
# LDAPv3
# base <> with scope base
# filter: (objectclass=*)
# requesting: namingContexts
#

#
dn:
namingContexts: dc=gsr,dc=pt

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

2.3.2.1. Posibles problemas de conexión

2.3.2.1.1. TCP Wrappers

Se han de tener en cuenta las opciones de configuración pasadas, antes de la compilación de OpenLDAP, para generar los paquetes que se están utilizando. Si nos fijamos en las opciones de configuración que posee OpenLDAP por defecto en Debian GNU/Linux (consulte el Apéndice O, Opciones de compilación de OpenLDAP en Debian GNU/Linux) veremos que utiliza la opción --enable-wrappers, lo que habilita el soporte de los TCP Wrappers en OpenLDAP.

Si se posee una configuración restrictiva de los TCP Wrappers, puede que sea esta la causa de los problemas de conexión. A continuación se simulará un fallo de conexión debido a un bloqueo de los TCP Wrappers, mostrándola manera de detectarlo y corregirlo.

Se supone la siguiente configuración de los TCP Wrappers (en los Apéndice AM, Archivo de configuración /etc/hosts.allow y Apéndice AN, Archivo de configuración /etc/hosts.deny se encuentran los archivos finales para los TCP Wrappers):

Ejemplo 2.6. Archivo /etc/hosts.allow

# /etc/hosts.allow: list of hosts that are allowed to access the system.
#                   See the manual pages hosts_access(5), hosts_options(5)
#                   and /usr/doc/netbase/portmapper.txt.gz
#
# Example:    ALL: LOCAL @some_netgroup
#             ALL: .foobar.edu EXCEPT terminalserver.foobar.edu
#
# If you're going to protect the portmapper use the name "portmap" for the
# daemon name. Remember that you can only use the keyword "ALL" and IP
# addresses (NOT host or domain names) for the portmapper. See portmap(8)
# and /usr/doc/portmap/portmapper.txt.gz for further information.
#

Ejemplo 2.7. Archivo /etc/hosts.deny

# /etc/hosts.deny: list of hosts that are _not_ allowed to access the system.
#                  See the manual pages hosts_access(5), hosts_options(5)
#                  and /usr/doc/netbase/portmapper.txt.gz
#
# Example:    ALL: some.host.name, .some.domain
#             ALL EXCEPT in.fingerd: other.host.name, .other.domain
#
# If you're going to protect the portmapper use the name "portmap" for the
# daemon name. Remember that you can only use the keyword "ALL" and IP
# addresses (NOT host or domain names) for the portmapper. See portmap(8)
# and /usr/doc/portmap/portmapper.txt.gz for further information.
#
# The PARANOID wildcard matches any host whose name does not match its
# address. You may wish to enable this to ensure any programs that don't
# validate looked up hostnames still leave understandable logs. In past
# versions of Debian this has been the default.
# ALL: PARANOID

# Desautorizar a todos los hosts con nombre sospechoso
ALL: PARANOID

# Desautorizar a todos los hosts
ALL:ALL

Ahora se realizará la misma búsqueda que en Ejemplo 2.5, “Realización de una búsqueda simple con ldapsearch”:

Ejemplo 2.8. Realización de una búsqueda simple con ldapsearch (conexión fallida)

$ ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts
ldap_bind: Can't contact LDAP server (81)

Como se puede apreciar, no se ha podido conectar con el servidor LDAP. El siguiente ejemplo realizará la misma búsqueda, sólo que en este caso se activará el modo de depuración del comando ldapsearch-d -1” (se hará uso del nivel de depurado -1, que es el mayor nivel existente).

Ejemplo 2.9. Realización de una búsqueda simple con ldapsearch (modo depuración)

$ ldapsearch -d -1 -x -b '' -s base '(objectclass=*)' namingContexts
ldap_create
ldap_bind_s
ldap_simple_bind_s
ldap_sasl_bind_s
ldap_sasl_bind
ldap_send_initial_request
ldap_new_connection
ldap_int_open_connection
ldap_connect_to_host: TCP gsr.pt:389 1
ldap_new_socket: 3
ldap_prepare_socket: 3
ldap_connect_to_host: Trying 192.168.2.1:389 2
ldap_connect_timeout: fd: 3 tm: -1 async: 0
ldap_ndelay_on: 3
ldap_is_sock_ready: 3
ldap_ndelay_off: 3
ldap_int_sasl_open: host=gsr.pt
ldap_open_defconn: successful 3
ldap_send_server_request
ber_flush: 14 bytes to sd 3
  0000:  30 0c 02 01 01 60 07 02  01 03 04 00 80 00         0....`........
ldap_write: want=14, written=14
  0000:  30 0c 02 01 01 60 07 02  01 03 04 00 80 00         0....`........
ldap_result msgid 1
ldap_chkResponseList for msgid=1, all=1
ldap_chkResponseList returns NULL
wait4msg (infinite timeout), msgid 1
wait4msg continue, msgid 1, all 1
** Connections:
* host: gsr.pt  port: 389  (default)
  refcnt: 2  status: Connected
  last used: Tue Mar  9 16:18:26 2004

** Outstanding Requests:
 * msgid 1,  origid 1, status InProgress
   outstanding referrals 0, parent count 0
** Response Queue:
   Empty
ldap_chkResponseList for msgid=1, all=1
ldap_chkResponseList returns NULL
ldap_int_select
read1msg: msgid 1, all 1
ber_get_next
ldap_read: want=8, got=0

ber_get_next failed. 4
ldap_perror 5
ldap_bind: Can't contact LDAP server (81) 6
1 2

Aquí se puede ver que el host con el que establece la conexión es el correcto.

3

Una vez encontrado el host, se conecta satisfactoriamente al mismo.

4 5 6

En este momento comienzan los errores de conexión.

Como se puede observar en el Ejemplo 2.9, “Realización de una búsqueda simple con ldapsearch (modo depuración)”, que no se obtiene la información suficiente para deducir cual ha sido el problema que ocasiona el error en la conexión. Por este motivo se ejecutará el demonio slapd en modo depuración y, aunque no sea necesario, se ejecutará con el nivel de depurado “-1”.

Antes proceder con este ejemplo, se mostrarán los posibles valores que puede tomar el modo de depuración de slapd y su significado[8]:

Tabla 2.1. Niveles de depurado de slapd

NivelDescripción
-1Habilita todo el depurado
0Sin depurado
1Rastrea las llamadas a funciones
2Depura el manejo de paquetes
4Rastreo de depuración intensivo
8Administración de la conexión
16Muestra los paquetes enviados y recibidos
32Procesado de búsqueda por filtro
64Procesado del archivo de configuración
128Procesado de la lista de control de acceso
256stats log connections/operations/results
512stats log entries sent
1024Muestra las comunicaciones con los backends de la shell
2048Muestra las entradas analizadas (parsing)

Ejemplo 2.10. Ejecución del servidor slapd en modo de depuración

# /usr/sbin/slapd -d -1 -h ldap://gsr.pt:389/
@(#) $OpenLDAP: slapd 2.1.30 (May 24 2004 23:50:57) $
        @pulsar:/home/torsten/packages/openldap/release-2.1.30-1/openldap2-2.1.30/debian/build/servers/slapd
daemon_init: ldap://gsr.pt:389/
daemon_init: listen on ldap://gsr.pt:389/
daemon_init: 1 listeners to open...
ldap_url_parse_ext(ldap://gsr.pt:389/)
daemon: initialized ldap://gsr.pt:389/
daemon_init: 1 listeners opened
slapd init: initiated server.
slap_sasl_init: initialized!
reading config file /etc/ldap/slapd.conf
line 11 (include         /etc/ldap/schema/core.schema)
reading config file /etc/ldap/schema/core.schema/

(...)

slapd startup: initiated.
slapd starting
daemon: added 6r
daemon: select: listen=6 active_threads=0 tvp=NULL

En este momento ya tenemos el demonio slapd en modo depuración, por lo que si realizamos de nuevo la búsqueda del Ejemplo 2.8, “Realización de una búsqueda simple con ldapsearch (conexión fallida)”, se verá la información que muestra el servidor cuando esta se realiza:

Ejemplo 2.11. Ejecución del servidor slapd en modo de depuración (mensaje de rechazo de una conexión)

daemon: activity on 1 descriptors
daemon: new connection on 9
fd=9 DENIED from unknown (192.168.2.1) 1
daemon: closing 9
daemon: activity on:
daemon: select: listen=6 active_threads=0 tvp=NULL
1

Esta línea muestra el motivo del rechazo de la conexión, no se permite la conexión desde la IP 192.168.2.1, que es desde la que se está tratando de realizar la consulta precisamente.

Si se añade la siguiente línea al archivo /etc/hosts.allowslapd: 192.168.2.1” y se ejecuta de nuevo la búsqueda del Ejemplo 2.8, “Realización de una búsqueda simple con ldapsearch (conexión fallida)”, sucede lo siguiente:

  • El servidor muestra la siguiente información:

    Ejemplo 2.12. Ejecución del servidor slapd en modo de depuración (mensaje de aceptación de una conexión)

    daemon: activity on 1 descriptors
    daemon: new connection on 9
    conn=2 fd=9 ACCEPT from IP=192.168.2.1:32852 (IP=192.168.2.1:389) 1
    daemon: added 9r
    daemon: activity on:
    daemon: select: listen=6 active_threads=0 tvp=NULL
    daemon: activity on 1 descriptors
    daemon: activity on: 9r
    daemon: read activity on 9
    connection_get(9)
    connection_get(9): got connid=2
    connection_read(9): checking for input on id=2
    ber_get_next
    
    (...)
    
    conn=2 op=1 SRCH base="" scope=0 filter="(objectClass=*)"
    conn=2 op=1 SRCH attr=namingContexts
    => test_filter
        PRESENT
    => access_allowed: search access to "" "objectClass" requested
    => acl_get: [1] check attr objectClass
    => dn: [2]
    => acl_get: [2] matched
    => acl_get: [2] check attr objectClass
    <= acl_get: [2] acl  attr: objectClass
    => acl_mask: access to entry "", attr "objectClass" requested
    => acl_mask: to all values by "", (=n)
    <= check a_dn_pat: *
    <= acl_mask: [1] applying read(=rscx) (stop)
    <= acl_mask: [1] mask: read(=rscx)
    => access_allowed: search access granted by read(=rscx)
    <= test_filter 6
    => send_search_entry: dn=""
    => access_allowed: read access to "" "entry" requested
    => acl_get: [1] check attr entry
    => dn: [2]
    => acl_get: [2] matched
    => acl_get: [2] check attr entry
    <= acl_get: [2] acl  attr: entry
    => acl_mask: access to entry "", attr "entry" requested
    => acl_mask: to all values by "", (=n)
    <= check a_dn_pat: *
    <= acl_mask: [1] applying read(=rscx) (stop)
    <= acl_mask: [1] mask: read(=rscx)
    => access_allowed: read access granted by read(=rscx)
    => access_allowed: read access to "" "namingContexts" requested
    => acl_get: [1] check attr namingContexts
    => dn: [2]
    => acl_get: [2] matched
    => acl_get: [2] check attr namingContexts
    <= acl_get: [2] acl  attr: namingContexts
    access_allowed: no res from state (namingContexts)
    => acl_mask: access to entry "", attr "namingContexts" requested
    => acl_mask: to all values by "", (=n)
    <= check a_dn_pat: *
    <= acl_mask: [1] applying read(=rscx) (stop)
    <= acl_mask: [1] mask: read(=rscx)
    => access_allowed: read access granted by read(=rscx)
    
    (...)
    
    ber_get_next on fd 9 failed errno=0 (Success)
    connection_read(9): input error=-2 id=2, closing.
    connection_closing: readying conn=2 sd=9 for close
    connection_close: deferring conn=2 sd=9
    do_unbind
    conn=2 op=2 UNBIND
    connection_resched: attempting closing conn=2 sd=9
    connection_close: conn=2 sd=9
    daemon: removing 9
    conn=2 fd=9 closed
    daemon: select: listen=6 active_threads=0 tvp=NULL
    daemon: activity on 1 descriptors
    daemon: select: listen=6 active_threads=0 tvp=NULL
    1

    Finalmente se ha aceptado la conexión.

  • Del lado del cliente se obtiene la misma información que en el Ejemplo 2.5, “Realización de una búsqueda simple con ldapsearch”.

2.3.2.1.2. Address family not supported by protocol

Un error derivado de la instalación por defecto, es el que se muestra en título de esta sección. Si no se especifica en que interfaces ha de escuchar el demonio slapd, dará el mentado error.

A continuación se verá la diferencia de ejecutar el servidor especificando o no la interfaz sobre la que tiene que escuchar. Para ello, una vez más se ejecutará en modo depuración.

Ejemplo 2.13. Ejecución del demonio slapd sin especificar la interfaz donde escuchar

# /usr/sbin/slapd -d -1
@(#) $OpenLDAP: slapd 2.1.30 (May 24 2004 23:50:57) $
        @pulsar:/home/torsten/packages/openldap/release-2.1.30-1/\
                              openldap2-2.1.30/debian/build/servers/slapd
daemon_init: <null>
daemon_init: listen on ldap:///
daemon_init: 1 listeners to open...
ldap_url_parse_ext(ldap:///)
slap_open_listener: socket() failed for AF_INET6 errno=97 (Address family not supported by protocol) 1
daemon: initialized ldap:///
daemon_init: 2 listeners opened
ldap_pvt_gethostbyname_a: host=todoscsi, r=0
slapd init: initiated server.
slap_sasl_init: initialized!
reading config file /etc/ldap/slapd.conf
line 11 (include         /etc/ldap/schema/core.schema)
reading config file /etc/ldap/schema/core.schema

(...)

slapd startup: initiated.
slapd starting
daemon: added 6r
daemon: select: listen=6 active_threads=0 tvp=NULL
1

Aquí se muestra el error.

Ejemplo 2.14. Ejecución del demonio slapd especificando la interfaz donde escuchar

# /usr/sbin/slapd -d -1 -h ldap://gsr.pt:389/
@(#) $OpenLDAP: slapd 2.1.30 (May 24 2004 23:50:57) $
        @pulsar:/home/torsten/packages/openldap/release-2.1.30-1/\
                              openldap2-2.1.30/debian/build/servers/slapd
daemon_init: ldap://gsr.pt:389/
daemon_init: listen on ldap://gsr.pt:389/
daemon_init: 1 listeners to open...
ldap_url_parse_ext(ldap://gsr.pt:389/)
daemon: initialized ldap://gsr.pt:389/
daemon_init: 1 listeners opened
slapd init: initiated server.
slap_sasl_init: initialized!
reading config file /etc/ldap/slapd.conf
line 11 (include         /etc/ldap/schema/core.schema)
reading config file /etc/ldap/schema/core.schema

(...)

slapd startup: initiated.
slapd starting
daemon: added 6r
daemon: select: listen=6 active_threads=0 tvp=NULL

En el Ejemplo 2.14, “Ejecución del demonio slapd especificando la interfaz donde escuchar” se puede ver que ya no muestra ningún tipo de error al inicializar el servidor.

[Note]Nota

En el Capítulo 3, Retoques iniciales a la configuración por defecto de OpenLDAP se verá como configurar slapd para que arranque automáticamente con la especificación de la interfaces.



[7] Puede ajustar más la búsqueda seleccionando sólo aquellas conexiones que quiera ver. Para ello puede hacer uso de grep y las cadenas “LISTEN” y “slapd”.

[8] Si quiere obtener más información sobre los niveles de depurado, vea el archivo ldap_log.h que viene con el código fuente de OpenLDAP.