Archivos Mensuales: junio 2019

ModSecurity con Nginx en Buster

Tras pasarlo regular para poner a marchar un Nginx como proxy inverso con ModSecurity, he pensado que sería buena idea volcar en alguna parte mis notas para ahorrar quebraderos de cabeza a otros sufridos informáticos.

Buster lleva la librería ModSecurity 3 ya empaquetada. No hay más que instalarla con apt.

Lo que da un poco de problema es compilar el módulo de nginx. Esto, por ahora, hay que hacerlo a mano.

Primero, instalar nginx con apt.

Luego, bajar el fuente de la versión exacta. En el momento de escribir esto:

dpkg -l nginx
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-============-============-==========================================
ii nginx 1.14.2-2 all small, powerful, scalable web/proxy server

Por tanto:

wget -O - http://nginx.org/download/nginx-1.14.2.tar.gz | tar xzf -

También necesitamos el conector de ModSecurity con nginx:

git clone https://github.com/SpiderLabs/ModSecurity-nginx.git

Ahora, ojo a esto. Aparte de build-essential, hacen falta otras cosas. La más enrevesada es libpcre3-dev. Sin esto, no compila el módulo de nginx. Pero es que además hay que configurar el conector para que la use. Es decir, ya en el directorio del fuente de nginx (nginx-1.14.2 en este caso):

./configure --with-compat --add-dynamic-module=../ModSecurity-nginx --without-http_rewrite_module --without-http_gzip_module --with-pcre

Hecho esto, ya no hay más que hacer make.

Otra cosa que despista un poco es dónde pone Debian las cosas. El módulo compilado lo podemos encontrar en objs/ngx_http_modsecurity_module.so y casi cualquier guía que encontremos por ahí dice de ponerlo en /etc/nginx/modules. Pero nop, eso no es el estilo Debian. Para hacerlo al estilo Debian, hay que soltarlo en /usr/lib/nginx/modules/ y seguidamente crear la configuración que lo carga. Verbigracia:

echo "load_module modules/ngx_http_modsecurity_module.so;" > /tmp/mod-security.conf && sudo mv /tmp/mod-security.conf /etc/nginx/modules-available/

cd /etc/nginx/modules-enabled/

sudo ln -s ../modules-available/mod-security.conf 50-mod-security.conf

sudo service nginx restart

Y nuestros esfuerzos se verán recompensados con un:

nginx: [emerg] module "/usr/share/nginx/modules/ngx_http_modsecurity_module.so" is not binary compatible in /etc/nginx/modules-enabled/50-mod-security.conf:1

Mierda.

Total. Que vamos a ver cómo está construído el nginx del paquete Debian:

nginx -V

Esto suelta el chorizo que en su día le pasaron al nginx al compilarlo para empaquetarlo. Y nos dice que:

configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-sWHVb6/nginx-1.14.2=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-mail=dynamic --with-mail_ssl_module --add-dynamic-module=/build/nginx-sWHVb6/nginx-1.14.2/debian/modules/http-auth-pam --add-dynamic-module=/build/nginx-sWHVb6/nginx-1.14.2/debian/modules/http-dav-ext --add-dynamic-module=/build/nginx-sWHVb6/nginx-1.14.2/debian/modules/http-echo --add-dynamic-module=/build/nginx-sWHVb6/nginx-1.14.2/debian/modules/http-upstream-fair --add-dynamic-module=/build/nginx-sWHVb6/nginx-1.14.2/debian/modules/http-subs-filter

Vale

Pues nada, paciencia y vamos a ver.

make clean

./configure --add-dynamic-module=../ModSecurity-nginx --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-sWHVb6/nginx-1.14.2=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-mail=dynamic --with-mail_ssl_module

make

sudo cp objs/ngx_http_modsecurity_module.so /usr/lib/nginx/modules/ngx_http_modsecurity_module.so

sudo service nginx start

Los otros –add-dynamic-module se pueden omitir. Y ya estamos listos.

Configurar un proxy inverso con ModSecurity es otra historia y debe ser contada en otra ocasión.