Configuración de SSSD: nested groups

En el post anterior se describía la sustitución natural de libnss_ldap en RHEL6 que conocíamos hasta RHEL5. El inconveniente que presenta es que ahora ya no incluye soporte para nested_groups (grupos dentro de grupos) tal y como se recoge en el README del paquete: /usr/share/doc/nss-pam-ldapd-0.7.5/README

Para conseguir que nuestro sistema soporte los grupos dentro de grupos que hay en el directorio OpenLDAP, tendremos que configurar la segunda alternativa que incluye nuestro sistema RHEL6. Se trata de SSSD: System Security Services Daemon (SSSD). Este es un nuevo servicio que aparece en Fedora 11, y pretende ofrecer una interfaz para NSS y PAM, única desde la que administrar el acceso remoto a directorios LDAP y múltiples mecanismos de autenticación desde un único punto. Este servicio es un elemento fundamental en FreeIPA (el proyecto de identity-manager de RedHat, basado en su LDAP, no en OpenLDAP).

La idea es la misma que la anterior: Disponer un servicio independiente de nss que se encargue de las búsquedas en LDAP, Kerberos, etc, y que si se detiene el sistema no se ralentice. Para configurar este nuevo servicio de forma que busque los usuarios y grupos en nuestro OpenLDAP editaremos el fichero /etc/sssd/sssd.conf y configuraremos la sección [domain/LDAP] para que tenga el siguiente contenido:

[domain/LDAP]

id_provider = ldap
auth_provider = ldap
ldap_schema = rfc2307bis
ldap_uri = ldap://LDAPSERVER.tecnoquia.com

ldap_user_search_base = o=tecnoquia,c=es
ldap_group_search_base = ou=grupos,o=tecnoquia,c=es
ldap_default_bind_dn = cn=nss,o=tecnoquia,c=es
ldap_default_authtok_type = password
ldap_default_authtok = super-secreto

ldap_group_member = uniqueMember
cache_credentials = true
enumerate = true
Lo importante para el soporte de nested_groups es la declaración de ldap_schema=rfc2307bis. Además, debemos descomentar la línea:
domains = LOCAL,LDAP
y también la definición del dominio [domain/LOCAL], para quede como:
[domain/LOCAL]
description = LOCAL Users domain
id_provider = local

enumerate = true
min_id = 500
max_id = 999
Luego editar el fichero /etc/nsswitch.conf para cambiar la configuración de donde debemos buscar los usuarios y grupos:
passwd:  files [NOTFOUND=continue] sss
shadow: files
group: files [NOTFOUND=continue] sss
Para aplicar estos cambios, tendremos que iniciar el demonio sssd:
/etc/init.d/sssd start
chkconfig sssd on
y luego si, podremos ejecutar los comandos:
  • getent passwd, que nos mostrará un listado de todos los usuarios locales y en LDAP
  • getent group, nos mostrará un listado de las cuentas de grupo locales y en el directorio, expandiendo correctamente los usuarios de grupos que contenidos en otros grupos.
  • id <LOGIN> nos mostrará información del usuario, que puede estar almacenada en LDAP

La foto la he sacado del album de challiyan en flickr

Configuración de NSS para la integración con LDAP en RHLE6

NSS (Name Service Switch) es el componente de nuestro sistema Linux encargado de listar todos los usuarios, grupos, hosts, etc de nuestro sistema. Cómo consultar esta información se configura en el fichero /etc/nsswitch.conf y en él, normalmente encontramos las líneas:

passwd:         files
group: files
shadow: files
Estas líneas configuran que busque los grupos (groups), cuentas de usuario (passwd) y contraseñas del sistema (shadow) en ficheros, los archi conocidos/etc/group, /etc/passwd y /etc/shadow. Cuando queremos configurar que nuestro sistema Linux busque las cuentas de usuario en un directorio LDAP, instalaremos las librerías ldapnss, y configuraremos apropiadamente los ficheros /etc/ldap.conf y /etc/nsswitch.conf.

