]>
Commit | Line | Data |
---|---|---|
ff484825 | 1 | -- listen for console connection with the given secret key |
fa7d3e7c | 2 | controlSocket("0.0.0.0") |
ff484825 RG |
3 | setKey("MXNeLFWHUe4363BBKrY06cAsH8NWNb+Se2eXU5+Bb74=") |
4 | ||
5 | -- start the web server on port 8083, using password 'geheim2' | |
50bed881 | 6 | webserver("0.0.0.0:8083", "geheim2") |
ff484825 RG |
7 | |
8 | -- accept DNS queries on UDP/5200 and TCP/5200 | |
2e72cc0e | 9 | addLocal("0.0.0.0:5200") |
ff484825 RG |
10 | |
11 | -- send statistics to PowerDNS metronome server | |
9ebc0e91 | 12 | -- carbonServer("2001:888:2000:1d::2") |
6d01c80c | 13 | |
ff484825 RG |
14 | -- fix up possibly badly truncated answers from pdns 2.9.22 |
15 | truncateTC(true) | |
16 | ||
4c6f4321 | 17 | warnlog(string.format("Script starting %s", "up!")) |
18 | ||
773470ca | 19 | -- define the good servers |
20 | newServer("8.8.8.8", 2) -- 2 qps | |
ff484825 | 21 | newServer("8.8.4.4", 2) |
773470ca | 22 | newServer("208.67.222.222", 1) |
ff484825 | 23 | newServer("208.67.220.220", 1) |
773470ca | 24 | newServer("2001:4860:4860::8888", 1) |
ff484825 RG |
25 | newServer("2001:4860:4860::8844",1) |
26 | newServer("2620:0:ccc::2", 10) | |
27 | newServer("2620:0:ccd::2", 10) | |
bf9edc24 RG |
28 | newServer({address="192.168.1.2", qps=1000, order=2}) |
29 | newServer({address="192.168.1.79:5300", order=2}) | |
30 | newServer({address="127.0.0.1:5300", order=3}) | |
31 | newServer({address="192.168.1.30:5300", pool="abuse"}) | |
9dea07d2 | 32 | |
ff484825 RG |
33 | -- switch the server balancing policy to round robin, |
34 | -- the default being least outstanding queries | |
35 | -- setServerPolicy(roundrobin) | |
36 | ||
37 | -- send the queries for selected domain suffixes to the server | |
38 | -- in the 'abuse' pool | |
22b2b326 | 39 | addPoolRule({"ezdns.it.", "xxx."}, "abuse") |
ff484825 RG |
40 | |
41 | -- send the queries from a selected subnet to the | |
42 | -- abuse pool | |
22b2b326 | 43 | addPoolRule("192.168.1.0/24", "abuse") |
4f4ad7f5 | 44 | |
ff484825 RG |
45 | -- send the queries for the "com" suffix to the "abuse" |
46 | -- pool, but only up to 100 qps | |
fd010ca3 | 47 | addQPSPoolRule("com.", 100, "abuse") |
9dea07d2 | 48 | |
ff484825 RG |
49 | -- declare a Lua action function, routing NAPTR queries |
50 | -- to the abuse pool | |
497a6e3a | 51 | function luarule(dq) |
ff484825 | 52 | if(dq.qtype==dnsdist.NAPTR) |
d8d85a30 | 53 | then |
54 | return DNSAction.Pool, "abuse" -- send to abuse pool | |
55 | else | |
56 | return DNSAction.None, "" -- no action | |
57 | end | |
58 | end | |
ff484825 RG |
59 | -- send only queries from the selected subnet to |
60 | -- the luarule function | |
d8d85a30 | 61 | addLuaAction("192.168.1.0/24", luarule) |
4f4ad7f5 | 62 | |
ff484825 RG |
63 | -- drop queries exceeding 5 qps, grouped by /24 for IPv4 |
64 | -- and /64 for IPv6 | |
1b726acf | 65 | addAction(MaxQPSIPRule(5, 24, 64), DropAction()) |
66 | ||
ff484825 | 67 | -- move the last rule to the first position |
d8d85a30 | 68 | topRule() |
69 | ||
ff484825 | 70 | -- drop queries for the following suffixes: |
0940e4eb | 71 | addDomainBlock("powerdns.org.") |
72 | addDomainBlock("spectre.") | |
ff484825 | 73 | -- this is equivalent to addAction("isis.", DropAction()) |
0940e4eb | 74 | addDomainBlock("isis.") |
75 | ||
9dea07d2 | 76 | -- called before we distribute a question |
ff484825 | 77 | block=newDNSName("powerdns.org.") |
68e82cf9 | 78 | truncateNMG = newNMG() |
79 | truncateNMG:addMask("213.244.0.0/16") | |
80 | truncateNMG:addMask("2001:503:ba3e::2:30") | |
81 | truncateNMG:addMask("fe80::/16") | |
82 | ||
83 | print(string.format("Have %d entries in truncate NMG", truncateNMG:size())) | |
84 | ||
da4e7813 | 85 | -- called to pick a downstream server, ignores 'up' status |
ff484825 | 86 | counter=0 |
497a6e3a | 87 | function luaroundrobin(servers, dq) |
ceee6652 | 88 | counter=counter+1; |
773470ca | 89 | return servers[1+(counter % #servers)] |
9dea07d2 | 90 | end |
22b2b326 | 91 | -- setServerPolicyLua("luaroundrobin", luaroundrobin) |
9dea07d2 | 92 | |
bf9edc24 RG |
93 | newServer({address="2001:888:2000:1d::2", pool={"auth", "dnssec"}}) |
94 | newServer({address="2a01:4f8:110:4389::2", pool={"auth", "dnssec"}}) | |
50bed881 | 95 | --setDNSSECPool("dnssec") |
96 | --topRule() | |
520eb5a0 | 97 | |
ff484825 RG |
98 | -- split queries between the 'auth' pool and the regular one, |
99 | -- based on the RD flag | |
100 | function splitSetup(servers, dq) | |
101 | if(dq.dh:getRD() == false) | |
75a2db75 | 102 | then |
ff484825 | 103 | return firstAvailable.policy(getPoolServers("auth"), dq) |
75a2db75 | 104 | else |
ff484825 | 105 | return firstAvailable.policy(servers, dq) |
75a2db75 | 106 | end |
da4e7813 | 107 | end |
bac6e8fb | 108 | -- setServerPolicyLua("splitSetup", splitSetup) |
109 | ||
ff484825 | 110 | -- the 'maintenance' function is called every second |
bac6e8fb | 111 | function maintenance() |
ff484825 RG |
112 | -- block all hosts that exceeded 20 qps over the past 10s, |
113 | -- for 60s | |
114 | addDynBlocks(exceedQRate(20, 10), "Exceeded query rate", 60) | |
bac6e8fb | 115 | end |
116 | ||
ff484825 RG |
117 | -- allow queries for the domain powerdns.com., drop everything else |
118 | -- addAction(makeRule("powerdns.com."), AllowAction()) | |
119 | -- addAction(AllRule(), DropAction()) | |
120 | ||
121 | -- clear the RD flag in queries for powerdns.com. | |
122 | -- addNoRecurseRule("powerdns.com.") | |
123 | -- another way to do the exact same thing: | |
124 | -- addAction("powerdns.com.", NoRecurseAction()) | |
125 | ||
126 | -- set the CD flag in queries for powerdns.com. | |
127 | -- addDisableValidationRule("powerdns.com.") | |
128 | -- or: | |
129 | -- addAction("powerdns.com.", DisableValidationAction()) | |
130 | ||
131 | -- delay all responses for 1000ms | |
132 | -- addAction(AllRule(), DelayAction(1000)) | |
133 | ||
134 | -- truncate ANY queries over UDP only | |
135 | -- addAnyTCRule() | |
136 | ||
137 | -- truncate ANY queries over TCP only | |
138 | -- addAction(AndRule({QTypeRule(dnsdist.ANY), TCPRule(true)}), TCAction()) | |
139 | -- can also be written as: | |
140 | -- addAction(AndRule({QTypeRule("ANY"), TCPRule(true)}), TCAction()) | |
141 | ||
142 | -- return 'not implemented' for qtype != A over UDP | |
ce71f790 | 143 | -- addAction(AndRule({NotRule(QTypeRule("A")), TCPRule(false)}), RCodeAction(dnsdist.NOTIMP)) |
ff484825 RG |
144 | |
145 | -- return 'not implemented' for qtype == A OR received over UDP | |
ce71f790 | 146 | -- addAction(OrRule({QTypeRule("A"), TCPRule(false)}), RCodeAction(dnsdist.NOTIMP)) |
ff484825 | 147 | |
456fc645 | 148 | -- log all queries to a 'dndist.log' file, in text-mode (not binary) appending and unbuffered |
149 | -- addAction(AllRule(), LogAction("dnsdist.log", false, true, false)) | |
ff484825 RG |
150 | |
151 | -- drop all queries with the DO flag set | |
152 | -- addAction(DNSSECRule(), DropAction()) | |
153 | ||
154 | -- drop all queries for the CHAOS class | |
155 | -- addAction(QClassRule(3), DropAction()) | |
55baa1f2 RG |
156 | -- addAction(QClassRule(DNSClass.CHAOS), DropAction()) |
157 | ||
158 | -- drop all queries with the UPDATE opcode | |
159 | -- addAction(OpcodeRule(DNSOpcode.Update), DropAction()) | |
160 | ||
161 | -- refuse all queries not having exactly one question | |
162 | -- addAction(NotRule(RecordsCountRule(DNSSection.Question, 1, 1)), RCodeAction(dnsdist.REFUSED)) | |
ff484825 RG |
163 | |
164 | -- return 'refused' for domains matching the regex evil[0-9]{4,}.powerdns.com$ | |
55baa1f2 | 165 | -- addAction(RegexRule("evil[0-9]{4,}\\.powerdns\\.com$"), RCodeAction(dnsdist.REFUSED)) |
ff484825 RG |
166 | |
167 | -- spoof responses for A, AAAA and ANY for spoof.powerdns.com. | |
168 | -- A queries will get 192.0.2.1, AAAA 2001:DB8::1 and ANY both | |
169 | -- addDomainSpoof("spoof.powerdns.com.", "192.0.2.1", "2001:DB8::1") | |
170 | ||
171 | -- spoof responses will multiple records | |
172 | -- A will get 192.0.2.1 and 192.0.2.2, AAAA 20B8::1 and 2001:DB8::2 | |
173 | -- ANY all of that | |
174 | -- addDomainSpoof("spoof.powerdns.com", {"192.0.2.1", "192.0.2.2", "20B8::1", "2001:DB8::2"}) | |
175 | ||
176 | -- spoof responses with a CNAME | |
177 | -- addDomainCNAMESpoof("cnamespoof.powerdns.com.", "cname.powerdns.com.") | |
178 | ||
179 | -- spoof responses in Lua | |
180 | --[[ | |
181 | function spoof1rule(dq) | |
182 | if(dq.qtype==1) -- A | |
183 | then | |
184 | return DNSAction.Spoof, "192.0.2.1" | |
185 | elseif(dq.qtype == 28) -- AAAA | |
186 | then | |
187 | return DNSAction.Spoof, "2001:DB8::1" | |
188 | else | |
189 | return DNSAction.None, "" | |
190 | end | |
191 | end | |
192 | function spoof2rule(dq) | |
193 | return DNSAction.Spoof, "spoofed.powerdns.com." | |
194 | end | |
195 | addLuaAction("luaspoof1.powerdns.com.", spoof1rule) | |
196 | addLuaAction("luaspoof2.powerdns.com.", spoof2rule) | |
197 | ||
198 | --]] | |
a94673ea RG |
199 | |
200 | -- alter a protobuf response for anonymization purposes | |
201 | --[[ | |
202 | function alterProtobuf(dq, protobuf) | |
203 | requestor = newCA(dq.remoteaddr:toString()) | |
204 | if requestor:isIPv4() then | |
205 | requestor:truncate(24) | |
206 | else | |
207 | requestor:truncate(56) | |
208 | end | |
209 | protobuf:setRequestor(requestor) | |
210 | end | |
211 | ||
212 | rl = newRemoteLogger("127.0.0.1:4242") | |
213 | addAction(AllRule(), RemoteLogAction(rl, alterProtobuf)) | |
214 | --]] |