]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Send a HTTP 400 response to HTTP/1.1 clients
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 2 Nov 2023 09:30:19 +0000 (10:30 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 11 Dec 2023 14:06:09 +0000 (15:06 +0100)
Explaining that DNSdist with nghttp2 only supports DNS over HTTP2.

pdns/dnsdistdist/dnsdist-nghttp2-in.cc
pdns/tcpiohandler.cc
regression-tests.dnsdist/test_DOH.py

index 3fe0489ceea857fe632229ad83fc95d94b0f64de..2e25f0212ae16f5537212c45a7244baa1c827b12 100644 (file)
@@ -271,6 +271,11 @@ bool IncomingHTTP2Connection::checkALPN()
   if (protocols.size() == h2ALPN.size() && memcmp(protocols.data(), h2ALPN.data(), h2ALPN.size()) == 0) {
     return true;
   }
+
+  const std::string data("HTTP/1.1 400 Bad Request\r\nConnection: Close\r\n\r\n<html><body>This server implements RFC 8484 - DNS Queries over HTTP, and requires HTTP/2 in accordance to section 5.2 of the RFC.</body></html>\r\n");
+  d_out.insert(d_out.end(), data.begin(), data.end());
+  writeToSocket(false);
+
   vinfolog("DoH connection from %s expected ALPN value 'h2', got '%s'", d_ci.remote.toStringWithPort(), std::string(protocols.begin(), protocols.end()));
   return false;
 }
index ae8f0f10a5a3a31abc9a8fe88148ebc1d2dfbfa4..8435913e854cb13270e53b061725ef43793c39bc 100644 (file)
@@ -1816,8 +1816,9 @@ bool setupDoHProtocolNegotiation(std::shared_ptr<TLSCtx>& ctx)
     return false;
   }
   /* we want to set the ALPN to doh */
-  const std::vector<std::vector<uint8_t>> dohAlpns = {{'h', '2'}};
+  const std::vector<std::vector<uint8_t>> dohAlpns{{'h', '2'},{'h', 't', 't', 'p', '/', '1', '.', '1'}};
   ctx->setALPNProtos(dohAlpns);
+
   return true;
 }
 
index 81f39e659dbb6f72ad94b5ff66ba6aebaacf128f..bd831eb5c8c57aaea40e73fb5586c3b113e883c6 100644 (file)
@@ -377,6 +377,31 @@ class DOHTests(object):
         except:
             pass
 
+    def testDOHHTTP1(self):
+        """
+        DOH: HTTP/1.1
+        """
+        if self._dohLibrary == 'h2o':
+            raise unittest.SkipTest('h2o supports HTTP/1.1, this test is only relevant for nghttp2')
+        name = 'http11.doh.tests.powerdns.com.'
+        query = dns.message.make_query(name, 'A', 'IN', use_edns=False)
+        wire = query.to_wire()
+        b64 = base64.urlsafe_b64encode(wire).decode('UTF8').rstrip('=')
+        url = self._dohBaseURL + '?dns=' + b64
+        conn = pycurl.Curl()
+        conn.setopt(pycurl.HTTP_VERSION, pycurl.CURL_HTTP_VERSION_1_1)
+        conn.setopt(pycurl.HTTPHEADER, ["Content-type: application/dns-message",
+                                         "Accept: application/dns-message"])
+        conn.setopt(pycurl.URL, url)
+        conn.setopt(pycurl.RESOLVE, ["%s:%d:127.0.0.1" % (self._serverName, self._dohServerPort)])
+        conn.setopt(pycurl.SSL_VERIFYPEER, 1)
+        conn.setopt(pycurl.SSL_VERIFYHOST, 2)
+        conn.setopt(pycurl.CAINFO, self._caCert)
+        data = conn.perform_rb()
+        rcode = conn.getinfo(pycurl.RESPONSE_CODE)
+        self.assertEqual(rcode, 400)
+        self.assertEqual(data, b'<html><body>This server implements RFC 8484 - DNS Queries over HTTP, and requires HTTP/2 in accordance to section 5.2 of the RFC.</body></html>\r\n')
+
     def testDOHInvalid(self):
         """
         DOH: Invalid DNS query