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