En RHEL6 esta configuración ha cambiado con respecto a como la conocíamos en los sistemas RedHat hasta ahora. En esta versión, se usa un demonio independiente llamado nslcd. La configuración de este servicio se almacena en /etc/nslcd.conf y sustituye al antiguo /etc/ldap.conf. La configuración del servicio está documentada en las notas de RedHat: La mayor ventaja que podemos obtener de ello, es que si se para este servicio, el sistema no tratará de buscar usuarios en LDAP, y esto es una ventaja ante situaciones de parada o error, ya que el sistema no tiene que esperar a que expiren los timeouts de conexión al directorio, ni tener que editar el fichero /etc/nsswitch.conf para salvar este comportamiento.

Para configurar la búsqueda de usuarios y grupos en LDAP en nuestro sistema RHEL6 editaremos el fichero /etc/nslcd.conf y aplicaremos los siguientes cambios:
  1. Configurar la URI del servidor LDAP al que se conectará:
    uri ldap://LDAPSERVER.tecnoquia.com/
  2. Configurar la versión del protocolo que usaremos,
    ldap_version 3
  3. Configurar las credenciales del usuario LDAP que se usará para conectar al directorio, en las búsquedas de usuarios y grupos
    binddn cn=nss,o=tecnoquia,c=es
    bindpw super-secreto
  4. Definir que las búsquedas sean en profundidad
    scope sub
  5. Especificar que siempre deben recorrerse los alias
    deref always
  6. Indicar las ramas y filtros para localizar las cuentas de usuario y grupo en el directorio,
    base    group   ou=grupos,o=tecnoquia,c=es
    base passwd o=tecnoquia,c=es
    filter passwd (objectClass=posixAccount)

    scope passwd sub
    scope group sub
  7. Establecer los parámetros de timeout para la conexión/desconexión del servicio de directorio,
    bind_timelimit 2
    timelimit 4
    idle_timelimit 10
    reconnect_retrytime 2
  8. Indicar que no se usará SSL para conectar al directorio,
    ssl no
    tls_cacertdir /etc/openldap/cacerts
  9. y que NSS no busque los usuarios locales (que hay en /etc/passwd)
    nss_initgroups_ignoreusers  ALLLOCAL
Como se puede comprobar existe una diferencia con respecto a versiones anteriores: Tenemos que configurar como rama base para la búsqueda de cuentas de usuario la raíz del árbol, para que la búsqueda en profundidad incluya la rama de usuarios y cuentas de máquina y luego añadir un filtro. Esto anteriormente no era necesario porque se podían especificar varias ramas, pero en esta nueva versión ya no es posible y si las especificamos, sólo tomará la última que aparezca en el fichero. La verdad es que es un paso atrás.

Luego editar el fichero /etc/nsswitch.conf para cambiar la configuración de donde debemos buscar los usuarios y grupos:
passwd: files [NOTFOUND=continue] ldap
shadow: files
group: files [NOTFOUND=continue] ldap
Para aplicar estos cambios, tendremos que iniciar el demonio nslcd:
/etc/init.d/nslcd start
...y luego sí podremos ejecutar los comandos:
  • getent passwd, que nos mostrará un listado de todos los usuarios y máquinas locales y en LDAP
  • getent group, nos mostrará un listado de las cuentas de grupo locales y en el directorio,
  • id <LOGIN> nos mostrará información del usuario, que puede estar almacenada en LDAP

DBLinks desde MySQL hacia Oracle

En el anterior post veíamos cómo conectar Oracle hacia MySQL, aunque el procedimiento nos puede servir para conectar Oracle a cualquier base de datos (sqllite, Postgres, SQLServer, etc) a través de su correspondiente driver ODBC usando hg4odbc.

No siempre puede que Oracle sea el centro del universo del origen de la información de nuestra organización, y es posible que nuestra organización se encuentre usando Oracle de forma residual, sólo por tranquilizar y sosegar algunos de nuestros desarrolladores y administradores que añoran tiempos pasados creidos que fueron mejores, pero en realidad tengamos toda la lógica de nuestro negocio en MySQL: Puestos a suponer, echémosle imaginación.

En este escenario nos surgirá la pregunta: ¿cómo podemos vincular MySQL hacia otras bases de datos? ¿Existen DBLinks o algo parecido en MySQL?. La respuesta hasta el momento, es corta: MySQL sólo permite vincular tablas entre diferentes base de datos mediante el uso de Tablas Federadas, y esta funcionalidad sólo está disponible a partir de la versión 5.1 y para conectar a otras bases de datos MySQL exclusivamente. Para saber si nuestro servidor soporta tablas federadas, tendremos que conectarnos y ejecutar show plugin:

