sábado, noviembre 03, 2007

Fortificando un Servidor Apache (IV de IV)

***************************************************************************************
- Fortificando un Servidor Apache (I de IV)
- Fortificando un Servidor Apache (II de IV)
- Fortificando un Servidor Apache (III de IV)
- Fortificando un Servidor Apache (IV de IV)
***************************************************************************************

mod_chroot

Una de las características que se siguen por seguridad es “enjaular” los procesos de un sistema. El termino enjaular se utiliza para referirnos a diferentes grados de aislamiento del proceso dentro del sistema operativo. Se puede enjaular un proceso dentro del sistema de ficheros, dentro de su parcela de memoria o incluso en las funciones de red. Una de las características más comunes es aislar los demonios de los servidores web dentro un sistema de ficheros virtual mediante el uso de las funciones chroot.

Realizar un chroot a un proceso siempre ha sido una tarea ardua, ya que hay que proveerle a dicho proceso de todas las utilizadas y ficheros de configuración que pudiera necesitar dentro de una nueva estructura de ficheros. Esto es así para muchos servicios pero desde la aparición de mod_chroot no es necesario en Apache.
Este módulo se carga dentro del sistema y ya se encarga él de aislar el sistema de ficheros a los que se van a enlazar los demonios httpd y todos sus hijos. Esto se debe a la implementación a nivel de sistema operativo de la función chroot() en las principales distribuciones Linux.

