owasp-modsecurity / ModSecurity

ModSecurity is an open source, cross platform web application firewall (WAF) engine for Apache, IIS and Nginx. It has a robust event-based programming language which provides protection from a range of attacks against web applications and allows for HTTP traffic monitoring, logging and real-time analysis.
https://www.modsecurity.org
Apache License 2.0
7.67k stars 1.54k forks source link

Annoying DNS queries with @rbl operator #3111

Closed ne20002 closed 2 weeks ago

ne20002 commented 1 month ago

Describe the bug

Using a pihole in my network I realized that the rbl queries from Modsecurity are doing additional dns queries with the search domain (from resolv.conf) added. This happens only for @rbl queries (or maybe modsecurity in general). It does not happen from other containers in the pod nor any other system in my network.

grafik

I use the owasp/modsecurity-crs:nginx container from Docker hub.

Expected behavior

The additional queries are not done.

dune73 commented 1 month ago

That would be 0x42.ch in your case?

ne20002 commented 1 month ago

Yes

dune73 commented 1 month ago

Do you happen to know if the apache / ModSec2 docker container has the same problem?

ne20002 commented 1 month ago

No, sorry. I only use the Nginx version.

airween commented 1 month ago

@ne20002 thanks for the report.

Could you provide an example, how can I try the explained behavior?

It does not happen from other containers in the pod nor any other system in my network.

This means the "vanilla" ModSecurity instance does not do this?

ne20002 commented 1 month ago

This means the "vanilla" ModSecurity instance does not do this?

No, this just means that no other server in my network creates dns requests with the seen postfix. It's just the queries created by the @rbl checks.

This is the part in my config:

# xbl.spamhaus.org to block malicious/infected ips
SecRule IP:PREVIOUS_RBL_CHECK "@eq 1" "phase:1,id:910201,t:none,pass,nolog,skipAfter:END_RBL_LOOKUP"

SecRule REMOTE_ADDR "@rbl xbl.spamhaus.org" \
   "phase:1,id:910202,\
    t:none,pass,nolog,auditlog,\
    msg:'RBL Match for SPAM Source',\
    tag:'AUTOMATION/MALICIOUS',\
    severity:'CRITICAL',\
    setvar:'tx.msg=%{rule.msg}',\
    setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
    setvar:ip.spammer=1,\
    expirevar:ip.spammer=86400,\
    setvar:ip.previous_rbl_check=1,\
    expirevar:ip.previous_rbl_check=86400,\
    skipAfter:END_RBL_CHECK"

SecAction "phase:1,id:910203,\
    t:none,nolog,pass,\
    setvar:ip.previous_rbl_check=1,\
    expirevar:ip.previous_rbl_check=3600"

SecMarker END_RBL_LOOKUP

SecRule IP:SPAMMER "@eq 1" \
    "phase:1,id:910204,\
    t:none,pass,nolog,auditlog,\
    msg:'Request from Known SPAM Source (Previous RBL Match)',\
    tag:'AUTOMATION/MALICIOUS',\
    severity:'CRITICAL',\
    setvar:'tx.msg=%{rule.msg}',\
    setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"

SecMarker END_RBL_CHECK
fzipi commented 3 weeks ago

Who can spot the typos here? https://github.com/owasp-modsecurity/ModSecurity/blob/v3/master/src/operators/rbl.h#L70-L76

fzipi commented 3 weeks ago

Tip: lines 74 and 76.

fzipi commented 3 weeks ago

Don't know if it solves this, but it is definitely broken.

fzipi commented 3 weeks ago

So, not really fixing this, but #3127.

airween commented 3 weeks ago

@ne20002 could you check again with current master branch?

fzipi commented 3 weeks ago

It might be difficult for @ne20002 if he is using pods for this, as the container is not updated with the new code from master.

@airween Maybe we can do a quick build and use the secrule he posted above with a simple curl test? From the source code, debug information is being printed with level 4 or up.

airween commented 3 weeks ago

I can take a look at at the evening.

airween commented 3 weeks ago

Okay, I think I found the root cause.

libmodsecurity3 (I haven't checked mod_security2 yet) uses getaddrinfo() to make a DNS lookup here. This function uses the system's resolver.

If you have a search line in your /etc/resolv.conf, eg:

search 0x42.ch
nameserver ....
nameserver ....

then in case of a nonexistent domain response the resolver tries to look up the original query with appending your search value.

The possible workaround is that you use FQDN at the secrule:

SecRule REMOTE_ADDR "@rbl xbl.spamhaus.org." \

see the . (dot) character at the end of the service. This will prevent the second DNS query.

I don't know what would be the nice final solution: append an implicit . at the end of provider name if it does not contain, or just fix the documentation (which suggest this (used) form)?

(I think we have to check that in case of mod_security2 too).

Any ideas?

airween commented 3 weeks ago

Just FYI: mod_security2 works as the same as libmodsecurity3. With the rules above it repeats the query, appending a . (dot) character. If I add a . at the end of xpl.spamhaus.org, then the engine makes only one (A) query.

We should decide how we want to solve it: append explicit . to the provider's name if there isn't it, or modify the documentation.

theseion commented 3 weeks ago

Personally, I'd go with the FQDN approach. If you want to check multiple domains you can write multiple rules, so there shouldn't be an argument for using resolv.conf as a fallback.

ne20002 commented 3 weeks ago

@airween Thank you. This trick with the FQDN solves the queries with the search domain. It should be documented with the @rbl parameter. ;)

Seems the behaviour seen started with the upgrade to Debian Bookworm which installed systemd-resolved.

ne20002 commented 2 weeks ago

As the problem is solved (by using FQDN name) I'll close the issue.