]>
git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.dnsdist/test_Advanced.py
3 from datetime
import datetime
, timedelta
8 import clientsubnetoption
9 from dnsdisttests
import DNSDistTest
11 class TestAdvancedAllow(DNSDistTest
):
13 _config_template
= """
14 addAction(AllRule(), NoneAction())
15 addAction(makeRule("allowed.advanced.tests.powerdns.com."), AllowAction())
16 addAction(AllRule(), DropAction())
17 newServer{address="127.0.0.1:%s"}
20 def testAdvancedAllow(self
):
22 Advanced: Allowed qname is not dropped
24 A query for allowed.advanced.tests.powerdns.com. should be allowed
25 while others should be dropped.
27 name
= 'allowed.advanced.tests.powerdns.com.'
28 query
= dns
.message
.make_query(name
, 'A', 'IN')
29 response
= dns
.message
.make_response(query
)
30 rrset
= dns
.rrset
.from_text(name
,
35 response
.answer
.append(rrset
)
37 for method
in ("sendUDPQuery", "sendTCPQuery"):
38 sender
= getattr(self
, method
)
39 (receivedQuery
, receivedResponse
) = sender(query
, response
)
40 self
.assertTrue(receivedQuery
)
41 self
.assertTrue(receivedResponse
)
42 receivedQuery
.id = query
.id
43 self
.assertEquals(query
, receivedQuery
)
44 self
.assertEquals(response
, receivedResponse
)
46 def testAdvancedAllowDropped(self
):
48 Advanced: Not allowed qname is dropped
50 A query for notallowed.advanced.tests.powerdns.com. should be dropped.
52 name
= 'notallowed.advanced.tests.powerdns.com.'
53 query
= dns
.message
.make_query(name
, 'A', 'IN')
55 for method
in ("sendUDPQuery", "sendTCPQuery"):
56 sender
= getattr(self
, method
)
57 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
59 class TestAdvancedFixupCase(DNSDistTest
):
61 _config_template
= """
64 newServer{address="127.0.0.1:%s"}
67 def testAdvancedFixupCase(self
):
71 Send a query with lower and upper chars,
72 make the backend return a lowercase version,
73 check that dnsdist fixes the response.
75 name
= 'fiXuPCasE.advanced.tests.powerdns.com.'
76 query
= dns
.message
.make_query(name
, 'A', 'IN')
77 lowercasequery
= dns
.message
.make_query(name
.lower(), 'A', 'IN')
78 response
= dns
.message
.make_response(lowercasequery
)
79 expectedResponse
= dns
.message
.make_response(query
)
80 rrset
= dns
.rrset
.from_text(name
,
85 response
.answer
.append(rrset
)
86 expectedResponse
.answer
.append(rrset
)
88 for method
in ("sendUDPQuery", "sendTCPQuery"):
89 sender
= getattr(self
, method
)
90 (receivedQuery
, receivedResponse
) = sender(query
, response
)
91 self
.assertTrue(receivedQuery
)
92 self
.assertTrue(receivedResponse
)
93 receivedQuery
.id = query
.id
94 self
.assertEquals(query
, receivedQuery
)
95 self
.assertEquals(expectedResponse
, receivedResponse
)
97 class TestAdvancedRemoveRD(DNSDistTest
):
99 _config_template
= """
100 addAction("norecurse.advanced.tests.powerdns.com.", NoRecurseAction())
101 newServer{address="127.0.0.1:%s"}
104 def testAdvancedNoRD(self
):
108 Send a query with RD,
109 check that dnsdist clears the RD flag.
111 name
= 'norecurse.advanced.tests.powerdns.com.'
112 query
= dns
.message
.make_query(name
, 'A', 'IN')
113 expectedQuery
= dns
.message
.make_query(name
, 'A', 'IN')
114 expectedQuery
.flags
&= ~dns
.flags
.RD
116 response
= dns
.message
.make_response(query
)
117 rrset
= dns
.rrset
.from_text(name
,
122 response
.answer
.append(rrset
)
124 for method
in ("sendUDPQuery", "sendTCPQuery"):
125 sender
= getattr(self
, method
)
126 (receivedQuery
, receivedResponse
) = sender(query
, response
)
127 self
.assertTrue(receivedQuery
)
128 self
.assertTrue(receivedResponse
)
129 receivedQuery
.id = expectedQuery
.id
130 self
.assertEquals(expectedQuery
, receivedQuery
)
131 self
.assertEquals(response
, receivedResponse
)
133 def testAdvancedKeepRD(self
):
135 Advanced: No RD canary
137 Send a query with RD for a canary domain,
138 check that dnsdist does not clear the RD flag.
140 name
= 'keeprecurse.advanced.tests.powerdns.com.'
141 query
= dns
.message
.make_query(name
, 'A', 'IN')
143 response
= dns
.message
.make_response(query
)
144 rrset
= dns
.rrset
.from_text(name
,
149 response
.answer
.append(rrset
)
151 for method
in ("sendUDPQuery", "sendTCPQuery"):
152 sender
= getattr(self
, method
)
153 (receivedQuery
, receivedResponse
) = sender(query
, response
)
154 self
.assertTrue(receivedQuery
)
155 self
.assertTrue(receivedResponse
)
156 receivedQuery
.id = query
.id
157 self
.assertEquals(query
, receivedQuery
)
158 self
.assertEquals(response
, receivedResponse
)
160 class TestAdvancedAddCD(DNSDistTest
):
162 _config_template
= """
163 addAction("setcd.advanced.tests.powerdns.com.", DisableValidationAction())
164 addAction(makeRule("setcdviaaction.advanced.tests.powerdns.com."), DisableValidationAction())
165 newServer{address="127.0.0.1:%s"}
168 def testAdvancedSetCD(self
):
172 Send a query with CD cleared,
173 check that dnsdist set the CD flag.
175 name
= 'setcd.advanced.tests.powerdns.com.'
176 query
= dns
.message
.make_query(name
, 'A', 'IN')
177 expectedQuery
= dns
.message
.make_query(name
, 'A', 'IN')
178 expectedQuery
.flags |
= dns
.flags
.CD
180 response
= dns
.message
.make_response(query
)
181 rrset
= dns
.rrset
.from_text(name
,
186 response
.answer
.append(rrset
)
188 for method
in ("sendUDPQuery", "sendTCPQuery"):
189 sender
= getattr(self
, method
)
190 (receivedQuery
, receivedResponse
) = sender(query
, response
)
191 self
.assertTrue(receivedQuery
)
192 self
.assertTrue(receivedResponse
)
193 receivedQuery
.id = expectedQuery
.id
194 self
.assertEquals(expectedQuery
, receivedQuery
)
195 self
.assertEquals(response
, receivedResponse
)
197 def testAdvancedSetCDViaAction(self
):
199 Advanced: Set CD via Action
201 Send a query with CD cleared,
202 check that dnsdist set the CD flag.
204 name
= 'setcdviaaction.advanced.tests.powerdns.com.'
205 query
= dns
.message
.make_query(name
, 'A', 'IN')
206 expectedQuery
= dns
.message
.make_query(name
, 'A', 'IN')
207 expectedQuery
.flags |
= dns
.flags
.CD
209 response
= dns
.message
.make_response(query
)
210 rrset
= dns
.rrset
.from_text(name
,
215 response
.answer
.append(rrset
)
217 for method
in ("sendUDPQuery", "sendTCPQuery"):
218 sender
= getattr(self
, method
)
219 (receivedQuery
, receivedResponse
) = sender(query
, response
)
220 self
.assertTrue(receivedQuery
)
221 self
.assertTrue(receivedResponse
)
222 receivedQuery
.id = expectedQuery
.id
223 self
.assertEquals(expectedQuery
, receivedQuery
)
224 self
.assertEquals(response
, receivedResponse
)
226 def testAdvancedKeepNoCD(self
):
228 Advanced: Preserve CD canary
230 Send a query without CD for a canary domain,
231 check that dnsdist does not set the CD flag.
233 name
= 'keepnocd.advanced.tests.powerdns.com.'
234 query
= dns
.message
.make_query(name
, 'A', 'IN')
236 response
= dns
.message
.make_response(query
)
237 rrset
= dns
.rrset
.from_text(name
,
242 response
.answer
.append(rrset
)
244 for method
in ("sendUDPQuery", "sendTCPQuery"):
245 sender
= getattr(self
, method
)
246 (receivedQuery
, receivedResponse
) = sender(query
, response
)
247 self
.assertTrue(receivedQuery
)
248 self
.assertTrue(receivedResponse
)
249 receivedQuery
.id = query
.id
250 self
.assertEquals(query
, receivedQuery
)
251 self
.assertEquals(response
, receivedResponse
)
253 class TestAdvancedClearRD(DNSDistTest
):
255 _config_template
= """
256 addAction("clearrd.advanced.tests.powerdns.com.", NoRecurseAction())
257 addAction(makeRule("clearrdviaaction.advanced.tests.powerdns.com."), NoRecurseAction())
258 newServer{address="127.0.0.1:%s"}
261 def testAdvancedClearRD(self
):
265 Send a query with RD set,
266 check that dnsdist clears the RD flag.
268 name
= 'clearrd.advanced.tests.powerdns.com.'
269 query
= dns
.message
.make_query(name
, 'A', 'IN')
270 expectedQuery
= dns
.message
.make_query(name
, 'A', 'IN')
271 expectedQuery
.flags
&= ~dns
.flags
.RD
273 response
= dns
.message
.make_response(query
)
274 rrset
= dns
.rrset
.from_text(name
,
279 response
.answer
.append(rrset
)
281 for method
in ("sendUDPQuery", "sendTCPQuery"):
282 sender
= getattr(self
, method
)
283 (receivedQuery
, receivedResponse
) = sender(query
, response
)
284 self
.assertTrue(receivedQuery
)
285 self
.assertTrue(receivedResponse
)
286 receivedQuery
.id = expectedQuery
.id
287 self
.assertEquals(expectedQuery
, receivedQuery
)
288 self
.assertEquals(response
, receivedResponse
)
290 def testAdvancedClearRDViaAction(self
):
292 Advanced: Clear RD via Action
294 Send a query with RD set,
295 check that dnsdist clears the RD flag.
297 name
= 'clearrdviaaction.advanced.tests.powerdns.com.'
298 query
= dns
.message
.make_query(name
, 'A', 'IN')
299 expectedQuery
= dns
.message
.make_query(name
, 'A', 'IN')
300 expectedQuery
.flags
&= ~dns
.flags
.RD
302 response
= dns
.message
.make_response(query
)
303 rrset
= dns
.rrset
.from_text(name
,
308 response
.answer
.append(rrset
)
310 for method
in ("sendUDPQuery", "sendTCPQuery"):
311 sender
= getattr(self
, method
)
312 (receivedQuery
, receivedResponse
) = sender(query
, response
)
313 self
.assertTrue(receivedQuery
)
314 self
.assertTrue(receivedResponse
)
315 receivedQuery
.id = expectedQuery
.id
316 self
.assertEquals(expectedQuery
, receivedQuery
)
317 self
.assertEquals(response
, receivedResponse
)
319 def testAdvancedKeepRD(self
):
321 Advanced: Preserve RD canary
323 Send a query with RD for a canary domain,
324 check that dnsdist does not clear the RD flag.
326 name
= 'keeprd.advanced.tests.powerdns.com.'
327 query
= dns
.message
.make_query(name
, 'A', 'IN')
329 response
= dns
.message
.make_response(query
)
330 rrset
= dns
.rrset
.from_text(name
,
335 response
.answer
.append(rrset
)
337 for method
in ("sendUDPQuery", "sendTCPQuery"):
338 sender
= getattr(self
, method
)
339 (receivedQuery
, receivedResponse
) = sender(query
, response
)
340 self
.assertTrue(receivedQuery
)
341 self
.assertTrue(receivedResponse
)
342 receivedQuery
.id = query
.id
343 self
.assertEquals(query
, receivedQuery
)
344 self
.assertEquals(response
, receivedResponse
)
347 class TestAdvancedACL(DNSDistTest
):
349 _config_template
= """
350 newServer{address="127.0.0.1:%s"}
352 _acl
= ['192.0.2.1/32']
354 def testACLBlocked(self
):
356 Advanced: ACL blocked
358 Send an A query to "tests.powerdns.com.",
359 we expect no response since 127.0.0.1 is not on the
362 name
= 'tests.powerdns.com.'
363 query
= dns
.message
.make_query(name
, 'A', 'IN')
365 for method
in ("sendUDPQuery", "sendTCPQuery"):
366 sender
= getattr(self
, method
)
367 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
368 self
.assertEquals(receivedResponse
, None)
370 class TestAdvancedDelay(DNSDistTest
):
372 _config_template
= """
373 addAction(AllRule(), DelayAction(1000))
374 newServer{address="127.0.0.1:%s"}
377 def testDelayed(self
):
381 Send an A query to "tests.powerdns.com.",
382 check that the response delay is longer than 1000 ms
383 over UDP, less than that over TCP.
385 name
= 'tests.powerdns.com.'
386 query
= dns
.message
.make_query(name
, 'A', 'IN')
387 response
= dns
.message
.make_response(query
)
388 rrset
= dns
.rrset
.from_text(name
,
393 response
.answer
.append(rrset
)
395 begin
= datetime
.now()
396 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
398 receivedQuery
.id = query
.id
399 self
.assertEquals(query
, receivedQuery
)
400 self
.assertEquals(response
, receivedResponse
)
401 self
.assertTrue((end
- begin
) > timedelta(0, 1))
403 begin
= datetime
.now()
404 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
406 receivedQuery
.id = query
.id
407 self
.assertEquals(query
, receivedQuery
)
408 self
.assertEquals(response
, receivedResponse
)
409 self
.assertTrue((end
- begin
) < timedelta(0, 1))
412 class TestAdvancedTruncateAnyAndTCP(DNSDistTest
):
414 _config_template
= """
416 addAction(AndRule({QTypeRule("ANY"), TCPRule(true)}), TCAction())
417 newServer{address="127.0.0.1:%s"}
419 def testTruncateAnyOverTCP(self
):
421 Advanced: Truncate ANY over TCP
423 Send an ANY query to "anytruncatetcp.advanced.tests.powerdns.com.",
424 should be truncated over TCP, not over UDP (yes, it makes no sense,
427 name
= 'anytruncatetcp.advanced.tests.powerdns.com.'
428 query
= dns
.message
.make_query(name
, 'ANY', 'IN')
430 response
= dns
.message
.make_response(query
)
431 rrset
= dns
.rrset
.from_text(name
,
437 response
.answer
.append(rrset
)
439 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
440 self
.assertTrue(receivedQuery
)
441 self
.assertTrue(receivedResponse
)
442 receivedQuery
.id = query
.id
443 self
.assertEquals(query
, receivedQuery
)
444 self
.assertEquals(receivedResponse
, response
)
446 expectedResponse
= dns
.message
.make_response(query
)
447 expectedResponse
.flags |
= dns
.flags
.TC
449 (_
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
450 self
.assertEquals(receivedResponse
, expectedResponse
)
452 class TestAdvancedAndNot(DNSDistTest
):
454 _config_template
= """
455 addAction(AndRule({NotRule(QTypeRule("A")), TCPRule(false)}), RCodeAction(dnsdist.NOTIMP))
456 newServer{address="127.0.0.1:%s"}
458 def testAOverUDPReturnsNotImplementedCanary(self
):
460 Advanced: !A && UDP canary
462 dnsdist is configured to reply 'not implemented' for query
463 over UDP AND !qtype A.
464 We send an A query over UDP and TCP, and check that the
467 name
= 'andnot.advanced.tests.powerdns.com.'
468 query
= dns
.message
.make_query(name
, 'A', 'IN')
469 response
= dns
.message
.make_response(query
)
470 rrset
= dns
.rrset
.from_text(name
,
475 response
.answer
.append(rrset
)
477 for method
in ("sendUDPQuery", "sendTCPQuery"):
478 sender
= getattr(self
, method
)
479 (receivedQuery
, receivedResponse
) = sender(query
, response
)
480 self
.assertTrue(receivedQuery
)
481 self
.assertTrue(receivedResponse
)
482 receivedQuery
.id = query
.id
483 self
.assertEquals(query
, receivedQuery
)
484 self
.assertEquals(receivedResponse
, response
)
486 def testAOverUDPReturnsNotImplemented(self
):
490 dnsdist is configured to reply 'not implemented' for query
491 over UDP AND !qtype A.
492 We send a TXT query over UDP and TCP, and check that the
493 response is OK for TCP and 'not implemented' for UDP.
495 name
= 'andnot.advanced.tests.powerdns.com.'
496 query
= dns
.message
.make_query(name
, 'TXT', 'IN')
498 expectedResponse
= dns
.message
.make_response(query
)
499 expectedResponse
.set_rcode(dns
.rcode
.NOTIMP
)
501 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
502 self
.assertEquals(receivedResponse
, expectedResponse
)
504 response
= dns
.message
.make_response(query
)
505 rrset
= dns
.rrset
.from_text(name
,
509 'nothing to see here')
510 response
.answer
.append(rrset
)
512 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
513 self
.assertTrue(receivedQuery
)
514 self
.assertTrue(receivedResponse
)
515 receivedQuery
.id = query
.id
516 self
.assertEquals(query
, receivedQuery
)
517 self
.assertEquals(receivedResponse
, response
)
519 class TestAdvancedOr(DNSDistTest
):
521 _config_template
= """
522 addAction(OrRule({QTypeRule("A"), TCPRule(false)}), RCodeAction(dnsdist.NOTIMP))
523 newServer{address="127.0.0.1:%s"}
525 def testAAAAOverUDPReturnsNotImplemented(self
):
527 Advanced: A || UDP: AAAA
529 dnsdist is configured to reply 'not implemented' for query
531 We send an AAAA query over UDP and TCP, and check that the
532 response is 'not implemented' for UDP and OK for TCP.
534 name
= 'aorudp.advanced.tests.powerdns.com.'
535 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
536 response
= dns
.message
.make_response(query
)
537 rrset
= dns
.rrset
.from_text(name
,
542 response
.answer
.append(rrset
)
544 expectedResponse
= dns
.message
.make_response(query
)
545 expectedResponse
.set_rcode(dns
.rcode
.NOTIMP
)
547 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
548 self
.assertEquals(receivedResponse
, expectedResponse
)
550 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
551 self
.assertTrue(receivedQuery
)
552 self
.assertTrue(receivedResponse
)
553 receivedQuery
.id = query
.id
554 self
.assertEquals(query
, receivedQuery
)
555 self
.assertEquals(receivedResponse
, response
)
557 def testAOverUDPReturnsNotImplemented(self
):
559 Advanced: A || UDP: A
561 dnsdist is configured to reply 'not implemented' for query
563 We send an A query over UDP and TCP, and check that the
564 response is 'not implemented' for both.
566 name
= 'aorudp.advanced.tests.powerdns.com.'
567 query
= dns
.message
.make_query(name
, 'A', 'IN')
569 expectedResponse
= dns
.message
.make_response(query
)
570 expectedResponse
.set_rcode(dns
.rcode
.NOTIMP
)
572 for method
in ("sendUDPQuery", "sendTCPQuery"):
573 sender
= getattr(self
, method
)
574 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
575 self
.assertEquals(receivedResponse
, expectedResponse
)
578 class TestAdvancedLogAction(DNSDistTest
):
580 _config_template
= """
581 newServer{address="127.0.0.1:%s"}
582 addAction(AllRule(), LogAction("dnsdist.log", false))
584 def testAdvancedLogAction(self
):
586 Advanced: Log all queries
590 name
= 'logaction.advanced.tests.powerdns.com.'
591 query
= dns
.message
.make_query(name
, 'A', 'IN')
592 response
= dns
.message
.make_response(query
)
593 rrset
= dns
.rrset
.from_text(name
,
598 response
.answer
.append(rrset
)
600 for _
in range(count
):
601 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
602 self
.assertTrue(receivedQuery
)
603 self
.assertTrue(receivedResponse
)
604 receivedQuery
.id = query
.id
605 self
.assertEquals(query
, receivedQuery
)
606 self
.assertEquals(response
, receivedResponse
)
608 self
.assertTrue(os
.path
.isfile('dnsdist.log'))
609 self
.assertTrue(os
.stat('dnsdist.log').st_size
> 0)
611 class TestAdvancedDNSSEC(DNSDistTest
):
613 _config_template
= """
614 newServer{address="127.0.0.1:%s"}
615 addAction(DNSSECRule(), DropAction())
617 def testAdvancedDNSSECDrop(self
):
619 Advanced: DNSSEC Rule
622 name
= 'dnssec.advanced.tests.powerdns.com.'
623 query
= dns
.message
.make_query(name
, 'A', 'IN')
624 doquery
= dns
.message
.make_query(name
, 'A', 'IN', want_dnssec
=True)
625 response
= dns
.message
.make_response(query
)
626 rrset
= dns
.rrset
.from_text(name
,
631 response
.answer
.append(rrset
)
633 for method
in ("sendUDPQuery", "sendTCPQuery"):
634 sender
= getattr(self
, method
)
635 (receivedQuery
, receivedResponse
) = sender(query
, response
)
636 self
.assertTrue(receivedQuery
)
637 self
.assertTrue(receivedResponse
)
638 receivedQuery
.id = query
.id
639 self
.assertEquals(query
, receivedQuery
)
640 self
.assertEquals(response
, receivedResponse
)
642 for method
in ("sendUDPQuery", "sendTCPQuery"):
643 sender
= getattr(self
, method
)
644 (_
, receivedResponse
) = sender(doquery
, response
)
645 self
.assertEquals(receivedResponse
, None)
647 class TestAdvancedQClass(DNSDistTest
):
649 _config_template
= """
650 newServer{address="127.0.0.1:%s"}
651 addAction(QClassRule(DNSClass.CHAOS), DropAction())
653 def testAdvancedQClassChaosDrop(self
):
655 Advanced: Drop QClass CHAOS
658 name
= 'qclasschaos.advanced.tests.powerdns.com.'
659 query
= dns
.message
.make_query(name
, 'TXT', 'CHAOS')
661 for method
in ("sendUDPQuery", "sendTCPQuery"):
662 sender
= getattr(self
, method
)
663 (_
, receivedResponse
) = sender(query
, response
=None)
664 self
.assertEquals(receivedResponse
, None)
666 def testAdvancedQClassINAllow(self
):
668 Advanced: Allow QClass IN
671 name
= 'qclassin.advanced.tests.powerdns.com.'
672 query
= dns
.message
.make_query(name
, 'A', 'IN')
673 response
= dns
.message
.make_response(query
)
674 rrset
= dns
.rrset
.from_text(name
,
679 response
.answer
.append(rrset
)
681 for method
in ("sendUDPQuery", "sendTCPQuery"):
682 sender
= getattr(self
, method
)
683 (receivedQuery
, receivedResponse
) = sender(query
, response
)
684 self
.assertTrue(receivedQuery
)
685 self
.assertTrue(receivedResponse
)
686 receivedQuery
.id = query
.id
687 self
.assertEquals(query
, receivedQuery
)
688 self
.assertEquals(response
, receivedResponse
)
690 class TestAdvancedOpcode(DNSDistTest
):
692 _config_template
= """
693 newServer{address="127.0.0.1:%s"}
694 addAction(OpcodeRule(DNSOpcode.Notify), DropAction())
696 def testAdvancedOpcodeNotifyDrop(self
):
698 Advanced: Drop Opcode NOTIFY
701 name
= 'opcodenotify.advanced.tests.powerdns.com.'
702 query
= dns
.message
.make_query(name
, 'A', 'IN')
703 query
.set_opcode(dns
.opcode
.NOTIFY
)
705 for method
in ("sendUDPQuery", "sendTCPQuery"):
706 sender
= getattr(self
, method
)
707 (_
, receivedResponse
) = sender(query
, response
=None)
708 self
.assertEquals(receivedResponse
, None)
710 def testAdvancedOpcodeUpdateINAllow(self
):
712 Advanced: Allow Opcode UPDATE
715 name
= 'opcodeupdate.advanced.tests.powerdns.com.'
716 query
= dns
.message
.make_query(name
, 'A', 'IN')
717 query
.set_opcode(dns
.opcode
.UPDATE
)
718 response
= dns
.message
.make_response(query
)
719 rrset
= dns
.rrset
.from_text(name
,
724 response
.answer
.append(rrset
)
726 for method
in ("sendUDPQuery", "sendTCPQuery"):
727 sender
= getattr(self
, method
)
728 (receivedQuery
, receivedResponse
) = sender(query
, response
)
729 self
.assertTrue(receivedQuery
)
730 self
.assertTrue(receivedResponse
)
731 receivedQuery
.id = query
.id
732 self
.assertEquals(query
, receivedQuery
)
733 self
.assertEquals(response
, receivedResponse
)
735 class TestAdvancedNonTerminalRule(DNSDistTest
):
737 _config_template
= """
738 newServer{address="127.0.0.1:%s", pool="real"}
739 addAction(AllRule(), DisableValidationAction())
740 addAction(AllRule(), PoolAction("real"))
741 addAction(AllRule(), DropAction())
743 def testAdvancedNonTerminalRules(self
):
745 Advanced: Non terminal rules
747 We check that DisableValidationAction() is applied
748 but does not stop the processing, then that
749 PoolAction() is applied _and_ stop the processing.
751 name
= 'nonterminal.advanced.tests.powerdns.com.'
752 query
= dns
.message
.make_query(name
, 'A', 'IN')
753 expectedQuery
= dns
.message
.make_query(name
, 'A', 'IN')
754 expectedQuery
.flags |
= dns
.flags
.CD
755 response
= dns
.message
.make_response(query
)
756 rrset
= dns
.rrset
.from_text(name
,
761 response
.answer
.append(rrset
)
763 for method
in ("sendUDPQuery", "sendTCPQuery"):
764 sender
= getattr(self
, method
)
765 (receivedQuery
, receivedResponse
) = sender(query
, response
)
766 self
.assertTrue(receivedQuery
)
767 self
.assertTrue(receivedResponse
)
768 receivedQuery
.id = expectedQuery
.id
769 self
.assertEquals(expectedQuery
, receivedQuery
)
770 self
.assertEquals(response
, receivedResponse
)
772 class TestAdvancedStringOnlyServer(DNSDistTest
):
774 _config_template
= """
775 newServer("127.0.0.1:%s")
778 def testAdvancedStringOnlyServer(self
):
780 Advanced: "string-only" server is placed in the default pool
782 name
= 'string-only-server.advanced.tests.powerdns.com.'
783 query
= dns
.message
.make_query(name
, 'A', 'IN')
784 response
= dns
.message
.make_response(query
)
785 rrset
= dns
.rrset
.from_text(name
,
790 response
.answer
.append(rrset
)
792 for method
in ("sendUDPQuery", "sendTCPQuery"):
793 sender
= getattr(self
, method
)
794 (receivedQuery
, receivedResponse
) = sender(query
, response
)
795 self
.assertTrue(receivedQuery
)
796 self
.assertTrue(receivedResponse
)
797 receivedQuery
.id = query
.id
798 self
.assertEquals(query
, receivedQuery
)
799 self
.assertEquals(response
, receivedResponse
)
801 class TestAdvancedRestoreFlagsOnSelfResponse(DNSDistTest
):
803 _config_template
= """
804 addAction(AllRule(), DisableValidationAction())
805 addAction(AllRule(), SpoofAction("192.0.2.1"))
806 newServer{address="127.0.0.1:%s"}
809 def testAdvancedRestoreFlagsOnSpoofResponse(self
):
811 Advanced: Restore flags on spoofed response
813 Send a query with CD flag cleared, dnsdist is
814 instructed to set it, then to spoof the response,
815 check that response has the flag cleared.
817 name
= 'spoofed.restoreflags.advanced.tests.powerdns.com.'
818 query
= dns
.message
.make_query(name
, 'A', 'IN')
819 # dnsdist set RA = RD for spoofed responses
820 query
.flags
&= ~dns
.flags
.RD
822 response
= dns
.message
.make_response(query
)
823 rrset
= dns
.rrset
.from_text(name
,
828 response
.answer
.append(rrset
)
830 for method
in ("sendUDPQuery", "sendTCPQuery"):
831 sender
= getattr(self
, method
)
832 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
833 self
.assertTrue(receivedResponse
)
834 self
.assertEquals(response
, receivedResponse
)
836 class TestAdvancedQPS(DNSDistTest
):
838 _config_template
= """
839 addAction("qps.advanced.tests.powerdns.com", QPSAction(10))
840 newServer{address="127.0.0.1:%s"}
843 def testAdvancedQPSLimit(self
):
847 Send queries to "qps.advanced.tests.powerdns.com."
848 check that dnsdist drops queries when the max QPS has been reached.
851 name
= 'qps.advanced.tests.powerdns.com.'
852 query
= dns
.message
.make_query(name
, 'A', 'IN')
853 response
= dns
.message
.make_response(query
)
854 rrset
= dns
.rrset
.from_text(name
,
859 response
.answer
.append(rrset
)
861 for _
in range(maxQPS
):
862 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
863 receivedQuery
.id = query
.id
864 self
.assertEquals(query
, receivedQuery
)
865 self
.assertEquals(response
, receivedResponse
)
867 # we should now be dropped
868 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
869 self
.assertEquals(receivedResponse
, None)
873 # again, over TCP this time
874 for _
in range(maxQPS
):
875 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
876 receivedQuery
.id = query
.id
877 self
.assertEquals(query
, receivedQuery
)
878 self
.assertEquals(response
, receivedResponse
)
881 (_
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
882 self
.assertEquals(receivedResponse
, None)
884 class TestAdvancedQPSNone(DNSDistTest
):
886 _config_template
= """
887 addAction("qpsnone.advanced.tests.powerdns.com", QPSAction(100))
888 addAction(AllRule(), RCodeAction(dnsdist.REFUSED))
889 newServer{address="127.0.0.1:%s"}
892 def testAdvancedQPSNone(self
):
894 Advanced: Not matching QPS returns None, not Allow
896 Send queries to "qps.advanced.tests.powerdns.com."
897 check that the rule returns None when the QPS has not been
900 name
= 'qpsnone.advanced.tests.powerdns.com.'
901 query
= dns
.message
.make_query(name
, 'A', 'IN')
902 expectedResponse
= dns
.message
.make_response(query
)
903 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
905 for method
in ("sendUDPQuery", "sendTCPQuery"):
906 sender
= getattr(self
, method
)
907 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
908 self
.assertEquals(receivedResponse
, expectedResponse
)
910 class TestAdvancedNMGRule(DNSDistTest
):
912 _config_template
= """
914 allowed:addMask("192.0.2.1/32")
915 addAction(NotRule(NetmaskGroupRule(allowed)), RCodeAction(dnsdist.REFUSED))
916 newServer{address="127.0.0.1:%s"}
919 def testAdvancedNMGRule(self
):
921 Advanced: NMGRule should refuse our queries
923 Send queries to "nmgrule.advanced.tests.powerdns.com.",
924 check that we are getting a REFUSED response.
926 name
= 'nmgrule.advanced.tests.powerdns.com.'
927 query
= dns
.message
.make_query(name
, 'A', 'IN')
928 expectedResponse
= dns
.message
.make_response(query
)
929 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
931 for method
in ("sendUDPQuery", "sendTCPQuery"):
932 sender
= getattr(self
, method
)
933 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
934 self
.assertEquals(receivedResponse
, expectedResponse
)
936 class TestDSTPortRule(DNSDistTest
):
938 _config_params
= ['_dnsDistPort', '_testServerPort']
939 _config_template
= """
940 addAction(DSTPortRule(%d), RCodeAction(dnsdist.REFUSED))
941 newServer{address="127.0.0.1:%s"}
944 def testDSTPortRule(self
):
946 Advanced: DSTPortRule should capture our queries
948 Send queries to "dstportrule.advanced.tests.powerdns.com.",
949 check that we are getting a REFUSED response.
952 name
= 'dstportrule.advanced.tests.powerdns.com.'
953 query
= dns
.message
.make_query(name
, 'A', 'IN')
954 expectedResponse
= dns
.message
.make_response(query
)
955 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
957 for method
in ("sendUDPQuery", "sendTCPQuery"):
958 sender
= getattr(self
, method
)
959 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
960 self
.assertEquals(receivedResponse
, expectedResponse
)
962 class TestAdvancedLabelsCountRule(DNSDistTest
):
964 _config_template
= """
965 addAction(QNameLabelsCountRule(5,6), RCodeAction(dnsdist.REFUSED))
966 newServer{address="127.0.0.1:%s"}
969 def testAdvancedLabelsCountRule(self
):
971 Advanced: QNameLabelsCountRule(5,6)
973 # 6 labels, we should be fine
974 name
= 'ok.labelscount.advanced.tests.powerdns.com.'
975 query
= dns
.message
.make_query(name
, 'A', 'IN')
976 response
= dns
.message
.make_response(query
)
977 rrset
= dns
.rrset
.from_text(name
,
982 response
.answer
.append(rrset
)
984 for method
in ("sendUDPQuery", "sendTCPQuery"):
985 sender
= getattr(self
, method
)
986 (receivedQuery
, receivedResponse
) = sender(query
, response
)
987 self
.assertTrue(receivedQuery
)
988 self
.assertTrue(receivedResponse
)
989 receivedQuery
.id = query
.id
990 self
.assertEquals(query
, receivedQuery
)
991 self
.assertEquals(response
, receivedResponse
)
993 # more than 6 labels, the query should be refused
994 name
= 'not.ok.labelscount.advanced.tests.powerdns.com.'
995 query
= dns
.message
.make_query(name
, 'A', 'IN')
996 expectedResponse
= dns
.message
.make_response(query
)
997 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
999 for method
in ("sendUDPQuery", "sendTCPQuery"):
1000 sender
= getattr(self
, method
)
1001 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1002 self
.assertEquals(receivedResponse
, expectedResponse
)
1004 # less than 5 labels, the query should be refused
1005 name
= 'labelscountadvanced.tests.powerdns.com.'
1006 query
= dns
.message
.make_query(name
, 'A', 'IN')
1007 expectedResponse
= dns
.message
.make_response(query
)
1008 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
1010 for method
in ("sendUDPQuery", "sendTCPQuery"):
1011 sender
= getattr(self
, method
)
1012 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1013 self
.assertEquals(receivedResponse
, expectedResponse
)
1015 class TestAdvancedWireLengthRule(DNSDistTest
):
1017 _config_template
= """
1018 addAction(QNameWireLengthRule(54,56), RCodeAction(dnsdist.REFUSED))
1019 newServer{address="127.0.0.1:%s"}
1022 def testAdvancedWireLengthRule(self
):
1024 Advanced: QNameWireLengthRule(54,56)
1026 name
= 'longenough.qnamewirelength.advanced.tests.powerdns.com.'
1027 query
= dns
.message
.make_query(name
, 'A', 'IN')
1028 response
= dns
.message
.make_response(query
)
1029 rrset
= dns
.rrset
.from_text(name
,
1034 response
.answer
.append(rrset
)
1036 for method
in ("sendUDPQuery", "sendTCPQuery"):
1037 sender
= getattr(self
, method
)
1038 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1039 self
.assertTrue(receivedQuery
)
1040 self
.assertTrue(receivedResponse
)
1041 receivedQuery
.id = query
.id
1042 self
.assertEquals(query
, receivedQuery
)
1043 self
.assertEquals(response
, receivedResponse
)
1045 # too short, the query should be refused
1046 name
= 'short.qnamewirelength.advanced.tests.powerdns.com.'
1047 query
= dns
.message
.make_query(name
, 'A', 'IN')
1048 expectedResponse
= dns
.message
.make_response(query
)
1049 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
1051 for method
in ("sendUDPQuery", "sendTCPQuery"):
1052 sender
= getattr(self
, method
)
1053 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1054 self
.assertEquals(receivedResponse
, expectedResponse
)
1056 # too long, the query should be refused
1057 name
= 'toolongtobevalid.qnamewirelength.advanced.tests.powerdns.com.'
1058 query
= dns
.message
.make_query(name
, 'A', 'IN')
1059 expectedResponse
= dns
.message
.make_response(query
)
1060 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
1062 for method
in ("sendUDPQuery", "sendTCPQuery"):
1063 sender
= getattr(self
, method
)
1064 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1065 self
.assertEquals(receivedResponse
, expectedResponse
)
1067 class TestAdvancedIncludeDir(DNSDistTest
):
1069 _config_template
= """
1070 -- this directory contains a file allowing includedir.advanced.tests.powerdns.com.
1071 includeDirectory('test-include-dir')
1072 newServer{address="127.0.0.1:%s"}
1075 def testAdvancedIncludeDirAllowed(self
):
1077 Advanced: includeDirectory()
1079 name
= 'includedir.advanced.tests.powerdns.com.'
1080 query
= dns
.message
.make_query(name
, 'A', 'IN')
1081 response
= dns
.message
.make_response(query
)
1082 rrset
= dns
.rrset
.from_text(name
,
1087 response
.answer
.append(rrset
)
1089 for method
in ("sendUDPQuery", "sendTCPQuery"):
1090 sender
= getattr(self
, method
)
1091 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1092 self
.assertTrue(receivedQuery
)
1093 self
.assertTrue(receivedResponse
)
1094 receivedQuery
.id = query
.id
1095 self
.assertEquals(query
, receivedQuery
)
1096 self
.assertEquals(response
, receivedResponse
)
1098 # this one should be refused
1099 name
= 'notincludedir.advanced.tests.powerdns.com.'
1100 query
= dns
.message
.make_query(name
, 'A', 'IN')
1101 expectedResponse
= dns
.message
.make_response(query
)
1102 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
1104 for method
in ("sendUDPQuery", "sendTCPQuery"):
1105 sender
= getattr(self
, method
)
1106 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1107 self
.assertEquals(receivedResponse
, expectedResponse
)
1109 class TestAdvancedLuaDO(DNSDistTest
):
1111 _config_template
= """
1112 function nxDOLua(dq)
1114 return DNSAction.Nxdomain, ""
1116 return DNSAction.None, ""
1118 addAction(AllRule(), LuaAction(nxDOLua))
1119 newServer{address="127.0.0.1:%s"}
1122 def testNxDOViaLua(self
):
1124 Advanced: Nx DO queries via Lua
1126 name
= 'nxdo.advanced.tests.powerdns.com.'
1127 query
= dns
.message
.make_query(name
, 'A', 'IN')
1128 response
= dns
.message
.make_response(query
)
1129 rrset
= dns
.rrset
.from_text(name
,
1134 response
.answer
.append(rrset
)
1135 queryWithDO
= dns
.message
.make_query(name
, 'A', 'IN', want_dnssec
=True)
1136 doResponse
= dns
.message
.make_response(queryWithDO
)
1137 doResponse
.set_rcode(dns
.rcode
.NXDOMAIN
)
1140 for method
in ("sendUDPQuery", "sendTCPQuery"):
1141 sender
= getattr(self
, method
)
1142 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1143 self
.assertTrue(receivedQuery
)
1144 self
.assertTrue(receivedResponse
)
1145 receivedQuery
.id = query
.id
1146 self
.assertEquals(query
, receivedQuery
)
1147 self
.assertEquals(receivedResponse
, response
)
1150 for method
in ("sendUDPQuery", "sendTCPQuery"):
1151 sender
= getattr(self
, method
)
1152 (_
, receivedResponse
) = sender(queryWithDO
, response
=None, useQueue
=False)
1153 self
.assertTrue(receivedResponse
)
1154 doResponse
.id = receivedResponse
.id
1155 self
.assertEquals(receivedResponse
, doResponse
)
1157 class TestAdvancedLuaRefused(DNSDistTest
):
1159 _config_template
= """
1161 return DNSAction.Refused, ""
1163 addAction(AllRule(), LuaAction(refuse))
1164 newServer{address="127.0.0.1:%s"}
1167 def testRefusedViaLua(self
):
1169 Advanced: Refused via Lua
1171 name
= 'refused.advanced.tests.powerdns.com.'
1172 query
= dns
.message
.make_query(name
, 'A', 'IN')
1173 response
= dns
.message
.make_response(query
)
1174 rrset
= dns
.rrset
.from_text(name
,
1179 response
.answer
.append(rrset
)
1180 refusedResponse
= dns
.message
.make_response(query
)
1181 refusedResponse
.set_rcode(dns
.rcode
.REFUSED
)
1183 for method
in ("sendUDPQuery", "sendTCPQuery"):
1184 sender
= getattr(self
, method
)
1185 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1186 self
.assertTrue(receivedResponse
)
1187 refusedResponse
.id = receivedResponse
.id
1188 self
.assertEquals(receivedResponse
, refusedResponse
)
1190 class TestAdvancedLuaActionReturnSyntax(DNSDistTest
):
1192 _config_template
= """
1194 return DNSAction.Refused
1196 addAction(AllRule(), LuaAction(refuse))
1197 newServer{address="127.0.0.1:%s"}
1200 def testRefusedWithEmptyRule(self
):
1202 Advanced: Short syntax for LuaAction return values
1204 name
= 'short.refused.advanced.tests.powerdns.com.'
1205 query
= dns
.message
.make_query(name
, 'A', 'IN')
1206 response
= dns
.message
.make_response(query
)
1207 rrset
= dns
.rrset
.from_text(name
,
1212 response
.answer
.append(rrset
)
1213 refusedResponse
= dns
.message
.make_response(query
)
1214 refusedResponse
.set_rcode(dns
.rcode
.REFUSED
)
1216 for method
in ("sendUDPQuery", "sendTCPQuery"):
1217 sender
= getattr(self
, method
)
1218 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1219 self
.assertTrue(receivedResponse
)
1220 refusedResponse
.id = receivedResponse
.id
1221 self
.assertEquals(receivedResponse
, refusedResponse
)
1223 class TestAdvancedLuaTruncated(DNSDistTest
):
1225 _config_template
= """
1228 return DNSAction.Truncate, ""
1230 return DNSAction.None, ""
1232 addAction(AllRule(), LuaAction(trunc))
1233 newServer{address="127.0.0.1:%s"}
1236 def testTCViaLua(self
):
1238 Advanced: TC via Lua
1240 name
= 'tc.advanced.tests.powerdns.com.'
1241 query
= dns
.message
.make_query(name
, 'A', 'IN')
1242 response
= dns
.message
.make_response(query
)
1243 rrset
= dns
.rrset
.from_text(name
,
1248 response
.answer
.append(rrset
)
1250 truncatedResponse
= dns
.message
.make_response(query
)
1251 truncatedResponse
.flags |
= dns
.flags
.TC
1253 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1254 self
.assertTrue(receivedResponse
)
1255 truncatedResponse
.id = receivedResponse
.id
1256 self
.assertEquals(receivedResponse
, truncatedResponse
)
1258 # no truncation over TCP
1259 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
1260 self
.assertTrue(receivedQuery
)
1261 self
.assertTrue(receivedResponse
)
1262 receivedQuery
.id = query
.id
1263 self
.assertEquals(query
, receivedQuery
)
1264 self
.assertEquals(receivedResponse
, response
)
1266 class TestStatNodeRespRingSince(DNSDistTest
):
1268 _consoleKey
= DNSDistTest
.generateConsoleKey()
1269 _consoleKeyB64
= base64
.b64encode(_consoleKey
).decode('ascii')
1270 _config_params
= ['_consoleKeyB64', '_consolePort', '_testServerPort']
1271 _config_template
= """
1273 controlSocket("127.0.0.1:%s")
1274 s1 = newServer{address="127.0.0.1:%s"}
1276 function visitor(node, self, childstat)
1277 table.insert(nodesSeen, node.fullname)
1281 def testStatNodeRespRingSince(self
):
1283 Advanced: StatNodeRespRing with optional since parameter
1286 name
= 'statnodesince.advanced.tests.powerdns.com.'
1287 query
= dns
.message
.make_query(name
, 'A', 'IN')
1288 response
= dns
.message
.make_response(query
)
1289 rrset
= dns
.rrset
.from_text(name
,
1294 response
.answer
.append(rrset
)
1296 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1297 self
.assertTrue(receivedQuery
)
1298 self
.assertTrue(receivedResponse
)
1299 receivedQuery
.id = query
.id
1300 self
.assertEquals(query
, receivedQuery
)
1301 self
.assertEquals(response
, receivedResponse
)
1303 self
.sendConsoleCommand("nodesSeen = {}")
1304 self
.sendConsoleCommand("statNodeRespRing(visitor)")
1305 nodes
= self
.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
1306 nodes
= nodes
.strip("\n")
1307 self
.assertEquals(nodes
, """statnodesince.advanced.tests.powerdns.com.
1308 advanced.tests.powerdns.com.
1313 self
.sendConsoleCommand("nodesSeen = {}")
1314 self
.sendConsoleCommand("statNodeRespRing(visitor, 0)")
1315 nodes
= self
.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
1316 nodes
= nodes
.strip("\n")
1317 self
.assertEquals(nodes
, """statnodesince.advanced.tests.powerdns.com.
1318 advanced.tests.powerdns.com.
1325 self
.sendConsoleCommand("nodesSeen = {}")
1326 self
.sendConsoleCommand("statNodeRespRing(visitor)")
1327 nodes
= self
.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
1328 nodes
= nodes
.strip("\n")
1329 self
.assertEquals(nodes
, """statnodesince.advanced.tests.powerdns.com.
1330 advanced.tests.powerdns.com.
1335 self
.sendConsoleCommand("nodesSeen = {}")
1336 self
.sendConsoleCommand("statNodeRespRing(visitor, 5)")
1337 nodes
= self
.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
1338 nodes
= nodes
.strip("\n")
1339 self
.assertEquals(nodes
, """""")
1341 self
.sendConsoleCommand("nodesSeen = {}")
1342 self
.sendConsoleCommand("statNodeRespRing(visitor, 10)")
1343 nodes
= self
.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
1344 nodes
= nodes
.strip("\n")
1345 self
.assertEquals(nodes
, """statnodesince.advanced.tests.powerdns.com.
1346 advanced.tests.powerdns.com.
1351 class TestAdvancedRD(DNSDistTest
):
1353 _config_template
= """
1354 addAction(RDRule(), RCodeAction(dnsdist.REFUSED))
1355 newServer{address="127.0.0.1:%s"}
1358 def testAdvancedRDRefused(self
):
1360 Advanced: RD query is refused
1362 name
= 'rd.advanced.tests.powerdns.com.'
1363 query
= dns
.message
.make_query(name
, 'A', 'IN')
1364 expectedResponse
= dns
.message
.make_response(query
)
1365 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
1367 for method
in ("sendUDPQuery", "sendTCPQuery"):
1368 sender
= getattr(self
, method
)
1369 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1370 self
.assertEquals(receivedResponse
, expectedResponse
)
1372 def testAdvancedNoRDAllowed(self
):
1374 Advanced: No-RD query is allowed
1376 name
= 'no-rd.advanced.tests.powerdns.com.'
1377 query
= dns
.message
.make_query(name
, 'A', 'IN')
1378 query
.flags
&= ~dns
.flags
.RD
1379 response
= dns
.message
.make_response(query
)
1381 for method
in ("sendUDPQuery", "sendTCPQuery"):
1382 sender
= getattr(self
, method
)
1383 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1384 receivedQuery
.id = query
.id
1385 self
.assertEquals(receivedQuery
, query
)
1386 self
.assertEquals(receivedResponse
, response
)
1388 class TestAdvancedGetLocalPort(DNSDistTest
):
1390 _config_template
= """
1391 function answerBasedOnLocalPort(dq)
1392 local port = dq.localaddr:getPort()
1393 return DNSAction.Spoof, "port-was-"..port..".local-port.advanced.tests.powerdns.com."
1395 addAction("local-port.advanced.tests.powerdns.com.", LuaAction(answerBasedOnLocalPort))
1396 newServer{address="127.0.0.1:%s"}
1399 def testAdvancedGetLocalPort(self
):
1401 Advanced: Return CNAME containing the local port
1403 name
= 'local-port.advanced.tests.powerdns.com.'
1404 query
= dns
.message
.make_query(name
, 'A', 'IN')
1405 # dnsdist set RA = RD for spoofed responses
1406 query
.flags
&= ~dns
.flags
.RD
1408 response
= dns
.message
.make_response(query
)
1409 rrset
= dns
.rrset
.from_text(name
,
1412 dns
.rdatatype
.CNAME
,
1413 'port-was-{}.local-port.advanced.tests.powerdns.com.'.format(self
._dnsDistPort
))
1414 response
.answer
.append(rrset
)
1416 for method
in ("sendUDPQuery", "sendTCPQuery"):
1417 sender
= getattr(self
, method
)
1418 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1419 self
.assertEquals(receivedResponse
, response
)
1421 class TestAdvancedGetLocalPortOnAnyBind(DNSDistTest
):
1423 _config_template
= """
1424 function answerBasedOnLocalPort(dq)
1425 local port = dq.localaddr:getPort()
1426 return DNSAction.Spoof, "port-was-"..port..".local-port-any.advanced.tests.powerdns.com."
1428 addAction("local-port-any.advanced.tests.powerdns.com.", LuaAction(answerBasedOnLocalPort))
1429 newServer{address="127.0.0.1:%s"}
1431 _dnsDistListeningAddr
= "0.0.0.0"
1433 def testAdvancedGetLocalPortOnAnyBind(self
):
1435 Advanced: Return CNAME containing the local port for an ANY bind
1437 name
= 'local-port-any.advanced.tests.powerdns.com.'
1438 query
= dns
.message
.make_query(name
, 'A', 'IN')
1439 # dnsdist set RA = RD for spoofed responses
1440 query
.flags
&= ~dns
.flags
.RD
1442 response
= dns
.message
.make_response(query
)
1443 rrset
= dns
.rrset
.from_text(name
,
1446 dns
.rdatatype
.CNAME
,
1447 'port-was-{}.local-port-any.advanced.tests.powerdns.com.'.format(self
._dnsDistPort
))
1448 response
.answer
.append(rrset
)
1450 for method
in ("sendUDPQuery", "sendTCPQuery"):
1451 sender
= getattr(self
, method
)
1452 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1453 self
.assertEquals(receivedResponse
, response
)
1455 class TestAdvancedGetLocalAddressOnAnyBind(DNSDistTest
):
1457 _config_template
= """
1458 function answerBasedOnLocalAddress(dq)
1459 local dest = dq.localaddr:toString()
1460 local i, j = string.find(dest, "[0-9.]+")
1461 local addr = string.sub(dest, i, j)
1462 local dashAddr = string.gsub(addr, "[.]", "-")
1463 return DNSAction.Spoof, "address-was-"..dashAddr..".local-address-any.advanced.tests.powerdns.com."
1465 addAction("local-address-any.advanced.tests.powerdns.com.", LuaAction(answerBasedOnLocalAddress))
1466 newServer{address="127.0.0.1:%s"}
1468 _dnsDistListeningAddr
= "0.0.0.0"
1470 def testAdvancedGetLocalAddressOnAnyBind(self
):
1472 Advanced: Return CNAME containing the local address for an ANY bind
1474 name
= 'local-address-any.advanced.tests.powerdns.com.'
1475 query
= dns
.message
.make_query(name
, 'A', 'IN')
1476 # dnsdist set RA = RD for spoofed responses
1477 query
.flags
&= ~dns
.flags
.RD
1479 response
= dns
.message
.make_response(query
)
1480 rrset
= dns
.rrset
.from_text(name
,
1483 dns
.rdatatype
.CNAME
,
1484 'address-was-127-0-0-1.local-address-any.advanced.tests.powerdns.com.')
1485 response
.answer
.append(rrset
)
1487 for method
in ("sendUDPQuery", "sendTCPQuery"):
1488 sender
= getattr(self
, method
)
1489 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1490 self
.assertEquals(receivedResponse
, response
)
1492 class TestAdvancedLuaTempFailureTTL(DNSDistTest
):
1494 _config_template
= """
1495 function testAction(dq)
1496 if dq.tempFailureTTL ~= nil then
1497 return DNSAction.Spoof, "initially.not.nil.but." + dq.tempFailureTTL + ".tests.powerdns.com."
1499 dq.tempFailureTTL = 30
1500 if dq.tempFailureTTL ~= 30 then
1501 return DNSAction.Spoof, "after.set.not.expected.value.but." + dq.tempFailureTTL + ".tests.powerdns.com."
1503 dq.tempFailureTTL = nil
1504 if dq.tempFailureTTL ~= nil then
1505 return DNSAction.Spoof, "after.unset.not.nil.but." + dq.tempFailureTTL + ".tests.powerdns.com."
1507 return DNSAction.None, ""
1509 addAction(AllRule(), LuaAction(testAction))
1510 newServer{address="127.0.0.1:%s"}
1513 def testTempFailureTTLBinding(self
):
1515 Advanced: Exercise dq.tempFailureTTL Lua binding
1517 name
= 'tempfailurettlbinding.advanced.tests.powerdns.com.'
1518 query
= dns
.message
.make_query(name
, 'A', 'IN')
1519 response
= dns
.message
.make_response(query
)
1520 rrset
= dns
.rrset
.from_text(name
,
1525 response
.answer
.append(rrset
)
1527 for method
in ("sendUDPQuery", "sendTCPQuery"):
1528 sender
= getattr(self
, method
)
1529 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1530 self
.assertTrue(receivedQuery
)
1531 self
.assertTrue(receivedResponse
)
1532 receivedQuery
.id = query
.id
1533 self
.assertEquals(query
, receivedQuery
)
1534 self
.assertEquals(receivedResponse
, response
)
1536 class TestAdvancedEDNSOptionRule(DNSDistTest
):
1538 _config_template
= """
1539 newServer{address="127.0.0.1:%s"}
1540 addAction(EDNSOptionRule(EDNSOptionCode.ECS), DropAction())
1543 def testDropped(self
):
1545 Advanced: A question with ECS is dropped
1548 name
= 'ednsoptionrule.advanced.tests.powerdns.com.'
1550 ecso
= clientsubnetoption
.ClientSubnetOption('127.0.0.1', 24)
1551 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=True, options
=[ecso
], payload
=512)
1553 for method
in ("sendUDPQuery", "sendTCPQuery"):
1554 sender
= getattr(self
, method
)
1555 (_
, receivedResponse
) = sender(query
, response
=None)
1556 self
.assertEquals(receivedResponse
, None)
1558 def testReplied(self
):
1560 Advanced: A question without ECS is answered
1563 name
= 'ednsoptionrule.advanced.tests.powerdns.com.'
1566 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=True, options
=[], payload
=512)
1567 response
= dns
.message
.make_response(query
)
1569 for method
in ("sendUDPQuery", "sendTCPQuery"):
1570 sender
= getattr(self
, method
)
1571 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1572 self
.assertTrue(receivedQuery
)
1573 self
.assertTrue(receivedResponse
)
1575 receivedQuery
.id = query
.id
1576 self
.assertEquals(query
, receivedQuery
)
1577 self
.assertEquals(receivedResponse
, response
)
1579 # and with no EDNS at all
1580 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=False)
1581 response
= dns
.message
.make_response(query
)
1583 for method
in ("sendUDPQuery", "sendTCPQuery"):
1584 sender
= getattr(self
, method
)
1585 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1586 self
.assertTrue(receivedQuery
)
1587 self
.assertTrue(receivedResponse
)
1589 receivedQuery
.id = query
.id
1590 self
.assertEquals(query
, receivedQuery
)
1591 self
.assertEquals(receivedResponse
, response
)
1593 class TestAdvancedAllowHeaderOnly(DNSDistTest
):
1595 _config_template
= """
1596 newServer{address="127.0.0.1:%s"}
1597 setAllowEmptyResponse(true)
1600 def testHeaderOnlyRefused(self
):
1602 Advanced: Header-only refused response
1604 name
= 'header-only-refused-response.advanced.tests.powerdns.com.'
1605 query
= dns
.message
.make_query(name
, 'A', 'IN')
1606 response
= dns
.message
.make_response(query
)
1607 response
.set_rcode(dns
.rcode
.REFUSED
)
1608 response
.question
= []
1610 for method
in ("sendUDPQuery", "sendTCPQuery"):
1611 sender
= getattr(self
, method
)
1612 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1613 self
.assertTrue(receivedQuery
)
1614 receivedQuery
.id = query
.id
1615 self
.assertEquals(query
, receivedQuery
)
1616 self
.assertEquals(receivedResponse
, response
)
1618 def testHeaderOnlyNoErrorResponse(self
):
1620 Advanced: Header-only NoError response should be allowed
1622 name
= 'header-only-noerror-response.advanced.tests.powerdns.com.'
1623 query
= dns
.message
.make_query(name
, 'A', 'IN')
1624 response
= dns
.message
.make_response(query
)
1625 response
.question
= []
1627 for method
in ("sendUDPQuery", "sendTCPQuery"):
1628 sender
= getattr(self
, method
)
1629 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1630 self
.assertTrue(receivedQuery
)
1631 receivedQuery
.id = query
.id
1632 self
.assertEquals(query
, receivedQuery
)
1633 self
.assertEquals(receivedResponse
, response
)
1635 def testHeaderOnlyNXDResponse(self
):
1637 Advanced: Header-only NXD response should be allowed
1639 name
= 'header-only-nxd-response.advanced.tests.powerdns.com.'
1640 query
= dns
.message
.make_query(name
, 'A', 'IN')
1641 response
= dns
.message
.make_response(query
)
1642 response
.set_rcode(dns
.rcode
.NXDOMAIN
)
1643 response
.question
= []
1645 for method
in ("sendUDPQuery", "sendTCPQuery"):
1646 sender
= getattr(self
, method
)
1647 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1648 self
.assertTrue(receivedQuery
)
1649 receivedQuery
.id = query
.id
1650 self
.assertEquals(query
, receivedQuery
)
1651 self
.assertEquals(receivedResponse
, response
)
1653 class TestAdvancedEDNSVersionRule(DNSDistTest
):
1655 _config_template
= """
1656 newServer{address="127.0.0.1:%s"}
1657 addAction(EDNSVersionRule(0), ERCodeAction(dnsdist.BADVERS))
1660 def testDropped(self
):
1662 Advanced: A question with ECS version larger than 0 is dropped
1665 name
= 'ednsversionrule.advanced.tests.powerdns.com.'
1667 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=1)
1668 expectedResponse
= dns
.message
.make_response(query
)
1669 expectedResponse
.set_rcode(dns
.rcode
.BADVERS
)
1671 for method
in ("sendUDPQuery", "sendTCPQuery"):
1672 sender
= getattr(self
, method
)
1673 (_
, receivedResponse
) = sender(query
, response
=None)
1674 self
.assertEquals(receivedResponse
, expectedResponse
)
1676 def testNoEDNS0Pass(self
):
1678 Advanced: A question with ECS version 0 goes through
1681 name
= 'ednsversionrule.advanced.tests.powerdns.com.'
1683 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=True)
1684 response
= dns
.message
.make_response(query
)
1686 for method
in ("sendUDPQuery", "sendTCPQuery"):
1687 sender
= getattr(self
, method
)
1688 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1689 receivedQuery
.id = query
.id
1690 self
.assertEquals(query
, receivedQuery
)
1691 self
.assertEquals(receivedResponse
, response
)
1693 def testReplied(self
):
1695 Advanced: A question without ECS goes through
1698 name
= 'ednsoptionrule.advanced.tests.powerdns.com.'
1700 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=False)
1701 response
= dns
.message
.make_response(query
)
1703 for method
in ("sendUDPQuery", "sendTCPQuery"):
1704 sender
= getattr(self
, method
)
1705 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1706 receivedQuery
.id = query
.id
1707 self
.assertEquals(query
, receivedQuery
)
1708 self
.assertEquals(receivedResponse
, response
)
1710 class TestSetRules(DNSDistTest
):
1712 _consoleKey
= DNSDistTest
.generateConsoleKey()
1713 _consoleKeyB64
= base64
.b64encode(_consoleKey
).decode('ascii')
1714 _config_params
= ['_consoleKeyB64', '_consolePort', '_testServerPort']
1715 _config_template
= """
1717 controlSocket("127.0.0.1:%s")
1718 newServer{address="127.0.0.1:%s"}
1719 addAction(AllRule(), SpoofAction("192.0.2.1"))
1722 def testClearThenSetRules(self
):
1724 Advanced: Clear rules, set rules
1727 name
= 'clearthensetrules.advanced.tests.powerdns.com.'
1728 query
= dns
.message
.make_query(name
, 'A', 'IN')
1729 # dnsdist set RA = RD for spoofed responses
1730 query
.flags
&= ~dns
.flags
.RD
1731 expectedResponse
= dns
.message
.make_response(query
)
1732 rrset
= dns
.rrset
.from_text(name
,
1737 expectedResponse
.answer
.append(rrset
)
1739 for method
in ("sendUDPQuery", "sendTCPQuery"):
1740 sender
= getattr(self
, method
)
1742 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1743 self
.assertTrue(receivedResponse
)
1744 self
.assertEquals(expectedResponse
, receivedResponse
)
1746 # clear all the rules, we should not be spoofing and get a SERVFAIL from the responder instead
1747 self
.sendConsoleCommand("clearRules()")
1749 expectedResponse
= dns
.message
.make_response(query
)
1750 expectedResponse
.set_rcode(dns
.rcode
.SERVFAIL
)
1752 for method
in ("sendUDPQuery", "sendTCPQuery"):
1753 sender
= getattr(self
, method
)
1755 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1756 self
.assertTrue(receivedResponse
)
1757 self
.assertEquals(expectedResponse
, receivedResponse
)
1759 # insert a new spoofing rule
1760 self
.sendConsoleCommand("setRules({ newRuleAction(AllRule(), SpoofAction(\"192.0.2.2\")) })")
1762 expectedResponse
= dns
.message
.make_response(query
)
1763 rrset
= dns
.rrset
.from_text(name
,
1768 expectedResponse
.answer
.append(rrset
)
1770 for method
in ("sendUDPQuery", "sendTCPQuery"):
1771 sender
= getattr(self
, method
)
1773 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1774 self
.assertTrue(receivedResponse
)
1775 self
.assertEquals(expectedResponse
, receivedResponse
)