[dnsdist] rules to block dns tunneling trafic from iodine, dnscat2, ...

Denis MACHARD d.machard at gmail.com
Wed Jul 5 08:19:36 UTC 2023


Hi all,

I want to share with you the following config to block malicious DNS
traffic like tunneling with dnsdist
lua-dnsdist-config-examples/security_blocking_dnstunneling.lua at main ·
dmachard/lua-dnsdist-config-examples · GitHub
<https://github.com/dmachard/lua-dnsdist-config-examples/blob/main/security_blocking_dnstunneling.lua>

Do you have any suggestions for improving this configuration?
Below a part of the LUA configuration:

-- Generic rules to block malicious dns traffic with regex

-- remote dnstap logger for security events
security_dnstap_logger = newFrameStreamTcpLogger("10.0.0.100:6000")

-- white list to ignore some trusted domains
malicious_white_list = newSuffixMatchNode()
malicious_white_list:add(newDNSName("powerdns.com"))

-- match uncommon qtype like NULL (10), PRIVATE (65399) - works fine to
block iodine
addAction(AndRule({OrRule({QTypeRule(10), QTypeRule(65399)}),
NotRule(SuffixMatchNodeRule(malicious_white_list, true)) }),
SetTagAction('block_malicious', ''))

-- match long qname - 2 labels with a minimum of 50 bytes each - works fine
to block tools like iodine, dnscat2, dns2tcp...
-- to avoid false-positive. The regex has been tested on the top 1 million
list exposed by Cisco Umbrella
http://s3-us-west-1.amazonaws.com/umbrella-static/top-1m.csv.zip
addAction(AndRule({RegexRule('([^.]{50,}\\.){2,}'),
NotRule(SuffixMatchNodeRule(malicious_white_list, true)) }),
SetTagAction('block_malicious', ''))

-- logging malicious queries on remote dnstap logger
addAction(TagRule('block_malicious'), DnstapLogAction("malicious_blocked",
security_dnstap_logger))

-- finally refused malicious queries
addAction(TagRule('block_malicious'), RCodeAction(DNSRCode.REFUSED))

-- Update the dynamic blocks with refused reply by default
setDynBlocksAction(DNSAction.Refused)

-- Rate exceeded detection with automatic ip blacklisting during 60s
--  * max 5req/s during 5s for TXT, CNAME and MX
--  * max bw to 1000bytes/s during 5s
local dbr = dynBlockRulesGroup()
dbr:setQTypeRate(DNSQType.TXT, 5, 5, "Exceeded TXT rate", 60)
dbr:setQTypeRate(DNSQType.CNAME, 5, 5, "Exceeded CNAME rate", 60)
dbr:setQTypeRate(DNSQType.MX, 5, 5, "Exceeded MX rate", 60)
dbr:setResponseByteRate(1000, 5, "Exceeded resp BW rate", 60)

-- check dynamic rule every second
function maintenance()
  dbr:apply()
end


Denis
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.powerdns.com/pipermail/dnsdist/attachments/20230705/de28c363/attachment.htm>


More information about the dnsdist mailing list