]> git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.dnsdist/test_Advanced.py
Merge pull request #6764 from rgacogne/dnsdist-rotate-certs
[thirdparty/pdns.git] / regression-tests.dnsdist / test_Advanced.py
1 #!/usr/bin/env python
2 import base64
3 from datetime import datetime, timedelta
4 import os
5 import string
6 import time
7 import dns
8 from dnsdisttests import DNSDistTest
9
10 class TestAdvancedAllow(DNSDistTest):
11
12 _config_template = """
13 addAction(AllRule(), NoneAction())
14 addAction(makeRule("allowed.advanced.tests.powerdns.com."), AllowAction())
15 addAction(AllRule(), DropAction())
16 newServer{address="127.0.0.1:%s"}
17 """
18
19 def testAdvancedAllow(self):
20 """
21 Advanced: Allowed qname is not dropped
22
23 A query for allowed.advanced.tests.powerdns.com. should be allowed
24 while others should be dropped.
25 """
26 name = 'allowed.advanced.tests.powerdns.com.'
27 query = dns.message.make_query(name, 'A', 'IN')
28 response = dns.message.make_response(query)
29 rrset = dns.rrset.from_text(name,
30 3600,
31 dns.rdataclass.IN,
32 dns.rdatatype.A,
33 '127.0.0.1')
34 response.answer.append(rrset)
35
36 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
37 self.assertTrue(receivedQuery)
38 self.assertTrue(receivedResponse)
39 receivedQuery.id = query.id
40 self.assertEquals(query, receivedQuery)
41 self.assertEquals(response, receivedResponse)
42
43 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
44 self.assertTrue(receivedQuery)
45 self.assertTrue(receivedResponse)
46 receivedQuery.id = query.id
47 self.assertEquals(query, receivedQuery)
48 self.assertEquals(response, receivedResponse)
49
50 def testAdvancedAllowDropped(self):
51 """
52 Advanced: Not allowed qname is dropped
53
54 A query for notallowed.advanced.tests.powerdns.com. should be dropped.
55 """
56 name = 'notallowed.advanced.tests.powerdns.com.'
57 query = dns.message.make_query(name, 'A', 'IN')
58 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
59 self.assertEquals(receivedResponse, None)
60
61 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
62 self.assertEquals(receivedResponse, None)
63
64 class TestAdvancedFixupCase(DNSDistTest):
65
66 _config_template = """
67 truncateTC(true)
68 fixupCase(true)
69 newServer{address="127.0.0.1:%s"}
70 """
71
72 def testAdvancedFixupCase(self):
73 """
74 Advanced: Fixup Case
75
76 Send a query with lower and upper chars,
77 make the backend return a lowercase version,
78 check that dnsdist fixes the response.
79 """
80 name = 'fiXuPCasE.advanced.tests.powerdns.com.'
81 query = dns.message.make_query(name, 'A', 'IN')
82 lowercasequery = dns.message.make_query(name.lower(), 'A', 'IN')
83 response = dns.message.make_response(lowercasequery)
84 expectedResponse = dns.message.make_response(query)
85 rrset = dns.rrset.from_text(name,
86 3600,
87 dns.rdataclass.IN,
88 dns.rdatatype.A,
89 '127.0.0.1')
90 response.answer.append(rrset)
91 expectedResponse.answer.append(rrset)
92
93 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
94 self.assertTrue(receivedQuery)
95 self.assertTrue(receivedResponse)
96 receivedQuery.id = query.id
97 self.assertEquals(query, receivedQuery)
98 self.assertEquals(expectedResponse, receivedResponse)
99
100 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
101 self.assertTrue(receivedQuery)
102 self.assertTrue(receivedResponse)
103 receivedQuery.id = query.id
104 self.assertEquals(query, receivedQuery)
105 self.assertEquals(expectedResponse, receivedResponse)
106
107
108 class TestAdvancedRemoveRD(DNSDistTest):
109
110 _config_template = """
111 addAction("norecurse.advanced.tests.powerdns.com.", NoRecurseAction())
112 newServer{address="127.0.0.1:%s"}
113 """
114
115 def testAdvancedNoRD(self):
116 """
117 Advanced: No RD
118
119 Send a query with RD,
120 check that dnsdist clears the RD flag.
121 """
122 name = 'norecurse.advanced.tests.powerdns.com.'
123 query = dns.message.make_query(name, 'A', 'IN')
124 expectedQuery = dns.message.make_query(name, 'A', 'IN')
125 expectedQuery.flags &= ~dns.flags.RD
126
127 response = dns.message.make_response(query)
128 rrset = dns.rrset.from_text(name,
129 3600,
130 dns.rdataclass.IN,
131 dns.rdatatype.A,
132 '127.0.0.1')
133 response.answer.append(rrset)
134
135 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
136 self.assertTrue(receivedQuery)
137 self.assertTrue(receivedResponse)
138 receivedQuery.id = expectedQuery.id
139 self.assertEquals(expectedQuery, receivedQuery)
140 self.assertEquals(response, receivedResponse)
141
142 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
143 self.assertTrue(receivedQuery)
144 self.assertTrue(receivedResponse)
145 receivedQuery.id = expectedQuery.id
146 self.assertEquals(expectedQuery, receivedQuery)
147 self.assertEquals(response, receivedResponse)
148
149 def testAdvancedKeepRD(self):
150 """
151 Advanced: No RD canary
152
153 Send a query with RD for a canary domain,
154 check that dnsdist does not clear the RD flag.
155 """
156 name = 'keeprecurse.advanced.tests.powerdns.com.'
157 query = dns.message.make_query(name, 'A', 'IN')
158
159 response = dns.message.make_response(query)
160 rrset = dns.rrset.from_text(name,
161 3600,
162 dns.rdataclass.IN,
163 dns.rdatatype.A,
164 '127.0.0.1')
165 response.answer.append(rrset)
166
167 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
168 self.assertTrue(receivedQuery)
169 self.assertTrue(receivedResponse)
170 receivedQuery.id = query.id
171 self.assertEquals(query, receivedQuery)
172 self.assertEquals(response, receivedResponse)
173
174 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
175 self.assertTrue(receivedQuery)
176 self.assertTrue(receivedResponse)
177 receivedQuery.id = query.id
178 self.assertEquals(query, receivedQuery)
179 self.assertEquals(response, receivedResponse)
180
181
182 class TestAdvancedAddCD(DNSDistTest):
183
184 _config_template = """
185 addAction("setcd.advanced.tests.powerdns.com.", DisableValidationAction())
186 addAction(makeRule("setcdviaaction.advanced.tests.powerdns.com."), DisableValidationAction())
187 newServer{address="127.0.0.1:%s"}
188 """
189
190 def testAdvancedSetCD(self):
191 """
192 Advanced: Set CD
193
194 Send a query with CD cleared,
195 check that dnsdist set the CD flag.
196 """
197 name = 'setcd.advanced.tests.powerdns.com.'
198 query = dns.message.make_query(name, 'A', 'IN')
199 expectedQuery = dns.message.make_query(name, 'A', 'IN')
200 expectedQuery.flags |= dns.flags.CD
201
202 response = dns.message.make_response(query)
203 rrset = dns.rrset.from_text(name,
204 3600,
205 dns.rdataclass.IN,
206 dns.rdatatype.A,
207 '127.0.0.1')
208 response.answer.append(rrset)
209
210 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
211 self.assertTrue(receivedQuery)
212 self.assertTrue(receivedResponse)
213 receivedQuery.id = expectedQuery.id
214 self.assertEquals(expectedQuery, receivedQuery)
215 self.assertEquals(response, receivedResponse)
216
217 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
218 self.assertTrue(receivedQuery)
219 self.assertTrue(receivedResponse)
220 receivedQuery.id = expectedQuery.id
221 self.assertEquals(expectedQuery, receivedQuery)
222 self.assertEquals(response, receivedResponse)
223
224 def testAdvancedSetCDViaAction(self):
225 """
226 Advanced: Set CD via Action
227
228 Send a query with CD cleared,
229 check that dnsdist set the CD flag.
230 """
231 name = 'setcdviaaction.advanced.tests.powerdns.com.'
232 query = dns.message.make_query(name, 'A', 'IN')
233 expectedQuery = dns.message.make_query(name, 'A', 'IN')
234 expectedQuery.flags |= dns.flags.CD
235
236 response = dns.message.make_response(query)
237 rrset = dns.rrset.from_text(name,
238 3600,
239 dns.rdataclass.IN,
240 dns.rdatatype.A,
241 '127.0.0.1')
242 response.answer.append(rrset)
243
244 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
245 self.assertTrue(receivedQuery)
246 self.assertTrue(receivedResponse)
247 receivedQuery.id = expectedQuery.id
248 self.assertEquals(expectedQuery, receivedQuery)
249 self.assertEquals(response, receivedResponse)
250
251 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
252 self.assertTrue(receivedQuery)
253 self.assertTrue(receivedResponse)
254 receivedQuery.id = expectedQuery.id
255 self.assertEquals(expectedQuery, receivedQuery)
256 self.assertEquals(response, receivedResponse)
257
258 def testAdvancedKeepNoCD(self):
259 """
260 Advanced: Preserve CD canary
261
262 Send a query without CD for a canary domain,
263 check that dnsdist does not set the CD flag.
264 """
265 name = 'keepnocd.advanced.tests.powerdns.com.'
266 query = dns.message.make_query(name, 'A', 'IN')
267
268 response = dns.message.make_response(query)
269 rrset = dns.rrset.from_text(name,
270 3600,
271 dns.rdataclass.IN,
272 dns.rdatatype.A,
273 '127.0.0.1')
274 response.answer.append(rrset)
275
276 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
277 self.assertTrue(receivedQuery)
278 self.assertTrue(receivedResponse)
279 receivedQuery.id = query.id
280 self.assertEquals(query, receivedQuery)
281 self.assertEquals(response, receivedResponse)
282
283 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
284 self.assertTrue(receivedQuery)
285 self.assertTrue(receivedResponse)
286 receivedQuery.id = query.id
287 self.assertEquals(query, receivedQuery)
288 self.assertEquals(response, receivedResponse)
289
290 class TestAdvancedClearRD(DNSDistTest):
291
292 _config_template = """
293 addAction("clearrd.advanced.tests.powerdns.com.", NoRecurseAction())
294 addAction(makeRule("clearrdviaaction.advanced.tests.powerdns.com."), NoRecurseAction())
295 newServer{address="127.0.0.1:%s"}
296 """
297
298 def testAdvancedClearRD(self):
299 """
300 Advanced: Clear RD
301
302 Send a query with RD set,
303 check that dnsdist clears the RD flag.
304 """
305 name = 'clearrd.advanced.tests.powerdns.com.'
306 query = dns.message.make_query(name, 'A', 'IN')
307 expectedQuery = dns.message.make_query(name, 'A', 'IN')
308 expectedQuery.flags &= ~dns.flags.RD
309
310 response = dns.message.make_response(query)
311 rrset = dns.rrset.from_text(name,
312 3600,
313 dns.rdataclass.IN,
314 dns.rdatatype.A,
315 '127.0.0.1')
316 response.answer.append(rrset)
317
318 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
319 self.assertTrue(receivedQuery)
320 self.assertTrue(receivedResponse)
321 receivedQuery.id = expectedQuery.id
322 self.assertEquals(expectedQuery, receivedQuery)
323 self.assertEquals(response, receivedResponse)
324
325 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
326 self.assertTrue(receivedQuery)
327 self.assertTrue(receivedResponse)
328 receivedQuery.id = expectedQuery.id
329 self.assertEquals(expectedQuery, receivedQuery)
330 self.assertEquals(response, receivedResponse)
331
332 def testAdvancedClearRDViaAction(self):
333 """
334 Advanced: Clear RD via Action
335
336 Send a query with RD set,
337 check that dnsdist clears the RD flag.
338 """
339 name = 'clearrdviaaction.advanced.tests.powerdns.com.'
340 query = dns.message.make_query(name, 'A', 'IN')
341 expectedQuery = dns.message.make_query(name, 'A', 'IN')
342 expectedQuery.flags &= ~dns.flags.RD
343
344 response = dns.message.make_response(query)
345 rrset = dns.rrset.from_text(name,
346 3600,
347 dns.rdataclass.IN,
348 dns.rdatatype.A,
349 '127.0.0.1')
350 response.answer.append(rrset)
351
352 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
353 self.assertTrue(receivedQuery)
354 self.assertTrue(receivedResponse)
355 receivedQuery.id = expectedQuery.id
356 self.assertEquals(expectedQuery, receivedQuery)
357 self.assertEquals(response, receivedResponse)
358
359 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
360 self.assertTrue(receivedQuery)
361 self.assertTrue(receivedResponse)
362 receivedQuery.id = expectedQuery.id
363 self.assertEquals(expectedQuery, receivedQuery)
364 self.assertEquals(response, receivedResponse)
365
366 def testAdvancedKeepRD(self):
367 """
368 Advanced: Preserve RD canary
369
370 Send a query with RD for a canary domain,
371 check that dnsdist does not clear the RD flag.
372 """
373 name = 'keeprd.advanced.tests.powerdns.com.'
374 query = dns.message.make_query(name, 'A', 'IN')
375
376 response = dns.message.make_response(query)
377 rrset = dns.rrset.from_text(name,
378 3600,
379 dns.rdataclass.IN,
380 dns.rdatatype.A,
381 '127.0.0.1')
382 response.answer.append(rrset)
383
384 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
385 self.assertTrue(receivedQuery)
386 self.assertTrue(receivedResponse)
387 receivedQuery.id = query.id
388 self.assertEquals(query, receivedQuery)
389 self.assertEquals(response, receivedResponse)
390
391 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
392 self.assertTrue(receivedQuery)
393 self.assertTrue(receivedResponse)
394 receivedQuery.id = query.id
395 self.assertEquals(query, receivedQuery)
396 self.assertEquals(response, receivedResponse)
397
398
399 class TestAdvancedACL(DNSDistTest):
400
401 _config_template = """
402 newServer{address="127.0.0.1:%s"}
403 """
404 _acl = ['192.0.2.1/32']
405
406 def testACLBlocked(self):
407 """
408 Advanced: ACL blocked
409
410 Send an A query to "tests.powerdns.com.",
411 we expect no response since 127.0.0.1 is not on the
412 ACL.
413 """
414 name = 'tests.powerdns.com.'
415 query = dns.message.make_query(name, 'A', 'IN')
416
417 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
418 self.assertEquals(receivedResponse, None)
419
420 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
421 self.assertEquals(receivedResponse, None)
422
423 class TestAdvancedDelay(DNSDistTest):
424
425 _config_template = """
426 addAction(AllRule(), DelayAction(1000))
427 newServer{address="127.0.0.1:%s"}
428 """
429
430 def testDelayed(self):
431 """
432 Advanced: Delayed
433
434 Send an A query to "tests.powerdns.com.",
435 check that the response delay is longer than 1000 ms
436 over UDP, less than that over TCP.
437 """
438 name = 'tests.powerdns.com.'
439 query = dns.message.make_query(name, 'A', 'IN')
440 response = dns.message.make_response(query)
441 rrset = dns.rrset.from_text(name,
442 60,
443 dns.rdataclass.IN,
444 dns.rdatatype.A,
445 '192.0.2.1')
446 response.answer.append(rrset)
447
448 begin = datetime.now()
449 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
450 end = datetime.now()
451 receivedQuery.id = query.id
452 self.assertEquals(query, receivedQuery)
453 self.assertEquals(response, receivedResponse)
454 self.assertTrue((end - begin) > timedelta(0, 1))
455
456 begin = datetime.now()
457 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
458 end = datetime.now()
459 receivedQuery.id = query.id
460 self.assertEquals(query, receivedQuery)
461 self.assertEquals(response, receivedResponse)
462 self.assertTrue((end - begin) < timedelta(0, 1))
463
464
465 class TestAdvancedTruncateAnyAndTCP(DNSDistTest):
466
467 _config_template = """
468 truncateTC(false)
469 addAction(AndRule({QTypeRule("ANY"), TCPRule(true)}), TCAction())
470 newServer{address="127.0.0.1:%s"}
471 """
472 def testTruncateAnyOverTCP(self):
473 """
474 Advanced: Truncate ANY over TCP
475
476 Send an ANY query to "anytruncatetcp.advanced.tests.powerdns.com.",
477 should be truncated over TCP, not over UDP (yes, it makes no sense,
478 deal with it).
479 """
480 name = 'anytruncatetcp.advanced.tests.powerdns.com.'
481 query = dns.message.make_query(name, 'ANY', 'IN')
482
483 response = dns.message.make_response(query)
484 rrset = dns.rrset.from_text(name,
485 3600,
486 dns.rdataclass.IN,
487 dns.rdatatype.A,
488 '127.0.0.1')
489
490 response.answer.append(rrset)
491
492 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
493 self.assertTrue(receivedQuery)
494 self.assertTrue(receivedResponse)
495 receivedQuery.id = query.id
496 self.assertEquals(query, receivedQuery)
497 self.assertEquals(receivedResponse, response)
498
499 expectedResponse = dns.message.make_response(query)
500 expectedResponse.flags |= dns.flags.TC
501
502 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
503 self.assertEquals(receivedResponse, expectedResponse)
504
505 class TestAdvancedAndNot(DNSDistTest):
506
507 _config_template = """
508 addAction(AndRule({NotRule(QTypeRule("A")), TCPRule(false)}), RCodeAction(dnsdist.NOTIMP))
509 newServer{address="127.0.0.1:%s"}
510 """
511 def testAOverUDPReturnsNotImplementedCanary(self):
512 """
513 Advanced: !A && UDP canary
514
515 dnsdist is configured to reply 'not implemented' for query
516 over UDP AND !qtype A.
517 We send an A query over UDP and TCP, and check that the
518 response is OK.
519 """
520 name = 'andnot.advanced.tests.powerdns.com.'
521 query = dns.message.make_query(name, 'A', 'IN')
522 response = dns.message.make_response(query)
523 rrset = dns.rrset.from_text(name,
524 3600,
525 dns.rdataclass.IN,
526 dns.rdatatype.A,
527 '127.0.0.1')
528 response.answer.append(rrset)
529
530 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
531 self.assertTrue(receivedQuery)
532 self.assertTrue(receivedResponse)
533 receivedQuery.id = query.id
534 self.assertEquals(query, receivedQuery)
535 self.assertEquals(receivedResponse, response)
536
537 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
538 self.assertTrue(receivedQuery)
539 self.assertTrue(receivedResponse)
540 receivedQuery.id = query.id
541 self.assertEquals(query, receivedQuery)
542 self.assertEquals(receivedResponse, response)
543
544 def testAOverUDPReturnsNotImplemented(self):
545 """
546 Advanced: !A && UDP
547
548 dnsdist is configured to reply 'not implemented' for query
549 over UDP AND !qtype A.
550 We send a TXT query over UDP and TCP, and check that the
551 response is OK for TCP and 'not implemented' for UDP.
552 """
553 name = 'andnot.advanced.tests.powerdns.com.'
554 query = dns.message.make_query(name, 'TXT', 'IN')
555
556 expectedResponse = dns.message.make_response(query)
557 expectedResponse.set_rcode(dns.rcode.NOTIMP)
558
559 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
560 self.assertEquals(receivedResponse, expectedResponse)
561
562 response = dns.message.make_response(query)
563 rrset = dns.rrset.from_text(name,
564 3600,
565 dns.rdataclass.IN,
566 dns.rdatatype.TXT,
567 'nothing to see here')
568 response.answer.append(rrset)
569
570 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
571 self.assertTrue(receivedQuery)
572 self.assertTrue(receivedResponse)
573 receivedQuery.id = query.id
574 self.assertEquals(query, receivedQuery)
575 self.assertEquals(receivedResponse, response)
576
577 class TestAdvancedOr(DNSDistTest):
578
579 _config_template = """
580 addAction(OrRule({QTypeRule("A"), TCPRule(false)}), RCodeAction(dnsdist.NOTIMP))
581 newServer{address="127.0.0.1:%s"}
582 """
583 def testAAAAOverUDPReturnsNotImplemented(self):
584 """
585 Advanced: A || UDP: AAAA
586
587 dnsdist is configured to reply 'not implemented' for query
588 over UDP OR qtype A.
589 We send an AAAA query over UDP and TCP, and check that the
590 response is 'not implemented' for UDP and OK for TCP.
591 """
592 name = 'aorudp.advanced.tests.powerdns.com.'
593 query = dns.message.make_query(name, 'AAAA', 'IN')
594 response = dns.message.make_response(query)
595 rrset = dns.rrset.from_text(name,
596 3600,
597 dns.rdataclass.IN,
598 dns.rdatatype.AAAA,
599 '::1')
600 response.answer.append(rrset)
601
602 expectedResponse = dns.message.make_response(query)
603 expectedResponse.set_rcode(dns.rcode.NOTIMP)
604
605 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
606 self.assertEquals(receivedResponse, expectedResponse)
607
608 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
609 self.assertTrue(receivedQuery)
610 self.assertTrue(receivedResponse)
611 receivedQuery.id = query.id
612 self.assertEquals(query, receivedQuery)
613 self.assertEquals(receivedResponse, response)
614
615 def testAOverUDPReturnsNotImplemented(self):
616 """
617 Advanced: A || UDP: A
618
619 dnsdist is configured to reply 'not implemented' for query
620 over UDP OR qtype A.
621 We send an A query over UDP and TCP, and check that the
622 response is 'not implemented' for both.
623 """
624 name = 'aorudp.advanced.tests.powerdns.com.'
625 query = dns.message.make_query(name, 'A', 'IN')
626
627 expectedResponse = dns.message.make_response(query)
628 expectedResponse.set_rcode(dns.rcode.NOTIMP)
629
630 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
631 self.assertEquals(receivedResponse, expectedResponse)
632
633 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
634 self.assertEquals(receivedResponse, expectedResponse)
635
636
637 class TestAdvancedLogAction(DNSDistTest):
638
639 _config_template = """
640 newServer{address="127.0.0.1:%s"}
641 addAction(AllRule(), LogAction("dnsdist.log", false))
642 """
643 def testAdvancedLogAction(self):
644 """
645 Advanced: Log all queries
646
647 """
648 count = 50
649 name = 'logaction.advanced.tests.powerdns.com.'
650 query = dns.message.make_query(name, 'A', 'IN')
651 response = dns.message.make_response(query)
652 rrset = dns.rrset.from_text(name,
653 3600,
654 dns.rdataclass.IN,
655 dns.rdatatype.A,
656 '127.0.0.1')
657 response.answer.append(rrset)
658
659 for _ in range(count):
660 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
661 self.assertTrue(receivedQuery)
662 self.assertTrue(receivedResponse)
663 receivedQuery.id = query.id
664 self.assertEquals(query, receivedQuery)
665 self.assertEquals(response, receivedResponse)
666
667 self.assertTrue(os.path.isfile('dnsdist.log'))
668 self.assertTrue(os.stat('dnsdist.log').st_size > 0)
669
670 class TestAdvancedDNSSEC(DNSDistTest):
671
672 _config_template = """
673 newServer{address="127.0.0.1:%s"}
674 addAction(DNSSECRule(), DropAction())
675 """
676 def testAdvancedDNSSECDrop(self):
677 """
678 Advanced: DNSSEC Rule
679
680 """
681 name = 'dnssec.advanced.tests.powerdns.com.'
682 query = dns.message.make_query(name, 'A', 'IN')
683 doquery = dns.message.make_query(name, 'A', 'IN', want_dnssec=True)
684 response = dns.message.make_response(query)
685 rrset = dns.rrset.from_text(name,
686 3600,
687 dns.rdataclass.IN,
688 dns.rdatatype.A,
689 '127.0.0.1')
690 response.answer.append(rrset)
691
692 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
693 self.assertTrue(receivedQuery)
694 self.assertTrue(receivedResponse)
695 receivedQuery.id = query.id
696 self.assertEquals(query, receivedQuery)
697 self.assertEquals(response, receivedResponse)
698
699 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
700 self.assertTrue(receivedQuery)
701 self.assertTrue(receivedResponse)
702 receivedQuery.id = query.id
703 self.assertEquals(query, receivedQuery)
704 self.assertEquals(response, receivedResponse)
705
706 (_, receivedResponse) = self.sendUDPQuery(doquery, response)
707 self.assertEquals(receivedResponse, None)
708 (_, receivedResponse) = self.sendTCPQuery(doquery, response)
709 self.assertEquals(receivedResponse, None)
710
711 class TestAdvancedQClass(DNSDistTest):
712
713 _config_template = """
714 newServer{address="127.0.0.1:%s"}
715 addAction(QClassRule(DNSClass.CHAOS), DropAction())
716 """
717 def testAdvancedQClassChaosDrop(self):
718 """
719 Advanced: Drop QClass CHAOS
720
721 """
722 name = 'qclasschaos.advanced.tests.powerdns.com.'
723 query = dns.message.make_query(name, 'TXT', 'CHAOS')
724
725 (_, receivedResponse) = self.sendUDPQuery(query, response=None)
726 self.assertEquals(receivedResponse, None)
727 (_, receivedResponse) = self.sendTCPQuery(query, response=None)
728 self.assertEquals(receivedResponse, None)
729
730 def testAdvancedQClassINAllow(self):
731 """
732 Advanced: Allow QClass IN
733
734 """
735 name = 'qclassin.advanced.tests.powerdns.com.'
736 query = dns.message.make_query(name, 'A', 'IN')
737 response = dns.message.make_response(query)
738 rrset = dns.rrset.from_text(name,
739 3600,
740 dns.rdataclass.IN,
741 dns.rdatatype.A,
742 '127.0.0.1')
743 response.answer.append(rrset)
744
745 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
746 self.assertTrue(receivedQuery)
747 self.assertTrue(receivedResponse)
748 receivedQuery.id = query.id
749 self.assertEquals(query, receivedQuery)
750 self.assertEquals(response, receivedResponse)
751
752 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
753 self.assertTrue(receivedQuery)
754 self.assertTrue(receivedResponse)
755 receivedQuery.id = query.id
756 self.assertEquals(query, receivedQuery)
757 self.assertEquals(response, receivedResponse)
758
759 class TestAdvancedOpcode(DNSDistTest):
760
761 _config_template = """
762 newServer{address="127.0.0.1:%s"}
763 addAction(OpcodeRule(DNSOpcode.Notify), DropAction())
764 """
765 def testAdvancedOpcodeNotifyDrop(self):
766 """
767 Advanced: Drop Opcode NOTIFY
768
769 """
770 name = 'opcodenotify.advanced.tests.powerdns.com.'
771 query = dns.message.make_query(name, 'A', 'IN')
772 query.set_opcode(dns.opcode.NOTIFY)
773
774 (_, receivedResponse) = self.sendUDPQuery(query, response=None)
775 self.assertEquals(receivedResponse, None)
776 (_, receivedResponse) = self.sendTCPQuery(query, response=None)
777 self.assertEquals(receivedResponse, None)
778
779 def testAdvancedOpcodeUpdateINAllow(self):
780 """
781 Advanced: Allow Opcode UPDATE
782
783 """
784 name = 'opcodeupdate.advanced.tests.powerdns.com.'
785 query = dns.message.make_query(name, 'A', 'IN')
786 query.set_opcode(dns.opcode.UPDATE)
787 response = dns.message.make_response(query)
788 rrset = dns.rrset.from_text(name,
789 3600,
790 dns.rdataclass.IN,
791 dns.rdatatype.A,
792 '127.0.0.1')
793 response.answer.append(rrset)
794
795 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
796 self.assertTrue(receivedQuery)
797 self.assertTrue(receivedResponse)
798 receivedQuery.id = query.id
799 self.assertEquals(query, receivedQuery)
800 self.assertEquals(response, receivedResponse)
801
802 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
803 self.assertTrue(receivedQuery)
804 self.assertTrue(receivedResponse)
805 receivedQuery.id = query.id
806 self.assertEquals(query, receivedQuery)
807 self.assertEquals(response, receivedResponse)
808
809 class TestAdvancedNonTerminalRule(DNSDistTest):
810
811 _config_template = """
812 newServer{address="127.0.0.1:%s", pool="real"}
813 addAction(AllRule(), DisableValidationAction())
814 addAction(AllRule(), PoolAction("real"))
815 addAction(AllRule(), DropAction())
816 """
817 def testAdvancedNonTerminalRules(self):
818 """
819 Advanced: Non terminal rules
820
821 We check that DisableValidationAction() is applied
822 but does not stop the processing, then that
823 PoolAction() is applied _and_ stop the processing.
824 """
825 name = 'nonterminal.advanced.tests.powerdns.com.'
826 query = dns.message.make_query(name, 'A', 'IN')
827 expectedQuery = dns.message.make_query(name, 'A', 'IN')
828 expectedQuery.flags |= dns.flags.CD
829 response = dns.message.make_response(query)
830 rrset = dns.rrset.from_text(name,
831 3600,
832 dns.rdataclass.IN,
833 dns.rdatatype.A,
834 '192.0.2.1')
835 response.answer.append(rrset)
836
837 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
838 self.assertTrue(receivedQuery)
839 self.assertTrue(receivedResponse)
840 receivedQuery.id = expectedQuery.id
841 self.assertEquals(expectedQuery, receivedQuery)
842 self.assertEquals(response, receivedResponse)
843
844 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
845 self.assertTrue(receivedQuery)
846 self.assertTrue(receivedResponse)
847 receivedQuery.id = expectedQuery.id
848 self.assertEquals(expectedQuery, receivedQuery)
849 self.assertEquals(response, receivedResponse)
850
851 class TestAdvancedStringOnlyServer(DNSDistTest):
852
853 _config_template = """
854 newServer("127.0.0.1:%s")
855 """
856
857 def testAdvancedStringOnlyServer(self):
858 """
859 Advanced: "string-only" server is placed in the default pool
860 """
861 name = 'string-only-server.advanced.tests.powerdns.com.'
862 query = dns.message.make_query(name, 'A', 'IN')
863 response = dns.message.make_response(query)
864 rrset = dns.rrset.from_text(name,
865 3600,
866 dns.rdataclass.IN,
867 dns.rdatatype.A,
868 '192.0.2.1')
869 response.answer.append(rrset)
870
871 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
872 self.assertTrue(receivedQuery)
873 self.assertTrue(receivedResponse)
874 receivedQuery.id = query.id
875 self.assertEquals(query, receivedQuery)
876 self.assertEquals(response, receivedResponse)
877
878 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
879 self.assertTrue(receivedQuery)
880 self.assertTrue(receivedResponse)
881 receivedQuery.id = query.id
882 self.assertEquals(query, receivedQuery)
883 self.assertEquals(response, receivedResponse)
884
885 class TestAdvancedRestoreFlagsOnSelfResponse(DNSDistTest):
886
887 _config_template = """
888 addAction(AllRule(), DisableValidationAction())
889 addAction(AllRule(), SpoofAction("192.0.2.1"))
890 newServer{address="127.0.0.1:%s"}
891 """
892
893 def testAdvancedRestoreFlagsOnSpoofResponse(self):
894 """
895 Advanced: Restore flags on spoofed response
896
897 Send a query with CD flag cleared, dnsdist is
898 instructed to set it, then to spoof the response,
899 check that response has the flag cleared.
900 """
901 name = 'spoofed.restoreflags.advanced.tests.powerdns.com.'
902 query = dns.message.make_query(name, 'A', 'IN')
903 # dnsdist set RA = RD for spoofed responses
904 query.flags &= ~dns.flags.RD
905
906 response = dns.message.make_response(query)
907 rrset = dns.rrset.from_text(name,
908 60,
909 dns.rdataclass.IN,
910 dns.rdatatype.A,
911 '192.0.2.1')
912 response.answer.append(rrset)
913
914 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
915 self.assertTrue(receivedResponse)
916 self.assertEquals(response, receivedResponse)
917
918 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
919 self.assertTrue(receivedResponse)
920 self.assertEquals(response, receivedResponse)
921
922 class TestAdvancedQPS(DNSDistTest):
923
924 _config_template = """
925 addAction("qps.advanced.tests.powerdns.com", QPSAction(10))
926 newServer{address="127.0.0.1:%s"}
927 """
928
929 def testAdvancedQPSLimit(self):
930 """
931 Advanced: QPS Limit
932
933 Send queries to "qps.advanced.tests.powerdns.com."
934 check that dnsdist drops queries when the max QPS has been reached.
935 """
936 maxQPS = 10
937 name = 'qps.advanced.tests.powerdns.com.'
938 query = dns.message.make_query(name, 'A', 'IN')
939 response = dns.message.make_response(query)
940 rrset = dns.rrset.from_text(name,
941 60,
942 dns.rdataclass.IN,
943 dns.rdatatype.A,
944 '192.0.2.1')
945 response.answer.append(rrset)
946
947 for _ in range(maxQPS):
948 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
949 receivedQuery.id = query.id
950 self.assertEquals(query, receivedQuery)
951 self.assertEquals(response, receivedResponse)
952
953 # we should now be dropped
954 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
955 self.assertEquals(receivedResponse, None)
956
957 time.sleep(1)
958
959 # again, over TCP this time
960 for _ in range(maxQPS):
961 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
962 receivedQuery.id = query.id
963 self.assertEquals(query, receivedQuery)
964 self.assertEquals(response, receivedResponse)
965
966
967 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
968 self.assertEquals(receivedResponse, None)
969
970 class TestAdvancedQPSNone(DNSDistTest):
971
972 _config_template = """
973 addAction("qpsnone.advanced.tests.powerdns.com", QPSAction(100))
974 addAction(AllRule(), RCodeAction(dnsdist.REFUSED))
975 newServer{address="127.0.0.1:%s"}
976 """
977
978 def testAdvancedQPSNone(self):
979 """
980 Advanced: Not matching QPS returns None, not Allow
981
982 Send queries to "qps.advanced.tests.powerdns.com."
983 check that the rule returns None when the QPS has not been
984 reached, not Allow.
985 """
986 name = 'qpsnone.advanced.tests.powerdns.com.'
987 query = dns.message.make_query(name, 'A', 'IN')
988 expectedResponse = dns.message.make_response(query)
989 expectedResponse.set_rcode(dns.rcode.REFUSED)
990
991 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
992 self.assertEquals(receivedResponse, expectedResponse)
993
994 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
995 self.assertEquals(receivedResponse, expectedResponse)
996
997 class TestAdvancedNMGRule(DNSDistTest):
998
999 _config_template = """
1000 allowed = newNMG()
1001 allowed:addMask("192.0.2.1/32")
1002 addAction(NotRule(NetmaskGroupRule(allowed)), RCodeAction(dnsdist.REFUSED))
1003 newServer{address="127.0.0.1:%s"}
1004 """
1005
1006 def testAdvancedNMGRule(self):
1007 """
1008 Advanced: NMGRule should refuse our queries
1009
1010 Send queries to "nmgrule.advanced.tests.powerdns.com.",
1011 check that we are getting a REFUSED response.
1012 """
1013 name = 'nmgrule.advanced.tests.powerdns.com.'
1014 query = dns.message.make_query(name, 'A', 'IN')
1015 expectedResponse = dns.message.make_response(query)
1016 expectedResponse.set_rcode(dns.rcode.REFUSED)
1017
1018 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1019 self.assertEquals(receivedResponse, expectedResponse)
1020
1021 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1022 self.assertEquals(receivedResponse, expectedResponse)
1023
1024 class TestAdvancedLabelsCountRule(DNSDistTest):
1025
1026 _config_template = """
1027 addAction(QNameLabelsCountRule(5,6), RCodeAction(dnsdist.REFUSED))
1028 newServer{address="127.0.0.1:%s"}
1029 """
1030
1031 def testAdvancedLabelsCountRule(self):
1032 """
1033 Advanced: QNameLabelsCountRule(5,6)
1034 """
1035 # 6 labels, we should be fine
1036 name = 'ok.labelscount.advanced.tests.powerdns.com.'
1037 query = dns.message.make_query(name, 'A', 'IN')
1038 response = dns.message.make_response(query)
1039 rrset = dns.rrset.from_text(name,
1040 3600,
1041 dns.rdataclass.IN,
1042 dns.rdatatype.A,
1043 '192.0.2.1')
1044 response.answer.append(rrset)
1045
1046 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1047 self.assertTrue(receivedQuery)
1048 self.assertTrue(receivedResponse)
1049 receivedQuery.id = query.id
1050 self.assertEquals(query, receivedQuery)
1051 self.assertEquals(response, receivedResponse)
1052
1053 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
1054 self.assertTrue(receivedQuery)
1055 self.assertTrue(receivedResponse)
1056 receivedQuery.id = query.id
1057 self.assertEquals(query, receivedQuery)
1058 self.assertEquals(response, receivedResponse)
1059
1060 # more than 6 labels, the query should be refused
1061 name = 'not.ok.labelscount.advanced.tests.powerdns.com.'
1062 query = dns.message.make_query(name, 'A', 'IN')
1063 expectedResponse = dns.message.make_response(query)
1064 expectedResponse.set_rcode(dns.rcode.REFUSED)
1065
1066 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1067 self.assertEquals(receivedResponse, expectedResponse)
1068
1069 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1070 self.assertEquals(receivedResponse, expectedResponse)
1071
1072 # less than 5 labels, the query should be refused
1073 name = 'labelscountadvanced.tests.powerdns.com.'
1074 query = dns.message.make_query(name, 'A', 'IN')
1075 expectedResponse = dns.message.make_response(query)
1076 expectedResponse.set_rcode(dns.rcode.REFUSED)
1077
1078 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1079 self.assertEquals(receivedResponse, expectedResponse)
1080
1081 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1082 self.assertEquals(receivedResponse, expectedResponse)
1083
1084 class TestAdvancedWireLengthRule(DNSDistTest):
1085
1086 _config_template = """
1087 addAction(QNameWireLengthRule(54,56), RCodeAction(dnsdist.REFUSED))
1088 newServer{address="127.0.0.1:%s"}
1089 """
1090
1091 def testAdvancedWireLengthRule(self):
1092 """
1093 Advanced: QNameWireLengthRule(54,56)
1094 """
1095 name = 'longenough.qnamewirelength.advanced.tests.powerdns.com.'
1096 query = dns.message.make_query(name, 'A', 'IN')
1097 response = dns.message.make_response(query)
1098 rrset = dns.rrset.from_text(name,
1099 3600,
1100 dns.rdataclass.IN,
1101 dns.rdatatype.A,
1102 '192.0.2.1')
1103 response.answer.append(rrset)
1104
1105 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1106 self.assertTrue(receivedQuery)
1107 self.assertTrue(receivedResponse)
1108 receivedQuery.id = query.id
1109 self.assertEquals(query, receivedQuery)
1110 self.assertEquals(response, receivedResponse)
1111
1112 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
1113 self.assertTrue(receivedQuery)
1114 self.assertTrue(receivedResponse)
1115 receivedQuery.id = query.id
1116 self.assertEquals(query, receivedQuery)
1117 self.assertEquals(response, receivedResponse)
1118
1119 # too short, the query should be refused
1120 name = 'short.qnamewirelength.advanced.tests.powerdns.com.'
1121 query = dns.message.make_query(name, 'A', 'IN')
1122 expectedResponse = dns.message.make_response(query)
1123 expectedResponse.set_rcode(dns.rcode.REFUSED)
1124
1125 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1126 self.assertEquals(receivedResponse, expectedResponse)
1127
1128 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1129 self.assertEquals(receivedResponse, expectedResponse)
1130
1131 # too long, the query should be refused
1132 name = 'toolongtobevalid.qnamewirelength.advanced.tests.powerdns.com.'
1133 query = dns.message.make_query(name, 'A', 'IN')
1134 expectedResponse = dns.message.make_response(query)
1135 expectedResponse.set_rcode(dns.rcode.REFUSED)
1136
1137 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1138 self.assertEquals(receivedResponse, expectedResponse)
1139
1140 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1141 self.assertEquals(receivedResponse, expectedResponse)
1142
1143 class TestAdvancedIncludeDir(DNSDistTest):
1144
1145 _config_template = """
1146 -- this directory contains a file allowing includedir.advanced.tests.powerdns.com.
1147 includeDirectory('test-include-dir')
1148 newServer{address="127.0.0.1:%s"}
1149 """
1150
1151 def testAdvancedIncludeDirAllowed(self):
1152 """
1153 Advanced: includeDirectory()
1154 """
1155 name = 'includedir.advanced.tests.powerdns.com.'
1156 query = dns.message.make_query(name, 'A', 'IN')
1157 response = dns.message.make_response(query)
1158 rrset = dns.rrset.from_text(name,
1159 3600,
1160 dns.rdataclass.IN,
1161 dns.rdatatype.A,
1162 '192.0.2.1')
1163 response.answer.append(rrset)
1164
1165 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1166 self.assertTrue(receivedQuery)
1167 self.assertTrue(receivedResponse)
1168 receivedQuery.id = query.id
1169 self.assertEquals(query, receivedQuery)
1170 self.assertEquals(response, receivedResponse)
1171
1172 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
1173 self.assertTrue(receivedQuery)
1174 self.assertTrue(receivedResponse)
1175 receivedQuery.id = query.id
1176 self.assertEquals(query, receivedQuery)
1177 self.assertEquals(response, receivedResponse)
1178
1179 # this one should be refused
1180 name = 'notincludedir.advanced.tests.powerdns.com.'
1181 query = dns.message.make_query(name, 'A', 'IN')
1182 expectedResponse = dns.message.make_response(query)
1183 expectedResponse.set_rcode(dns.rcode.REFUSED)
1184
1185 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1186 self.assertEquals(receivedResponse, expectedResponse)
1187
1188 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1189 self.assertEquals(receivedResponse, expectedResponse)
1190
1191 class TestAdvancedLuaDO(DNSDistTest):
1192
1193 _config_template = """
1194 function nxDOLua(dq)
1195 if dq:getDO() then
1196 return DNSAction.Nxdomain, ""
1197 end
1198 return DNSAction.None, ""
1199 end
1200 addAction(AllRule(), LuaAction(nxDOLua))
1201 newServer{address="127.0.0.1:%s"}
1202 """
1203
1204 def testNxDOViaLua(self):
1205 """
1206 Advanced: Nx DO queries via Lua
1207 """
1208 name = 'nxdo.advanced.tests.powerdns.com.'
1209 query = dns.message.make_query(name, 'A', 'IN')
1210 response = dns.message.make_response(query)
1211 rrset = dns.rrset.from_text(name,
1212 3600,
1213 dns.rdataclass.IN,
1214 dns.rdatatype.AAAA,
1215 '::1')
1216 response.answer.append(rrset)
1217 queryWithDO = dns.message.make_query(name, 'A', 'IN', want_dnssec=True)
1218 doResponse = dns.message.make_response(queryWithDO)
1219 doResponse.set_rcode(dns.rcode.NXDOMAIN)
1220
1221 # without DO
1222 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1223 self.assertTrue(receivedQuery)
1224 self.assertTrue(receivedResponse)
1225 receivedQuery.id = query.id
1226 self.assertEquals(query, receivedQuery)
1227 self.assertEquals(receivedResponse, response)
1228
1229 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
1230 self.assertTrue(receivedQuery)
1231 self.assertTrue(receivedResponse)
1232 receivedQuery.id = query.id
1233 self.assertEquals(query, receivedQuery)
1234 self.assertEquals(receivedResponse, response)
1235
1236 # with DO
1237 (_, receivedResponse) = self.sendUDPQuery(queryWithDO, response=None, useQueue=False)
1238 self.assertTrue(receivedResponse)
1239 doResponse.id = receivedResponse.id
1240 self.assertEquals(receivedResponse, doResponse)
1241
1242 (_, receivedResponse) = self.sendTCPQuery(queryWithDO, response=None, useQueue=False)
1243 self.assertTrue(receivedResponse)
1244 doResponse.id = receivedResponse.id
1245 self.assertEquals(receivedResponse, doResponse)
1246
1247 class TestAdvancedLuaRefused(DNSDistTest):
1248
1249 _config_template = """
1250 function refuse(dq)
1251 return DNSAction.Refused, ""
1252 end
1253 addAction(AllRule(), LuaAction(refuse))
1254 newServer{address="127.0.0.1:%s"}
1255 """
1256
1257 def testRefusedViaLua(self):
1258 """
1259 Advanced: Refused via Lua
1260 """
1261 name = 'refused.advanced.tests.powerdns.com.'
1262 query = dns.message.make_query(name, 'A', 'IN')
1263 response = dns.message.make_response(query)
1264 rrset = dns.rrset.from_text(name,
1265 3600,
1266 dns.rdataclass.IN,
1267 dns.rdatatype.AAAA,
1268 '::1')
1269 response.answer.append(rrset)
1270 refusedResponse = dns.message.make_response(query)
1271 refusedResponse.set_rcode(dns.rcode.REFUSED)
1272
1273 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1274 self.assertTrue(receivedResponse)
1275 refusedResponse.id = receivedResponse.id
1276 self.assertEquals(receivedResponse, refusedResponse)
1277
1278 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1279 self.assertTrue(receivedResponse)
1280 refusedResponse.id = receivedResponse.id
1281 self.assertEquals(receivedResponse, refusedResponse)
1282
1283 class TestAdvancedLuaActionReturnSyntax(DNSDistTest):
1284
1285 _config_template = """
1286 function refuse(dq)
1287 return DNSAction.Refused
1288 end
1289 addAction(AllRule(), LuaAction(refuse))
1290 newServer{address="127.0.0.1:%s"}
1291 """
1292
1293 def testRefusedWithEmptyRule(self):
1294 """
1295 Advanced: Short syntax for LuaAction return values
1296 """
1297 name = 'short.refused.advanced.tests.powerdns.com.'
1298 query = dns.message.make_query(name, 'A', 'IN')
1299 response = dns.message.make_response(query)
1300 rrset = dns.rrset.from_text(name,
1301 3600,
1302 dns.rdataclass.IN,
1303 dns.rdatatype.AAAA,
1304 '::1')
1305 response.answer.append(rrset)
1306 refusedResponse = dns.message.make_response(query)
1307 refusedResponse.set_rcode(dns.rcode.REFUSED)
1308
1309 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1310 self.assertTrue(receivedResponse)
1311 refusedResponse.id = receivedResponse.id
1312 self.assertEquals(receivedResponse, refusedResponse)
1313
1314 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1315 self.assertTrue(receivedResponse)
1316 refusedResponse.id = receivedResponse.id
1317 self.assertEquals(receivedResponse, refusedResponse)
1318
1319 class TestAdvancedLuaTruncated(DNSDistTest):
1320
1321 _config_template = """
1322 function trunc(dq)
1323 if not dq.tcp then
1324 return DNSAction.Truncate, ""
1325 end
1326 return DNSAction.None, ""
1327 end
1328 addAction(AllRule(), LuaAction(trunc))
1329 newServer{address="127.0.0.1:%s"}
1330 """
1331
1332 def testTCViaLua(self):
1333 """
1334 Advanced: TC via Lua
1335 """
1336 name = 'tc.advanced.tests.powerdns.com.'
1337 query = dns.message.make_query(name, 'A', 'IN')
1338 response = dns.message.make_response(query)
1339 rrset = dns.rrset.from_text(name,
1340 3600,
1341 dns.rdataclass.IN,
1342 dns.rdatatype.AAAA,
1343 '::1')
1344 response.answer.append(rrset)
1345
1346 truncatedResponse = dns.message.make_response(query)
1347 truncatedResponse.flags |= dns.flags.TC
1348
1349 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1350 self.assertTrue(receivedResponse)
1351 truncatedResponse.id = receivedResponse.id
1352 self.assertEquals(receivedResponse, truncatedResponse)
1353
1354 # no truncation over TCP
1355 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
1356 self.assertTrue(receivedQuery)
1357 self.assertTrue(receivedResponse)
1358 receivedQuery.id = query.id
1359 self.assertEquals(query, receivedQuery)
1360 self.assertEquals(receivedResponse, response)
1361
1362 class TestStatNodeRespRingSince(DNSDistTest):
1363
1364 _consoleKey = DNSDistTest.generateConsoleKey()
1365 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
1366 _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort']
1367 _config_template = """
1368 setKey("%s")
1369 controlSocket("127.0.0.1:%s")
1370 s1 = newServer{address="127.0.0.1:%s"}
1371 s1:setUp()
1372 function visitor(node, self, childstat)
1373 table.insert(nodesSeen, node.fullname)
1374 end
1375 """
1376
1377 def testStatNodeRespRingSince(self):
1378 """
1379 Advanced: StatNodeRespRing with optional since parameter
1380
1381 """
1382 name = 'statnodesince.advanced.tests.powerdns.com.'
1383 query = dns.message.make_query(name, 'A', 'IN')
1384 response = dns.message.make_response(query)
1385 rrset = dns.rrset.from_text(name,
1386 1,
1387 dns.rdataclass.IN,
1388 dns.rdatatype.A,
1389 '127.0.0.1')
1390 response.answer.append(rrset)
1391
1392 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1393 self.assertTrue(receivedQuery)
1394 self.assertTrue(receivedResponse)
1395 receivedQuery.id = query.id
1396 self.assertEquals(query, receivedQuery)
1397 self.assertEquals(response, receivedResponse)
1398
1399 self.sendConsoleCommand("nodesSeen = {}")
1400 self.sendConsoleCommand("statNodeRespRing(visitor)")
1401 nodes = self.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
1402 nodes = nodes.strip("\n")
1403 self.assertEquals(nodes, """statnodesince.advanced.tests.powerdns.com.
1404 advanced.tests.powerdns.com.
1405 tests.powerdns.com.
1406 powerdns.com.
1407 com.""")
1408
1409 self.sendConsoleCommand("nodesSeen = {}")
1410 self.sendConsoleCommand("statNodeRespRing(visitor, 0)")
1411 nodes = self.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
1412 nodes = nodes.strip("\n")
1413 self.assertEquals(nodes, """statnodesince.advanced.tests.powerdns.com.
1414 advanced.tests.powerdns.com.
1415 tests.powerdns.com.
1416 powerdns.com.
1417 com.""")
1418
1419 time.sleep(5)
1420
1421 self.sendConsoleCommand("nodesSeen = {}")
1422 self.sendConsoleCommand("statNodeRespRing(visitor)")
1423 nodes = self.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
1424 nodes = nodes.strip("\n")
1425 self.assertEquals(nodes, """statnodesince.advanced.tests.powerdns.com.
1426 advanced.tests.powerdns.com.
1427 tests.powerdns.com.
1428 powerdns.com.
1429 com.""")
1430
1431 self.sendConsoleCommand("nodesSeen = {}")
1432 self.sendConsoleCommand("statNodeRespRing(visitor, 5)")
1433 nodes = self.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
1434 nodes = nodes.strip("\n")
1435 self.assertEquals(nodes, """""")
1436
1437 self.sendConsoleCommand("nodesSeen = {}")
1438 self.sendConsoleCommand("statNodeRespRing(visitor, 10)")
1439 nodes = self.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
1440 nodes = nodes.strip("\n")
1441 self.assertEquals(nodes, """statnodesince.advanced.tests.powerdns.com.
1442 advanced.tests.powerdns.com.
1443 tests.powerdns.com.
1444 powerdns.com.
1445 com.""")
1446
1447 class TestAdvancedRD(DNSDistTest):
1448
1449 _config_template = """
1450 addAction(RDRule(), RCodeAction(dnsdist.REFUSED))
1451 newServer{address="127.0.0.1:%s"}
1452 """
1453
1454 def testAdvancedRDRefused(self):
1455 """
1456 Advanced: RD query is refused
1457 """
1458 name = 'rd.advanced.tests.powerdns.com.'
1459 query = dns.message.make_query(name, 'A', 'IN')
1460 expectedResponse = dns.message.make_response(query)
1461 expectedResponse.set_rcode(dns.rcode.REFUSED)
1462
1463 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1464 self.assertEquals(receivedResponse, expectedResponse)
1465
1466 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1467 self.assertEquals(receivedResponse, expectedResponse)
1468
1469 def testAdvancedNoRDAllowed(self):
1470 """
1471 Advanced: No-RD query is allowed
1472 """
1473 name = 'no-rd.advanced.tests.powerdns.com.'
1474 query = dns.message.make_query(name, 'A', 'IN')
1475 query.flags &= ~dns.flags.RD
1476 response = dns.message.make_response(query)
1477
1478 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1479 receivedQuery.id = query.id
1480 self.assertEquals(receivedQuery, query)
1481 self.assertEquals(receivedResponse, response)
1482
1483 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
1484 receivedQuery.id = query.id
1485 self.assertEquals(receivedQuery, query)
1486 self.assertEquals(receivedResponse, response)
1487
1488 class TestAdvancedGetLocalPort(DNSDistTest):
1489
1490 _config_template = """
1491 function answerBasedOnLocalPort(dq)
1492 local port = dq.localaddr:getPort()
1493 return DNSAction.Spoof, "port-was-"..port..".local-port.advanced.tests.powerdns.com."
1494 end
1495 addAction("local-port.advanced.tests.powerdns.com.", LuaAction(answerBasedOnLocalPort))
1496 newServer{address="127.0.0.1:%s"}
1497 """
1498
1499 def testAdvancedGetLocalPort(self):
1500 """
1501 Advanced: Return CNAME containing the local port
1502 """
1503 name = 'local-port.advanced.tests.powerdns.com.'
1504 query = dns.message.make_query(name, 'A', 'IN')
1505 # dnsdist set RA = RD for spoofed responses
1506 query.flags &= ~dns.flags.RD
1507
1508 response = dns.message.make_response(query)
1509 rrset = dns.rrset.from_text(name,
1510 60,
1511 dns.rdataclass.IN,
1512 dns.rdatatype.CNAME,
1513 'port-was-{}.local-port.advanced.tests.powerdns.com.'.format(self._dnsDistPort))
1514 response.answer.append(rrset)
1515
1516 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1517 self.assertEquals(receivedResponse, response)
1518
1519 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1520 self.assertEquals(receivedResponse, response)
1521
1522 class TestAdvancedGetLocalPortOnAnyBind(DNSDistTest):
1523
1524 _config_template = """
1525 function answerBasedOnLocalPort(dq)
1526 local port = dq.localaddr:getPort()
1527 return DNSAction.Spoof, "port-was-"..port..".local-port-any.advanced.tests.powerdns.com."
1528 end
1529 addAction("local-port-any.advanced.tests.powerdns.com.", LuaAction(answerBasedOnLocalPort))
1530 newServer{address="127.0.0.1:%s"}
1531 """
1532 _dnsDistListeningAddr = "0.0.0.0"
1533
1534 def testAdvancedGetLocalPortOnAnyBind(self):
1535 """
1536 Advanced: Return CNAME containing the local port for an ANY bind
1537 """
1538 name = 'local-port-any.advanced.tests.powerdns.com.'
1539 query = dns.message.make_query(name, 'A', 'IN')
1540 # dnsdist set RA = RD for spoofed responses
1541 query.flags &= ~dns.flags.RD
1542
1543 response = dns.message.make_response(query)
1544 rrset = dns.rrset.from_text(name,
1545 60,
1546 dns.rdataclass.IN,
1547 dns.rdatatype.CNAME,
1548 'port-was-{}.local-port-any.advanced.tests.powerdns.com.'.format(self._dnsDistPort))
1549 response.answer.append(rrset)
1550
1551 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1552 self.assertEquals(receivedResponse, response)
1553
1554 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1555 self.assertEquals(receivedResponse, response)
1556
1557 class TestAdvancedLuaTempFailureTTL(DNSDistTest):
1558
1559 _config_template = """
1560 function testAction(dq)
1561 if dq.tempFailureTTL ~= nil then
1562 return DNSAction.Spoof, "initially.not.nil.but." + dq.tempFailureTTL + ".tests.powerdns.com."
1563 end
1564 dq.tempFailureTTL = 30
1565 if dq.tempFailureTTL ~= 30 then
1566 return DNSAction.Spoof, "after.set.not.expected.value.but." + dq.tempFailureTTL + ".tests.powerdns.com."
1567 end
1568 dq.tempFailureTTL = nil
1569 if dq.tempFailureTTL ~= nil then
1570 return DNSAction.Spoof, "after.unset.not.nil.but." + dq.tempFailureTTL + ".tests.powerdns.com."
1571 end
1572 return DNSAction.None, ""
1573 end
1574 addAction(AllRule(), LuaAction(testAction))
1575 newServer{address="127.0.0.1:%s"}
1576 """
1577
1578 def testTempFailureTTLBinding(self):
1579 """
1580 Exercise dq.tempFailureTTL Lua binding
1581 """
1582 name = 'tempfailurettlbinding.advanced.tests.powerdns.com.'
1583 query = dns.message.make_query(name, 'A', 'IN')
1584 response = dns.message.make_response(query)
1585 rrset = dns.rrset.from_text(name,
1586 3600,
1587 dns.rdataclass.IN,
1588 dns.rdatatype.AAAA,
1589 '::1')
1590 response.answer.append(rrset)
1591
1592 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1593 self.assertTrue(receivedQuery)
1594 self.assertTrue(receivedResponse)
1595 receivedQuery.id = query.id
1596 self.assertEquals(query, receivedQuery)
1597 self.assertEquals(receivedResponse, response)