Desde hace tiempo tengo ganas de instalar un Web Application Firewall (WAF) y siempre tuve ModSecurity en la mira. Hoy con un poco de tiempo, decidí darle una chance y jugar un rato.
ModSecurity es un módulo para Apache que permite analizar los pedidos en distintas fases del protocolo HTTP. De esta forma, es posible procesar los pedidos antes de ser entregados a la aplicación subyacente (por ejemplo, escrita en PHP), o luego de que se completó la ejecución. Con este sistema es posible prevenir ataques de SQL Injection, XSS, LDAP Injection, File Injection, Session Fixation, etc.
Como es un módulo para Apache, es muy fácil de instalar, aunque requiere algunos pasos para su configuración. En este artículo explicaré cómo instalar, configurar y poner en funcionamiento ModSecurity. La explicación culmina con una configuración básica de ModSecurity trabajando en modo monitoreo, es decir, sólo loggea los eventos, no actúa de forma activa. Por supuesto que la verdadera utilidad de un WAF es la prevención de los ataques, pero para evitar falsos positivos que afecten la funcionalidad de los sites que se encuentren activos, es preferible comenzar en un modo pasivo e ir habilitando reglas a medida que se va conociendo el tráfico.
Instalar ModSecurity en debian, una vez que ya está instalado Apache, es tan simple como ejecutar:
apt-get install libapache2-modsecurity modsecurity-crs
El paquete modsecurity-crs contiene el conjunto de reglas core creado por OWASP. ModSecurity es simplemente el motor del firewall y todo firewall necesita reglas para funcionar. Las reglas creadas por OWASP abarcan todos los ataques más comunes de la web y por supuesto que son gratuitas de utilizar.
Una vez instalado el módulo, debe activarse ejecutando:
a2enmod mod-security
En el paquete de debian encontré un error al intentar cargar el módulo, dado que las librerías estaban mal referenciadas en el archivo .load. Para arreglar el problema, debe modificarse la línea Load del archivo /etc/apache2/mods-enabled/modsecurity.load para que quede
LoadFile /usr/lib/libxml2.so.2
en lugar de "LoadFile libxml2.so.2".
Para probar que el módulo está instalado correctamente, renombrar el archivo de configuración default:
mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
reiniciar Apache:
/etc/init.d/apache2 restart
y ejecutar nikto:
nikto -host http://localhost
Puede utilizarse cualquier otra herramienta que genere tráfico malicioso, nikto es solamente un ejemplo.
Con esto ya debería existir el archivo de auditoría /var/log/apache2/modsec_audit.log, donde deberían estar las entradas generadas por nikto.
Como explicaba al principio, por si solo ModSecurity no hace nada, necesita ser alimentado con reglas, para ello el paquete modsecurity-crs. Si ya está instalado, las reglas se encontrarán en /usr/share/modsecurity-crs/. Este directorio está dividido en 5 subdirectorios:
activated_rules
base_rules
experimental_rules
optional_rules
slr_rules
Los nombres explican por si mismos el contenido. La idea es colocar en activated_rules links simbólicos a las reglas que deseemos activar, como por ejemplo "/usr/share/modsecurity-crs/base_rules/modsecurity_crs_41_sql_injection_attacks.conf". Todo dependerá de qué deseen hacer, es una cuestión organizativa.
Para una configuración básica, simplemente incluiremos todo el directorio base_rules, en lugar de incluir activated_rules y agregar de a una las reglas. También debe incluirse el archivo de configuración modsecurity_crs_10_config.conf, que cuenta con seteos básicos. Esto se realiza editando el archivo "/etc/apache2/mods-enabled/mod-security.conf" y agregando las siguientes líneas:
Include "/usr/share/modsecurity-crs/modsecurity_crs_10_config.conf"
Include "/usr/share/modsecurity-crs/base_rules/*.conf"
es decir, el archivo debería quedar como a continuación:
<ifmodule security2_module="">
SecDataDir /var/cache/modsecurity
Include "/etc/modsecurity/*.conf"
Include "/usr/share/modsecurity-crs/modsecurity_crs_10_config.conf"
Include "/usr/share/modsecurity-crs/base_rules/*.conf"
</ifmodule>
Cada vez que realicen un cambio en la configuración deberán cargar nuevamente Apache. Claro que no es necesario reiniciarlo, también es posible hacer un reload más sutil y no matar las conexiones existentes:
/etc/init.d/apache2 graceful
Un error bastante común al ejecutar las reglas de OWASP es el exceso en el límite de la librería PCRE que viene por defecto en el archivo modsecurity.conf. El error contiene el siguiente mensaje:
Execution error - PCRE limits exceeded
Estos límites se configuran mediante las directivas SecPcreMatchLimit y SecPcreMatchLimitRecursion (modsecurity - Configuration Directives) y previenen que expresiones regulares mal formadas se salgan de control. Aumenten con cuidado este valor, tratando de que las reglas se ejecuten, pero sin asignar un número exorbitante. Por ejemplo, un valor que a mi me funcionó bien es 5000:
SecPcreMatchLimit 5000
SecPcreMatchLimitRecursion 5000
Con esto ya cuentan con ModSecurity habilitado y funcionando en modo "sniffer", dado que sólo revisa el contenido y loggea los ataques. A partir de aquí deberán analizarse dichos logs y decidir qué tipo de prevención aplicar. Hay que tener cuidado con los falsos positivos, dado que pueden influir en el correcto funcionamiento de los sites que intentamos proteger.
Una idea interesante es utilizar ModSecurity en conjunto con el módulo mod_proxy, es decir, utilizar Apache como un reverse Proxy y proteger con una sola instancia de ModSecurity varios web servers que se encuentren detrás.
Referencias
- ModSecurity Reference Manual
- Category: OWASP ModSecurity Core Rule Set Project
- mod_security on Apache
Etiquetas:
apache,
articulos,
debian,
GNU/Linux,
mod_security,
ModSecurity,
seguridad,
WAF,
Web Application Firewall
Hace algunos meses, debian testing, como muchas distribuciones, decidió actualizar sus paquetes para dar comienzo a la era Gnome 3. Yo siempre tuve más feeling con KDE que con Gnome, pero debido a lo "pesado" que se volvió KDE 4 en mi máquina, decidí darle una chance más a Gnome 2, y realmente me resultaba cómodo. El problema fue cuando actualicé a Gnome 3... resumiendo, mi sensación fue "oh, come on!!!".
Gnome 3, que utiliza la interfaz Gnome Shell, no sólo me resultó incómodo, sino que además extremadamente pesado. Intenté tunearlo de varias maneras, hasta incluso llegué a adaptarme un poco, pero después de un tiempo seguía teniendo esa sensación de "me molesta usar esto". Luego de darle una oportunidad a Enlightenment (esa historia la dejo para otro día), hoy volví a intentarlo con Gnome 3, pero con su versión classic.
Para los que no lo sepan, Gnome 3 viene con la premisa "la nueva versión te parece una patada en los huevos? no nos abandones, tenemos una versión más liviana y similar a Gnome 2", la cual denominan Classic (o Fall-Back Mode). Gnome Classic posee un entorno muy similar a Gnome 2, con barra de tareas, menú de inicio, botones para maximizar, y, tal vez lo más importante, una interfaz más liviana.
Para iniciar Gnome en su versión Classic, deberán elegir "Gnome Classic" en el apartado session del display manager que estén utilizando (GDM, KDM, XDM, etc). Esta opción aparece como si eligieran entre usar Gnome o KDE.
Una vez dentro de Gnome encontrarán el panel con el menu inicio clásico de Gnome 2 (Aplicaciones y Lugares), fecha y hora, y la tray. Abajo cuentan con una barra de tareas, algo muy extrañable en Gnome Shell. A partir de aquí hay que hacer un par de cambios para acercarse un poco más la versión 2.
Como paso inicial, recomiendo instalar la herramienta gnome-tweak-tool. Esta es una suerte de herramienta de configuración avanzada, la cual les permitirá configurar varios aspectos de Gnome 3, no configurables desde la herramienta de configuración básica. Con esta herramienta podrán permitir que el administrador de archivos administre el escritorio, lo cual se traduce a que vuelvan a aparecer los archivos e íconos que tuviesen en el escritorio, algo que en Gnome 3 no existe por defecto. Para lograrlo deberán dirigirse al apartado File Manager y poner en 1 la opción "Have file manager handle the desktop"
Con esta herramienta también podrán configurar varias opciones de visualización, como el estilo de las ventanas, el theme a utilizar, los íconos, las fuentes, etc.
Otras herramientas que ayudan mucho en la configuración son dconf-editor y gconf-editor. Gnome desde hace tiempo trae una especie de "registry" a lo Windows, la cual se puede acceder con estas herramientas. La versión 2 utilizaba gconf-editor, mientras que Gnome 3 usa dconf... el problema es que no acceden a los mismos valores, sino que poseen configuraciones separadas. Los programas nuevos ya vienen preparados para utilizar dconf, pero algunas configuraciones antiguas guardan sus datos con gconf. Utilizando estas herramientas es conveniente configurar la forma en que se hace foco en una ventana, y desactivar las alertas de poco espacio en disco.
A algunos puede molestarles tener que hacer click en la ventana para que obtenga el foco. Esto se puede cambiar en la opción apps -> metacity -> general -> focus_mode, utilizando gconf-editor. Las opciones son click (clickear para obtener foco), sloppy (la ventana obtiene el foco cuando pasamos el mouse encima) y mouse (la ventana obtiene foco cuando el mouse pasa encima y lo pierde cuando el mouse se va).
Aparentemente existe un bug en las alertas de disco lleno. Me sucedió que aún indicando al sistema que no vuelva a alertarme acerca de los discos llenos, lo seguía haciendo! Es posible desactivar completamente esta funcionalidad modificando el valor de org -> gnome -> settings-daemon -> plugins -> housekeeping -> active, utilizando dconf-editor.
Otra cosa muy útil es saber cómo agregar íconos de acceso rápido al panel. En todo panel un click derecho significa poder ver un listado con acceso a las propiedades, agregar, mover y quitar íconos... pero no en Gnome 3. No se quién habrá tenido la brillante idea de tener que pulstar el botón Alt antes de hacer click derecho para poder ver estas opciones. Con "Alt + Click derecho" podrán acceder todo lo mencionado y agregar paneles. Si quieren añadir un shortcut al panel, ejecutan Alt + Click derecho y luego eligen "Añadir al panel"... el resto es igual que antes.
Un tip adicional es cómo apagar/cerrar sesión ya que no existe un botón para tal fin en el menú ni en el panel. Todas estas acciones se encuentran al pulsar (botón izquierdo del mouse) el nombre del usuario, que se encuentra a la derecha del panel.
Otro faltante que encontré en las opciones de configuración es la edición de qué aplicaciones ejecutar al inicio. A pesar de que recorrí varias opciones en los paneles de configuración, no pude dar en la tecla, por lo que recurrí al comando gnome-session-properties.
Con esto, básicamente cubrí lo que necesitaba para asemejar el entorno a lo que venía utilizando en Gnome 2. Encontrar todo esto me llevó un buen rato de pruebas y búsquedas, así que espero les resulte útil =)
Algunos links que me ayudaron
- Add/Remove shortcut icon to the GNOME panel in Ubuntu Linux [video]
- How to customize the gnome classic panel
- Gnome 3 - This is the end, it seems
- Startup Applications in Gnome 3 [Fedora Forum]
- Gnome gconf docs: chapter 3 - Metacity
- Gnome 3 focus follows mouse
Gnome 3, que utiliza la interfaz Gnome Shell, no sólo me resultó incómodo, sino que además extremadamente pesado. Intenté tunearlo de varias maneras, hasta incluso llegué a adaptarme un poco, pero después de un tiempo seguía teniendo esa sensación de "me molesta usar esto". Luego de darle una oportunidad a Enlightenment (esa historia la dejo para otro día), hoy volví a intentarlo con Gnome 3, pero con su versión classic.
Para los que no lo sepan, Gnome 3 viene con la premisa "la nueva versión te parece una patada en los huevos? no nos abandones, tenemos una versión más liviana y similar a Gnome 2", la cual denominan Classic (o Fall-Back Mode). Gnome Classic posee un entorno muy similar a Gnome 2, con barra de tareas, menú de inicio, botones para maximizar, y, tal vez lo más importante, una interfaz más liviana.
Para iniciar Gnome en su versión Classic, deberán elegir "Gnome Classic" en el apartado session del display manager que estén utilizando (GDM, KDM, XDM, etc). Esta opción aparece como si eligieran entre usar Gnome o KDE.
Una vez dentro de Gnome encontrarán el panel con el menu inicio clásico de Gnome 2 (Aplicaciones y Lugares), fecha y hora, y la tray. Abajo cuentan con una barra de tareas, algo muy extrañable en Gnome Shell. A partir de aquí hay que hacer un par de cambios para acercarse un poco más la versión 2.
Como paso inicial, recomiendo instalar la herramienta gnome-tweak-tool. Esta es una suerte de herramienta de configuración avanzada, la cual les permitirá configurar varios aspectos de Gnome 3, no configurables desde la herramienta de configuración básica. Con esta herramienta podrán permitir que el administrador de archivos administre el escritorio, lo cual se traduce a que vuelvan a aparecer los archivos e íconos que tuviesen en el escritorio, algo que en Gnome 3 no existe por defecto. Para lograrlo deberán dirigirse al apartado File Manager y poner en 1 la opción "Have file manager handle the desktop"
Con esta herramienta también podrán configurar varias opciones de visualización, como el estilo de las ventanas, el theme a utilizar, los íconos, las fuentes, etc.
Otras herramientas que ayudan mucho en la configuración son dconf-editor y gconf-editor. Gnome desde hace tiempo trae una especie de "registry" a lo Windows, la cual se puede acceder con estas herramientas. La versión 2 utilizaba gconf-editor, mientras que Gnome 3 usa dconf... el problema es que no acceden a los mismos valores, sino que poseen configuraciones separadas. Los programas nuevos ya vienen preparados para utilizar dconf, pero algunas configuraciones antiguas guardan sus datos con gconf. Utilizando estas herramientas es conveniente configurar la forma en que se hace foco en una ventana, y desactivar las alertas de poco espacio en disco.
A algunos puede molestarles tener que hacer click en la ventana para que obtenga el foco. Esto se puede cambiar en la opción apps -> metacity -> general -> focus_mode, utilizando gconf-editor. Las opciones son click (clickear para obtener foco), sloppy (la ventana obtiene el foco cuando pasamos el mouse encima) y mouse (la ventana obtiene foco cuando el mouse pasa encima y lo pierde cuando el mouse se va).
Aparentemente existe un bug en las alertas de disco lleno. Me sucedió que aún indicando al sistema que no vuelva a alertarme acerca de los discos llenos, lo seguía haciendo! Es posible desactivar completamente esta funcionalidad modificando el valor de org -> gnome -> settings-daemon -> plugins -> housekeeping -> active, utilizando dconf-editor.
Otra cosa muy útil es saber cómo agregar íconos de acceso rápido al panel. En todo panel un click derecho significa poder ver un listado con acceso a las propiedades, agregar, mover y quitar íconos... pero no en Gnome 3. No se quién habrá tenido la brillante idea de tener que pulstar el botón Alt antes de hacer click derecho para poder ver estas opciones. Con "Alt + Click derecho" podrán acceder todo lo mencionado y agregar paneles. Si quieren añadir un shortcut al panel, ejecutan Alt + Click derecho y luego eligen "Añadir al panel"... el resto es igual que antes.
Un tip adicional es cómo apagar/cerrar sesión ya que no existe un botón para tal fin en el menú ni en el panel. Todas estas acciones se encuentran al pulsar (botón izquierdo del mouse) el nombre del usuario, que se encuentra a la derecha del panel.
Otro faltante que encontré en las opciones de configuración es la edición de qué aplicaciones ejecutar al inicio. A pesar de que recorrí varias opciones en los paneles de configuración, no pude dar en la tecla, por lo que recurrí al comando gnome-session-properties.
Con esto, básicamente cubrí lo que necesitaba para asemejar el entorno a lo que venía utilizando en Gnome 2. Encontrar todo esto me llevó un buen rato de pruebas y búsquedas, así que espero les resulte útil =)
Algunos links que me ayudaron
- Add/Remove shortcut icon to the GNOME panel in Ubuntu Linux [video]
- How to customize the gnome classic panel
- Gnome 3 - This is the end, it seems
- Startup Applications in Gnome 3 [Fedora Forum]
- Gnome gconf docs: chapter 3 - Metacity
- Gnome 3 focus follows mouse
Hasta ahora se mostró como utilizar OpenLDAP con autenticación anónima, es decir, sin autenticación (ver Instalar y configurar el directorio OpenLDAP y Autenticar con kerberos y almacenar información de usuarios con LDAP en GNU/Linux). Si bien este modelo puede servir en algunos casos donde el servicio de directorio es público, en general se desea que la información sea accesible sólo para ciertos usuarios. De las autenticaciones soportadas en LDAP, la más segura es SASL-GSSAPI con kerberos y sobre conexión encriptada.
En este artículo veremos cómo utilizar GSSAPI, y cómo definir los accesos al directorio en base a los usuarios autenticados con kerberos para obtener una estructura de usuarios centralizada con autenticación segura, similar a Active Directory.
Con esto cierro la serie de artículos Autenticación y administración centralizada de usuarios en GNU/Linux, la cual comencé a publicar en julio del año pasado y contempla todos los pasos necesarios para armar dicha estructura. En el artículo principal pueden encontrar los links a todos los artículos de la serie.
Autenticar con SASL-GSSAPI kerberos
Para poder utilizar SASL-GSSAPI en LDAP, es necesario instalar el API Cyrus SASL compilado para el kerberos de MIT, tanto en el servidor como en clientes:
Como vimos en la descripción de kerberos, cada servicio que desee kerberizarse deberá tener un principal en la base de datos. Entonces, para poder utilizar GSSAPI con kerberos necesitamos crear el principal correspondiente. Esto se logra utilizando kadmin o kadmin.local de la siguiente manera:
Una vez creado el principal y exportado a un archivo, hay que copiar el mismo al servidor donde se encuentre OpenLDAP y darle permiso de lectura/escritura al usuario openldap, que es el usuario con el que se ejecuta el servicio. Un buen lugar para ubicar el archivo es dentro del mismo directorio de ldap.
OpenLDAP mapea los principals de kerberos a DNs especiales, que tienen el siguiente formato:
uid=demasiadovivo,cn=DEMASIADOVIVO.ORG,cn=gssapi,cn=auth
es decir, para poder utilizar autenticación kerberos en LDAP, debe existir una entrada en el directorio con el formato mostrado.
Si están utilizando LDAP como directorio de usuarios, el formato de los DN para estos usuarios (uid=demasiadovivo,ou=People,dc=demasiadovivo,dc=org) es muy diferente al recién mostrado (uid=demasiadovivo,cn=DEMASIADOVIVO.ORG,cn=gssapi,cn=auth). Esta diferencia se debe a que una entrada es para usuarios de LDAP y el otro es para usuarios almacenados en LDAP. Una entrada es para autenticar quién es el usuario y qué puede hacer en el directorio, y la otra es para almacenar datos de un usuario.
En el caso de utilizar autenticación kerberos y tomar los datos del usuario de LDAP con NSS, ambos usuarios son el mismo usuario, entonces se necesita una forma de mapearlos.
Para esto, OpenLDAP provee reemplazo de nombres de autenticación utilizando expresiones regulares. Esto es, en lugar de tener que definir dos entradas para el mismo usuario, es posible definir la entrada con los datos del usuario y mapear el DN de autenticación al DN real. La forma de hacerlo es ingresando una regla authz-regexp en el archivo slapd.conf (/usr/share/slapd/slapd.conf en debian). La directiva utiliza dos parámetros:
Finalmente hay que reiniciar el servicio slapd para que tome los cambios:
Para probar que la autenticación funciona, adquirimos un token y ejecutamos un ldapwhoami:
CUIDADO: Asegúrense de que el servidor LDAP tiene resolución DNS inversa (registro PTR), caso contrario pueden encontrarse con un error como el siguiente:
Para ver los mecanismos de autenticación habilitados, se puede ejecutar:
Configurar permisos para acceder LDAP
Hasta ahora la configuración cuenta con autenticación GSSAPI-kerberos que es mucho mejor a tener autenticación simple, o no tener autenticación, pero todavía no se definió ningún rol de usuario que determine qué usuario puede hacer qué.
Por default OpenLDAP cuenta con el usuario admin que posee control total sobre el directorio, y se autentica utilizando autenticación simple con password. Además cuenta con un perfil público a través del cual cualquier persona, utilizando autenticación simple, puede leer los datos del directorio. Como se mostró en el artículo de instalación y configuración de LDAP, estos permisos se pueden observar ejecutando:
Como la autenticación la realizaremos a través de kerberos, una configuración interesante es permitir acceso de lectura de atributos no confidenciales a todo usuario autenticado mediante kerberos (en lugar de acceso anónimo), y acceso total a un grupo administrador, cuyos miembros sean usuarios autorizados y autenticados con kerberos.
Para lograr esta configuración, los pasos a realizar son los siguientes:
1. Eliminar usuario admin y accesos default
Por defecto, OpenLDAP provee acceso de escritura para el usuario admin y de lectura sin autenticación. En la configuración de un servicio centralizado de usuarios con kerberos, estos accesos son poco flexibles e inseguros, por lo tanto hay que eliminarlos, y luego plantear nuevos accesos que utilicen usuarios autenticados con kerberos.
Al utilizar la estructura kerberos, los atributos userPassword y shadowLastChange no son necesarios, por lo que se puede eliminar dicho acceso.
Para lograr este objetivo, crear el siguiente LDIF llamado delete-default.ldif:
y ejecutar el comando:
Se puede verificar que todo salió como se deseaba con el comando:
2. Crear grupo administrador del dominio
Como muchos sabrán, en Active Directory existe un grupo denominado Domain Admins, el cual tiene permiso de administración sobre todo el directorio y las máquinas unidas al dominio.
En el caso del dominio que se está configurando, es muy útil tener un grupo con las mismas características, que permita administrar el directorio. El siguiente LDIF denominado domain-root.ldif crea dicho grupo, cuyo único miembro (por ahora) es el usuario demasiadovivo:
Como todavía el único usuario con permiso de administración es admin, se debe utilizar el mismo con la herramienta ldapadd:
3. Otorgar control total al grupo domain_root sobre el directorio
Este punto es uno de los más complejos. Como vimos, OpenLDAP es muy flexible en cuanto a otorgar permisos y posee una facilidad para otorgar permisos por grupo (by group). El problema es que este se aplica a la clase groupOfNames y no sirve para posixGroup.
Se me ocurrieron varias alternativas para solucionar este problema:
Como se puede observar, opciones hay, pero ninguna satisfactoria del todo. Yo opté por la 4ta, dado que encontré una buena definición del permiso por parte de Pierangelo Masarati. De todas, creo que es la que menos complicaciones trae, al menos para este setup inicial. Si bien el acceso que defino a continuación tiene la misma base que el de Pierangelo, tuve que cambiar el DN del conjunto, porque el original no me funcionó.
Para el permiso definimos el siguiente LDIF denominado domain_root-access.ldif:
Al principio puede resultar confuso, pero analicemos un poco qué es lo que se está haciendo.
En la primer línea se indica que se está otorgando permiso a todo el dominio demasiadovivo.org. dn.subtree es el scope, e indica que se aplique a todo lo que contiene el dominio.
En la segunda línea se indica a quién se otorga el permiso y qué tipo de permiso (write). Esta es la parte más confusa.
Primero hay que entender qué es lo que se desea otorgar. Lo que debemos hacer es otorgar permiso de escritura a todos los miembros del grupo domain_root. Los miembros se obtienen del atributo memberUid, pero este atributo no es un DN, sino sólo el nombre del usuario. Como el permiso debe otorgarse a un DN, primero hay que armarlo.
El DN de un usuario consta de uid=,cn=gssapi,cn=auth. Lo único que tenemos es el nombre de usuario, por lo tanto, hay que armar el resto del string (los strings se concatenan con el signo +). Para hacerlo se utilizan los siguientes valores:
Para obtener el DN definitivo, se encierra todo entre paréntesis y se obtiene el atributo entryDN. El resultado es la lista de todos los usuarios que integran el grupo domain_root. Este conjunto se intersecta (operador &) con la base "user" que referencia al usuario autenticado actualmente. La intersección retornará el DN del usuario, si el usuario está en el grupo, o vacío si no lo está, otorgando o negando el permiso.
Para agregar este nuevo acceso, utilizar ldapmodify con el usuario administrador de la base de datos de configuración (cn=admin,cn=config):
4. Asignar acceso de lectura a usuarios autenticados
Llegado este punto, ya tenemos el grupo de administración del dominio, pero no los accesos de lectura para que los usuarios lean las entradas. Esto se logra definiendo el siguiente LDIF denominado read-access.ldif:
que se agrega con:
Configurar las máquinas cliente para usar GSSAPI
De la configuración anterior tenemos que ahora sólo se puede consultar al servidor LDAP si el cliente se autenticó previamente ante kerberos. Debido a esto, hay que configurar NSS-LDAP de forma especial, para que el servicio pueda consultar el directorio y obtener los datos del usuario que se está autenticando.
Hasta ahora, cuando un usuario se autentica ante el sistema, primero PAM valida las credenciales con kerberos, y luego NSS se conecta de forma anónima al servidor LDAP para traer los datos del usuario. Como ahora no es posible obtener datos de forma anónima, es necesario que NSS utilice GSSAPI con un ticket kerberos. El problema es qué ticket utilizar? dado que no podemos utilizar el ticket que se obtiene al validar al usuario.
Para solucionar este problema, es necesario realizar los siguientes pasos:
Crear principal para host y exportar clave en keytab
Para crear el principal del host maquina01 y exportarlo en el keytab maquina01.keytab, nuevamente hacemos uso de la herramienta kadmin.local (o kadmin si se conectan remoto), y ejecutamos lo siguiente:
Se utiliza -randkey para generar una clave aleatoria, dado que se utilizará directamente desde el archivo maquina01.keytab.
El paso anterior podría haberse realizado directamente desde el host maquina01, utilizando el comando kadmin y descargando la clave a un keytab local (/etc/krb5.keytab). En resultado es el mismo.
Configurar NSS-LDAP para utilizar kerberos en los clientes
Una vez generado el principal del host maquina01, hay que mover el keytab recién creado al host correspondiente. Un buen lugar para colocar el keytab es en /etc/krb5.keytab, que es el archivo default de kerberos. Por seguridad, el archivo debe poseer permisos 640:
Con la clave en su lugar, procedemos a configurar NSS-LDAP. En debian el archivo de configuración se encuentra en /etc/nslcd.conf. En dicho archivo se deben agregar las siguientes líneas:
sasl_mech gssapi
krb5_ccname FILE:/tmp/krb5cc_0
donde:
Una vez especificados los parámetros anteriores, nslcd comenzará a utilizar k5start para obtener el ticket del host antes de acceder a LDAP. Este demonio permite configurar algunos aspectos de cómo utilizar k5start a través del archivo /etc/default/nslcd. En el mismo se puede forzar la ejecución de k5start, como configurar la ubicación de la clave, el nombre del principal, y cada cuánto refrescar el ticket. La configuración por default es buena para la mayoría de los casos, aunque recomiendo agregar las siguientes líneas:
donde K5START_START="yes" fuerza el uso de k5start, y K5START_PRINCIPAL="host/maquina01.dvpem.org" indica cuál es el nombre del principal.
Si todavía no tienen instalado kstart, pueden hacerlo con:
Al finalizar la configuración, reiniciar el demonio nslcd para que tome los cambios:
Para probar, simplemente realizar un login con una cuenta que esté definida en LDAP. También pueden ver que se consulta LDAP al utilizar el comando:
En caso de que no esté funcionando y debamos revisar la configuración, primero detener el demonio nscd, dado que este cachea los resultados de las consultas, y por lo tanto, el resultado que se obtiene puede no ser el real:
Luego revisar los siguientes logs:
Otra ayuda es observar en el cliente si el proceso login se conecta al servidor LDAP al momento de autenticar, con el siguiente comando:
donde:
Referencias
- OpenLDAP - 15. Using SASL
- LDAP, Kerberos 5, SASL and Passwords
- Debian OpenLDAP with Kerberos Authentication
- Red Hat Documentation - 10.2.6. Setting Up Kerberos Authentication
- OpenLDAP - 5. Configuring slapd
- LDAP Administration Guide
- OpenLDAP FAQ - Sets in Access Controls
- Integrated Kerberos-OpenLDAP client on Debian lenny
- Configuring LDAP Authentication
- FreeBSD Forum - nss_ldap sasl gssapi authentication?
- RedHat mailing list - nss_ldap using sasl with gssapi. Kerberos credentials cache problem[Scanned]
En este artículo veremos cómo utilizar GSSAPI, y cómo definir los accesos al directorio en base a los usuarios autenticados con kerberos para obtener una estructura de usuarios centralizada con autenticación segura, similar a Active Directory.
Con esto cierro la serie de artículos Autenticación y administración centralizada de usuarios en GNU/Linux, la cual comencé a publicar en julio del año pasado y contempla todos los pasos necesarios para armar dicha estructura. En el artículo principal pueden encontrar los links a todos los artículos de la serie.
Autenticar con SASL-GSSAPI kerberos
Para poder utilizar SASL-GSSAPI en LDAP, es necesario instalar el API Cyrus SASL compilado para el kerberos de MIT, tanto en el servidor como en clientes:
# apt-get install libsasl2-modules-gssapi-mit
Como vimos en la descripción de kerberos, cada servicio que desee kerberizarse deberá tener un principal en la base de datos. Entonces, para poder utilizar GSSAPI con kerberos necesitamos crear el principal correspondiente. Esto se logra utilizando kadmin o kadmin.local de la siguiente manera:
# kadmin.localEl siguiente paso es guardar la clave del principal recién creado en un archivo (keytab), el cual luego se utilizará desde OpeLDAP para la autenticación:
Authenticating as principal root/admin@DEMASIADOVIVO.ORG with password.
kadmin.local: addprinc -randkey ldap/ldap01.demasiadovivo.org@DEMASIADOVIVO.ORG
WARNING: no policy specified for ldap/ldap01.demasiadovivo.org@DEMASIADOVIVO.ORG; defaulting to no policy
Principal "ldap/ldap01.demasiadovivo.org@DEMASIADOVIVO.ORG" created.
donde ldap01.demasiadovivo.org es la dirección del servidor ldap y -randkey permite generar un password random.
kadmin.local: ktadd -k /root/ldap.keytab ldap/ldap01.demasiadovivo.orgSi no especifican el nombre del archivo (-k), la clave se escribe en /etc/krb5.keytab. Esto no es aconsejable porque este archivo será utilizado por OpenLDAP, para lo cual debemos darle permiso de lectura/escritura, y al hacerlo, le damos acceso a todas las claves que se encuentren en el. Por ello, es mejor separar la clave de OpenLDAP en un archivo propio.
Entry for principal ldap/ldap01.demasiadovivo.org with kvno 5, encryption type AES-256 CTS mode with 96-bit SHA-1 HMAC added to keytab WRFILE:/root/ldap.keytab.
Entry for principal ldap/ldap01.demasiadovivo.org with kvno 5, encryption type ArcFour with HMAC/md5 added to keytab WRFILE:/root/ldap.keytab.
Entry for principal ldap/ldap01.demasiadovivo.org with kvno 5, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/root/ldap.keytab.
Entry for principal ldap/ldap01.demasiadovivo.org with kvno 5, encryption type DES cbc mode with CRC-32 added to keytab WRFILE:/root/ldap.keytab.
Una vez creado el principal y exportado a un archivo, hay que copiar el mismo al servidor donde se encuentre OpenLDAP y darle permiso de lectura/escritura al usuario openldap, que es el usuario con el que se ejecuta el servicio. Un buen lugar para ubicar el archivo es dentro del mismo directorio de ldap.
/etc/ldap# chown openldap:openldap ldap.keytabA continuación hay que editar el archivo /etc/default/slapd para indicar donde se encuentra el keytab para utilizar con SASL, ya que por default intentará usar /etc/krb5.keytab. Esto se hace editando o agregando la siguiente línea:
/etc/ldap# chmod 750 ldap.keytab
export KRB5_KTNAME=/etc/ldap/ldap.keytab
OpenLDAP mapea los principals de kerberos a DNs especiales, que tienen el siguiente formato:
uid=<nombre de="" usuario="">,cn=<realm>,cn=<mecanismo>,cn=autho
<nombre de="" usuario=""><realm><mecanismo>
<nombre de="" usuario=""><realm><mecanismo>
<nombre de="" usuario=""><realm><mecanismo> uid=<nombre de="" usuario="">,cn=<mecanismo>,cn=authPor ejemplo, si el principal es demasiadovivo@DEMASIADOVIVO.ORG, éste se mapeará con el DN:
<nombre de="" usuario=""><realm><mecanismo><nombre de="" usuario=""><mecanismo>
uid=demasiadovivo,cn=DEMASIADOVIVO.ORG,cn=gssapi,cn=auth
es decir, para poder utilizar autenticación kerberos en LDAP, debe existir una entrada en el directorio con el formato mostrado.
Si están utilizando LDAP como directorio de usuarios, el formato de los DN para estos usuarios (uid=demasiadovivo,ou=People,dc=demasiadovivo,dc=org) es muy diferente al recién mostrado (uid=demasiadovivo,cn=DEMASIADOVIVO.ORG,cn=gssapi,cn=auth). Esta diferencia se debe a que una entrada es para usuarios de LDAP y el otro es para usuarios almacenados en LDAP. Una entrada es para autenticar quién es el usuario y qué puede hacer en el directorio, y la otra es para almacenar datos de un usuario.
En el caso de utilizar autenticación kerberos y tomar los datos del usuario de LDAP con NSS, ambos usuarios son el mismo usuario, entonces se necesita una forma de mapearlos.
Para esto, OpenLDAP provee reemplazo de nombres de autenticación utilizando expresiones regulares. Esto es, en lugar de tener que definir dos entradas para el mismo usuario, es posible definir la entrada con los datos del usuario y mapear el DN de autenticación al DN real. La forma de hacerlo es ingresando una regla authz-regexp en el archivo slapd.conf (/usr/share/slapd/slapd.conf en debian). La directiva utiliza dos parámetros:
authz-regexp <patron buscado=""> <patron de="" reemplazo="">Entonces, ingresando la siguiente regla, se tiene el reemplazo buscado:
authz-regexp
uid=([^,]*),cn=DEMASIADOVIVO.ORG,cn=gssapi,cn=auth
uid=$1,cn=People,dc=demasiadovivo,dc=org
# /etc/init/slapd restart
$ kinit demasiadovivo
Password for demasiadovivo@DEMASIADOVIVO.ORG:
$ ldapwhoami
SASL/GSSAPI authentication started
SASL username: demasiadovivo@DEMASIADOVIVO.ORG:
SASL SSF: 56
SASL data security layer installed.
dn:uid=demasiadovivo,cn=gssapi,cn=auth
Cannot determine realm for numeric host address
$ ldapsearch -s base -b "" supportedSASLMechanisms
Configurar permisos para acceder LDAP
Hasta ahora la configuración cuenta con autenticación GSSAPI-kerberos que es mucho mejor a tener autenticación simple, o no tener autenticación, pero todavía no se definió ningún rol de usuario que determine qué usuario puede hacer qué.
Por default OpenLDAP cuenta con el usuario admin que posee control total sobre el directorio, y se autentica utilizando autenticación simple con password. Además cuenta con un perfil público a través del cual cualquier persona, utilizando autenticación simple, puede leer los datos del directorio. Como se mostró en el artículo de instalación y configuración de LDAP, estos permisos se pueden observar ejecutando:
# slapcat -b cn=config -a olcDatabase={1}hdb
Para lograr esta configuración, los pasos a realizar son los siguientes:
1. Eliminar al usuario admin y accesos default.
2. Crear un grupo administrador de dominio.
3. Otorgar control total al grupo del paso anterior (como suele ser el grupo Domain Admins en Active Directory).
4. Asignar acceso de lectura a usuarios autenticados.
1. Eliminar usuario admin y accesos default
Por defecto, OpenLDAP provee acceso de escritura para el usuario admin y de lectura sin autenticación. En la configuración de un servicio centralizado de usuarios con kerberos, estos accesos son poco flexibles e inseguros, por lo tanto hay que eliminarlos, y luego plantear nuevos accesos que utilicen usuarios autenticados con kerberos.
Al utilizar la estructura kerberos, los atributos userPassword y shadowLastChange no son necesarios, por lo que se puede eliminar dicho acceso.
Para lograr este objetivo, crear el siguiente LDIF llamado delete-default.ldif:
dn: olcDatabase={1}hdb,cn=config
changetype: modify
#
# Eliminar acceso al usuario admin
delete: olcAccess
olcAccess: {2}to *
by self write
by dn="cn=admin,dc=dvpem,dc=org" write
by * read
-
# Eliminar acceso de lectura sin autenticacion
delete: olcAccess
olcAccess: {1}to dn.base=""
by * read
-
# Eliminar accesos a los atributos password de los usuarios
delete: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange
by self write
by anonymous auth
by dn="cn=admin,dc=dvpem,dc=org" write
by * none
-
# Prohibir acceso al atributo password
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange
by * none
-
# Eliminar el usuario admin
delete: olcRootPW
-
$ ldapmodify -f delete-default.ldif -x -D cn=admin,cn=config -W
# slapcat -b cn=config -a olcDatabase={1}hdb
2. Crear grupo administrador del dominio
Como muchos sabrán, en Active Directory existe un grupo denominado Domain Admins, el cual tiene permiso de administración sobre todo el directorio y las máquinas unidas al dominio.
En el caso del dominio que se está configurando, es muy útil tener un grupo con las mismas características, que permita administrar el directorio. El siguiente LDIF denominado domain-root.ldif crea dicho grupo, cuyo único miembro (por ahora) es el usuario demasiadovivo:
dn: cn=domain_root,ou=Group,dc=demasiadovivo,dc=org
cn: domain_root
gidNumber: 1000
objectClass: top
objectClass: posixGroup
memberUid: demasiadovivo
$ ldapadd -x -D cn=admin,cn=config -W -f domain-root.ldif
Enter LDAP Password:
adding new entry "cn=domain_root,ou=Group,dc=demasiadovivo,dc=org"
3. Otorgar control total al grupo domain_root sobre el directorio
Este punto es uno de los más complejos. Como vimos, OpenLDAP es muy flexible en cuanto a otorgar permisos y posee una facilidad para otorgar permisos por grupo (by group). El problema es que este se aplica a la clase groupOfNames y no sirve para posixGroup.
Se me ocurrieron varias alternativas para solucionar este problema:
1- Utilizar groupOfNames y mapear los request NSS_LDAP con una expresión regular que sustituya los pedidos, como se mostró en la sección anterior.
2- Editar el esquema de posixGroup para agregar el atributo member.
3- Utilizar la definición de posixGroup del RFC 2307bis, la cual expiró y nunca se aprobó. Esta RFC incluye el campo member en la definición.
4- Otorgar permisos basados en sets.
5- Cambiar el formato de las consultas LDAP de la librería NSS_LDAP para que utilice groupOfNames.
Para el permiso definimos el siguiente LDIF denominado domain_root-access.ldif:
dn: olcDatabase={1}hdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to dn.subtree="dc=demasiadovivo,dc=org"
by set="([uid=] + ([cn=domain_root,ou=Group,dc=demasiadovivo,dc=org])/memberUid + [,cn=gssapi,cn=auth])/entryDN & user" write
En la primer línea se indica que se está otorgando permiso a todo el dominio demasiadovivo.org. dn.subtree es el scope, e indica que se aplique a todo lo que contiene el dominio.
En la segunda línea se indica a quién se otorga el permiso y qué tipo de permiso (write). Esta es la parte más confusa.
Primero hay que entender qué es lo que se desea otorgar. Lo que debemos hacer es otorgar permiso de escritura a todos los miembros del grupo domain_root. Los miembros se obtienen del atributo memberUid, pero este atributo no es un DN, sino sólo el nombre del usuario. Como el permiso debe otorgarse a un DN, primero hay que armarlo.
El DN de un usuario consta de uid=
[uid=], para agregar el string uid= ([cn=domain_root,ou=Groups,dc=demasiadovivo,dc=org])/memberUid para agregar el nombre de usuario de los miembros del grupo. Se utilizan los parentesis porque los mismos indican precedencia, de esta forma se evalúa primero el grupo y luego se obtienen los miembros. [,cn=gssapi,cn=auth] para agregar la parte restante del DN
Para agregar este nuevo acceso, utilizar ldapmodify con el usuario administrador de la base de datos de configuración (cn=admin,cn=config):
$ ldapmodify -f domain_root-access.ldif -x -D cn=admin,cn=config -W
4. Asignar acceso de lectura a usuarios autenticados
Llegado este punto, ya tenemos el grupo de administración del dominio, pero no los accesos de lectura para que los usuarios lean las entradas. Esto se logra definiendo el siguiente LDIF denominado read-access.ldif:
dn: olcDatabase={1}hdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {1}to *
by users read
by * none
$ ldapmodify -f read-access.ldif -x -D cn=admin,cn=config -W
Configurar las máquinas cliente para usar GSSAPI
De la configuración anterior tenemos que ahora sólo se puede consultar al servidor LDAP si el cliente se autenticó previamente ante kerberos. Debido a esto, hay que configurar NSS-LDAP de forma especial, para que el servicio pueda consultar el directorio y obtener los datos del usuario que se está autenticando.
Hasta ahora, cuando un usuario se autentica ante el sistema, primero PAM valida las credenciales con kerberos, y luego NSS se conecta de forma anónima al servidor LDAP para traer los datos del usuario. Como ahora no es posible obtener datos de forma anónima, es necesario que NSS utilice GSSAPI con un ticket kerberos. El problema es qué ticket utilizar? dado que no podemos utilizar el ticket que se obtiene al validar al usuario.
Para solucionar este problema, es necesario realizar los siguientes pasos:
1. crear un principal por cada host,
2. exportar la clave de cada principal a keytabs,
3. mover cada keytab al host correspondiente,
4. configurar NSS de cada host para utilizar kerberos y realizar la autenticación con el keytab correspondiente.
Crear principal para host y exportar clave en keytab
Para crear el principal del host maquina01 y exportarlo en el keytab maquina01.keytab, nuevamente hacemos uso de la herramienta kadmin.local (o kadmin si se conectan remoto), y ejecutamos lo siguiente:
kadmin.local: addprinc -randkey host/maquina01.dvpem.org@DVPEM.ORG
WARNING: no policy specified for host/maquina01.dvpem.org@DVPEM.ORG; defaulting to no policy
Principal "host/maquina01.dvpem.org@DVPEM.ORG" created.
kadmin.local: ktadd -k /root/maquina01.keytab host/maquina01.dvpem.org
Entry for principal host/maquina01.dvpem.org with kvno 2, encryption type AES-256 CTS mode with 96-bit SHA-1 HMAC added to keytab WRFILE:/root/maquina01.keytab.
Entry for principal host/maquina01.dvpem.org with kvno 2, encryption type ArcFour with HMAC/md5 added to keytab WRFILE:/root/maquina01.keytab.
Entry for principal host/maquina01.dvpem.org with kvno 2, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/root/maquina01.keytab.
Entry for principal host/maquina01.dvpem.org with kvno 2, encryption type DES cbc mode with CRC-32 added to keytab WRFILE:/root/maquina01.keytab.
El paso anterior podría haberse realizado directamente desde el host maquina01, utilizando el comando kadmin y descargando la clave a un keytab local (/etc/krb5.keytab). En resultado es el mismo.
Configurar NSS-LDAP para utilizar kerberos en los clientes
Una vez generado el principal del host maquina01, hay que mover el keytab recién creado al host correspondiente. Un buen lugar para colocar el keytab es en /etc/krb5.keytab, que es el archivo default de kerberos. Por seguridad, el archivo debe poseer permisos 640:
# chmod 640 /etc/krb5.keytab
sasl_mech gssapi
krb5_ccname FILE:/tmp/krb5cc_0
donde:
- sasl_mech indica el mecanismo SASL a utilizar (GSSAPI)
- krb5_ccname informa donde se encuentra el ticket kerberos
K5START_START="yes"
K5START_PRINCIPAL="host/maquina01.dvpem.org"
Si todavía no tienen instalado kstart, pueden hacerlo con:
# apt-get install kstart
# /etc/init.d/nslcd restart
$ getent passwd
# /etc/init.d/nscd stop
- en el cliente:
/var/log/auth.log
- en el servidor:
/var/log/debug
# lsof -r 2 -i
-r 2 pone lsof en modo repetición. De esta forma lsof lista lo seleccionado por otros argumentos, espera 2 segundos y vuelve a listar.
-i lista los procesos que estan escuchando en sockets tcp o udp.
Referencias
- OpenLDAP - 15. Using SASL
- Red Hat Documentation - 10.2.6. Setting Up Kerberos Authentication
- OpenLDAP - 5. Configuring slapd
- LDAP Administration Guide
- OpenLDAP FAQ - Sets in Access Controls
- Integrated Kerberos-OpenLDAP client on Debian lenny
- Configuring LDAP Authentication
- RedHat mailing list - nss_ldap using sasl with gssapi. Kerberos credentials cache problem[Scanned]
Etiquetas:
administracion,
articulos,
GNU/Linux,
GSSAPI,
kerberos,
LDAP,
MIT Kerberos,
OpenLDAP,
SASL,
seguridad
Desde hace varias semanas vengo peleando con OSSIM y el plugin que utiliza para parsear logs de arpwatch. En el artículo anterior les conté cómo modifiqué el código de arpwatch para que reporte sólo el cambio de MAC de hosts específicos, y no todos los cambios de MACs. Ahora mi meta era hacer que OSSIM me envíe un mail cada vez que detecte el cambio de MAC de estos hosts.
El envío de este tipo de alertas por mail es muy simple y lo describiré luego. Primero veamos qué información brinda el plugin de arpwatch y entenderán por qué tuve que crear un nuevo plugin.
El plugin original (/etc/ossim/agent/plugins/arpwatch.cfg o /etc/ossim/agent/plugins/arpwatch_eth0.cfg) utiliza el tipo de evento host-mac-event, un tipo de evento que posee un conjunto fijo de atributos y no se pueden agregar, ni quitar, ni modificar, a menos que modifiquemos el código C del servidor OSSIM. Los atributos que brinda este tipo de evento, según la documentación oficial, son:
Entonces, si no se puede utilizar en las acciones, no es posible enviar mails que incluyan la MAC de origen en ellos, algo que, al menos para mi, es de mucha utilidad.
Supongan que arman una política que les envíe una alerta por mail cada vez que un host importante cambia su MAC. Con el plugin original sólo tendrían la nueva MAC y deberían ir a revisar la larga lista de eventos SIEM para encontrar cual era la MAC anterior y ver la diferencia.
Nuevo plugin para arpwatch
En fin. Para arreglar esto, definí un nuevo plugin para arpwatch, denominado arpwatch_new.cfg (oh si, muy original):
Para habilitar este nuevo plugin, hay que ingresarlo en las tablas plugin y plugin_sid de la base de datos OSSIM. Esto se hace a través del siguiente archivo sql (arpwatch_new.sql):
cat arpwatch_new.sql | mysql -u root -p ossim
Luego deben modificar la configuración del agente OSSIM para que incluya este plugin, es decir, comentar la línea del plugin de arpwatch anterior y agregar el nuevo en el archivo /etc/ossim/agent/config.cfg, en la sección plugins:
#arpwatch_eth0=/etc/ossim/agent/plugins/arpwatch_eth0.cfg
arpwatch_new=/etc/ossim/agent/plugins/arpwatch_new.cfg
Finalmente reinicien los servicios de ossim server y agent:
/etc/init.d/ossim-server restart
/etc/init.d/ossim-agent restart
y verifiquen que se encuentre cargado en la pestaña Collections de la interfaz web.
Reporte de cambios por mail
Con el nuevo plugin ya es posible crear una política que ejecute una acción que envíe mails. Las políticas y las acciones se pueden crear fácilmente desde la interfaz web. Para hacerlo, hay que dirigirse a la opción Intelligence -> Policy & Actions.
Primero crearemos la acción que ejecutará el envío de mail, para luego poder seleccionarla en la política. La acción se crea desde la pestaña Actions y dando al botón New. Una acción puede ser la creación de un ticket, o, como deseamos nosotros, el envío de un mail. Este tipo se elige en el desplegable Type. Es obligatorio colocar una descripción de la acción.
El resto de los campos son muy intuitivos, el originario del mail, el destinatario, el asunto y el mensaje. Se pueden utilizar palabras claves especiales tanto en el contenido como en el asunto del mail, las cuales OSSIM reemplazará por el valor correspondiente. En la parte superior de la acción estan los atributos elegibles, entre los que se cuenta con las IPs de orígen y destino, puertos, protocolos y varios campos más. Para el caso en cuestión, lo importante es que el reporte contenga la IP del host y las MACs anterior y nueva, las cuales se encuentran en los atributos userdata1 y userdata3, según lo definimos en el plugin.
La política se crea de forma bastante intuitiva, en la pestaña Policy, dando New y siguiendo los pasos. Los primeros pasos describen atributos que deben tener los paquetes para que esta política se aplique, como IPs orígen y destino, y Ports destino.
Uno de los pasos relevantes es la definición del "DS Groups", donde se elige el grupo de plugins a tener en cuenta a la hora de analizar los paquetes. OSSIM trae algunos grupos de plugins ya armados, pero para nuestro caso, hay que insertar uno nuevo, dandole al link "Insert new DS Group?". En este punto hay que ingresar un nombre y una descripción, acompañado por el plugin a utilizar, que se selecciona dando en el +
En el listado debería aparecer el nuevo plugin que creamos anteriormente con ID 51512. Una vez seleccionado es posible elegir que tipos de evento, del mencionado plugin, deben tenerse en cuenta. Es así como podemos reportar sólo eventos de cambio de MAC y no cuando se ve un host nuevo. El tipo de evento que nos interesa es el que tiene el identificador 2.
Cuando el grupo DS ya está ingresado, es posible seleccionarlo y continuar con la definición de la política.
El otro paso relevante es la elección de las consecuencias que tiene la política. Es decir, qué acción tomar cuando detectamos un evento que cumple con las características descriptas en la política. Para este caso, elegiremos la acción que creamos anteriormente, y además podríamos elevar la prioridad del evento a 5.
En fin
Con estos cambios ya es posible recibir por mail reportes de cambios de MACs en hosts importantes, que incluyan la MAC anterior y la nueva, gracias a la nueva definición del plugin y la política creada.
Referencias
- OSSIM Sensor - The Agent
- Creating a Custom OSSIM 3 policy
El envío de este tipo de alertas por mail es muy simple y lo describiré luego. Primero veamos qué información brinda el plugin de arpwatch y entenderán por qué tuve que crear un nuevo plugin.
El plugin original (/etc/ossim/agent/plugins/arpwatch.cfg o /etc/ossim/agent/plugins/arpwatch_eth0.cfg) utiliza el tipo de evento host-mac-event, un tipo de evento que posee un conjunto fijo de atributos y no se pueden agregar, ni quitar, ni modificar, a menos que modifiquemos el código C del servidor OSSIM. Los atributos que brinda este tipo de evento, según la documentación oficial, son:
host: IP del host que cambio su MACSi prestan atención, pueden ver que la MAC anterior sólo figura en el atributo log. Cuál es el problema? que el atributo log no se puede utilizar en las acciones (y presupongo que tampoco en las correlaciones, pero no puedo asegurarlo).
mac: nueva dirección MAC en hexadecmal
vendor: fabricante de la placa
sensor
interface
date
plugin_id: el ID del plugin, el cual es siemrpe 1512 (arpwatch)
plugin_sid: sin importancia ya que el servidor OSSIM asignará el que corresponda
log: contiene una copia del cambio de MAC
userdata1: copia de la nueva dirección MAC nueva
userdata2: copia del nombre fabricante
Entonces, si no se puede utilizar en las acciones, no es posible enviar mails que incluyan la MAC de origen en ellos, algo que, al menos para mi, es de mucha utilidad.
Supongan que arman una política que les envíe una alerta por mail cada vez que un host importante cambia su MAC. Con el plugin original sólo tendrían la nueva MAC y deberían ir a revisar la larga lista de eventos SIEM para encontrar cual era la MAC anterior y ver la diferencia.
Nuevo plugin para arpwatch
En fin. Para arreglar esto, definí un nuevo plugin para arpwatch, denominado arpwatch_new.cfg (oh si, muy original):
[DEFAULT]Como verán, cambié el identificador a 51512 para no colisionar con el anterior (1512) y utilicé el tipo de evento genérico "event", que permite flexibilidad en los atributos a utilizar. Gracias a esto, ahora puedo ver la MAC origen en el atributo userdata3, mientras que la nueva MAC está en userdata1, como antes.
plugin_id=51512
[arpwatch-changed-address]
event_type=event
src_ip={resolv($1)}
host={$1}
interface={$4}
mac={$2}
userdata1={$2}
userdata3={$3}
plugin_sid=2
regexp="arpwatch.*?: changed ethernet address (\IPV4) (\MAC) \((\MAC)\) (\S+)"
vendor=unknown
[arpwatch-flipflop]
event_type=event
src_ip={resolv($1)}
host={$1}
interface={$4}
mac={$2}
userdata1={$2}
userdata3={$3}
plugin_sid=2
regexp="arpwatch.*?: flip flop (\IPV4) (\MAC) \((\MAC)\) (\S+)"
vendor=unknown
[arpwatch-new-station]
event_type=event
src_ip={resolv($1)}
host={$1}
interface={$3}
mac={$2}
plugin_sid=1
regexp="arpwatch.*?: new station (\IPV4) (\MAC) (\S+)"
vendor=unknown
[arpwatch-reused-address]
event_type=event
src_ip={resolv($1)}
host={$1}
interface={$4}
mac={$2}
userdata1={$2}
userdata3={$3}
plugin_sid=2
regexp="arpwatch.*?: reused old ethernet address (\IPV4) (\MAC) \((\MAC)\) (\S+)"
vendor=unknown
[config]
create_file=true
enable=yes
interface=eth0
location=/var/log/ossim/arpwatch-new.log
process=/usr/sbin/arpwatch_eth0
restart=no
restart_interval=\_CFG(watchdog,restart_interval)
shutdown=killall %(process)s
source=log
start=yes
startup=%(process)s -d -d -i %(interface)s -f /var/lib/arpwatch/arp-eth0.dat -N >> %(location)s 2>&1 &
stop=yes
type=detector
Para habilitar este nuevo plugin, hay que ingresarlo en las tablas plugin y plugin_sid de la base de datos OSSIM. Esto se hace a través del siguiente archivo sql (arpwatch_new.sql):
-- uncomment the following lines to delete old arpwatch pluginInluir esto en la base de datos es tan simple como ejectutar:
-- DELETE FROM plugin WHERE id = "1512";
-- DELETE FROM plugin_sid WHERE plugin_id="1512";
-- delete old entries of this plugin
DELETE FROM plugin WHERE id = "51512";
DELETE FROM plugin_sid WHERE plugin_id = "51512";
INSERT INTO plugin (id, type, name, description) VALUES (51512, 1, 'arpwatch_new', 'Ethernet/FDDI station monitor daemon');
INSERT INTO plugin_sid (plugin_id, sid, category_id, class_id, name) VALUES (51512, 1, NULL, NULL, 'arpwatch_new: Mac address New');
INSERT INTO plugin_sid (plugin_id, sid, category_id, class_id, name) VALUES (51512, 2, NULL, NULL, 'arpwatch_new: Mac address Change');
INSERT INTO plugin_sid (plugin_id, sid, category_id, class_id, name) VALUES (51512, 3, NULL, NULL, 'arpwatch_new: Mac address Deleted');
INSERT INTO plugin_sid (plugin_id, sid, category_id, class_id, name) VALUES (51512, 4, NULL, NULL, 'arpwatch_new: Mac address Same');
INSERT INTO plugin_sid (plugin_id, sid, category_id, class_id, name) VALUES (51512, 5, NULL, NULL, 'arpwatch_new: Mac address Event unknown');
cat arpwatch_new.sql | mysql -u root -p ossim
Luego deben modificar la configuración del agente OSSIM para que incluya este plugin, es decir, comentar la línea del plugin de arpwatch anterior y agregar el nuevo en el archivo /etc/ossim/agent/config.cfg, en la sección plugins:
#arpwatch_eth0=/etc/ossim/agent/plugins/arpwatch_eth0.cfg
arpwatch_new=/etc/ossim/agent/plugins/arpwatch_new.cfg
Finalmente reinicien los servicios de ossim server y agent:
/etc/init.d/ossim-server restart
/etc/init.d/ossim-agent restart
y verifiquen que se encuentre cargado en la pestaña Collections de la interfaz web.
Reporte de cambios por mail
Con el nuevo plugin ya es posible crear una política que ejecute una acción que envíe mails. Las políticas y las acciones se pueden crear fácilmente desde la interfaz web. Para hacerlo, hay que dirigirse a la opción Intelligence -> Policy & Actions.
Primero crearemos la acción que ejecutará el envío de mail, para luego poder seleccionarla en la política. La acción se crea desde la pestaña Actions y dando al botón New. Una acción puede ser la creación de un ticket, o, como deseamos nosotros, el envío de un mail. Este tipo se elige en el desplegable Type. Es obligatorio colocar una descripción de la acción.
El resto de los campos son muy intuitivos, el originario del mail, el destinatario, el asunto y el mensaje. Se pueden utilizar palabras claves especiales tanto en el contenido como en el asunto del mail, las cuales OSSIM reemplazará por el valor correspondiente. En la parte superior de la acción estan los atributos elegibles, entre los que se cuenta con las IPs de orígen y destino, puertos, protocolos y varios campos más. Para el caso en cuestión, lo importante es que el reporte contenga la IP del host y las MACs anterior y nueva, las cuales se encuentran en los atributos userdata1 y userdata3, según lo definimos en el plugin.
La política se crea de forma bastante intuitiva, en la pestaña Policy, dando New y siguiendo los pasos. Los primeros pasos describen atributos que deben tener los paquetes para que esta política se aplique, como IPs orígen y destino, y Ports destino.
Uno de los pasos relevantes es la definición del "DS Groups", donde se elige el grupo de plugins a tener en cuenta a la hora de analizar los paquetes. OSSIM trae algunos grupos de plugins ya armados, pero para nuestro caso, hay que insertar uno nuevo, dandole al link "Insert new DS Group?". En este punto hay que ingresar un nombre y una descripción, acompañado por el plugin a utilizar, que se selecciona dando en el +
En el listado debería aparecer el nuevo plugin que creamos anteriormente con ID 51512. Una vez seleccionado es posible elegir que tipos de evento, del mencionado plugin, deben tenerse en cuenta. Es así como podemos reportar sólo eventos de cambio de MAC y no cuando se ve un host nuevo. El tipo de evento que nos interesa es el que tiene el identificador 2.
Cuando el grupo DS ya está ingresado, es posible seleccionarlo y continuar con la definición de la política.
El otro paso relevante es la elección de las consecuencias que tiene la política. Es decir, qué acción tomar cuando detectamos un evento que cumple con las características descriptas en la política. Para este caso, elegiremos la acción que creamos anteriormente, y además podríamos elevar la prioridad del evento a 5.
En fin
Con estos cambios ya es posible recibir por mail reportes de cambios de MACs en hosts importantes, que incluyan la MAC anterior y la nueva, gracias a la nueva definición del plugin y la política creada.
Referencias
- OSSIM Sensor - The Agent
- Creating a Custom OSSIM 3 policy
Desde que instalé arpwatch en la red de la empresa donde trabajo, me encontré con una necesidad imperiosa. Nuestra red otorga las IPs de las workstations por DHCP, pero en la misma red existen host importantes que tienen IPs fijas.
Arpwatch no se desempeña demasiado bien en redes con DHCP, dado que con este esquema las IPs de las máquinas suelen cambiar cada tanto, generando reportes sin utilidad para quien revisa los logs de seguridad. Entre tantos reportes sin utilidad pueden quedar escondidos reportes que si nos interesan, como por ejemplo ver que la IP de un proxy, gateway, server, cambió su MAC, algo que es en extremo sospechoso y muy importante para detectar intrusos.
De esta manera tenemos una herramienta muy simple y poderosa, pero que al generar tantos reportes molestos, resulta poco útil en este tipo de redes.
Para obtener lo mejor de esta herramienta contaba con dos opciones:
1) desarrollar un script que parsee los logs buscando sólo las IPs que me interesan,
2) agregar al código de arpwatch la funcionalidad necesaria para poder filtrar ciertas IPs.
La primera era más rápida y simple, pero la segunda mucho más interesante. Por fin esta semana conté con tiempo libre, así que puse manos a la obra y actualicé el código de arpwatch para que incluya esta funcionalidad. Esta es una de las grandes ventajas de utilizar software libre, si necesitas más funcionalidad, podes agregarla vos mismo!
Por lo que encontré, arpwatch no se actualiza desde 2006, pero hay parches como el de debian, que agregaron cierta funcionalidad. Como ya sabrán, utilizo debian para todo y es la base de una gran porción de distribuciones, así que decidí partir del paquete de debian. Este paquete incluye opciones como ignorar una red entera, o enviar reportes por mail, y pueden verlas marcadas con el prefijo "(Debian)" en la man page.
Yendo al grano, qué provee el código que desarrolle?
- la posibilidad de reportar cambios de MAC sólo de IPs específicas
- una nueva opción en la línea de comandos (-H <filename>) para activar esta funcionalidad e indicar el archivo donde se encuentran los hosts a seguir
- configuración simple del archivo de hosts a seguir:
- se puede especificar un host según su IP (ej: 192.168.0.2), hostname (mihost.mired.com), o red entera (192.168.0.0/24),
- es posible dejar líneas en blanco para separar grupos de host visualmente
- permite la adición de comentarios utilizando el símbolo # al comienzo de cada línea.
- man page actualizada explicando la nueva funcionalidad.
Si por ejemplo quisiéramos seguir sólo los hosts 192.168.0.2, www.miempresa.com, y la red 192.168.10.0/24, el archivo de hosts (denominado hosts.dat) podría ser:
#ip interna
192.168.0.2
#web de la empresa
www.miempresa.com
#red de compras
192.168.10.0/24
Luego bastaría con ejecutar arpwatch de la siguiente manera:
# arpwatch -H hosts.dat
La instalación de esta nueva versión debe hacerse de la siguiente manera:
1) descargar el código de arpwatch original
2) descargar el parche de debian
3) descargar mi parche
4) desomprimir el código original y los parches:
$ tar -xzvf arpwatch_2.1a15.orig.tar.gz
$ tar -xzvf arpwatch_2.1a15-1.1.diff.gz
$ tar -xzvf arpwatch-2.1a15-2-diff.diff.gz
5) parchar el código original con el parche de debian, parados en el directorio del código original:
$ cd arpwatch_2.1a15
$ patch < ../arpwatch_2.1a15-1.1.diff
6) parchar lo anterior con la extensión que programé:
$ patch < ../arpwatch-2.1a15-2-diff.diff
7) compilar:
$ ./configure
$ make
8) instalar:
$ make install
Algo a tener en cuenta es que deberán tener las fuentes de pcap para poder compilar arpwatch. En debian el paquete se denomina libpcap-dev.
Si tienen alguna duda o encuentran algún fallo en el programa, por favor reportenmelo. Contacté al maintainer del paquete en debian y espero le interese incorporar este parche para ampliar la funcionalidad de esta excelente herramienta.
Espero les resulte tan útil como a mi!
Que tengan un feliz año nuevo y arranquen el 2012 con todo. Recuerden que, según los mayas, será el último =P
Arpwatch no se desempeña demasiado bien en redes con DHCP, dado que con este esquema las IPs de las máquinas suelen cambiar cada tanto, generando reportes sin utilidad para quien revisa los logs de seguridad. Entre tantos reportes sin utilidad pueden quedar escondidos reportes que si nos interesan, como por ejemplo ver que la IP de un proxy, gateway, server, cambió su MAC, algo que es en extremo sospechoso y muy importante para detectar intrusos.
De esta manera tenemos una herramienta muy simple y poderosa, pero que al generar tantos reportes molestos, resulta poco útil en este tipo de redes.
Para obtener lo mejor de esta herramienta contaba con dos opciones:
1) desarrollar un script que parsee los logs buscando sólo las IPs que me interesan,
2) agregar al código de arpwatch la funcionalidad necesaria para poder filtrar ciertas IPs.
La primera era más rápida y simple, pero la segunda mucho más interesante. Por fin esta semana conté con tiempo libre, así que puse manos a la obra y actualicé el código de arpwatch para que incluya esta funcionalidad. Esta es una de las grandes ventajas de utilizar software libre, si necesitas más funcionalidad, podes agregarla vos mismo!
Por lo que encontré, arpwatch no se actualiza desde 2006, pero hay parches como el de debian, que agregaron cierta funcionalidad. Como ya sabrán, utilizo debian para todo y es la base de una gran porción de distribuciones, así que decidí partir del paquete de debian. Este paquete incluye opciones como ignorar una red entera, o enviar reportes por mail, y pueden verlas marcadas con el prefijo "(Debian)" en la man page.
Yendo al grano, qué provee el código que desarrolle?
- la posibilidad de reportar cambios de MAC sólo de IPs específicas
- una nueva opción en la línea de comandos (-H <filename>) para activar esta funcionalidad e indicar el archivo donde se encuentran los hosts a seguir
- configuración simple del archivo de hosts a seguir:
- se puede especificar un host según su IP (ej: 192.168.0.2), hostname (mihost.mired.com), o red entera (192.168.0.0/24),
- es posible dejar líneas en blanco para separar grupos de host visualmente
- permite la adición de comentarios utilizando el símbolo # al comienzo de cada línea.
- man page actualizada explicando la nueva funcionalidad.
Si por ejemplo quisiéramos seguir sólo los hosts 192.168.0.2, www.miempresa.com, y la red 192.168.10.0/24, el archivo de hosts (denominado hosts.dat) podría ser:
#ip interna
192.168.0.2
#web de la empresa
www.miempresa.com
#red de compras
192.168.10.0/24
Luego bastaría con ejecutar arpwatch de la siguiente manera:
# arpwatch -H hosts.dat
La instalación de esta nueva versión debe hacerse de la siguiente manera:
1) descargar el código de arpwatch original
2) descargar el parche de debian
3) descargar mi parche
4) desomprimir el código original y los parches:
$ tar -xzvf arpwatch_2.1a15.orig.tar.gz
$ tar -xzvf arpwatch_2.1a15-1.1.diff.gz
$ tar -xzvf arpwatch-2.1a15-2-diff.diff.gz
5) parchar el código original con el parche de debian, parados en el directorio del código original:
$ cd arpwatch_2.1a15
$ patch < ../arpwatch_2.1a15-1.1.diff
6) parchar lo anterior con la extensión que programé:
$ patch < ../arpwatch-2.1a15-2-diff.diff
7) compilar:
$ ./configure
$ make
8) instalar:
$ make install
Algo a tener en cuenta es que deberán tener las fuentes de pcap para poder compilar arpwatch. En debian el paquete se denomina libpcap-dev.
Si tienen alguna duda o encuentran algún fallo en el programa, por favor reportenmelo. Contacté al maintainer del paquete en debian y espero le interese incorporar este parche para ampliar la funcionalidad de esta excelente herramienta.
Espero les resulte tan útil como a mi!
Que tengan un feliz año nuevo y arranquen el 2012 con todo. Recuerden que, según los mayas, será el último =P
Etiquetas:
administracion,
Arpwatch,
debian,
GNU/Linux,
monitoreo,
programacion,
redes,
seguridad
Una vez más me veo sorprendido por la ignorancia que existe en el mundo TI acerca de conceptos básicos de seguridad. En los casi tres años que llevo trabajando en seguridad informática, toda aplicación que audité (desktop o web) poseía vulnerabilidades críticas y muy básicas.
Cuando recién empecé a trabajar en el rubro, creía que vulnerabilidades como buffer overflow, SQL Injection, XSS, eran raras de encontrar debido a la gran difusión que poseen y lo fáciles que son de evitar, sin embargo, tres años de experiencia y trato con una cantidad considerable de desarrolladores y empresas (más de 15), me demostraron lo contrario.
Lo peor no es encontrar que toda aplicación que analizo es vulnerable a ataques simples, sino que al tratar con los desarrolladores me encuentro con una ignorancia espeluznante. Muy pocos de los programadores con los que traté conocían al menos de nombre los ataques, y la gran mayoría no tenía ni idea de cómo solucionar los problemas.
Es así como me encuentro una y otra vez explicando ataques, explicando métodos para mitigarlos, demostrando dónde están los errores. Cada proveedor de software con el que tengo contacto tengo que volver a explicar lo mismo. Lo más indignante es que la gran mayoría te termina tratando como que lo que pedís es exagerado, que controles así no se utilizan, que la seguridad no se encuentra en los requerimientos! (WTF!) La defensa de las empresas de desarrollo es atacar en lugar de reconocer su ignorancia. Pedir más dinero por lo que debería haber estado contemplado desde el principio, culpar al auditor de retrasar la puesta en producción de productos incompletos y de baja calidad, porque recuerden amigos, la seguridad forma una parte esencial del software de calidad.
Al principio creía que la falta de conocimiento era local en la ciudad donde vivo, pero luego de tratar con muchas empresas de Buenos Aires y, recientemente, extranjeras, me terminaron de demostrar que la ignorancia es general.
El catalizador de este post es que en estos días me tocó auditar una aplicación web provista por una importante empresa de Brasil. Lo raro no fue encontrar que el sitio era vulnerable a distintos ataques, sino que al entablar conversaciones con los desarrolladores encontré la mayor ignorancia en seguridad que vi en estos tres años. No tenían absolutamente idea de nada relacionado a seguridad web, no habían escuchado ni nombrar ataques de SQL Injection, XSS, XSRF, ni OWASP, ni mucho menos prepared statements o como escapar caracteres HTML, NADA! En la conferencia que tuvimos tuve que improvisar una suerte de cátedra en seguridad Web. Realmente se hace muy muy difícil que alguien entienda los riesgos de lo que estas exponiendo si no tienen idea de lo que estás tratando. Decían que yo era un genio por lo que había descubierto y que el 99.9% de la gente no podría encontrar esos errores... si bien me sentí alagado, me causó mucha gracia, dado que las técnicas que emplee eran tan simples que cualquiera siguiendo un tutorial de la web podría hacerlo.
En una era donde todo está informatizado y poco a poco todo se va moviendo hacia servicios cloud, tener tanta información en la web en manos de desarrolladores que no tienen ni idea de cómo protegerla, o peor aún, no les interesa, realmente da miedo.
Por favor, si estás leyendo esto y sos desarrollador, toma conciencia, capacitate en seguridad, como mínimo date una vuelta por la web de OWASP. La seguridad es MUY fácil de implementar, y aprender, sólo necesitas saber conceptos básicos, no necesitas ser un experto en el tema, basta con estar interesado en mejorar como programador.
Yo seguiré aportando mi granito de arena desde este blog y dando conferencias donde pueda, espero lograr aunque sea un pequeño cambio. Algo es seguro, ninguna empresa que haya desarrollado para la empresa que trabajo se olvidará de los conceptos que les enseñé y sabrán que mientras esté ahí no podrán obviar la seguridad en sus programas, así me hayan odiado por ello =)
Cuando recién empecé a trabajar en el rubro, creía que vulnerabilidades como buffer overflow, SQL Injection, XSS, eran raras de encontrar debido a la gran difusión que poseen y lo fáciles que son de evitar, sin embargo, tres años de experiencia y trato con una cantidad considerable de desarrolladores y empresas (más de 15), me demostraron lo contrario.
Lo peor no es encontrar que toda aplicación que analizo es vulnerable a ataques simples, sino que al tratar con los desarrolladores me encuentro con una ignorancia espeluznante. Muy pocos de los programadores con los que traté conocían al menos de nombre los ataques, y la gran mayoría no tenía ni idea de cómo solucionar los problemas.
Es así como me encuentro una y otra vez explicando ataques, explicando métodos para mitigarlos, demostrando dónde están los errores. Cada proveedor de software con el que tengo contacto tengo que volver a explicar lo mismo. Lo más indignante es que la gran mayoría te termina tratando como que lo que pedís es exagerado, que controles así no se utilizan, que la seguridad no se encuentra en los requerimientos! (WTF!) La defensa de las empresas de desarrollo es atacar en lugar de reconocer su ignorancia. Pedir más dinero por lo que debería haber estado contemplado desde el principio, culpar al auditor de retrasar la puesta en producción de productos incompletos y de baja calidad, porque recuerden amigos, la seguridad forma una parte esencial del software de calidad.
Al principio creía que la falta de conocimiento era local en la ciudad donde vivo, pero luego de tratar con muchas empresas de Buenos Aires y, recientemente, extranjeras, me terminaron de demostrar que la ignorancia es general.
El catalizador de este post es que en estos días me tocó auditar una aplicación web provista por una importante empresa de Brasil. Lo raro no fue encontrar que el sitio era vulnerable a distintos ataques, sino que al entablar conversaciones con los desarrolladores encontré la mayor ignorancia en seguridad que vi en estos tres años. No tenían absolutamente idea de nada relacionado a seguridad web, no habían escuchado ni nombrar ataques de SQL Injection, XSS, XSRF, ni OWASP, ni mucho menos prepared statements o como escapar caracteres HTML, NADA! En la conferencia que tuvimos tuve que improvisar una suerte de cátedra en seguridad Web. Realmente se hace muy muy difícil que alguien entienda los riesgos de lo que estas exponiendo si no tienen idea de lo que estás tratando. Decían que yo era un genio por lo que había descubierto y que el 99.9% de la gente no podría encontrar esos errores... si bien me sentí alagado, me causó mucha gracia, dado que las técnicas que emplee eran tan simples que cualquiera siguiendo un tutorial de la web podría hacerlo.
En una era donde todo está informatizado y poco a poco todo se va moviendo hacia servicios cloud, tener tanta información en la web en manos de desarrolladores que no tienen ni idea de cómo protegerla, o peor aún, no les interesa, realmente da miedo.
Por favor, si estás leyendo esto y sos desarrollador, toma conciencia, capacitate en seguridad, como mínimo date una vuelta por la web de OWASP. La seguridad es MUY fácil de implementar, y aprender, sólo necesitas saber conceptos básicos, no necesitas ser un experto en el tema, basta con estar interesado en mejorar como programador.
Yo seguiré aportando mi granito de arena desde este blog y dando conferencias donde pueda, espero lograr aunque sea un pequeño cambio. Algo es seguro, ninguna empresa que haya desarrollado para la empresa que trabajo se olvidará de los conceptos que les enseñé y sabrán que mientras esté ahí no podrán obviar la seguridad en sus programas, así me hayan odiado por ello =)
Si son seguidores del blog, saben que utilizo un GNU/Linux unido a un dominio AD desde hace tiempo. Algo que siempre estuve por configurar es el automontaje de los shares para no tener que escribir las direcciones una y otra vez. Hoy llegó el momento =D
A continuación describiré un poco cómo acceder y montar shares SMB en GNU/Linux y luego les mostraré cómo hacer para que un share se monte automáticamente al inicio de sesión, utilizando el ticket kerberos que nos entrega el controlador de dominio en el login.
Montar shares
Para los que trabajan con GNU/Linux es muy común acceder sistemas de archivos Windows a través del protocolo SMB (CIFS es el nombre actual del protocolo). Samba posee una excelente compatibilidad con el protocolo y provee diversas herramientas para el acceso.
Una vez que Samba está instalado, acceder un servidor de archivos es tan simple como escribir la siguiente URL en su navegador de archivos favorito (Dolphin, Nautilus, Krusader, etc):
En una red hogareña, sin AD, la autenticación con el servidor se realiza utilizando el viejo NTLM, con lo cual, al tipear la URL anterior, el navegador les pedirá que ingresen las credenciales de un usuario válido (desde la visión del servidor).
Otra forma de acceder a los archivos es montar el sistema remoto en un directorio local. El paquete smbfs provee soporte para el sistema de archivos smb/cifs, el cual se puede utilizar en el comando mount de la siguiente manera:
Por supuesto que también es posible agregar una entrada en /etc/fstab para hacer el montaje más rápido y/o automático. La entrada en fstab correspondiente al ejemplo anterior es la siguiente:
Digo poco atractivas porque en ambos casos es necesario colocar las credenciales en texto plano. Con la segunda opción se evita que otro usuario abra el fstab y vea el password, pero igualmente no es del todo satisfactoria.
Automontar shares en redes corporativas
En una red corporativa con servidores Windows, es muy probable que se utilice Active Directory. La autenticación en estos entornos se lleva a cabo utilizando kerberos, aunque por defecto (al menos hasta Windows 2003) los servidores de archivos soportan NTLM por compatibilidad. Incluso en redes corporativas con servicios integrados con kerberos provistos por servidores GNU/Linux se está utilizando bastante Samba como protocolo para la compartición de archivos, lo que hace doblemente atractiva la siguiente explicación.
Ahora, gracias a Samba y PAM, es posible mejorar el esquema de clientes Linux dentro de la corporación. Algo muy común es que los usuarios de workstations con Windows tengan mapeos automáticos al realizar un login, como por ejemplo el disco F:\ apuntando al servidor server1.ejemplo.com. Un cliente GNU/Linux puede tener esta misma comodidad, con mapeos automáticos de shares de red al árbol de directorios de su máquina.
La siguiente configuración tiene en cuenta que la workstation GNU/Linux autentica usuarios contra Domain Controllers (o servidores kerberos de GNU/Linux) con PAM y kerberos, como se explicó en el artículo Configurar PAM para utilizar kerberos.
Utilizando el entorno descripto en el artículo, los usuarios contarán con un ticket kerberos luego de que se autentiquen. Como Samba es compatible con kerberos, no es necesario seguir ingresando las credenciales al montar o acceder un share, Samba hará la autenticación de forma transparente utilizando el ticket correspondiente.
No existe una alternativa segura para hacer que un usuario monte un share que no figure en el fstab, sólo un administrador puede hacerlo. Claro que no sirve colocar una entrada en fstab que intente montar automáticamente un share, dado que se hará a nombre de root y root no posee un ticket kerberos... es decir, access denied!
La solución entonces consta de dos pasos. Agregar la línea en el fstab, y luego configurar kde, gnome, o el desktop que utilicen, para que realice el mount cuando el usuario se loguea.
Teniendo en cuenta el ejemplo con el que venimos trabajando, deberá agregarse la siguiente línea en fstab para utilizar kerberos:
El siguiente paso es agregar un script que desmonte los shares una vez que el usuario ejecuta logout, porque si la misma workstation es compartida por diferentes usuarios, dejar el acceso a los shares de otro usuario no es buena idea. Esta tarea debe realizarse con un script similar al anterior:
To Do
Como bien dije, no es posible que los usuarios monten los shares que no se encuentren definidos en fstab. Es decir, en fstab deben figurar todos los shares disponibles para los usuarios de una dada workstation, porque sino no podrán montarlos. Esto es un inconveniente bastante molesto, dado que si el usuario puede acceder a los shares, no tiene mucho sentido restringir para que no pueda montarlo en el árbol de directorios local.
Existe, claro, una forma indirecta y que en general es considerada insegura. La misma se basa en otorgar setuid root al ejecutable mount.cifs. Con esto, cuando un usuario ejecute el comando mount.cifs, éste se ejecuta con permisos de root, y por consiguiente puede montar los shares, aunque en este caso, probablemente no funcione el ticket kerberos (no lo probé). Queda en ustedes si se deciden por esta alternativa.
Referencia
- Samba HowTo: Mount a CIFS Network Share [Mapped Drive] in openSUSE
A continuación describiré un poco cómo acceder y montar shares SMB en GNU/Linux y luego les mostraré cómo hacer para que un share se monte automáticamente al inicio de sesión, utilizando el ticket kerberos que nos entrega el controlador de dominio en el login.
Montar shares
Para los que trabajan con GNU/Linux es muy común acceder sistemas de archivos Windows a través del protocolo SMB (CIFS es el nombre actual del protocolo). Samba posee una excelente compatibilidad con el protocolo y provee diversas herramientas para el acceso.
Una vez que Samba está instalado, acceder un servidor de archivos es tan simple como escribir la siguiente URL en su navegador de archivos favorito (Dolphin, Nautilus, Krusader, etc):
smb://server1.ejemplo.com/donde server1.ejemplo.com es el nombre del servidor.
En una red hogareña, sin AD, la autenticación con el servidor se realiza utilizando el viejo NTLM, con lo cual, al tipear la URL anterior, el navegador les pedirá que ingresen las credenciales de un usuario válido (desde la visión del servidor).
Otra forma de acceder a los archivos es montar el sistema remoto en un directorio local. El paquete smbfs provee soporte para el sistema de archivos smb/cifs, el cual se puede utilizar en el comando mount de la siguiente manera:
mount -t cifs //server1.ejemplo.com /media/samba -o user=pepeAl ejecutar el comando anterior, aparecerá un prompt solicitando el password del usuario en cuestión.
Por supuesto que también es posible agregar una entrada en /etc/fstab para hacer el montaje más rápido y/o automático. La entrada en fstab correspondiente al ejemplo anterior es la siguiente:
//server1.ejemplo.com /media/samba cifs user,auto,username=pepe 0 0donde las opciones son:
user -> para que lo pueda montar un usuario común (sin ser root)Claro que al intentar montar el sistema solicitará el password correspondiente. Hay dos formas de evitar que esto pase, aunque ninguna es muy atractiva:
auto -> debe montarse automáticamente al iniciar el sistema
username=pepe -> especifica el nombre del usuario a utilizar
- utilizar la opción password=y luego utilizar la opción credentials=/home/pepe/cred.smb en fstab.
- crear un archivo (por ejemplo /home/pepe/cred.smb) que contenga las líneas:
username=pepe
password=elpassword
Digo poco atractivas porque en ambos casos es necesario colocar las credenciales en texto plano. Con la segunda opción se evita que otro usuario abra el fstab y vea el password, pero igualmente no es del todo satisfactoria.
Automontar shares en redes corporativas
En una red corporativa con servidores Windows, es muy probable que se utilice Active Directory. La autenticación en estos entornos se lleva a cabo utilizando kerberos, aunque por defecto (al menos hasta Windows 2003) los servidores de archivos soportan NTLM por compatibilidad. Incluso en redes corporativas con servicios integrados con kerberos provistos por servidores GNU/Linux se está utilizando bastante Samba como protocolo para la compartición de archivos, lo que hace doblemente atractiva la siguiente explicación.
Ahora, gracias a Samba y PAM, es posible mejorar el esquema de clientes Linux dentro de la corporación. Algo muy común es que los usuarios de workstations con Windows tengan mapeos automáticos al realizar un login, como por ejemplo el disco F:\ apuntando al servidor server1.ejemplo.com. Un cliente GNU/Linux puede tener esta misma comodidad, con mapeos automáticos de shares de red al árbol de directorios de su máquina.
La siguiente configuración tiene en cuenta que la workstation GNU/Linux autentica usuarios contra Domain Controllers (o servidores kerberos de GNU/Linux) con PAM y kerberos, como se explicó en el artículo Configurar PAM para utilizar kerberos.
Utilizando el entorno descripto en el artículo, los usuarios contarán con un ticket kerberos luego de que se autentiquen. Como Samba es compatible con kerberos, no es necesario seguir ingresando las credenciales al montar o acceder un share, Samba hará la autenticación de forma transparente utilizando el ticket correspondiente.
No existe una alternativa segura para hacer que un usuario monte un share que no figure en el fstab, sólo un administrador puede hacerlo. Claro que no sirve colocar una entrada en fstab que intente montar automáticamente un share, dado que se hará a nombre de root y root no posee un ticket kerberos... es decir, access denied!
La solución entonces consta de dos pasos. Agregar la línea en el fstab, y luego configurar kde, gnome, o el desktop que utilicen, para que realice el mount cuando el usuario se loguea.
Teniendo en cuenta el ejemplo con el que venimos trabajando, deberá agregarse la siguiente línea en fstab para utilizar kerberos:
//server1.ejemplo.com /media/samba cifs user,noauto,sec=krb5 0 0las opciones relevantes aquí son:
noauto -> no montar automáticamentePara el automontaje se crea un script en bash (o su shell favorito) con el siguiente contenido:
sec=krb5 -> indica a samba que utilice kerberos en la autenticación
#!/bin/bashy se coloca en el directorio correspondiente (dándole ejecución con chmod +x) para que desktop lo ejecute al iniciar la sesión del usuario. Por ejemplo:
mount //server1.ejemplo.com
- en kde deberá colocarse en $HOME/.kde/Autostart/De esta forma, una vez que el usuario se validó contra kerberos, el sistema automáticamente montará sus shares en el lugar correspondiente, una verdadera comodidad, y un paso más para extender el uso de GNU/Linux en las corporaciones =)
- en gnome debe abrirse el "Gnome Control Center" ir a "aplicaciones al inicio" y agregar la ruta al script.
El siguiente paso es agregar un script que desmonte los shares una vez que el usuario ejecuta logout, porque si la misma workstation es compartida por diferentes usuarios, dejar el acceso a los shares de otro usuario no es buena idea. Esta tarea debe realizarse con un script similar al anterior:
#!/bin/bashy colocarlo en el directorio correspondiente al desktop que utilicen. Por ejemplo:
umount //server1.ejemplo.com
- en kde existe el directorio $HOME/.kde/shutdow destinado a tal fin
- en gnome ??? (avísenme si lo encuentran)
To Do
Como bien dije, no es posible que los usuarios monten los shares que no se encuentren definidos en fstab. Es decir, en fstab deben figurar todos los shares disponibles para los usuarios de una dada workstation, porque sino no podrán montarlos. Esto es un inconveniente bastante molesto, dado que si el usuario puede acceder a los shares, no tiene mucho sentido restringir para que no pueda montarlo en el árbol de directorios local.
Existe, claro, una forma indirecta y que en general es considerada insegura. La misma se basa en otorgar setuid root al ejecutable mount.cifs. Con esto, cuando un usuario ejecute el comando mount.cifs, éste se ejecuta con permisos de root, y por consiguiente puede montar los shares, aunque en este caso, probablemente no funcione el ticket kerberos (no lo probé). Queda en ustedes si se deciden por esta alternativa.
Referencia
- Samba HowTo: Mount a CIFS Network Share [Mapped Drive] in openSUSE
Etiquetas:
Active Directory,
AD,
administracion,
articulos,
CIFS,
GNU/Linux,
kerberos,
Samba,
SMB
Suscribirse a:
Entradas (Atom)








