Seguridad

Fortificar su servidor web: guía de seguridad para Nginx y Apache

Opciones de seguridad para un VirtualHost de Apache o un bloque server de Nginx: HTTPS con Certbot, HTTP/2, cabeceras, métodos y límite de peticiones.

· 11 min de lectura · nivel intermedio
Illustration 1 — Fortifier votre Serveur Web : Guide de Sécurité pour Nginx et Apache

Al configurar un VirtualHost en Apache o un Server Bloc en Nginx (dos de los servidores web más utilizados), existen varias opciones de seguridad que puede plantearse.

Estas son algunas de ellas, aunque los detalles concretos dependen del tipo de servidor web que utilice y de los requisitos de seguridad propios de su aplicación.

Índice

Configuración de HTTPS con Certbot

Actualización a las versiones HTTP/2 y HTTP/3

Desactivación del envío de la información de versión

Configuración de las cabeceras de seguridad HTTP

Desactivación de los métodos HTTP no utilizados

Activación de la protección contra la denegación de servicio

Configuración de HTTPS

Se trata del primer paso y del más importante. HTTPS cifra el tráfico entre el cliente y el servidor, lo que hace mucho más difícil interceptarlo y leerlo. Para ello necesitará un certificado SSL, que puede obtenerse gratuitamente a través de Let's Encrypt o comprarse a distintos proveedores. Una vez que disponga de un certificado, puede configurar su servidor para utilizarlo.

Asegúrese de sustituir "exemple.com" y "www.exemple.com" por su dominio.

< w/ Nginx >

Así es como puede instalar Certbot y obtener un certificado SSL para Nginx en un sistema Linux basado en Debian (como Ubuntu):

Instale el programa Certbot y el complemento Nginx ejecutando el siguiente comando:


sudo apt-get install certbot python3-certbot-nginx

A continuación, utilice Certbot para obtener un certificado SSL y configurar Nginx:


sudo certbot --nginx -d exemple.com -d www.exemple.com

Siga las instrucciones que aparecen en pantalla. Certbot modificará automáticamente la configuración de Nginx para aplicar el certificado SSL.

< w/ Apache >

Así es como puede instalar Certbot y obtener un certificado SSL para Apache en un sistema Linux basado en Debian (como Ubuntu):

Instale el programa Certbot y el complemento Apache ejecutando el siguiente comando:


sudo apt-get install certbot python3-certbot-apache

A continuación, utilice Certbot para obtener un certificado SSL y configurar Apache:


sudo certbot --apache -d exemple.com -d www.exemple.com

Siga las instrucciones que aparecen en pantalla. Certbot modificará automáticamente la configuración de Apache para utilizar el certificado SSL.

Certbot también intentará renovar automáticamente sus certificados antes de que caduquen. Puede probar el proceso de renovación automática con el siguiente comando:


sudo certbot renew --dry-run

Activación de la versión 2 de HTTP

HTTP/2 es la segunda versión principal del protocolo HTTP y aporta numerosas mejoras de rendimiento frente a HTTP/1.1, en particular gracias a la multiplexación de las peticiones, que permite enviar varias peticiones en paralelo por una sola conexión.

< w/ Nginx >

Para activar HTTP/2 en Nginx, basta con añadir el parámetro http2 a sus directivas listen en la configuración de su servidor.

Abra el archivo de configuración de Nginx correspondiente a su sitio. Suele encontrarse en /etc/nginx/ o /etc/nginx/sites-available/.

Añada http2 a la directiva listen para las conexiones SSL, de la siguiente manera:


server {
    listen 443 ssl http2;
    ...
}

< w/ Apache>

En Apache, la activación de HTTP/2 requiere el uso del módulo mod_http2.

Asegúrese de que el módulo mod_http2 está activado. Puede activarlo ejecutando el siguiente comando:


sudo a2enmod http2

A continuación, abra el archivo de configuración de su sitio Apache. Suele encontrarse en el directorio /etc/apache2/sites-available/.

Añada la directiva Protocols para activar HTTP/2:


<VirtualHost *:443>
    Protocols h2 http/1.1
    ...
</VirtualHost>

Esto activará HTTP/2 para su sitio web. Tenga en cuenta que HTTP/2 se utiliza generalmente con HTTPS, así que asegúrese de que su sitio está protegido con él.


Desactivación de la información de versión del servidor

De forma predeterminada, su servidor puede incluir información de versión en sus respuestas a través de las cabeceras HTTP, lo que puede ayudar a los atacantes a identificar posibles vulnerabilidades. Aunque esto puede resultar útil para depurar, también puede facilitar información valiosa a un posible atacante. Por ejemplo, si su servidor utiliza una versión de software con fallos de seguridad conocidos, un atacante puede aprovechar esos fallos para atacar su servidor.

