Antes de comenzar a probar ataques sobre servidores y aplicaciones web, es importante saber como funciona el servidor web que estamos probando, es por este motivo que conocer las medidas de seguridad, módulos y demás herramientas con las que cuenta un administrador de sistemas es realmente importante ya que este conocimiento le permite a un hacker entender y detectar con mayor facilidad cuando un servidor web se encuentra mal configurado o es vulnerable en algún punto. Aunque existen muchísimos servidores web en el mercado, en esta entrada y en las próximas se hablará sobre uno de los más conocidos y utilizados en todo el mundo: Apache web server (en próximas publicaciones se hablará sobre Apache Tomcat). Vamos a comenzar…
INSTALACIÓN DE APACHE
Asumiendo que nos encontramos en alguna distribución Debian (o alguno de sus derivados) se procederá a descargar, compilar e instalar el servidor web, aunque evidentemente se puede hacer lo mismo utilizando un simple comando “apt-get” es mucho más ilustrativo hacerlo manualmente, aunque a efectos prácticos no representa mayores dificultades hacerlo de un modo o del otro.
NOTA: Se asume también se utilizará Apache 2.2.X o 2.4.X dado que las versiones anteriores de este servidor web (por ejemplo la 1.3) tienen un proceso de instalación un poco distinto, además también se recomienda utilizar versiones de Apache 2.2.X/2.4.X principalmente por seguridad.
Lo primero es descargar la ultima versión del software, para ello dirigirse a la siguiente página: http://httpd.apache.org/download.cgi desde allí descargar el código fuente comprimido de la última versión estable, después de descargar, descomprimir en una ubicación fácil de encontrar. Ahora solamente resta compilar y generar los ejecutables, para ello se siguen los siguientes pasos:
- Verificar las dependencias y recursos necesarios para la correcta ejecución del servicio, para ello se utiliza el script “configure”
>./configure –prefix=/opt/apache2.2.22/ El parámetro “prefix” simplemente indica la ruta donde se realizará la instalación del software. En algunos casos la ejecución del comando anterior puede fallar debido a que en las últimas versiones de Apache, la librería apr-util es una dependencia necesaria por defecto, sino se encuentra instalada en la máquina el script “configure” finalizará su ejecución erróneamente, en tales casos se cuenta con dos opciones, indicar de forma explicita que no se desea utilizar dicha librería para esta instalación o simplemente instalarla para satisfacer la dependencia requerida. En el primero de los casos, se adiciona al script “configure” la opción “-with-included-apr”
>./configure –prefix=/opt/apache2.2.22/ -with-included-apr En el caso de que se desee instalar la librería y cumplir con esta dependencia (en el caso de que se desee utilizar sus características) se puede instalar esta librería utilizando un simplemente comando apt-get para obtener las dos dependencias necesarias
>apt-get install libaprutil1 >apt-get install libaprutil1-dev
Con esto será suficiente para que el script “configure” funcione adecuadamente.
NOTA: La librería APR Util es un sistema portable de apache que permite realizar operaciones de acceso a base de datos, tratamiento de ficheros xml y manipulación de ficheros de forma independiente de la plataforma en la cual se ejecuta el servidor web. Se trata de una utilidad imprescindible si desea realizar una instalación portable que funcione de forma adecuada en cualquier entorno sin depender de forma directa de la plataforma en la que se ejecuta el servidor.
- Ahora solamente resta ejecutar el comando “make” para que se generen los ficheros ejecutables necesarios para arrancar el servidor. Finalmente se debe ejecutar el comando “make install” para que se instale el servidor web en la ruta especificada en la opción “–prefix”
- Con los pasos anteriores ha quedado instalado el servidor web en la ruta “/opt/apache2.2.22/” tal como se ha indicado anteriormente cuando se ha ejecutado el script “configure”, sin embargo esto es solamente “la punta del iceberg”, un administrador debe contar con experiencia y conocimientos avanzados sobre una adecuada configuración del servidor web para que sea lo más “seguro” posible, ya que normalmente es un blanco muy deseado por atacantes de todo tipo en internet. En estas entradas se intentará explicar algunas de las medidas de seguridad que se deben de tener en cuenta al momento de configurar un servidor web apache.
CONFIGURACIÓN DE APACHE
El comando principal de Apache, una vez se han seguido los pasos de instalación anteriores, se encuentra ubicado en “<PREFIX>/bin/apachectl” desde allí es posible iniciar, detener y reiniciar el servidor web, así como establecer un fichero de configuración personalizado para controlar el comportamiento del servidor. Por defecto el fichero de configuración que toma Apache se encuentra ubicado en “<PREFIX>/config/httpd.conf” si por alguna razón se desea crear un nuevo fichero que sea tomado por el servidor en el proceso de arranque, es necesario indicar su ubicación con la opción “-f” de esta forma es posible ejecutar arrancar Apache con un fichero de configuración personalizado
>apachectl -k start -f /opt/apache2.2.22/adastra-httpd.config |
Existen dos elementos básicos que deben incluirse en dicho fichero de configuración y estos son, las directivas “DocumentRoot” y el parámetro “Listen” que indican la ruta donde se encuentran instaladas las aplicaciones web y el puerto por el cual el servidor web iniciará su ejecución. Las directivas en Apache son las unidades de configuración más utilizadas y probablemente las más importantes, ya que cada directiva activa o desactiva (según su valor) determinadas características del servidor web, su entendimiento y correcto uso es vital. Sin embargo las directivas no son los únicos elementos que se incluyen en un fichero de configuración de Apache, de hecho existen 3 secciones que conforman el fichero de configuración que son: Los parámetros Globales, Las directivas y los Hosts Virtuales. A continuación se explican estas secciones.
Parámetros Globales
Los parámetros globales, tal como su nombre lo indica son valores que se establecen globalmente en el servidor web, por lo que no esta permitido establecer ninguno de estos atributos dentro de ninguna directiva, cada parámetro global debe ser especificado de forma independiente y no puede estar asociado a ningún otro elemento de configuración del servidor. Básicamente son iguales a cualquier directiva de Apache, sin embargo como ya se ha comentado, no pueden combinarse con otras directivas y son completamente independientes. Algunas de estas opciones son:
Listen: Indica el puerto que utilizará Apache para iniciar el servicio, por defecto el valor de esta opción es “80” sin embargo, puede establecerse cualquier valor. No obstante si dicho valor es inferior o igual a 1024, se debe ejecutar el servicio de Apache con el usuario root o empleando técnicas de asignación de privilegios como se explica aquí: https://thehackerway.com/2011/10/07/bind-a-puertos-reservados-utilizando-usuarios-sin-privilegios-de-root/
PidFile: Indica la ubicación donde se creará el fichero con el PID del proceso creado al iniciar el servidor web.
ServerRoot: Indica la ubicación (directorio) donde se encuentra instalado el servidor web, por ejemplo en los pasos de instalación que se han explicado en los párrafos anteriores se ha utilizado la opción “–prefix” del script “configure” con el valor “/opt/apache2.2.22/”, este valor puede establecerse en el parámetro“ServerRoot” del fichero de configuración.
Timeout: Se trata del valor en segundos que esperará el servidor web en procesar peticiones de clientes, en el caso de que una petición tarde más tiempo del permitido en esta propiedad, la respuesta que dará el servidor sera un error de Timeout. El valor que se asigne a esta propiedad debe ser medido con cuidado, ya que si se establece un valor muy pequeño, muchas peticiones darán como resultado un error de Timeout, y en el caso de que el valor sea muy alto, se puede producir una sobre carga en la máquina.
KeepAlive: Se trata de una directiva que le indica al Apache que debe utilizar la misma conexión para procesar todas las peticiones de un cliente determinado, esta características solamente se encuentra soportada desde el protocolo HTTP versión 1.1
MaxKeepAliveRequest: Con este parámetro se suele determinar el número máximo de conexiones persistentes que mantendrá el servidor web (KeepAlive debe de estar en ON). Este valor debe ser medido en función al ancho de banda disponible.
KeepAliveTimeout: Tiempo en el que una conexión persistente podrá permanecer activa antes de que el servidor web determine que debe cerrarla.
LoadModule: Este es probablemente uno de los parámetros más utilizados e importantes desde el punto de vista del administrador, ya que permite cargar módulos en el servidor web que permitirán activar determinadas funcionalidades relacionadas con el rendimiento, la escalabilidad, la seguridad y muchas otras características deseables en un servidor web robusto. Se verá con mayor detalle próximamente.
Directivas en Apache
Las directivas en Apache son bastante similares a los parámetros de configuración globales, de hecho la diferencia es sutil, los parámetros globales son obligatorios y no pueden incluirse en ninguna sección del fichero de configuración diferente a la principal.
A continuación se indican las principales directivas de Apache.
ServerName: Se trata nombre que tendrá el servidor web y (opcionalmente) el puerto que usará Apache para identificarse. Puede ser un dominio DNS o directamente una dirección IP.
NOTA: Si se especifica un valor en esta propiedad, debe de coincidir con el valor del fichero /etc/hosts de lo contrario no será posible acceder al servidor web utilizando el “ServerName”.
ServerAdmin: Se trata simplemente la dirección de correo electrónico del administrador del servidor web.
DocumentRoot: Es una de las principales directivas utilizadas en Apache, ya que determina el directorio donde se almacenarán los directorios y ficheros que conforman las aplicaciones web que se alojarán en el servidor web. Por defecto el valor de esta directiva es el documento “htdocs” ubicado en el directorio principal de Apache.
DirectoryIndex: Indica el fichero que Apache servirá por defecto en el caso de que una petición se lleve a cabo contra un directorio del servidor (ver la directiva DocumentRoot) sin especificar un fichero concreto. Por ejemplo, al poner en el navegador algo como http://localhost/aplicacion se busca el fichero que se ha indicado en esta directiva, ya que en la petición anterior no se ha consultado ningún servidor en concreto. Por defecto el valor de esta directiva es “index.html”
AccessFileName: Por defecto, todos los directorios estan alojados en el servidor web (por defecto en htdocs) cuenta con un fichero de configuración de acceso llamado .htaccess con esta directiva es posible especificar un nombre de fichero distinto. Debe ir acompañada de la directiva AllowOverride
Alias: Se trata de una directiva bastante útil, que le permite al servidor web acceder a recursos que se encuentran fuera del directorio especificado en la directiva DocumentRoot de esta forma, las peticiones que se lleven a cabo contra dicho Alias, le permitirán al servidor web acceder a recursos externos. Por ejemplo:
Alias documentos /home/adastra/Documentos
Ahora cuando se intente realizar la siguiente petición: http://localhost/documentos/documento.pdf se buscará el fichero “documento.pdf” en el directorio “/home/adastra/Documentos” de la máquina.
User / Group: Estos parámetros permiten definir el usuario y el grupo utilizados para ejecutar el servidor web. Normalmente se arranca utilizando el usuario “root” y posteriormente este parámetro realiza el cambio de usuario “bajando” el nivel de privilegios de root a los definidos en el usuario y grupo asignados en este parámetro.
NOTA 1: Estos valores son de carácter obligatorio, si no se especifican el servidor web simplemente no arrancará. Se recomienda crear un usuario y un grupo con privilegios limitados.
NOTA 2:
En versiones de Apache 2.4 es necesario cargar el modulo mod_unixd para que funcionen correctamente las directivas User y Group, para ello incluir en el fichero de configuración la siguiente linea:
LogLevel: Permite controlar el numero de mensajes reportados en el fichero de logs (error_log). Los posibles valores que se pueden establecer en este parámetro son: debug, info, notice, warn, error, crit, alert, emerg. Siendo los primeros los de prioridad más baja (carácter informativo) y los últimos de prioridad alta (carácter urgente)
DefaultType: Es el tipo MIME por defecto en el caso de que el servidor web no pueda determinar uno adecuado para una petición concreta. Si se trata de un servidor web estándar donde la mayoría de documentos almacenados son ficheros HTML y texto plano, probablemente el valor más acertado para establecer en este parámetro es “text/plain” en el caso de que el servidor aloje en su mayoría ficheros binarios, el mejor valor para este parámetro seria “application/octet-stream”
ErrorDocument: Con este parámetro se pueden definir respuestas personalizadas para diferentes tipos de errores HTTP producidos en alguna de las peticiones realizadas por el cliente. Por ejemplo:
ErrorDocument 500 «El servidor ha fallado. Algo ha ido muy mal y no lo estamos controlando…»
ErrorDocument 404 /paginaNoEncontrada.html
Include: Permite incluir otros ficheros de configuración con parámetros globales, directivas y otros elementos de configuración validos para el servidor web que se anexan el fichero principal, es simplemente la inclusión de otros ficheros de configuración al fichero principal.
<Directory>: Con esta directiva se pueden agrupar otras directivas y opciones que permiten controlar el acceso a un directorio y/o fichero determinado
<DirectoryMatch>: Funciona del mismo modo que la directiva <Directory> sin embargo, permite el uso de expresiones regulares.
<Files>: Permite el control de acceso a determinados ficheros.
<FilesMatch>: Funciona igual que <Files> sin embargo, permite el uso de expresiones regulares.
<Location>: Permite el control de acceso a determinados ficheros mediante URL.
<LocationMatch>: Funciona igual que la directiva <Localtion> sin embargo, permite el uso de expresiones regulares.
<IfDefine>: Solo se aplica si al arrancar el servidor existe un determinado parámetro definido en el comando utilizado para arrancar el servidor web.
<IfModule>: Se trata de parámetros que se aplican únicamente si un determinado modulo se encuentra cargado con la directiva “LoadModule” anteriormente explicada.
DIRECTIVAS DE SECCION:
La mayoría de las directivas relacionadas con el control de ficheros (<Directory>, <Files>, <Location>, etc.) incluyen una serie de directivas de sección que permiten establecer diferentes niveles de configuración. Estas directivas de sección son:
Allow: Permite especificar que direcciones Ip, Dominios, fragmentos de nombres de dominio o variables de petición que pueden tener acceso a un determinado recurso
Deny: Funciona igual que Allow, con la diferencia que no permite, deniega el acceso a un determinado recurso.
Order: Permite especificar el orden que se debe seguir sobre las dos directivas anteriormente descritas en un recurso determinado. Por ejemplo:
Order allow, deny: Por defecto se permite el acceso y se deniega el mismo solamente a aquellos que cumplan con las condiciones indicadas en la directiva “deny”. (Modelo Permisivo)
Order deny, allow: Por defecto se deniega el acceso y solamente se permite el mismo a aquellos que cumplan con las condiciones indicadas en la directiva “allow”. (Modelo Restrictivo)
SERVIDORES VIRTUALES
Los servidores virtuales han sido desde siempre, una de las características más interesantes en Apache, además de ser uno de los primeros servidores web que soportaban esta característica. Un host virtual desde un punto de vista practico es la agrupación de uno o muchos sitios web en una misma dirección IP o nombre de dominio, es por este motivo que cada servidor virtual puede (y debe) contener algunas de las directivas anteriormente descritas para personalizar el comportamiento de dicho host. Como su nombre lo indica, da la sensación al usuario que esta accediendo a un servidor web diferente, sin embargo en realidad esta accediendo a la misma instancia del servidor web, esto supone un ahorro en términos de direcciones IP e incluso máquinas en el caso de que se desee publicar varios servidores con características diferentes. Ahora bien, es posible definir dos tipos de servidores virtuales, por dirección IP o por Nombre.
Servidores virtuales por Dirección IP:
Los servidores virtuales por dirección IP, permiten definir diversos hosts virtuales cada uno con su propia dirección IP, evidentemente es necesario que el servidor web tenga acceso a dicha dirección IP. Para ello es necesario utilizar la directiva <VirtualHost> de la siguiente forma:
<VirtualHost 192.168.1.2>
ServerAdmin adastra@i2p.com DocumentRoot /home/adastra/web ServerName adastra.com </VirtualHost> <VirtualHost 192.168.1.3> ServerAdmin adastra2@i2p.com DocumentRoot /home/adastra/web2 ServerName adastra2.com </VirtualHost> |
Como puede apreciarse, cada Virtual Host tiene su propia dirección IP y sus directivas personalizadas (incluyendo un DocumentRoot) de esta forma es relativamente fácil definir varios servidores web virtuales en una única instancia de Apache.
Servidores Virtuales por Nombre
Funcionan de un modo muy similar a los servidores virtuales por dirección IP, con la diferencia que en este tipo de servidores virtuales se comparte la misma dirección IP y solamente es necesario declarar un nombre de servidor único para cada Host virtual. Un ejemplo valido de este tipo de configuración seria:
NameVirtualHost *:80
<VirtualHost *:80> ServerAdmin adastra@i2p.com DocumentRoot /home/adastra/web ServerName adastra.com </VirtualHost> <VirtualHost *:80> ServerAdmin adastra2@i2p.com DocumentRoot /home/adastra/web2 ServerName adastra2.com </VirtualHost>. |
Como puede apreciarse, contienen básicamente la misma configuración que se ha declarado para los hosts virtuales por dirección IP, la diferencia esta en la directiva NameVirtualHost en donde se define que se tratarán todas las peticiones por el puerto 80 y además, la misma regla para cada host virtual (aceptar todas las peticiones por el puerto 80). En este caso el ServerName es único para cada host virtual.
Los conceptos que se han indicado en esta publicación, probablemente ya serán conocidos por muchos de los lectores de este blog, no obstante por algunos otros serán conceptos nuevos y es para ellos a los que va dirigida esta entrada, principalmente porque es necesario entender como se lleva a cabo el proceso de configuración de este servidor web para conseguir elaborar configuraciones un poco más elaboradas que permitan mejorar la seguridad y estabilidad del servidor web, en la próxima publicación se hablará un poco más sobre estos temas.