mysql> show plugin;
+------------+--------+----------------+---------+---------+
| Name | Status | Type | Library | License |
+------------+--------+----------------+---------+---------+
| binlog | ACTIVE | STORAGE ENGINE | NULL | GPL |
| partition | ACTIVE | STORAGE ENGINE | NULL | GPL |
| ARCHIVE | ACTIVE | STORAGE ENGINE | NULL | GPL |
| BLACKHOLE | ACTIVE | STORAGE ENGINE | NULL | GPL |
| CSV | ACTIVE | STORAGE ENGINE | NULL | GPL |
| FEDERATED | ACTIVE | STORAGE ENGINE | NULL | GPL |
| MEMORY | ACTIVE | STORAGE ENGINE | NULL | GPL |
| InnoDB | ACTIVE | STORAGE ENGINE | NULL | GPL |
| MyISAM | ACTIVE | STORAGE ENGINE | NULL | GPL |
| MRG_MYISAM | ACTIVE | STORAGE ENGINE | NULL | GPL |
+------------+--------+----------------+---------+---------+

Si no está activo este almacenamiento, tendremos que editar el fichero de configuración de nuestro servidor /etc/mysql/my.cnf y habilitar el soporte para tablas federadas en la sección [mysqld]. Cuando hayamos guardado los cambios, tendremos que reiniciar el servidor MySQL y volver a comprobar con show plugin.
[mysqld]
federated = ON

Como he escrito, el inconveniente a mi jucio de este soporte para tablas federadas es que sólo permite URLs que apuntan a bases de datos en MySQL, con formato:
CONNECTION='mysql://username:password@hostname:port/database/tablename'
CONNECTION='mysql://username@hostname/database/tablename'
CONNECTION='mysql://username:password@hostname/database/tablename'


Patrick Galbraith allá por el año 2008 desarrolló un plugin para MySQL que soportaba tablas federadas vía ODBC, pero parece que el desarrollo se quedó en su primera versión ALPHA, y ha quedado desmantenido. Yo no lo he probado, pero el propio Patrick demuestra que puede conectar a PostGres vía ODBC.
Cambiando de estrategia, Giuseppe Maxia escribió un interesante artículo titulado MySQL as universal server, donde se basaba en el módulo PERL DBIx::MyServer. Este módulo implementa un servidor y cliente MySQL, a modo de proxy, que usa la interfaz de clases DBI (DataBase Interface) de PERL para conectar a bases de datos remotas MYSQL. En el artículo Giuseppe Maxia, nos cuenta cómo aprovechar este módulo para conectar de forma remota a PostGres y SqlLite vía DBI. La idea es sencilla: Se implementa un pequeño demonio en PERL que use DBIx::MyServer y ofrezca un puerto de escucha para el protocolo MySQL, al que vincularemos nuestras tablas federadas, y luego internamente, este demonio reenviará las consultas y comandos a una base de datos remota usando su interfaz DBI.


El artículo es muy esclarecedor, pero tiene el problema que los scripts en los que se apoya no están accesibles y no podremos examinar cómo construía ese demonio que usaba DBIx::MyServer, para saber cuánto de bien funcionaba, así que... dependeremos de nuestras habilidades en PERL :P para conectarnos a Oracle.
Si retocar PERL no nos supone un problema, podemos atrevernos: El primer paso será, desde nuestro servidor MySQL en Ubuntu (por ejemplo) instalar el soporte DBI para PERL, ejecutando:
apt-get -y install libdbd-mysql libdbi-dev libdbi-perl libdbi1 \
libclass-dbi-perl libdbd-anydata-perl \
libdbix-simple-perl cpan

Además, debemos haber instalado correctamente los paquetes basic, sqlplus y sdk(devel) de Oracle Instant Client en nuestro servidor MySQL, para poder conectar a Oracle, y haber definido las siguientes variables de entorno en el fichero /etc/profile:
export ORACLE_HOME=/usr/lib/oracle/11.2/client32
export PATH=$ORACLE_HOME/bin:$PATH
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
export TNS_ADMIN=$ORACLE_HOME/network/admin

