Dentro de la serie de entradas que le estoy dedicando al noble arte del hardening software, en esta ocasión nos vamos a detener en uno de los stacks más utilizados a nivel global: (Linux+Apache+MySQL+PHP/Perl/Python).

lamp_ubuntu

Este paquete de soluciones está disponible para casi cualquier sistema operativo de Escritorio ó Servidor y con él cubriremos el ciclo completo de vida de muchas aplicaciones tanto web como standalone.

El proceso de instalación y configuración es muy sencillo y no es el objetivo de este post (ya que la red rebosa tutoriales de ello), por lo que vamos a partir de que ya tenemos los paquetes descargados e instalados en nuestro sabor de favorito (tened siempre presente las contraseñas de administrador que le hayáis puesto a cada uno de los servicios para ahorraros problemas en pasos futuros).

1. First things first. Ficheros de configuración.

Ubuntu, Debian & Linux Mint:

  • 2: /etc/apache2/apache2.conf
  • 5: /etc/php5/apache2/php.ini
  • : /etc/mysql/my.cnf

CentOS, RedHat & Fedora:

  • Apache: /etc/httpd/conf/httpd.conf
  • PHP: /etc/php.ini
  • MySQL: /etc/my.cnf

2. Retocando Linux

hardening_linux

Fortificar un Sistema Operativo es un proceso complejo en el que tenemos que tener en cuenta muchos factores, entre ellos -y principalmente- el propósito de la máquina y las aplicaciones que necesita ejecutar.

Entre las medidas concretas que abordaría en una instalación limpia de un servidor Linux, yo empezaría por particionar de forma correcta el disco duro de nuestra máquina, para luego cifrar nuestra carpeta de usuario (ó una partición entera) o montar otra únicamente por SSH, restringir el acceso remoto a la misma y recibir notificaciones de los intentos no autorizados, tener configurado de forma correcta un firewall software, programar una buena política de backups e implementar las medidas de protección física necesarias si es que la tenemos en nuestras oficinas o DataCenter, entre muchas otras.

3. Retocando Apache

apache-lock

3.1. Ocultando la version y SO(Apache)

La directive ServerTokens controla la información enviada en las respuestas del servidor. Con ServerSignature se configura la firma en los archivos generados por el servidor.

Por tanto, editaríamos el fichero de configuración de Apache con:

ServerTokens Prod
ServerSignature Off

3.2. Comprobar que Apache está ejecutándose bajo su propio usuario y grupo

El usuario por defecto tras la instalación es “nobody”. Puede haber otras aplicaciones que también se ejecuten con el mismo usuario, por lo que si ese usuario es comprometido puede afectar a otros servicios. Lo recomendable es crear un usuario específico “apache” en el sistema y modificar httpd.conf con las siguientes directivas:

User apache
Group apache

3.3. Desactivar el listado de directorios

Todos los archivos y directorios aparecerán listados si en el recurso solicitado no tiene documento por defecto a mostrar.

<Directory />
Options -Indexes
</Directory>

3.4. Restringir el acceso a archivos y directorios

Para restringir y permitir el acceso por dirección IP, podemos definir en nuestros Virtual Hosts la siguiente directiva:

<Directory "/home/user/public_html">
Order Deny,Allow
Deny from all
Allow from 192.168.1.0/24
Allow from .example.com
</Directory>

3.5. Desactivar “Server Side Includes” y “CGI Execution”

Con esto evitaremos que se ejecuten scripts de código malicioso potencial del lado del servidor. Para ello, modificaremos en el fichero de configuración lo siguiente:

<Directory "/home/user/public_html">
Options -Includes -ExecCGI
</Directory>

3.6. Mitigación ataques DoS

3.6.1. Modificar el valor “timeout”:

El valor por defecto del timeout es 300 segundos. Decrementando este valor puede mitigarse los efectos de ataques de denegación de servicio:
Timeout 45

3.6.2. Limitar el tamaño de las peticiones HTTP:

Para mitigar ataques de denegación de servicio a nivel de aplicación (http) se puede limitar el tamaño del cuerpo de las peticiones. Si el servicio lo permite, se puede limitar, por ejemplo, a 1Mb:
LimitRequestBody 1048576

4. Retocando PHP

hardening_php

4.1. Controlar la fuga de información

Por defecto, las instalaciones PHP exponen públicamente información sobre la instalación en el servidor, incluyendo la versión dentro de cabeceras HTTP (Ej:, X-Powered-By: PHP/5.4.20). Para evitar esto, editaremos php.ini deshabilitando la siguiente directiva:
expose_php = Off

Por otro lado, si queremos logear todos los errores PHP en un fichero y no en recursos web accesibles:
display_errors = Off
log_errors = On
error_log = /var/log/httpd/php_error.log

4.2. Deshabilitar la ejecución de código remota

La directiva allow_url_fopen permite la ejecución de funciones de manejo de archivos tales como file_get_contents(), lo que permite extraer información mediante HTTP o FTP de sitios remotos y ejecutar su código, lo cual puede resultar peligroso. Para evitarlo:

