<div dir="ltr"><div>Hi all,<br></div><div><br></div><div>I want to share with you the following config to block malicious DNS traffic like tunneling with dnsdist<br></div><div>

<a href="https://github.com/dmachard/lua-dnsdist-config-examples/blob/main/security_blocking_dnstunneling.lua">lua-dnsdist-config-examples/security_blocking_dnstunneling.lua at main · dmachard/lua-dnsdist-config-examples · GitHub</a></div><div> <br></div><div>
<span class="gmail-HwtZe" lang="en"><span class="gmail-jCAhz gmail-ChMk0b"><span class="gmail-ryNqvb">Do you have any suggestions for improving this configuration?</span></span></span>

</div><div>Below a part of the LUA configuration:</div><div><br></div><div>-- Generic rules to block malicious dns traffic with regex<br><br>-- remote dnstap logger for security events<br>security_dnstap_logger = newFrameStreamTcpLogger("<a href="http://10.0.0.100:6000">10.0.0.100:6000</a>")<br><br>-- white list to ignore some trusted domains<br>malicious_white_list = newSuffixMatchNode()<br>malicious_white_list:add(newDNSName("<a href="http://powerdns.com">powerdns.com</a>"))<br><br>-- match uncommon qtype like NULL (10), PRIVATE (65399) - works fine to block iodine<br>addAction(AndRule({OrRule({QTypeRule(10), QTypeRule(65399)}), NotRule(SuffixMatchNodeRule(malicious_white_list, true)) }), SetTagAction('block_malicious', ''))<br><br>-- match long qname - 2 labels with a minimum of 50 bytes each - works fine to block tools like iodine, dnscat2, dns2tcp...<br>-- to avoid false-positive. The regex has been tested on the top 1 million list exposed by Cisco Umbrella <a href="http://s3-us-west-1.amazonaws.com/umbrella-static/top-1m.csv.zip">http://s3-us-west-1.amazonaws.com/umbrella-static/top-1m.csv.zip</a><br>addAction(AndRule({RegexRule('([^.]{50,}\\.){2,}'), NotRule(SuffixMatchNodeRule(malicious_white_list, true)) }), SetTagAction('block_malicious', ''))<br><br>-- logging malicious queries on remote dnstap logger<br>addAction(TagRule('block_malicious'), DnstapLogAction("malicious_blocked", security_dnstap_logger))<br><br>-- finally refused malicious queries<br>addAction(TagRule('block_malicious'), RCodeAction(DNSRCode.REFUSED))<br><br>-- Update the dynamic blocks with refused reply by default<br>setDynBlocksAction(DNSAction.Refused)<br><br>-- Rate exceeded detection with automatic ip blacklisting during 60s<br>--  * max 5req/s during 5s for TXT, CNAME and MX<br>--  * max bw to 1000bytes/s during 5s<br>local dbr = dynBlockRulesGroup()<br>dbr:setQTypeRate(DNSQType.TXT, 5, 5, "Exceeded TXT rate", 60)<br>dbr:setQTypeRate(DNSQType.CNAME, 5, 5, "Exceeded CNAME rate", 60)<br>dbr:setQTypeRate(DNSQType.MX, 5, 5, "Exceeded MX rate", 60)<br>dbr:setResponseByteRate(1000, 5, "Exceeded resp BW rate", 60)<br><br>-- check dynamic rule every second<br>function maintenance()<br>  dbr:apply()<br>end</div><div><br></div><div><br></div><div>Denis<br></div></div>