A la hora de tener mantener un servidor web, es necesario tenerlo controlado y securizarlo todo lo posible para evitar ataques, penetraciones o exponer información sensible. En este post, se van a dar ciertos consejos para poder tener un apache optimizado y securizado. Además de para apache, se darán pequeñas indicaciones para mejorar la seguridad en PHP y MySQL.
Apache
Para empezar con la securización, empezamos editando los archivos de configuración y modificando lo siguiente:
vim /etc/apache2/apache2.conf
Y aquí modificar lo siguiente (puede que haya cosas que no haga falta cambiar)
Timeout 100 KeepAlive On KeepAliveTimeout 5 MaxKeepAliveRequests 100
Luego, es recomendable ajustar los valores de nuestro mpm. Para ver que mpm se está usando hay que hacerlo con el comando apachectl -M y ver los módulos cargados. En este caso se usará prefork que es el que viene por defecto. Estos valores variaran dependiendo de los recursos de la máquina. El ejemplo que se muestra es para una VPS sencilla. Si se quieren ajustar mas, recomiendo este post.
<IfModule mpm_prefork_module> StartServers 5 MinSpareServers 5 MaxSpareServers 10 ServerLimit 100 MaxClients 150 MaxRequestsPerChild 500 </IfModule>
A continuación modificar el fichero de seguridad de apache
vim /etc/apache2/conf-available/security.conf
Cambiar lo siguiente:
ServerTokens Prod ServerSignature Off TraceEnable Off FileETag None
Y por último añadir las siguientes líneas
Header set X-Content-Type-Options: "nosniff" Header set X-XSS-Protection: "1; mode=block" Header always append X-Frame-Options "SAMEORIGIN" Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure Header set X-Permitted-Cross-Domain-Policies "none" Header unset "X-Powered-By" Header always unset "X-Powered-By" Header always unset "X-Pingback" Header always unset "X-CF-Powered-By" Header always unset "X-Mod-Pagespeed" Header set Referrer-Policy "no-referrer-when-downgrade" #Esta cabecera puede que haya que ajustarla en base a las necesidades de la web Header set Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval';
Es recomendable habilitar la cabecera CSP, pero hay que tener cuidado ya que al ser tan restrictiva puede deshabilitar ciertas funciones de la página. Para utilizar la configuración adecuada, recomiendo la extensión para firefox: Laboratory (Content Security Policy / CSP Toolkit)
Habilitar el modulo de headers
a2enmod headers
Deshabilitar módulos innecesarios por defecto
a2dismod status a2dismod autoindex
MOD_SECURITY2
Mod_Security2, es uno de los WAF (Web Application Firewall), mas famosos que hay. Lo que hace es proteger las aplicaciones web mediante un firewall con unas reglas predefinidas que se cargan evitando así posibles ataques XSS, sqli…
Instalar el modulo
apt install libapache2-mod-security2
Editar el archivo de configuración y configurar lo siguiente
vim /etc/apache2/mods-enabled/security2.conf
#IncludeOptional /etc/modsecurity/*.conf Include /etc/modsecurity/owasp-modsecurity-crs/crs-setup.conf Include /etc/modsecurity/owasp-modsecurity-crs/rules/*.conf Include /etc/modsecurity/modsecurity.conf
Descargar las reglas de OWASP para modsecurity2
cd /etc/modsecurity/ && git clone https://github.com/SpiderLabs/owasp-modsecurity-crs && cd owasp-modsecurity-crs
Crear el archivo de configuración de crs
cp /etc/modsecurity/owasp-modsecurity-crs/crs-setup.conf.example /etc/modsecurity/owasp-modsecurity-crs/crs-setup.conf
Crear el archivo de configuración de modsecurity
cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
Editar la configuración
vim /etc/modsecurity/modsecurity.conf
Y añadir los siguiente
SecServerSignature " "
Activar el módulo
a2enmod security2
Más info: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual
MOD_QOS
El módulo QoS previene los ataques DoS evitando así la sobrecarga de peticiones en el servidor y la caída de los servicios. Este módulo no es soportado por apache 2.4
Instalar el modulo QoS
apt install libapache2-mod-qos
Editar el archivo de configuración
vim /etc/apache2/mods-enabled/qos.conf
<IfModule qos_module> QS_ClientEntries 100000 MaxClients 50 QS_SrvMaxConn 1000 QS_SrvMaxConnClose 700 QS_SrvMaxConnPerIP 150 </IfModule>
REQTIMEOUT
Este módulo viene en apache por defecto por lo tanto solo hay que activarlo. Y lo que hace es establecer limites de tiempo en las peticiones.
Habilitar el módulo
a2enmod reqtimeout
Editar el archivo de configuración
vim /etc/apache2/mods-enabled/reqtimeout.conf
<IfModule reqtimeout_module> RequestReadTimeout header=10-40,minrate=500 RequestReadTimeout body=10-30,minrate=500 </IfModule>
Mod_evasive
Instalar el modulo mod_evasive
apt install libapache2-mod-evasive
Crear el directorio de logs
mkdir -p /var/log/apache2/evasive chown -R www-data:root /var/log/apache2/evasive
Editar la configuración del módulo
vim /etc/apache2/mods-available/evasive.load
LoadModule evasive20_module /usr/lib/apache2/modules/mod_evasive20.so DOSHashTableSize 3097 DOSPageCount 2 DOSSiteCount 50 DOSPageInterval 5 DOSSiteInterval 1 DOSBlockingPeriod 10 DOSLogDir "/var/log/apache2/evasive"
SITES
Por último, hay que tener los sites bien configurados. Es recomendable el forzar que las conexiones se realicen por HTTPS para que sean cifradas.
Activar el módulo de reescritura
a2enmod rewrite
Editar el archivo de site que esté escuchando en el puerto 80 y forzar la reescritura y personalizar los logs
vim /etc/apache2/sites-available/000-default
Redirect permanent / https://dominio.com/ ErrorLog ${APACHE_LOG_DIR}/error-web80.log CustomLog ${APACHE_LOG_DIR}/access-web80.log combined env=!client-ip-request CustomLog ${APACHE_LOG_DIR}/access-web80.log proxy env=client-ip-request
Activar el módulo de SSL
a2enmod ssl
Editar el archivo del site que esté escuchando en el 443 y habilitar los certificados, crear el diffie-hellman y personalizar los logs.
Crear el certificado diffie-hellman
cd /etc/ssl/certs
openssl dhparam -out dhparam.pem 4096
Configurar el site
vim /etc/apache2/sites-available/default-ssl.conf
SSLEngine on SSLCertificateFile /etc/ssl/ichasco/ichasco.crt SSLCertificateKeyFile /etc/ssl/ichaco/ichasco.key SSLCertificateChainFile /etc/ssl/ichasco/bundle.crt SSLCompression off SSLProtocol All -SSLv2 -SSLv3 SSLHonorCipherOrder on SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4 <IfModule headers> Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" </IfModule> # Hay que tener una version de openssl 1.0.2 SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem" ErrorLog ${APACHE_LOG_DIR}/error-web443.log CustomLog ${APACHE_LOG_DIR}/access-web443.log combined env=!client-ip-request CustomLog ${APACHE_LOG_DIR}/access-web443.log proxy env=client-ip-request
Una vez hecho todo esto hay que reiniciar apache
systemctl restart apache2.service
Comandos interesantes de apache
Ver los módulos cargados
apachectl -M
Comprobar si la sintaxis de los ficheros de configuración es correcta
apachectl configtest
Ver el estado de apache
apachectl fullstatus
PHP
Desactivar el que php exponga información
vim /etc/php5/apache2/php.ini
expose_php = Off
Comprobar los módulos de PHP
php -m
Para deshabilitar
phpdismod <módulo>
MySQL
Lanzar el comando propio de mysql para una instalación segura
mysql_secure_installation
Que solo esté escuchando en localhost
vim /etc/mysql/my.cnf
[mysqld] ... bind-address=127.0.0.1