allow_url_fopen=Off
allow_url_include=Off

4.3. Deshabilitar funciones PHP peligrosas

Podemos deshabilitar el uso de diversas funciones PHP usando la directiva disable_functions en el fichero de configuración de PHP. Se recomienda deshabilitar todas las funciones que puedan suponer un riesgo innecesario.

disable_functions =exec,shell_exec,passthru,system,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,proc_open,pcntl_exec

4.4. Limitar el acceso a PHP al sistema de ficheros

La directiva open_basedir establece los directorios a los que podrá acceder PHP:

open_basedir="/home/user/public_html"

4.5. Deshabilitar módulos PHP no utilizados

PHP soporta extensiones dinámicas para cargar módulos en su entorno. Se recomienda deshabilitar los módulos no usados que puedan ser cargados en el sistema.
Para buscar módulos instalados:

grep LoadModule httpd.conf

Algunos módulos que suelen estar habilitados y no suelen ser usados:

mod_imap
mod_include
mod_info
mod_userdir
mod_status
mod_cgi
mod_autoindex

4.6. Habilitar diversos límites

4.6.1. Tamaño máximo de los ficheros que los usuarios pueden subir:

upload_max_filesize = 2M #

4.6.2. Tiempo máximo de ejecución de los scripts:

max_execution_time = 30 # segundos

4.6.3. Tiempo máximo permitido a un script para parsear información:

max_input_time = 60 # segundos

5. Retocando MySQL

dolphin-simpsons

5.1. Restringir el acceso remoto a MySQL

Si la aplicación no requiere acceso remoto a la base de datos se recomienda deshabilitar esta opción. Una manera sencilla de hacerlo es decirle al servicio MySQL que escuche conexiones solo en localhost.
Editar el fichero de configuración MySQL con la siguiente directiva:

bind-address=127.0.0.1

5.2. Deshabilitar el acceso a ficheros locales

La directiva LOCAL-INFILE puede resultar peligrosa. Permite que un usuario pueda cargar ficheros locales ( /etc/passwd, /etc/shadow ) en una tabla de la base de datos. Modificar lo siguiente en la sección [mysqld].

[mysqld]
local-infile=0

5.3. Crear y usar un usuario específico para MySQL

NO se debe utilizar el usuario ‘root’ para acceder a la base de datos desde la aplicación. Se debe crear un usuario específico para ello con acceso y permisos limitados (sólo a la base de datos). Para conseguirlo, abrimos una terminal y escribimos:

~# mysql -u root -p

mysql> CREATE USER 'myusr'@'localhost' IDENTIFIED BY 'password';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE ON mydb.* TO 'myusr'@'localhost' IDENTIFIED BY 'password';
mysql> FLUSH PRIVILEGES;

5.4. Evitar que un usuario pueda ver el nombre de otras bases de datos

[mysqld]
skip-show-database

5.5. Usar mysql_secure_installation

Tras la instalación de MySQL, mysql_secure_installation puede resultar útil para una securización adicional del servidor MySQL.

# mysql_secure_installation

Change the root password? [Y/n] y
New password: **********
Re-enter new password: **********

Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] y
Remove test database and access to it? [Y/n] y
Reload privilege tables now? [Y/n] y

6. Últimos retoques

6.1. Proteger los archivos de configuración contra permisos de escritura (Apache/MySQL/PHP)

Eliminar los permisos de escritura de ficheros de configuración de LAMP de tal forma que ningún usuario pueda realizar cambios sobre ellos:

# chattr +i /etc/php.ini
# chattr +i /etc/php.d/*
# chattr +i /etc/my.cnf
# chattr +i /etc/httpd/conf/httpd.conf

(+i -> Establece que el archivo será inmutable. Es decir, se impide que el archivo sea eliminado, renombrado, que se pueden apuntar enlaces simbólicos hacia éste o escribir datos en el mismo)
OJO: Tras habilitar esta protección ni siquiera root podrá modificar estos archivos.

6.2. Para protección de ataques SQL y otros ataques

  • Asegurarse de que las aplicaciones y sus plugins están actualizadas (sobre todo CMS tipo Joomla, WordPress, Drupal, etc.).
  • Suscribirse a canales de publicación de actualizaciones y publicación de vulnerabilidades.
  • Evitar siempre permisos de tipo 777 en ficheros o directorios.
  • Chequeos frecuentes de software antivirus.
  • Siempre que la aplicación intercambie información confidencial con los usuarios email, passwords, tarjetas de crédito etc, asegurarse del uso de certificados digitales y TLS.

7. Conclusión

En fin, creo que si somos capaces de aplicar todas las directivas aquí expuestas, habremos dado un salto cualitativo en tareas de defensa de nuestras aplicaciones. Sin embargo, como cada maestrillo tiene su librillo, os animo a que compartáis en los comentarios alguna medida a mayores que se me haya quedado en el tintero y que sea una must en vuestro día a día de sistemas.

Deja un comentario