Obviamente, adaptaremos las rutas según nuestra instalación, y tendremos correctamente configurado nuestro fichero $TNS_ADMIN/tnsnames.ora, para conectar a los servidores Oracle que nos interese. Para ilustrar el ejemplo, conectaremos a la base de datos CASA, con el mallogrado usuario scott: Comprobar que podemos conectar desde el servidor MySQL...
sqlplus scott/tiger@CASA

Una vez que la conectividad hacia Oracle no es un problema desde nuestro servidor MySQL, procederemos a instalar DBIx::MyServer desde el repositorio CPAN:
cpan install DBIx::MyServer

...y después el soporte DBD para Oracle, también vía CPAN:
cpan install DBD::Oracle

Una vez instalado, extraeremos el servidor de prueba que viene con DBIx::MyServer ejecutando:
mkdir test
cd test
find ~/.cpan -name "myserver.*" -exec cp {} . \;

Esto nos copiará al menos dos ficheros:
  • myserver.pl, que implementa el servidor/cliente MySQL vía DBI y permite la traducción de sentencias SQL a través de un pequeño fichero de configuración. Esto es necesario porque el protocolo MySQL permite sentencias como SHOW TABLES o SHOW DATABASES, que en otros servidores de base de datos no tienen traducción, y de esta forma, podemos traducirlos en otras sentencias que no provoquen fallos internos.
  • myserver.conf, es el fichero de configuración que contiene expresiones PERL para realizar la traducción de sentencias SQL ON-THE-FLY, antes de enviarlas al servidor remoto vía DBI.

Podemos lanzar una primera prueba, para comprobar que tenemos todo bien. Para ello, lanzaremos la ejecución del demonio mediante:
cd test
perl myserver.pl --port=1234 \
--dsn="dbi:Oracle:CASA" \
--dsn_user="scott" --dsn_password="tiger" \
--conf=myserver.conf --debug

Este comando lanza el demonio Perl para que escuche conexiones MySQL por el puerto 1234, y las redirija hacia la conexión Oracle scott/tiger@CASA, además de indicarle que debe usar para traducir SQL el fichero myserver.conf y queremos debug. El que el demonio arranque con el sistema lo dejo al lector. Ahora, para probar la conexión usaremos nuestro cliente MySQL de toda la vida:
mysql -h 127.0.0.1 -P1234 -umyuser --password=myuser

Con este comando lanzamos una conexión MySQL al servidor local por el puerto 1234, con el usuario myuser y contraseña myuser: Este servidor MySQL, es el demonio en PERL que acabamos de lanzar. Una vez en la consola del cliente MySQL, podemos ejecutar el comando ORACLE para consultar las tablas:
mysql> select * from cat;
+------------+------------+
| TABLE_NAME | TABLE_TYPE |
+------------+------------+
| BONUS | TABLE |
| DEPT | TABLE |
| EMP | TABLE |
| SALGRADE | TABLE |
+------------+------------+
4 rows in set (0.13 sec)

Este comando (select * from cat) es propio de Oracle y no de MySQL, pero sin embargo estamos usando un cliente MySQL conectado a un servidor MySQL, aunque internamente este redirija las peticiones hacia un servidor Oracle. Ya tenemos casi configurado nuestro servidor DBIx::MyServer, sólo nos falta configurar alguna tabla federada en nuestro servidor MySQL, para que use los datos de Oracle. Para ello, crearemos una pequeña base de datos en MySQL con una tabla federada:
  1. Conectarnos a nuestra base de datos MySQL local, (la de nuestro servidor MySQL, no la del proxy este en PERL) y crear una nueva base de datos llamada oratest:
    # mysql -u root

    sql> create database oratest;
  2. Crear la tabla federeda en esta nueva base de datos...
    mysql> use oratest;

    mysql> drop table dept_scott;

    mysql> create table dept_scott(
    deptno integer(2) not null,
    dname varchar(14),
    loc varchar(14)
    ) engine = federated
    connection = 'mysql://myuser:myuser@127.0.0.1:1234/scott/dept'
    ;
    lo importante es definir los mismos campos que tenemos en Oracle y de la URL, el último token, que nos indica la tabla o vista hacia la que apuntamos, (en nuestro ejemplo DEPT).

