Instalar ModSecurity con Apache en un contenedor Docker

ModSecurity es un cortafuegos de aplicaciones web (WAF) gratuito, de código abierto, y el más popular, que protege tu aplicación web contra una amplia gama de ataques de capa 7. Ha sido diseñado para monitorizar, registrar y filtrar las peticiones del servidor web Apache. Viene con un conjunto de reglas básicas que detecta y detiene varios ataques, como la inyección SQL, el cross-site scripting, los troyanos, los agentes de usuario malintencionados, el secuestro de sesiones y otros.

En este tutorial, te mostraré cómo instalar ModSecurity 3 con Apache dentro de un contenedor Docker.

Requisitos

  • Un servidor con Ubuntu 20.04.
  • Una contraseña de root configurada en tu servidor.

Cómo empezar

En primer lugar, se recomienda actualizar tu sistema a la última versión. Puedes actualizarlo con el siguiente comando:

apt-get update -y

Una vez que tu sistema esté actualizado, necesitarás instalar algunas dependencias en tu sistema. Puedes instalarlas todas con el siguiente comando:

apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common -y

Una vez instaladas todas las dependencias, puedes pasar al siguiente paso.

Instalar Docker

A continuación, tendrás que instalar el CE de Docker en tu sistema. Por defecto, la última versión de Docker no está incluida en el repositorio por defecto de Ubuntu. Así que tendrás que añadir el repositorio oficial de Docker al APT.

Primero, descarga y añade la clave GPG de Docker con el siguiente comando:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -

A continuación, añade el repositorio Docker CE a la lista de fuentes de APT con el siguiente comando:

echo "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -sc) stable" > /etc/apt/sources.list.d/docker-ce.list

Una vez añadido el repositorio, actualiza el repositorio con el siguiente comando:

apt-get update -y

Una vez actualizado el repositorio, instala la última versión de Docker CE con el siguiente comando:

apt-get install docker-ce -y

Después de instalar Docker CE, verifica la versión instalada de Docker CE con el siguiente comando:

docker --version

Deberías obtener la siguiente salida:

Docker version 20.10.6, build 370c289

También puedes comprobar el estado del servicio Docker con el siguiente comando:

systemctl status docker

Deberías obtener la siguiente salida:

? docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2021-05-16 06:49:29 UTC; 38s ago
TriggeredBy: ? docker.socket
       Docs: https://docs.docker.com
   Main PID: 8964 (dockerd)
      Tasks: 8
     Memory: 40.6M
     CGroup: /system.slice/docker.service
             ??8964 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

May 16 06:49:29 ubuntu2004 dockerd[8964]: time="2021-05-16T06:49:29.365433228Z" level=warning msg="Your kernel does not support swap memory li>
May 16 06:49:29 ubuntu2004 dockerd[8964]: time="2021-05-16T06:49:29.365916961Z" level=warning msg="Your kernel does not support cgroup blkio w>
May 16 06:49:29 ubuntu2004 dockerd[8964]: time="2021-05-16T06:49:29.366112111Z" level=warning msg="Your kernel does not support cgroup blkio w>
May 16 06:49:29 ubuntu2004 dockerd[8964]: time="2021-05-16T06:49:29.366653374Z" level=info msg="Loading containers: start."
May 16 06:49:29 ubuntu2004 dockerd[8964]: time="2021-05-16T06:49:29.498790388Z" level=info msg="Default bridge (docker0) is assigned with an I>
May 16 06:49:29 ubuntu2004 dockerd[8964]: time="2021-05-16T06:49:29.576691602Z" level=info msg="Loading containers: done."
May 16 06:49:29 ubuntu2004 dockerd[8964]: time="2021-05-16T06:49:29.610542206Z" level=info msg="Docker daemon" commit=8728dd2 graphdriver(s)=o>
May 16 06:49:29 ubuntu2004 dockerd[8964]: time="2021-05-16T06:49:29.611668583Z" level=info msg="Daemon has completed initialization"
May 16 06:49:29 ubuntu2004 systemd[1]: Started Docker Application Container Engine.
May 16 06:49:29 ubuntu2004 dockerd[8964]: time="2021-05-16T06:49:29.690496888Z" level=info msg="API listen on /run/docker.sock"
lines 1-21/21 (END)

Una vez que hayas terminado, puedes pasar al siguiente paso.

Crear un Dockerfile para ModSecurity

A continuación, tendrás que crear un Dockerfile para instalar el ModSecurity dentro del contenedor de Ubuntu.

