If I was to give it a grade, I would say it is working better than my initial expectations. I was under the impression that it was going to take some effort to make it work with the core rule set but other than a few changes, it works perfectly on my test server. In the past, if I ran check_attacks.pl on a zimbra host with 443 open; I would see loads of status codes and multiple attacks from the same ip address. Check_attacks.pl now reporting single line output per ip address with a 403 status code - 100's of those but that means it seems to be working and we are blocking those incursions. If they attack at a lower part of the stack where modsecurity never see's the connection then fail2ban is mopping up those ip's and adding to the same set.
What the limited data is showing me given I still don't have a DNS entry for the host is that there are 100's of commercial and opportunistic bots investigating what is at port 443 at just the ip address. At present, the list is about 500 ip's but it has been slowing to a trickle as they exhaust their ipv4 ranges. Given that fail2ban seems to be required, having it do all the adds to null routes or ipset might be easier on the software install for a production system without the lua stack. Currently, I have lua enabled so I can extend modsecurity 3. If I can't find a use case (session tracking might be one where it could help) then I would probably not recommend building that which can make the install easier and smaller. My instructions however in this thread contains the full build including lua.
Zimbra's web interfaces seem to be working under this. I did some extensive work the other day in both the admin interface and web interface for my user account and forgot that it was in front as I was testing some things with gmail and focused on postfix issues and email send/receive. There is still a lot to do and one area I am thinking of exploring is having fail2ban whitelist successful authorized zimbra accounts in audit.log to an ipset and correlate that on the cookies in the headers. That should allow one to track mobile users as their ip addresses change but we don't see the normal authorization. In theory, I could create an ipset that is checked before I check the blacklist so we don't lock out users using this method should a FP happen. A major concern continues to be hijacked user credentials that are played back and how to track that.
Note: eventually, I will move the ipset to the raw/prerouting for efficiency but it is at filter/input so that I can make sure I don't get blocked while I am testing it. I have started down the path of learning metasploit which is slowing me down but I want to write some modules so I can verify if modsecurity would have protected an unpatched zimbra P38 from the new security patches in P40 for example.
At some point, I need to polish the instructions for building the modsecurity connector so this doesn't become another cold fusion example where no one can reproduce the results. I have been careful here because the 3rd party tree has some danger in the makefile for nginx where a production server could be wiped out if someone forgot and typed make. To be safe, do it on a development machine if someone wants to explore this thread. I add a rule that becomes the default that makes modSecurity as the first thing I do when using that tree is to modify its Makefile.
Code: Select all
modSecurity:
@echo $(PKG_BUILD) $(specfile)
@echo "installing /etc/nginx/zimbra-modsecurity/modules/ngx_http_modsecurity_module.so"
cp ./build/RHEL8_64/zimbra-nginx/rpm/BUILD/nginx-1.20.0-zimbra/objs/ngx_http_modsecurity_module.so /etc/nginx/zimbra-modsecurity/modules/
all: clean getsrc build pkgrm1
Code: Select all
#JAD#build: pkgadd setup build_$(PKG_EXT)
build: setup build_$(PKG_EXT)
Code: Select all
--add-dynamic-module=/usr/src/public/www/zimbra-nginx/ModSecurity-nginx \
Code: Select all
%files
%defattr(-,root,root)
OZC/sbin
/opt/zimbra/data/nginx
/opt/zimbra/common/modules/ngx_http_modsecurity_module.so
%exclude OZC/conf
Code: Select all
% make getsrc # only once
% make build
% make modSecurity
Without doing it in the 3rd party tree as shown above, the process I used before I learned how to build nginx was:
Code: Select all
% cat step2-connector.sh
#
# nginx -v
#
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
wget http://nginx.org/download/nginx-1.20.0.tar.gz
tar zxvf nginx-1.20.0.tar.gz
cd nginx-1.20.0
#
# Pulled these options from:
# https://github.com/Zimbra/packages/blob/develop/thirdparty/nginx/zimbra-nginx/rpm/SPECS/nginx.spec
# Note: just need the binary format... we are not replacing nginx with the compiled version here.
#
# Replace these
# OZCL is /opt/zimbra/common/lib
# OZC is /opt/zimbra/common
# OZCI is /opt/zimbra/common/include
#
#LDFLAGS="-Wl,-rpath,OZCL"; export LDFLAGS; \
#CFLAGS="-g -O0"; export CFLAGS; \
#./configure --prefix=OZC \
#--with-cc-opt="-g -IOZCI" \
#--with-ld-opt="-Wl,-rpath,/opt/zimbra/common/lib -L/opt/zimbra/common/lib" \
LDFLAGS="-Wl,-rpath,/opt/zimbra/common/lib"; export LDFLAGS; \
CFLAGS="-g -O0"; export CFLAGS; \
./configure --prefix=/opt/zimbra/common \
--with-cc-opt="-g -I/opt/zimbra/common/include" \
--with-ld-opt="-Wl,-rpath,/opt/zimbra/common/lib -L/opt/zimbra/common/lib" \
--add-dynamic-module=../ModSecurity-nginx \
--with-debug \
--with-ipv6 \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_v2_module \
--with-pcre \
--with-mail \
--with-mail_ssl_module \
--error-log-path=/opt/zimbra/log/nginx.log \
--http-log-path=/opt/zimbra/log/nginx.access.log \
--http-client-body-temp-path=/opt/zimbra/data/tmp/nginx/client \
--http-proxy-temp-path=/opt/zimbra/data/tmp/nginx/proxy \
--http-fastcgi-temp-path=/opt/zimbra/data/tmp/nginx/fastcgi \
--without-http_scgi_module \
--without-http_uwsgi_module
make
echo "cp ./objs/ngx_http_modsecurity_module.so /etc/nginx/zimbra-modsecurity/modules/"
Jim