Por lo tanto, es preferible desactivar esa información de versión. Así es como puede hacerlo:

< w/ Nginx >

En Nginx puede modificar la configuración básica, que se encuentra en /etc/nginx/nginx.conf, y utilizar la directiva server_tokens para controlar si se envía la información de versión del servidor.

Modifique el archivo de configuración predeterminado:


sudo nano /etc/nginx/nginx.conf

A continuación, descomente la siguiente línea (borre la #), si está presente, o añádala.


server_tokens off;

server_tokens off; indica a Nginx que no incluya la información de versión en las cabeceras HTTP.

Esta directiva también puede colocarse en un bloque server de un archivo de configuración de Nginx si no desea que se aplique de forma general.

< w/ Apache >

En la configuración básica de Apache, debe modificar el archivo de configuración principal. El nombre y la ubicación exactos de este archivo pueden variar según su sistema operativo y su método de instalación, pero suele llamarse apache2.conf o httpd.conf y encontrarse en un directorio como /etc/apache2/ o /etc/httpd/.

Modifique el archivo de configuración predeterminado:


sudo nano /etc/apache2/apache2.conf

Busque las directivas ServerTokens y ServerSignature y modifíquelas o añádalas de la siguiente manera:


ServerTokens Prod
ServerSignature Off

ServerTokens Prod indica a Apache que devuelva únicamente el nombre del producto (es decir, "Apache") sin ninguna información de versión. ServerSignature Off desactiva la inclusión de la información de versión del servidor en las páginas de error generadas por el servidor.

Estas directivas pueden colocarse en cualquier lugar en la raíz del archivo de configuración, fuera de todo bloque <VirtualHost> o <Directory>.


Configuración de las cabeceras de seguridad HTTP

Existen varias cabeceras HTTP que pueden mejorar la seguridad de su sitio web, como X-Content-Type-Options: nosniff (que impide que el navegador "adivine" el tipo de contenido) y Content-Security-Policy (que limita desde dónde puede cargarse el contenido).

< w/ Nginx >

En Nginx, las cabeceras de seguridad pueden añadirse mediante la directiva add_header dentro de un bloque server o location del archivo de configuración (habitualmente situado en /etc/nginx/nginx.conf o /etc/nginx/sites-available/default).

Por ejemplo:


server {
    ...
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-XSS-Protection "1; mode=block";
    add_header Content-Security-Policy "default-src 'self'";
    ...
}

< w/ Apache >

En Apache, puede utilizar el módulo mod_headers para añadir cabeceras de seguridad. Puede añadirlas dentro de un bloque Directory, Location o Files del archivo de configuración de Apache (habitualmente situado en /etc/apache2/sites-available/000-default.conf o /etc/httpd/conf/httpd.conf).

Por ejemplo:


<Directory /var/www/html>
    ...
    Header always set X-Frame-Options "SAMEORIGIN"
    Header set X-XSS-Protection "1; mode=block"
    Header set X-Content-Type-Options "nosniff"
    Header set Content-Security-Policy "default-src 'self'"
    ...
</Directory>

Tras añadir estas directivas, no olvide reiniciar o recargar su servidor web para que los cambios surtan efecto.

Estas directivas de cabecera tienen el mismo sentido tanto en Nginx como en Apache.

Explicaciones:

  • X-Frame-Options: SAMEORIGIN : impide que su sitio se incruste en un iframe, lo que puede ayudar a prevenir los ataques de tipo "clickjacking". SAMEORIGIN significa que la página solo puede mostrarse en un marco del mismo origen que la propia página.
  • X-XSS-Protection: 1; mode=block : esta cabecera activa el filtro de scripts entre sitios (XSS) incorporado en los navegadores web. En modo block, impide que la página se represente si se detecta un ataque.
  • X-Content-Type-Options: nosniff : impide que el navegador realice lo que se denomina "MIME-type sniffing", es decir, que intente adivinar el tipo MIME de las respuestas. Si el tipo MIME no es válido, el navegador no debe intentar adivinarlo, sino simplemente rechazar los datos.
  • Content-Security-Policy: default-src 'self' : esta cabecera permite controlar los recursos que el navegador está autorizado a cargar para una página. Con default-src 'self', solo se permiten las fuentes del mismo dominio.

Desactivación de los métodos HTTP no utilizados

Cuando utiliza un navegador para acceder a un sitio web, este envía al servidor lo que se denomina una petición HTTP. Esa petición puede ser de distintos tipos, o "métodos". Los dos métodos más habituales son "GET" (para solicitar datos, como una página web) y "POST" (para enviar datos, como cuando se rellena un formulario).

Sin embargo, existen otros métodos HTTP, como "PUT", "DELETE", "OPTIONS", etc. En muchos casos, un sitio web no necesita todos estos métodos, y algunos pueden suponer riesgos de seguridad si no se controlan correctamente.

Desactivar los métodos HTTP no utilizados significa indicar al servidor que no acepte peticiones de los tipos que usted no necesita. Esto reduce los medios de los que podría servirse un atacante para causar daños.

< w/ Nginx >

En Nginx, puede utilizar la directiva limit_except para limitar los métodos autorizados.

Por ejemplo:


location / {
    limit_except GET POST {
        deny all;
    }
}

Esto significa que solo se autorizan las peticiones GET y POST; todos los demás métodos serán rechazados.

< w/ Apache >

En Apache, puede utilizar las directivas Allow y Order para controlar los métodos autorizados.

Por ejemplo:


<Directory "/var/www/html">
    AllowOverride None
    Order allow,deny
    Allow from all
    <LimitExcept GET POST>
        Deny from all
    </LimitExcept>
</Directory>

De forma similar al ejemplo de Nginx, esto solo permite las peticiones GET y POST y rechaza los demás métodos.

Es una buena práctica desactivar los métodos HTTP que no tenga intención de utilizar, ya que así se reduce la superficie de ataque potencial.


Activación de la protección contra la denegación de servicio

Para proteger su sitio web frente a los ataques de denegación de servicio, puede limitar la tasa de peticiones (rate limiting). Esto permite limitar el número de peticiones que un cliente puede realizar en un intervalo de tiempo determinado.

Los servidores web suelen disponer de opciones para limitar el número de conexiones simultáneas, el tiempo de conexión, el tamaño de la petición, etc., que pueden contribuir a prevenir los ataques de denegación de servicio.

Así se procede con Nginx y Apache:

< w/ Nginx >

En Nginx, puede utilizar el módulo ngx_http_limit_req_module para limitar la tasa de peticiones.

Por ejemplo:


http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;

    server {
        ...
        location /login.html {
            limit_req zone=one;
            ...
        }
        ...
    }
}

