En nuestro día a día nuestro equipo DevOps construye multitud de arquitecturas para proporcionar una base sólida a las integraciones y desarrollos posteriores. Otras veces nuestro trabajo es revisar arquitecturas existentes, reorganizar y proponer mejoras, la mayoría de ocasiones la seguridad en el perímetro es un punto a reforzar. Por eso, en este artículo, os contaremos algunas de las mejoras que solemos ofrecer por defecto en la mayoría de situaciones y se explicará cómo proteger tus APIs instalando y configurando ModSecurity en Nginx.
Glosario de términos: Hardening, Red Tor, User Agent y WAF
A continuación se definirán algunos de los términos de los que iremos hablando durante el artículo:
Bastionado o Hardening
Bastionado o Hardening es el proceso de endurecimiento de las configuraciones por defecto que traen los sistemas operativos con el objetivo de mejorar la seguridad, evitar escalada de privilegios, evitar vulnerabilidades, servicios o puertos expuestos sin uso.
Red Tor
Red Tor es una red creada por software creada sobre la red de internet, usa encriptaciones, VPN y saltos entre nodos de esa red para proporcionar anonimato, suele ser usada por los piratas informáticos para ocultar su IP, esta red puede ser usada con fines simplemente de anonimato e investigación o con fines no tan lícitos.
User Agent
User Agent se refiere al identificador donde se muestra información del servicio y la versión, suele estar en las cabeceras de los servicios, escáneres de software, servidores web y servicios en general.
WAF
Web Application Firewall (WAF) es un firewall de aplicaciones, al igual que un firewall de red trabaja filtrando los paquetes en sus políticas o reglas, un WAF está especializado en la capa de aplicación, filtrando de manera minuciosa el tráfico a nivel de aplicación, pudiendo detectar los ataques y estableciendo filtro o reglas personalizadas o definidas en el estándar OWASP.
Casos de uso o ámbito de aplicación
Generalmente el contexto siempre es el mismo o muy similar, servidores web o máquinas virtuales Linux/Windows que hacen de entrada a la plataforma como servidor web de aplicaciones, proxy o balanceador.
El factor común es que normalmente estos sistemas operativos se encuentran por defecto, algo nada recomendable en un equipo que hace frontera entre internet y la nuestra red interna.
La realidad que nos encontramos
Hoy día ya casi todas las organizaciones tienen un firewall de red o NGF y una zona DMZ, lo que suele ocurrir es que el firewall de red si no se han ajustado muy bien las políticas se suele ignorar los servicios que están expuestos a nivel de aplicación, lo que quiero decir es que no está debidamente acotado al servicio, host u aplicación que estamos exponiendo, y es que lo correcto sería aplicar las firmas del sistema operativo (Ubuntu Linux, Windows server etc…), después aplicar las firmas del servicio (Apache, Nginx, ISS), después las firmas de la aplicación.
Una vez finalizados estos ajustes podemos añadir el módulo de WAF básico, algunos firewall traen este módulo, este módulo no actúa con la misma efectividad que un WAF, principalmente porque no lo es, pero añade alguna mejora, por otro lado tenemos las políticas anti DDoS, en este aspecto si vuestro firewall tiene esa opción, es recomendable habilitar, sabemos que estas funciones son eso funciones extras y que no serán tan efectivos como hardware o host dedicado.
En algunas organizaciones nos encontramos con el escenario anterior y realizamos nuestras recomendaciones, además cuando entramos a desplegar nuestra arquitectura o auditamos o rectificamos la arquitectura del cliente añadimos algunas mejoras de base.
Procedimiento realizado
- En primer lugar generamos un informe de pre-bastionado en todos los host que forman parte de la arquitectura o proyecto.
- En segundo lugar ponemos en común con el cliente el resultado, le hacemos nuestras recomendaciones y vemos hasta donde quiere llegar.
- El proceso de Hardening o bastionado varía por sistema operativo y existen varias guías o herramientas para gestionarlo como por ejemplo CIS Benchmarks, nosotros solemos preparar procesos automatizados para el bastionado de grandes números de activos, aunque previamente desarrollamos y probamos la automatizacion del hardering, después podemos usar Ansible o combinar con Bash o PowerShell según el caso.
Al final se trata de incorporar el punto de vista de la seguridad de manera transversal en todo el flujo de trabajo y en todas las áreas.
Y es que esto, no es opcional si queremos estar al día y proteger nuestros sistemas y aplicaciones, es aquí donde aparece el perfil o metodología DevSecOps.
DevOps + Automation = Security
Nginx protegiendo aplicaciones
Como mencionamos anteriormente nosotros incorporamos por defecto unas mejoras de seguridad sobre el bastionado comentado anteriormente y sobre el proxy o balanceador.
En este apartado vamos a comentar las mejoras técnicas que añadimos a NGINX y es que con NGINX tenemos la opción del WAF open source llamado modsecurity o su versión de pago NGINX+ llamada WAF.
Para poder hacer uso de modsecurity necesitamos compilar la última versión de Nginx preparándolo para usar el modulo modsecurity.
En esta ocasión daremos algunas instrucciones y requerimientos para Centos 8/Redhat.
Paquetes y repositorios necesarios
A continuación instalaremos los paquetes necesarios para una distribución Redhat/Centos 8:
# dnf update dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -y dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm -y dnf install gcc-c++ flex bison yajl curl-devel zlib-devel pcre-devel autoconf automake git curl make libxml2-devel pkgconfig libtool httpd-devel redhat-rpm-config wget openssl openssl-devel nano -y dnf --enablerepo=powertools install doxygen yajl-devel -y dnf --enablerepo=remi install geoip-devel -y yum install geoip-devel -y
Instalación y compilación modsecurity
Ahora instalaremos modsecurity, para ello vamos a compilar, podéis seguir las siguientes instrucciones:
#clonaremos repo de modsecurity para nginx en el dir opt cd /opt/ && git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity # Entramos en el directorio bajamos la última versión y compilamos el módulo. cd ModSecurity git submodule init git submodule update ./build.sh && ./configure make && make install # bajamos modsecurity-nginx cd /opt git clone https://github.com/SpiderLabs/ModSecurity-nginx.git
Instalación y compilación de Nginx con compatibilidad modsecurity
Descargamos la última versión estable de la página oficial, descomprimimos y compilamos e instalamos:
wget http://nginx.org/download/nginx-1.18.0.tar.gz tar -xvzf nginx-1.18.0.tar.gz cd /opt/nginx-1.18.0 ./configure --user=nginx --group=nginx --with-pcre-jit --with-debug --with-http_ssl_module --with-http_realip_module --add-module=/opt/ModSecurity-nginx
Puesta en funcionamiento de modsecurity
Ejemplo de archivo de configuración Nginx habilitando modsecurity:
#Plantilla ejemplo /usr/local/nginx/conf/nginx.conf user nginx; worker_processes 1; pid /run/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name your-server-ip; modsecurity on; modsecurity_rules_file /usr/local/nginx/conf/modsecurity.conf; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html;
Recargando y testeando la configuración
Ahora aplicaremos cambios para configurar modsecurity, validamos que la configuración es correcta y reiniciamos el servicio:
#Configurando modsecurity en nginx sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/g' /usr/local/nginx/conf/modsecurity.conf sed -i 's/\/var\/log\/modsec_audit.log/\/var\/log\/nginx\/modsec_audit.log/g' /usr/local/nginx/conf/modsecurity.conf #Testeamos la config nginx -t # Habilitamos el demonio e iniciamos el servicio nginx systemctl daemon-reload systemctl start nginx systemctl enable --now nginx systemctl status nginx
Configurando modsecurity con OWASP rules
Descargamos las reglas de OWASP desde su repositorio y las incluiremos en la configuración de modsecurity:
git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git /usr/local/nginx/conf/owasp-crs mv /usr/local/nginx/conf/owasp-crs/crs-setup.conf.example /usr/local/nginx/conf/owasp-crs/crs-setup.conf echo "Include owasp-crs/crs-setup.conf" >> /usr/local/nginx/conf/modsecurity.conf echo "Include owasp-crs/rules/*.conf" >> /usr/local/nginx/conf/modsecurity.conf nginx -t # si todo va bien reiniciamos. systemctl restart nginx
Bloqueando accesos desde la Red Tor
En este apartado explicaremos la capacidad que tiene Nginx de bloquear una IP para bloquear su acceso.
Para bloquear accesos a determinadas IP en Nginx la sintaxis es la siguiente.
deny 192.168.1.2; deny 192.168.1.3;
Ahora que ya conocéis cómo bloquear listados de IP, ahora desde la fuente torproject podemos descargar el listado de los nodos de salida.
Si creamos un script para la descarga del listado de IP y formateamos la salida podemos tener un listado similar a este:
deny 104.244.73.215; deny 198.98.62.107; deny 104.244.79.203; deny 209.141.55.90; deny 209.141.41.214; deny 143.110.236.82; deny 93.95.227.227;
Podemos guardar la salida anterior en un archivo, por ejemplo include /opt/nginx_deny_tor.txt;
Es recomendable automatizar el paso anterior para mantener actualizado el listado, podríamos hacerlo con CRONTAB.
Ahora si vamos a la documentación de Nginx podemos observar que entre sus muchas opciones una permite bloquear un listado de IP, podemos incluir el listado tal y como se muestra en el ejemplo:
location / { include /opt/nginx_deny_tor.txt; #…...etc... }
Bloqueando escáneres de vulnerabilidades o similares vía user agent
location / { include /opt/nginx_deny_tor.txt; if ($http_user_agent ~* (^w3af.sourceforge.net|dirbuster|nikto|wpscan|SF|sqlmap|fimap|nessus|whatweb|Openvas|jbrofuzz|libwhisker|webshag)) { return 444; }
Como podéis ver en el apartado anterior añadimos a la configuración location/un condicional basado en el User Agent, si coincide con una de las opciones se cerrará la conexión.
Podemos modificar nuestro user agent en nuestro navegador firefox con esta herramienta llamada User Agent Switcher para realizar pruebas.
Conclusiones
- Hemos comentado la importancia y algunas herramientas de bastionado de sistemas.
- Hemos comentado cómo podemos añadir modsecurity a Nginx como WAF.
- Hemos comentado cómo bloquear conexiones desde la Red Tor.
- Hemos explicado cómo cerrar la conexión a clientes con User Agent no deseado.