Blog

Seguridad de servidores – Parte IV – PHP, MariaDB y MySQL

En las entradas anteriores, vimos un ejemplo para enjaular los servicores web Apache y Nginx y cómo ocultar la información de versión y nombre de servidor. Pero, un servidor web requerirá que tenga soporte para PHP y MySQL o MariaDB. Por defecto, al igual que ocurre con los servidores, la configuración muestra demasiada información y es excesivamente permisiva. Veamos cómo securizarlos.

En el caso de PHP, lo primero que vamos a hacer es instalarlo. En el caso de Arch Linux, sería:

sudo pacman -S php

Para ver qué módulos tenemos disponibles, bastará hacer un filtrado de paquetes:

pacman -Ss php-

En el caso de Apache, necesitamos, cómo mínimo, el paquete php-apache. Este paquete nos proporciona un módulo para que Apache tenga soporte para PHP.  En el caso de Nginx, vamos a utilizar php-fpm. Actuará como un servidor y Nginx enviará a él las solicitudes de archivos .php. Es decir, Nginx actuará como proxy inverso.

sudo pacman -S php-apache php-fpm

Para la base de datos, la mayor de parte de aplicaciones utilizan MySQL. Algunas distribuciones incorporan MariaDB, que funciona como un reemplazo de MySQL. Comparten nombre de binario, localización de archivos de configuración y, en general, se puede sustituir MySQL por MariaDB sin inconvenientes. MariaDB surge al limitar Oracle la licencia a MySQL y, esta última, derrollada por el creador de MySQL, es licencia GPL.

La configuración de Apache la encontramos en /etc/http/conf. El archivo donde especificamos los módulos es /etc/http/conf/http.conf. Lo editamos y añadimos al final de la lista de módulos, el correspondiente a PHP:

LoadModule speling_module modules/mod_speling.so
LoadModule userdir_module modules/mod_userdir.so
LoadModule alias_module modules/mod_alias.so
LoadModule rewrite_module modules/mod_rewrite.so

#php
LoadModule php5_module modules/libphp5.so

Al final de la lista de “include” añadimos:

...
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>

#php
Include conf/extra/php5_module.conf

Nos aseguramos de que está descomentada la siguiente línea, dentro de la sección <IfModule mime_module>:

TypesConfig conf/mime.types

Y descomentamos también la línea:

MIMEMagicFile conf/magic

Vamos a crear en el directorio /srv/http/ el archivo index.php, con el siguiente contenido:

<?php phpinfo(); ?>

Reiniciamos Apache. Si en /srv/http tuviésemos un index.html, tendrá prioridad sobre el index.php, con la configuración actual.

Una vez reiniciado el servidor, veamos qué nos muestran las cabeceras al acceder al mismo:

php_con_expose

Podemos ver que, aunque Apache esté en modo producción, nos muestra la versión de PHP. Esto ocurre porque, por defecto, la variable expose_php está a On. La cambiamos a Off y observamos que ya no nos muestra la información sobre PHP:

php_sin_expose

Si accedemos a la dirección http://localhost, podemos ver que, al ejecutarse la función phpinfo, nos mostrará toda la información acerca de nuestro servidor, versión, módulos cargados, rutas,etc. Por defecto, podemos ejecutar todas las funciones que nos proporciona PHP. Esto resulta muy peligroso y es conveniente restrigirlas. Una lista de funciones que es conveniente restrigir es: system, passthru, escapeshellarg, escapeshellcmd, proc_close, proc_open, ini_alter, popen, show_source, pcntl_exec y phpinfo. Para hacerlo, bastará buscar la variable disable_functions y añadir aquí la lista:

disable_functions ="system,passthru,escapeshellarg,escapeshellcmd,proc_close,proc_open,ini_alter, /
 popen,show_source,pcntl_exec,phpinfo"

Ahora, si accedemos a http://localhost, veremos que no nos carga nada. Entre otras funciones, hemos deshabilitado aquellas que permiten ejecución de funciones de sistema.

Además de esto, es interesante que no se muestre la ID de la sesión en la dirección, cuando estemos navegando. Se deshabilita con session.use_trans_sid. Por defecto, está a 0, pero es conveniente comprobarlo.

Otra directiva que es interesante deshabilitar es allow_url_fopen. Por defecto, algunas funciones permiten hacer llamadas a archivos que no se encuentran en local. Esto es peligroso y lo mejor es que solo se pueda acceder a los archivos en local. Bastará establecerla a Off.

Conviene comprobar que está también está deshabilitada display_errors. En caso de no estarlo, mostrará los posibles errores al navegar y, un atacante, podrá aprovecharse de esto.

Todas estas directivas se toman como base para php-fpm, con lo que esta configuración nos vendrá bien también para Nginx, dado que será lo que utilizaremos para interpretar el código PHP.

En el caso de Apache, si lo hemos enjaulado, habrá que añadir también en la jaula los archivos correspondientes a PHP, junto con las bibliotecas que utilicen. Si estamos utilizando php-fpm, no es necesario, pues incluye una variable, chroot, donde podemos especificar el directorio a partir del cual está nuestra aplicación. Sí será necesario restringir qué máquinas pueden conectarse al servidor php-fpm. Esto se hace mediante la directiva listen.allowed_clients.

En el caso de la base de datos, MariaDB o MySQL, hay que tener en cuenta que no debe ser accesible desde el exterior de nuestra red local. El archivo de configuración en Arch Linux es /etc/mysql/my.cnf. Por defecto, la directiva skip-networking está descomentada y la configuración está preparada para escuchar socket. En caso de no estar descomentada, sería necesario añadir una #.

Una de las cosas que se pueden hacer dentro de MySQL o MariaDB es cargar archivos. Es interesante comprobar qué usuarios tienen este privilegio y revocarlo a aquellos que no lo necesiten. Podemos verificar este permiso con la setencia:

select user,host,file_priv from mysql.user;

Por defecto, MySQl y MariaDB instalan una base de datos de prueba y usuarios anónimos. Para eliminar esta base de datos y estos usuarios, además de establecer una contraseña para el usuario administrador, es conveniente ejecutar el script mysql_secure_installation.

Con esto, habremos conseguido obtener más seguridad en nuestro servidor, además de ocultar información que puede ser utilizada por un atacante. Puede aumentarse aún más, por ejemplo, ejaulando la base de datos.

Cómo vemos, siempre es necesario modificar la configuración por defecto de los servidores, pues ésta no está pensada para producción.

En el próximo artículo, veremos cómo utilizar algunas herramientas para prevenir ataques de fuerza bruta y mitigar atagar DDOS, happy hacking!

Mª José Montes – mjose@highsec.es – @MMontesDiaz

Leave a Reply

*

    No Twitter Messages