En este ejemplo, limit_req_zone define una zona de memoria denominada "one" que almacena las direcciones IP de los clientes y limita la tasa de peticiones a 10 por segundo. limit_req aplica ese límite a una location concreta, con una burst rate de 20 y sin ningún retardo.

< w/ Apache >

En Apache, puede utilizar el módulo mod_ratelimit para limitar la tasa de transferencia, o el módulo mod_evasive para una protección más completa frente a la denegación de servicio.

Este es un ejemplo de configuración con mod_ratelimit:


<VirtualHost *:80>
    ...
    <Location "/login.html">
        SetOutputFilter RATE_LIMIT
        SetEnv rate-limit 500
    </Location>
    ...
</VirtualHost>

En este ejemplo, SetOutputFilter RATE_LIMIT activa el filtrado de la tasa para la location indicada, y SetEnv rate-limit 500 limita la tasa a 500 bytes por segundo.

Para utilizar mod_evasive, primero deberá instalarlo, ya que no se incluye de forma predeterminada con Apache.


sudo apt-get install libapache2-mod-evasive

Tras la instalación, puede activarlo y configurarlo añadiendo algo como esto a su configuración:


<IfModule mod_evasive20.c>
    DOSHashTableSize    3097
    DOSPageCount        2
    DOSSiteCount        50
    DOSPageInterval     1
    DOSSiteInterval     1
    DOSBlockingPeriod   10
</IfModule>

Esto define varios parámetros, como el número de peticiones autorizadas por página y por sitio en un intervalo de tiempo determinado, y el período durante el cual un cliente será bloqueado si supera esos límites.


Activación del aislamiento del contenido: puede configurar su servidor para que utilice procesos o hilos separados para cada petición, lo que puede limitar los daños potenciales si una sola petición se ve comprometida.

  1. Limitación de la tasa de peticiones (Rate Limiting): para prevenir los ataques de fuerza bruta o DDoS, puede resultar útil limitar el número de peticiones que un cliente puede realizar en un intervalo de tiempo determinado.
  2. Implantación de un cortafuegos de aplicaciones web (WAF): se trata de otra capa de seguridad que puede ayudar a proteger su aplicación frente a ataques habituales, como la inyección de código SQL.
  3. Uso de la autenticación: si su sitio contiene secciones que no deben ser accesibles al público, asegúrese de utilizar alguna forma de autenticación. Apache dispone de varios módulos para ello, como mod_auth_basic o mod_auth_digest.