-
Notifications
You must be signed in to change notification settings - Fork 4
/
subdomain.lua
58 lines (48 loc) · 2.02 KB
/
subdomain.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
local bloom = require("bloom")
local countmin = require("countmin")
local preout_blockfilter = bloombits.new(100000, 0.0001)
local countfilter = bloomcount.new(1 / 10000, 0.0001)
local max_nx_count = 200 -- max number of NXDOMAIN for domain+IP before we block
function preoutquery(dq)
-- get query name
local qname = dq.qname
-- only queries with more than two labels, eg. 3.example.com are considered
-- counted for excessive NXDOMAIN lookups. And since we cut off the first
-- label the smallest names we are counting have 2 labels, eg. example.com
if qname:countLabels() > 2 and qname:chopOff() then
-- concatenate queryname and client IP address to create the key
local key = string.lower(qname:toStringNoDot() .. dq.localaddr:toString())
-- if the key has been added to the preout_blockfilter, drop the query
if preout_blockfilter.check(key) == 1 then
dq.rcode = -3
return true
end
end
return false
end
function nxdomain(dq)
-- get query name
local qname = dq.qname
-- only queries with more than two labels, eg. 3.example.com are considered
-- counted and considered for excessive NXDOMAIN lookups. And since we cut off
-- the first label the smallest names we are counting have 2 labels, eg.
-- example.com
if qname:countLabels() > 2 and qname:chopOff() then
-- concatenate queryname and client IP address to create the key
local key = string.lower(qname:toStringNoDot() .. dq.remoteaddr:toString())
-- don't do anything if the key is already blocked
if preout_blockfilter.check(key) == 1 then
return false
end
-- get the current count for this key
local c = countfilter.add(key)
if c >= max_nx_count then
-- log who and what we blocked in a Splunk friendly way
pdnslog('action=block type=nxdomain domain=' .. qname:toStringNoDot()
.. ' client=' .. dq.remoteaddr:toString() .. ' count=' .. c)
-- add the key to the boolean bloom filter used for blocking
preout_blockfilter.add(key)
end
end
return false
end