Si ahora ejecutamos desde nuestro cliente MySQL, la consulta...
mysql> select * from dept_scott;

Comprobaremos cómo no nos devuelve ningún valor, pero sí que nos funcionarán los inserts en la tabla:
insert into dept_scott values(49,'PRUEBAS','MADRID');

Para saber porqué no nos funcionan los SELECT sobre la tabla federada, tenemos que examinar la salida del demonio PERL y ver qué consultas se le envían a Oracle. El primer problema es que la clase DBIx::MyServer se empeña en entrecomillar los nombres de los campos y tablas con el símbolo ` , y ello provoca fallo en Oracle. Editar el fichero de la clase /usr/local/share/perl/5.12.4/DBIx/MyServer/DBI.pm, y aplicar el siguiente parche/chapuza:
24a25,26
> $query_text=~s/`//eg;
> print "----SE ENVIA A ORACLE --->[$query_text]\n";

Luego, podemos comprobar cómo MySQL se empeña en añadir WHERE 1=0 a las consultas que envía a Oracle. Esto no devolverá ningún resultado en Oracle. Para quitarlo, editaremos el fichero myserver.conf con el que lanzamos el demonio, y añadiremos el siguiente bloque entre las expresiones de traducción:
{
match => qr{^(SELECT.+)WHERE 1=0}io,
rewrite => sub { "$_[1]" },
}

Esta expresión en PERL permite eliminar el WHERE 1=0 de los SELECT. Si seguimos depurando, comprobaremos que MySQL se empeña en consultar las estadisticas de la tabla remota, cuando se hace un SELECT, ejecutando el comando SHOW TABLE STATUS LIKE DEPT. Este comando no existe en Oracle y provocará un fallo. Para evitarlo, añadiremos una nueva expresión a nuestro fichero myserver.conf :
{
match => qr{^show table status like\s+'([^']+)'}io,
rewrite => sub { "select table_name as Name, 'BDB' as Type, 'Fixed' as Row_Format, num_rows as \"ROWS\", AVG_ROW_LEN as Avg_row_length, BLOCKS as Data_length , MAX_EXTENTS as Max_data_length, INITIAL_EXTENT as Index_length, INITIAL_EXTENT as Data_free, 100 as Auto_increment, (sysdate-10) as Create_time, sysdate as Update_time, (sysdate+10) as Check_time, '' as Create_options, '' as \"Comment\" from user_tables where table_name='". uc($_[1]) ."'"
}

Lo que hacemos es capturar los SHOW TABLE STATUS que envía MySQL y traducirlos por lo análogo en Oracle (consulta a la vista USER_TABLES). Si reiniciamos nuestro demonio PERL (matando el proceso con kill -9) y volvemos a iniciarlo para que tome los cambios que hemos realizado en myserver.conf, podremos hacer la prueba definitiva:
# mysql

mysql> use oratest;

mysql>

mysql> select * from dept_scott;
+--------+------------+----------+
| deptno | dname | loc |
+--------+------------+----------+
| 49 | PRUEBAS | MADRID |
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+--------+------------+----------+
5 rows in set (0.10 sec)

La gran ventaja de usar DBLinks de este modo o como relatamos en el anterior post, no es otra que la de integrar datos de nuestra organización almacenados en servidores independientes, pero de forma cómoda en SQL (SELECT, INNER JOINs, etc) sin apoyarnos en otros mecanismos externos como WebServices, CSVs, SQL-Loaders, etc, etc, que siempre pueden fallar y cuando lo hacen, nos cuesta mucho tiempo averiguar la causa del problema. Suerte!

DBLinks desde Oracle hacia MySQL

A menudo nos encontramos con organizaciones que tienen ya implantados diferentes entornos para el almacenamiento de la información. Es habitual encontrar una base de datos Oracle para las aplicaciones más importantes con la lógica del negocio, escritas en Oracle Forms y Java, y luego, otras bases de datos (MySQL, Postgres) asociadas a proyectos OpenSource que han decidido usar, porque cubren con total garantía nuevas necesidades que en otro caso serían muy costosas de desarrollar en tiempo y dinero.