Primero, cambia el directorio a /opt y crea un archivo modsec_rules.conf con el siguiente comando:

cd /opt
nano modsec_rules.conf

Añade las siguientes líneas:

Include "/etc/apache2/modsecurity.d/modsecurity.conf"
Include "/etc/apache2/modsecurity.d/owasp-crs/crs-setup.conf"
Include "/etc/apache2/modsecurity.d/owasp-crs/rules/*.conf"

Guarda y cierra el archivo y luego crea otro archivo con el siguiente comando:

nano 000-default.conf

Añade las siguientes líneas:

<VirtualHost *:80>
	modsecurity on
	modsecurity_rules_file /etc/apache2/modsecurity.d/modsec_rules.conf 
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html
	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Guarda y cierra el archivo cuando hayas terminado. Dockerfile copiará los archivos anteriores al contenedor Docker durante el proceso de construcción.

Por último, crea un archivo Dockerfile con el siguiente comando

nano Dockerfile

Añade las siguientes líneas:

# Install Modsecurity in a Docker container;
FROM ubuntu:latest
ARG DEBIAN_FRONTEND=noninteractive
# update/upgrade your system
RUN apt-get update -y

# Install Required Dependencies
RUN apt-get install -y g++ flex bison curl apache2-dev \
	doxygen libyajl-dev ssdeep liblua5.2-dev \
	libgeoip-dev libtool dh-autoreconf \
	libcurl4-gnutls-dev libxml2 libpcre++-dev \
	libxml2-dev git wget tar apache2

# Download LibModsecurity 
RUN wget https://github.com/SpiderLabs/ModSecurity/releases/download/v3.0.4/modsecurity-v3.0.4.tar.gz

# Extract the Downloaded File
RUN tar xzf modsecurity-v3.0.4.tar.gz && rm -rf modsecurity-v3.0.4.tar.gz

# Compile and Install LibModsecurity
RUN cd modsecurity-v3.0.4 && \
	./build.sh && ./configure && \
	make && make install

# Install ModSecurity-Apache Connector
RUN cd ~ && git clone https://github.com/SpiderLabs/ModSecurity-apache

RUN cd ~/ModSecurity-apache && \
	./autogen.sh && \
	./configure --with-libmodsecurity=/usr/local/modsecurity/ && \
	make && \
	make install

# Load the Apache ModSecurity Connector Module
RUN echo "LoadModule security3_module /usr/lib/apache2/modules/mod_security3.so" >> /etc/apache2/apache2.conf

# Configure ModSecurity
RUN mkdir /etc/apache2/modsecurity.d && \
	cp modsecurity-v3.0.4/modsecurity.conf-recommended /etc/apache2/modsecurity.d/modsecurity.conf && \
	cp modsecurity-v3.0.4/unicode.mapping /etc/apache2/modsecurity.d/ && \
	sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/apache2/modsecurity.d/modsecurity.conf
ADD modsec_rules.conf /etc/apache2/modsecurity.d/

# Install OWASP ModSecurity Core Rule Set (CRS) on Ubuntu
RUN git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git /etc/apache2/modsecurity.d/owasp-crs && \
	cp /etc/apache2/modsecurity.d/owasp-crs/crs-setup.conf.example /etc/apache2/modsecurity.d/owasp-crs/crs-setup.conf

# Activate ModSecurity
RUN mv /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/000-default.conf.old
ADD 000-default.conf /etc/apache2/sites-available/

EXPOSE 80
CMD apachectl -D FOREGROUND

Guarda y cierra el archivo cuando hayas terminado.

El archivo anterior descargará la imagen de Ubuntu, instalará todas las dependencias, descargará el ModSecurity, lo compilará y configurará Apache para que funcione con el ModSecurity.

En este punto, el Dockerfile está listo. Ahora puedes pasar al siguiente paso.

Construye la imagen de ModSecurity de Apache e inicia el contenedor

Ahora, cambia el directorio a /opt y construye la imagen Docker para Apache ModSecurity con el siguiente comando:

cd /opt
docker build .

Una vez completado el proceso de construcción, deberías obtener la siguiente salida:

Step 13/17 : RUN git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git /etc/apache2/modsecurity.d/owasp-crs && 	cp /etc/apache2/modsecurity.d/owasp-crs/crs-setup.conf.example /etc/apache2/modsecurity.d/owasp-crs/crs-setup.conf
 ---> Running in 00dfa2a5cd23
Cloning into '/etc/apache2/modsecurity.d/owasp-crs'...
Removing intermediate container 00dfa2a5cd23
 ---> b38c1d874d2f
