From: Remi Gacogne Date: Thu, 2 Nov 2023 09:30:19 +0000 (+0100) Subject: dnsdist: Send a HTTP 400 response to HTTP/1.1 clients X-Git-Tag: dnsdist-1.9.0-alpha4~5^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7f84fd459257667590885979222e27aeadda519d;p=thirdparty%2Fpdns.git dnsdist: Send a HTTP 400 response to HTTP/1.1 clients Explaining that DNSdist with nghttp2 only supports DNS over HTTP2. --- diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index 3fe0489cee..2e25f0212a 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -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\nThis server implements RFC 8484 - DNS Queries over HTTP, and requires HTTP/2 in accordance to section 5.2 of the RFC.\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; } diff --git a/pdns/tcpiohandler.cc b/pdns/tcpiohandler.cc index ae8f0f10a5..8435913e85 100644 --- a/pdns/tcpiohandler.cc +++ b/pdns/tcpiohandler.cc @@ -1816,8 +1816,9 @@ bool setupDoHProtocolNegotiation(std::shared_ptr& ctx) return false; } /* we want to set the ALPN to doh */ - const std::vector> dohAlpns = {{'h', '2'}}; + const std::vector> dohAlpns{{'h', '2'},{'h', 't', 't', 'p', '/', '1', '.', '1'}}; ctx->setALPNProtos(dohAlpns); + return true; } diff --git a/regression-tests.dnsdist/test_DOH.py b/regression-tests.dnsdist/test_DOH.py index 81f39e659d..bd831eb5c8 100644 --- a/regression-tests.dnsdist/test_DOH.py +++ b/regression-tests.dnsdist/test_DOH.py @@ -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'This server implements RFC 8484 - DNS Queries over HTTP, and requires HTTP/2 in accordance to section 5.2 of the RFC.\r\n') + def testDOHInvalid(self): """ DOH: Invalid DNS query