En este escenario, suele aparecer la necesidad de vincular información desde el servidor Oracle hacia otras bases de datos como MySQL. Un ejemplo habitual es encontrar la base de datos de nuestros clientes en Oracle, mantenidos desde una aplicación Oracle Forms, y en un momento dado se quiere sincronizar los datos de contacto de estos clientes, con nuestra centralita Asterisk (que usa MySQL) de forma que, cuando la aplicación actualice los datos de algún cliente automáticamente estén disponibles para Asterisk.

Si las dos bases de datos fueran Oracle, podríamos resolverlo mediante un DBLink desde la base de datos de clientes hacia la de Asterisk y desarrollar un pequeño trigger PL/SQL para que cuando se actualicen ciertos datos, automáticamente se actualicen las tablas que lee Asterisk. Al estar este sobre MySQL, no podemos crear un DBLink. Afortunadamente Oracle contempla este escenario a través de Heterogeneus Service (HS) junto a Oracle Database Gateway for ODBC (hs4odbc).



Para configurar este servicio, tendremos que:

  1. Lo primero será comprobar que instalamos en nuestro servidor Oracle el servicio, chequeando que existe el ejecutable $ORACLE_HOME/bin/dg4odbc
  2. Lo siguiente será instalar el driver ODBC para MySQL, en nuestro servidor Oracle:
    yum install  unixODBC.x86_64 mysql-connector-odbc.x86_64 
  3. Ahora, en nuestro servidor MySQL, crearemos un base de datos de prueba, a la que conectar desde Oracle, (cualquiera sabe lo que podría hacernos en MySQL un administrador/desarrollador de Oracle)
    mysql> create database oracletest character set latin1;

    mysql> grant all privileges on oracletest.* to 'oracleconn'@'%'
    identified by 'demo' with grant option;

    mysql> flush privileges;

    mysql> exit;
    Es importante usar latin1 para la Base de datos, porque en caso de usar UTF8, tendremos problemas al acceder desde Oracle.
  4. Ahora, desde el servidor Oracle, probar a conectar al servidor MySQL, usando el cliente MySQL:
    mysql -h SERVIDOR_MYSQL  --user=oracleconn --password=demo oracletest 
    ... y una vez nos hayamos conectado, crearemos una pequeña tabla:
    create table demo (
    col1 integer,
    col2 date,
    col3 varchar(10),
    col4 varchar(10) character set utf8,
    col5 varbinary(10)) engine innodb;
    ... y aprovecharemos para insertar algún registro...
    insert into demo(col1, col2, col3, col4, col5)
    values(1, cast(now() as date), '0123456789', '0123456789', '0123456789');
  5. Ahora desde el servidor Oracle, editar el fichero ~oracle/.odbc.ini y configurar el acceso a MySQL vía ODBC, escribiendo el siguiente contenido:
    [ODBC Data Sources]
    test_mysql = MySQL ODBC Driver 5.1

    [test_mysql]
    Driver = /usr/lib64/libmyodbc3.so
    DATABASE = oracletest
    DESCRIPTION = Conexion a MySQL ODBC
    PORT = 3306
    SERVER = SERVIDOR_MYSQL# UID = oracleconn
    # PWD = demo

    CHARSET = latin1
    TRACEFILE = /tmp/myodbc-demodsn.trc
    TRACE = ON
  6. Crear el fichero $ORACLE_HOME/hs/admin/initMysql.ora. El nombre Mysql será el SID, y es un nombre arbitrario: Cualquiera que se cree, debe ser $ORACLE_HOME/hs/admin/init$SID.ora
    #
    # HS init parameters
    #

    HS_FDS_CONNECT_INFO=test_mysql
    HS_FDS_TRACE_LEVEL=0
    HS_FDS_SHAREABLE_NAME=/usr/lib64/libmyodbc3.so
    HS_LANGUAGE=AMERICAN_AMERICA.WE8ISO8859P15
    # HS_NLS_NCHAR=AL32UTF8
    #
    # ODBC specific environment variables
    #

    set ODBCINI=/home/oracle/.odbc.ini
    set LD_LIBRARY_PATH=/usr/lib64:/lib64:/usr/local/lib64:/u01/oracle/soft/product/11.1.0/db_1/lib:/u01/oracle/soft/product/11.1.0/db_1/oracm/lib:/lib:/usr/lib:/usr/local/lib

    #
    # Environment variables required for the non-Oracle system
    #

    set HOME=/home/oracle
  7. Añadir a $ORACLE_HOME/network/admin/listener.ora dentro del SID_LIST, el siguiente bloque SID_DESC:
        (SID_DESC =
    (ORACLE_HOME = /u01/oracle/soft/product/11.1.0/db_1)
    (SID_NAME = Mysql)
    (PROGRAM = dg4odbc)
    (ENVS ="LD_LIBRARY_PATH=/usr/lib64:/lib64:/usr/local/lib64:/u01/oracle/soft/product/11.1.0/db_1/lib:/u01/oracle/soft/product/11.1.0/db_1/oracm/lib:/lib:/usr/lib:/usr/local/lib")
    )
  8. Reiniciar el listener de Oracle...
    su - oracle
    lsnrctl stop
    lsnrctl start
  9. Ahora editar el fichero $ORACLE_HOME/network/admin/tnsnames.ora y añadir el siguiente bloque:
    DEMOMYSQL =
    (DESCRIPTION =
    (ADDRESS_LIST =
    (ADDRESS = (PROTOCOL = TCP)
    (HOST = localhost)
    (PORT = 1521)
    )
    )
    (CONNECT_DATA =
    (SID = Mysql)
    )
    (HS = OK)
    )
  10. Comprobar que está accesible...
    tnsping demoMYSQL
  11. Crear un DBLINK para acceder a MySQL desde nuestro servidor Oracle...
    su - oracle

    $ sqlplus / as sysdba;

    SQL> CREATE PUBLIC DATABASE LINK dbtestmysql
    CONNECT TO oracleconn
    IDENTIFIED BY demo
    USING 'DEMOMYSQL';
  12. .. y probar que funciona...
    su - oracle

    $ sqlplus / as sysdba;

    SQL> select * from demo@dbtestmysql ;
    Si estás usando Oracle 11.1.0.6 no te funcionará: Necesitas actualizar tu servidor a 11.1.0.7, porque una de los fallos que arregla tiene que ver con hs4odbc.