Step 14/17 : RUN mv /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/000-default.conf.old
 ---> Running in 12c9e6d2c559
Removing intermediate container 12c9e6d2c559
 ---> 899e26019297
Step 15/17 : ADD 000-default.conf /etc/apache2/sites-available/
 ---> eb11751afd6c
Step 16/17 : EXPOSE 80
 ---> Running in 2f4ba47e2b66
Removing intermediate container 2f4ba47e2b66
 ---> dd59b0ac7c7c
Step 17/17 : CMD apachectl -D FOREGROUND
 ---> Running in 98b8cc77df0f
Removing intermediate container 98b8cc77df0f
 ---> f603dbc38018
Successfully built f603dbc38018

Ahora puedes listar todas las imágenes Docker con el siguiente comando:

docker images

Deberías obtener el siguiente resultado:

REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
           f603dbc38018   32 seconds ago   2.48GB
ubuntu       latest    7e0aa2d69a15   3 weeks ago      72.7MB

Ahora, elige el primer id de imagen de la salida anterior e inicia el contenedor Apache ModSecurity con el siguiente comando:

docker run --name modsec-apache -ditp 80:80 f603dbc38018

Deberías obtener el siguiente resultado:

40eb0e77e61635c3cee2bfaffbd9489bc7d20aa3e1befb52749de079aaadb528

Ahora puedes verificar el contenedor en ejecución con el siguiente comando:

docker ps

Deberías obtener la siguiente salida:

CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                               NAMES
40eb0e77e616   f603dbc38018   "/bin/sh -c 'apachec…"   17 seconds ago   Up 15 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   modsec-apache

Como puedes ver, el contenedor ModSecurity está iniciado y escuchando en el puerto 80.

Verificar ModSecurity

Llegados a este punto, el contenedor ModSecurity se está ejecutando. Ahora, es el momento de comprobar si las reglas de ModSecurity bloquean las peticiones maliciosas o no.

Para ello, abre tu terminal y ejecuta el siguiente comando:

curl localhost?doc=/bin/ls

Deberías ver la siguiente salida:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
<hr>
<address>Apache/2.4.41 (Ubuntu) Server at localhost Port 80</address>
</body></html>

Deberías ver el error«403 Forbidden«. Porque ModSecurity ha bloqueado la petición anterior.

También puedes consultar el registro de Apache para obtener más información.

Para ello, primero conéctate al contenedor con el siguiente comando:

docker exec -it modsec-apache /bin/bash

Una vez conectado, deberías obtener el siguiente shell:

root@40eb0e77e616:/#

Ahora, comprueba el registro de Apache con el siguiente comando:

tail -f /var/log/apache2/error.log

Deberías ver que ModSecurity ha bloqueado la petición maliciosa:

[Sun May 16 07:24:54.456327 2021] [mpm_event:notice] [pid 15:tid 140204464299072] AH00489: Apache/2.4.41 (Ubuntu) configured -- resuming normal operations
[Sun May 16 07:24:54.456352 2021] [core:notice] [pid 15:tid 140204464299072] AH00094: Command line: '/usr/sbin/apache2 -D FOREGROUND'
[Sun May 16 07:25:36.680515 2021] [:error] [pid 16:tid 140204216108800] [client 172.17.0.1:45298] ModSecurity: Warning. Matched "Operator `PmFromFile' with parameter `unix-shell.data' against variable `ARGS:doc' (Value: `/bin/ls' ) [file "/etc/apache2/modsecurity.d/owasp-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf"] [line "496"] [id "932160"] [rev ""] [msg "Remote Command Execution: Unix Shell Code Found"] [data "Matched Data: bin/ls found within ARGS:doc: /bin/ls"] [severity "2"] [ver "OWASP_CRS/3.2.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-shell"] [tag "platform-unix"] [tag "attack-rce"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION"] [tag "WASCTC/WASC-31"] [tag "OWASP_TOP_10/A1"] [tag "PCI/6.5.2"] [hostname "172.17.0.2"] [uri "/"] [unique_id "162114993662.860969"] [ref "o1,6v10,7t:urlDecodeUni,t:cmdLine,t:normalizePath,t:lowercase"]

Conclusión

Enhorabuena! has instalado con éxito ModSecurity dentro del contenedor Docker. Espero que ahora tengas suficientes conocimientos para implementar esta solución en el entorno Docker. No dudes en preguntarme si tienes alguna duda.

También te podría gustar...