Para ello descargamos el modulo mod_chroot [http://core.segfault.pl/~hobbit/mod_chroot/] y lo incluimos dentro de los módulos del servidor Apache. Podemos realizar una compilación estática, con ./configure –add-module modules/mod_chroot o una compilación dinámica utilizando el DSO (Dynamic System Object) mediante el siguiente comando:

Imagen: Carga dinámica de mod_chroot

Una vez cargado el módulo, se procederá a configurar el archivo de configuración httpd.conf para decidir en qué directorio queremos enjaular los procesos httpd. Para ello se configura la directiva ChrootDir como se puede ver en la siguiente captura.

Imagen: Configuración mod_chroot en httpd.conf

Mod_chroot no realiza aislamiento de memoria, y en algunos casos puede requerir de la configuración de algún directorio especial dentro del sistema de ficheros “chrooteado” sobre todo para servicios de multiprocesamiento simétrico o para la inclusión dentro del servicio httpd del soporte de alguna función especial, pero como se puede comprobar, utilizando mod_chroot para Apache, es mucho más sencillo a como tradicionalmente había que configurar un soporte chroot para cualquier otro servicio.

Autenticación y Autorización

Autenticar es el mecanismo por el cual garantizamos que alguien es quien dice ser y autorizar es permitir que ese alguien pueda acceder a un determinado recurso. Para realizar estas dos funciones en Apache utilizamos en primer lugar un tipo de autenticación y un proveedor de autenticación. El tipo de autenticación es la forma en la que el cliente envía sus credenciales, esta puede ser en texto claro (Basic) utilizando el módulo mod_auth_basic o en codificación MD5 Digest utilizando mod_auth_digest. La elección de la autenticación se configura con la directiva AuthType Basic o AuthType Digest. Esto determina la forma en la que se transmiten las credenciales. Lógicamente en un entorno fortificado no se recomienda el uso de la autenticación Basic.

Una vez elegido el tipo de autenticación se debe configurar el proveedor de autenticación, o lo que es lo mismo, dónde está el repositorio de credenciales contra el que se deben comprobar las enviadas por el cliente. Estos repositorios pueden ser un árbol Ldad, un fichero del sistema operativo, una tabla en una base de datos, etc… Lógicamente, la configuración necesaria para cada entorno de autenticación será diferente.

Si se configura la autenticación utilizando un fichero, utilizando el módulo mod_authn_file, se debe crear dicho fichero previamente utilizando las herramientas htpasswd o htdigest. Estas herramientas nos crearán un fichero de usuarios, que deberemos situar fuera de la ruta pública del servidor Apache y se configurará en httpd.conf la directiva AuthUserFile como se ve en el siguiente ejemplo:

AuthType Basic
AuthName "Carpetas Privadas"
AuthUserFile /web/usuarios


Si se desea utilizar una tabla en una base de datos para autenticar a los usuarios, utilizando el módulo mod_authn_dbd, se debe configurar el conector con la base de datos, y la tabla de usuarios que se va a utilizar. El siguiente ejemplo muestra una posible configuración de httpd.conf. En primer lugar hay que cargar el driver de la base de datos con la que deseemos conectar. Este driver debe estar previamente cargado en el sistema operativo.

DBDriver pgsql

En segundo lugar se deberá configurar la cadena de conexión a la base de datos utilizando la directiva DBDParams:

DBDParams "dbname=mibasededatos user=miusuario password=mipassword"

Y por ultimo configurar las opciones de autenticación del servidor.

[Directory /www/privado]
AuthType Basic
AuthName "My Server"
AuthBasicProvider dbd
AuthDBDUserPWQuery "select password from authn where username = %s"
[/Directory]


Quizá, la forma más interesante de autenticar un sistema de usuarios complejo sea el uso de árboles LDAP. Para ello, se utilizan los módulos mod_authnz_ldap y mod_ldap. El primero se utiliza para autenticar y autorizar el acceso a recursos mediante la comprobación en árboles LDAP mientras que el segundo optimiza la gestión de memoria e hilos de procesos en las conexiones LDAP.

LDAP es un sistema jerárquico de objetos organizado en forma de árbol. Cada objeto pertenece a su clase y añade propiedades de su clase y propiedades heredadas de las clases madre. En un sistema LDAP se pueden dar de alta, usuarios, recursos y cualquier tipo de objeto que se desee. Cada elemento es posible referenciarlo mediante una descripción de la ruta que ocupa en el árbol o mediante el cumplimiento de unas condiciones de un filtro de búsqueda.

Para configurar la autenticación LDAP se deben configurar la directiva AuthLDAPURL que es la cadena de conexión al árbol LDAP y tiene la siguiente estructura:

ldap://host:port/basedn?attribute?scope?filter

- Host: Servidor dónde reside el árbol LDAP.
- Puerto: Generalmente el 389.
- Basedn: Es la ruta a un punto del árbol a partir del cual se realizan las búsquedas. Puede ser la raíz del árbol o una rama del mismo. Tiene la estructura de una ruta LDAP, es decir, ou=unidad_organizativa, dc= mi_dominio, o=organización
- Attribute: El atributo que identifica al usuario, por defecto, en los objetos user de los árboles LDAP es uid, pero puede cambiarse.
- Scope: Las consultas LDAP pueden ser sólo en la rama del árbol elegida o recursivamente en profundidad.
- Filter: filtro sobre los objetos. Por ejemplo que sean del tipo usuarios_reales o cualquier otro filtrado para determinar que un objeto es válido para logarse. (tipo=usuarios_reales).

Una vez autenticado a los usuarios por cualquiera de los proveedores anteriores se podrán establecer las reglas de control de acceso a los recursos. Así por ejemplo se podrá:

- Require valid-user: Se exige un usuario autenticado.
- Require user maligno: Se exige el usuario maligno.
- Require group locos: Se exige el grupo locos.
- Require ldap-user: Se exige un determinado usuario LDAP.
- Require ldap-group: Se exige un determinado grupo LDAP.
- Require ldap-dn: Se exige la pertenencia a una determinada ruta DN en LDAP.
- Require ldap-attribute tipo=admins: Se exige un determinado valor en un determinado atributo de un usuario ldap.
- Requite ldap-filter: Se exige el cumplimiento de un determinado filtro LDAP.

Mod_security

La securización y fortificación de un servidor Apache tiene muchos aspectos que tocar, pero después de todo lo que se ha tratado no me gustaría irme sin hacer una mención especial mod_security.

Este módulo nos permite realizar filtrado a nivel de aplicación, es decir, nos permite configurar reglas de firewall para las peticiones web que realizan los clientes. Es común que muchos de los ataques hoy en día no se produzcan contra el software del servidor y sí contra aplicaciones web mal desarrolladas o desactualizadas. Con mod_security vamos a poder configurar que peticiones van a ser procesadas o no por nuestras aplicaciones web.

Supongamos que tenemos una aplicación web vulnerable a un ataque de SQL Injection corriendo sobre nuestro servidor Apache. Con mod_security podremos evitar que cualquier intento de explotación llegue hasta la aplicación ya que será este componente el que la detenga antes de ser redirigida a la aplicación. Este tipo de comportamiento es deseable cuando estamos administrando un servicio sobre el que están corriendo aplicaciones web que no tenemos controladas. Ésta no es la mejor manera de proteger una aplicación web, pero sí es una forma de fortificarla aplicando el principio de Defensa en Profundidad ya que si la aplicación web queda comprometida puede quedar comprometida toda la infraestructura de los servicios web.
Al estar corriendo a nivel de aplicación y directamente sobre el servidor http el sistema no se ve limitado por los sistemas de cifrado. Hay que tener en cuenta que si disponemos de un NIDS (Network Intrusion Detection System) o sistema de detección de intrusiones de red, este no podrá analizar todas las peticiones que vayan cifradas sobre canales SSL, como por ejemplo http-s. En este caso, mod_security filtra las peticiones una vez se ha eliminado la capa SSL.

Es una buena decisión de diseño situar este componente en el frontal que redirige todas las peticiones hacia nuestros servicios, es decir, si tenemos un servidor que está realizando las opciones de Proxy reverso, es ahí donde hay que situar este componente.

El proceso de instalación se realiza mediante el uso del comando make. Para ello, tras descargar la última versión del módulo de http://www.modsecurity.org y descomprimir el paquete, hay que configurar en el archivo Makefile el valor la variable top_dir con la ruta dónde está instalado el software del servidor de Apache. Una vez configurado procedemos a realizar la ejecución de los comandos make y make install para dejar el módulo compilado y cargado en httdp.conf. Es necesario cargar la librería de objetos libxml2.so mediante la configuración de LoadFile /usr/lib/libxml2.so en el fichero httpd.conf.

Mod_security se configura por reglas, estas vienen en archivos independientes dentro del directorio rules. Todos los archivos tienen un numerito que se usa para indicar el orden de preferencia, ya que estas se van a ejecutar de menor a mayor. Es decir, si una petición de URL coincide con dos reglas se disparará la que primero se encuentre, ya sea de permitir o de denegar el acceso de esa petición.

Imagen: Directorio rules de mod_security

Así modsecurity_crs_10_config.conf será el primer conjunto de reglas a evaluar. Estas son las reglas "core" y siempre deben ser las primeras que se evalúen, así que, si queremos crear un fichero de reglas que evite un falso negativo o deseamos crearnos nuestra propia regla para evitar ataques de LDAP injection a nuestras aplicaciones podríamos crearnos un fichero de reglas que se llamara modsecurity_crs_15_ldapinjection.conf, y sería el segundo conjunto de reglas en ejecutarse.

Una vez instalado mod_security debemos configurar las directivas del módulo. Estas directivas se pueden configurar en diferentes ámbitos, es decir, de forma global, a nivel de servidor, de virtual host o de directorio.

[IfModule mod_security.c]
SecRuleEngine On
SecAuditEngine RelevantOnly
SecAuditLog logs/audit_log
SecDefaultAction "deny,log,status:500"
[/IfModule]


El segmento anterior es una configuración típica. Las directivas configuradas tienen las siguientes implicaciones:

- SecRuleEngine on/off: Activa o desactiva mod_security. Esta configuración se puede poner a nivel de servidor, virtual host o directorio.
- SecAuditLog: Ruta del fichero de log
- SecFilterSancPost on/off: Aplicar mod_security a peticiones por Post on/off.
- SecDefaultAction: Orden de actuación en caso de no estar definida una acción para la regla que hay que aplicar. En este caso denegar la petición, registrarlo y devolver un código de status 500. Las posibilidades que se pueden aplicar a una acción por defecto son más de 30 y van desde ejecutar un programar, dirigir la navegación a una redirección, devolver un mensaje, tirar la petición etc…

A partir de la configuración incial podemos personalizar las reglas tanto como deseemos. Mod_security viene acompañado de un conjunto básico de reglas preparadas para detectar violaciones de protocolo, ataques comunes de web, ocultar información ofrecida por el servidor, detección contra troyanos y contra recolectores de información. No obstante, es importante aplicar nuevas reglas frente a las nuevas amenazas por lo que la actualización debe ser constante.

La parte fuerte de mod_security es su motor de reglas. Está basado en perl y se tiene una estructura de definición de reglas tan compleja o tan sencilla como se necesite. Cada regla se define con el siguiente comando:

SecRule Varialbes Operadores [Acciones]

Por ejemplo, la siguiente regla bloquea el acceso a cualquier cliente que se identifique como uno de los User-Agents de la lista:

SecRule REQUEST_HEADERS:User-Agent "@pm WebZIP WebCopier Webster WebStripper SiteSnagger ProWebWalker CheeseBot" "deny,status:403

La configuración de mod_securty como un WAF (Web Application Filter) ajustado requiere conocer el lengunage de definición de las reglas, pero la documentación que se ofrece en sitio del proyecto es de muy buena calidad.

Otras acciones

Fortificar un servidor Apache implica fortificar toda la infraestructura, existen muchas más opciones para aumentar la seguridad en el servidor web pero lo más importante, además de todo lo visto en estos dos artículos, es la fortificación del sistema operativo dónde va a correr el servidor Apache, para ello puedes usar SELinux o herramientas como Bastille Linux si corre Apache sobre Linux  o Security Configuration Wizard (SCW) si corre sobre Windows Server [http://www.microsoft.com/windowsserver2003/technologies/security/configwiz/default.mspx] que te pueden ayudar.

13 comentarios:

Anónimo dijo...

Está muy bien el artículo. Dos preguntas:
¿Dirías que apache es el servidor web más fácil de asegurar?
¿Cuánto se debería pagar por configurar *bien* un apache (independientemente de SO, eso es otro concepto)?
Mójate, anda.

Saludos

Anónimo dijo...

Anónimo, y yo te pregunto.
¿Tiene sentido poner un Apache en Windows teniendo el IIS?

Chema Alonso dijo...

Joder, vaya preguntas comprometidas para un finde.

¿qué creeis que debería contestar alguien en el lado del mal?

Saludos!

Anónimo dijo...

Yo no pondría un apache con php y mysql sobre un windows...
Yo apache me lo conozco y me gusta, pero lo uso porque mi cms es php, sino seguramente usaría is con asp .net... me explico?

No se lo que se usaría por securizar apache... nunca se me dio bien echar precios. En mi dedicado no lo tengo enjaulado, pero bueno, es un riesgo. Uso open_basedir para restringir lo que php puede "tocar", y aunque muchas vuln de php explotar esto, el problema ocurre cuando se ejecuta codigo malicioso... vamos, que estaria afectado si fues eun isp de servicio web, sino.. no. deshabilitpo muchas funciones peligrosas como fsockopen, entre muchas otras... uso grsecurity, aunque no selinux por lo ardúo que es configurarlo.

Bueno, nos vemos por tribunal hoy... que os siente muy mal el alcohol.

Unknown dijo...

Buenas..!! maligno soy usuario de un blog el cual trata mediante tutoriales ayudar a los sysadmin como a usuarios en el mundo Linux, la web es www.wikipeando.com.
Se pueden usar los 4 tutoriales sobre Apache como base para armar un art en nuestro Blog?. cada aclarar que como siempre se dira la fuente de donde se baso el articulo.

Gracias

Chema Alonso dijo...

LPIArg,

No tengo ningún problema, pero citar también a PCWorld que fue dónde los publiqué inicalmente.

Saludos!

Unknown dijo...

Desde ya muchas gracias por la buena predisposicion.
Les dejo la url del blog, por si quieren visitarlo:
www.wikipeando.com

Anónimo dijo...

A pesar de que los articulos son una buena adaptación/traducción/resumen de la documentacion de Center of Internet Security, noto que te has dejado algunas cosas en el tintero, que estas otras guias ya incluian hace algunos años:

* Deshabilitar metodos innecesarios (quien no ha oido hablar del TRACE)
* Permisos de los archivos de configuración, arranque, documentRoot...
* La parte de mod_security es demasiado corta, aunqeu tambien hay 120.000 guias por ahí, ya que te pones...
* Que pasa con php, el ¿php.ini?, se podría escribir varios articulos también de como fortificar php... Como el que tienen publicado en hacktimes.com
* [...]

Me hace mucha gracia esta frase de la parte número 3: "este artículo no pretende mostrar el funcionamiento del sistema SSL, ampliamente descrito en numerosos artículos desde su aparición". Como si hablar de la fortificación de uno de los servidores webs más antiguos, fuese algo nuevo :-)


También hecho en falta las referencias que has utilizado...

En fin, un articulo técnico populista... es una lastima que no lo hagas de tuxedo, mqseries, tibco, adabas, o algun producto del que no hay tanta documentación.

Besitos constructivos

Chema Alonso dijo...

Hola aramosf!

¿dónde te metes últimamente?. No me he dejado cosas, he metido lo que he podido en el espacio que tenía y lógicamente no he creado algo nuevo (si no lo hubiera enviado a algún congreso que me viene bien todos los papers que consiga!!).

Muy bien tus recomondezaciones. Y sí, la fortificación es igual de antigua (o más) que el ssl, pero .... es que el artículo iba de fortificación!!!

Las referencias las puse en otro post ;)

Saludos!

Anónimo dijo...

Te doy las gracias por tus tutoriales tan completos.
Un saludo

Unknown dijo...

Una vez configurado el apache para que solicite al cliente un certificado, como hago para obtener la informacion de ese certificado? no se si me explico...

Bueno gracias y saludos

Chema Alonso dijo...

@José Luís, que quieres hacer con el certificado? Identificar a un usuario en concreto? A nivel de servidor basta con que exigas que sólo unos usuarios tengan acceso a esa parte del servidor.

Saludos!

Unknown dijo...

Buenas Maligno,
lo que quiero hacer es usar el dni que tiene dentro del certificado para poder identificar a esa persona en mi plataforma y saber el tipo de acceso que tiene.

Muchas gracias

Entrada destacada

10 maneras de sacarle el jugo a tu cuenta de @MyPublicInbox si eres un Perfil Público

Cuando doy una charla a algún amigo, conocido, o a un grupo de personas que quieren conocer MyPublicInbox , siempre se acaban sorprendiendo ...

Entradas populares