0003-Handle-DS-queries-to-auth-zones.patch 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. From 8ce27433f8b2e17c557cb55e4f16941d309deeac Mon Sep 17 00:00:00 2001
  2. From: Simon Kelley <[email protected]>
  3. Date: Fri, 17 Jan 2025 17:49:29 +0000
  4. Subject: [PATCH] Handle DS queries to auth zones.
  5. Origin: upstream, v2.91test8
  6. When dnsmasq is configured to act as an authoritative server and has
  7. an authoritative zone configured, and recieves a query for
  8. that zone _as_forwarder_ it answers the query directly rather
  9. than forwarding it. This doesn't affect the answer, but it
  10. saves dnsmasq forwarding the query to the recusor upstream,
  11. whch then bounces it back to dnsmasq in auth mode. The
  12. exception should be when the query is for the root of zone, for a DS
  13. RR. The answer to that has to come from the parent, via the
  14. recursor, and will typically be a proof-of-nonexistence since
  15. dnsmasq doesn't support signed zones. This patch suppresses
  16. local answers and forces forwarding to the upstream recursor
  17. for such queries. It stops breakage when a DNSSEC validating
  18. client makes queries to dnsmasq acting as forwarder for a zone
  19. for which it is authoritative.
  20. [ukleinek: drop changes to CHANGELOG to prevent conflicts]
  21. ---
  22. src/forward.c | 52 +++++++++++++++++++++++++++++++++++++--------------
  23. 1 file changed, 38 insertions(+), 14 deletions(-)
  24. --- a/src/forward.c
  25. +++ b/src/forward.c
  26. @@ -1744,15 +1744,27 @@ void receive_query(struct listener *list
  27. #endif
  28. #ifdef HAVE_AUTH
  29. - /* find queries for zones we're authoritative for, and answer them directly */
  30. + /* Find queries for zones we're authoritative for, and answer them directly.
  31. + The exception to this is DS queries for the zone route. They
  32. + have to come from the parent zone. Since dnsmasq's auth server
  33. + can't do DNSSEC, the zone will be unsigned, and anything using
  34. + dnsmasq as a forwarder and doing validation will be expecting to
  35. + see the proof of non-existence from the parent. */
  36. if (!auth_dns && !option_bool(OPT_LOCALISE))
  37. for (zone = daemon->auth_zones; zone; zone = zone->next)
  38. - if (in_zone(zone, daemon->namebuff, NULL))
  39. - {
  40. - auth_dns = 1;
  41. - local_auth = 1;
  42. - break;
  43. - }
  44. + {
  45. + char *cut;
  46. +
  47. + if (in_zone(zone, daemon->namebuff, &cut))
  48. + {
  49. + if (type != T_DS || cut)
  50. + {
  51. + auth_dns = 1;
  52. + local_auth = 1;
  53. + }
  54. + break;
  55. + }
  56. + }
  57. #endif
  58. #ifdef HAVE_LOOP
  59. @@ -2268,15 +2280,27 @@ unsigned char *tcp_request(int confd, ti
  60. &peer_addr, auth_dns ? "auth" : "query", qtype);
  61. #ifdef HAVE_AUTH
  62. - /* find queries for zones we're authoritative for, and answer them directly */
  63. + /* Find queries for zones we're authoritative for, and answer them directly.
  64. + The exception to this is DS queries for the zone route. They
  65. + have to come from the parent zone. Since dnsmasq's auth server
  66. + can't do DNSSEC, the zone will be unsigned, and anything using
  67. + dnsmasq as a forwarder and doing validation will be expecting to
  68. + see the proof of non-existence from the parent. */
  69. if (!auth_dns && !option_bool(OPT_LOCALISE))
  70. for (zone = daemon->auth_zones; zone; zone = zone->next)
  71. - if (in_zone(zone, daemon->namebuff, NULL))
  72. - {
  73. - auth_dns = 1;
  74. - local_auth = 1;
  75. - break;
  76. - }
  77. + {
  78. + char *cut;
  79. +
  80. + if (in_zone(zone, daemon->namebuff, &cut))
  81. + {
  82. + if (qtype != T_DS || cut)
  83. + {
  84. + auth_dns = 1;
  85. + local_auth = 1;
  86. + }
  87. + break;
  88. + }
  89. + }
  90. #endif
  91. }
  92. }