¿A cuántos targets iSCSI estoy conectado?

Siempre tengo que estar mirando la ayuda. Cuando ya tenemos un equipo Linux conectado a volúmenes iSCSI remotos, podemos ver si efectivamente se ha conectado o no mediante:


iscsiadm -m session

Curso de Nagios (I): Prólogo

Llevo ya varios años ofertando entre mis servicios de consultoría de sistemas, la puesta en marcha de sistemas de monitorización basados en herramientas OpenSource como Nagios, Cacti u Ossim. Nagios lo he visto crecer desde la versión 1.0 hasta la 3.2 y ahora, contemplo fascinado como el fork de Icinga mejora a su antecesor, sin quitarle la potencia y flexibilidad que teníamos de siempre. En todos estos años, he presenciado siempre la mismas diferentes historias con un mismo final, al conversar con los técnicos de las organizaciones:

  • Si, tenemos Nagios pero no lo usamos porque envía demasiados correos...
  • Si, tenemos Nagios pero sin notificaciones y sólo comprobamos que haga ping a los equipos, nadie lo mira
  • Oh si, claro, pero hay que saber mucho para mantenerlo bien, es un rollo
  • Ufff, Nagios está bien para monitorizar Linux, ¿pero qué hacemos con Windows?

... y el final que tienen todas estas historias en común, es siempre que acaban por apagar y desinstalar Nagios con un amargo sabor de boca sobre lo que és y para qué sirve, y claro, cuando llego vendiendo Nagios, pufff no veais lo que me lo que me cuesta :(. Al fín me he animado a escribir una serie de posts que, humildemente me he atrevido a llamar Curso de Nagios (ya se sabe que la ignorancia es muy atrevida), en el que intentaré ir mostrando uno de los caminos que podemos recorrer para configurarlo correctamente y descubrir su verdadera utilidad y potencia, evitar que lo desinstaleis, y contribuir modestamente con alguna de las deficiencias que creo que existen entorno a esta y otras herramientas similares:
  • De los libros que he leído, pienso que todos fallan en lo mismo: sólo llegan a ofrecernos recomendaciones sobre cómo configurarlo, sin proponer una configuración que luego poder adaptar a la realidad de nuestro servicio informático, e ir aprendiendo en el proceso. Reconozco que la curva de aprendizaje es muy elevada cuando empezamos a trabajar con Nagios, y los libros con los que he trabajado, ayudan pero no lo suficiente.
  • La gran mayoría de blogs que hablan sobre Nagios suelen quedarse en la superficie, y no nos explican qué preguntas debemos hacernos durante el proceso de configuración de Nagios, y por supuesto, no ofrecen respuestas.
  • Los servicios de informática están evolucionando en los últimos tiempos y ahora los técnicos tenemos que aprender las cosas de siempre a las que les han cambiado el nombre: ITIL, LeanIT, incidente, respuesta, proactividad, control del cambio, gestión de la capacidad, de la disponibilidad, etc.A veces, pienso que estas cosas se hacen para que los responsables de tomar las decisiones de compra y contratación, no les suene nada y decidan comprar esto que es lo más nuevo y lo mejor, y el futuro.

En resumen, entre tanta documentación técnica sobre Nagios, echo de menos una guía de consultoría que ayude a configurarlo paso a paso en entornos heterogéneos actuales de tamaño considerable (Windows, Linux, ESX, Novell, etc), con administradores que no se ven ni en la máquina del café, y en muchos casos mezclados con personal externo, que no se sienten parte de la organización, y consideran al administrador de Nagios el friki del Linux que se aburre, mientras ellos se dedican a administrar servidores, y todos dirigidos por responsables que pasan el tiempo pidiéndonos informes, y hablándonos de cosas como Itil, gestión de la disponibilidad, de la capacidad, etc.

Intentaré escribir esta guía en una serie de posts, de los que aún no sé el número al que llegaré ni la fecha, pero que espero que os sirva y podais adpatarla en vuestras configuraciones con éxito.

Multipath en OUL 5.7 con IBM Storwize V7000

Esta semana estoy configurando DeviceMapper Multipath en Oracle Unbreakable Linux 5 update 7, conectado a una SAN IBM Storwize V7000. El fichero /etc/multipath.conf que uso es el siguiente:

defaults {
user_friendly_names yes
udev_dir /dev
}

blacklist {
devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
devnode "^hd[a-z][[0-9]*]"
devnode "^cciss!c[0-9]d[0-9]*[p[0-9]*]"
}

devices {
device{
# Identificar la cabina (IBM v7000)
vendor "IBM*"
product "2145*"

# Como comprobar si los caminos estan arriba...
path_checker tur

# Como agrupar los caminos (por prioridad)
path_grouping_policy group_by_prio

# Como obtener los IDs de los discos...
getuid_callout "/sbin/scsi_id -g -u -s /block/%n"

# Como obtener las prioridades de los discos...
prio "alua"

# Algoritmo para presentar io al kernel por los caminos vivos
path_selector "round-robin 0"

# No reintente i/o por los caminos caido y haga fail immediate
no_path_retry fail

hardware_handler "1 alua"

# Le dice al demonio como manejar los caminos caídos...
failback immediate
}
}

multipaths {
multipath {
wwid 360050768028081874dc00000000000000
alias Lun_ibm
}
}

...y después de guardar los cambios del fichero, aplicar la configuración ejecutando la siguiente secuencia de pasos:
/etc/init.d/multipathd restart
multipath -F
multipath -v3

Al ejecutar el comando multipath -ll , deberíamos obtener una salida similar a la siguiente:
Lun_ibm (36005076802808187dc00000000000000) dm-18 IBM,2145
size=2.0G features='0' hwhandler='1 alua' wp=rw
|-+- policy='round-robin 0' prio=50 status=active
| |- 3:0:3:0 sdcc 69:0 active ready running
| `- 4:0:3:0 sdca 68:224 active ready running
`-+- policy='round-robin 0' prio=10 status=enabled
|- 3:0:2:0 sdcb 68:240 active ready running
`- 4:0:2:0 sdbz 68:208 active ready running