Skip to content

Commit

Permalink
Merge pull request #14591 from zeha/zeha-13039
Browse files Browse the repository at this point in the history
auth dnsproxy: make local port range configurable
  • Loading branch information
Habbie authored Aug 27, 2024
2 parents fb43684 + 60157e5 commit 7b76dcf
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 5 deletions.
14 changes: 14 additions & 0 deletions docs/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,20 @@ approximately doubles query load.
If this is turned off, DNAME records are treated as any other and served
only when queried explicitly.

.. _setting-dnsproxy-udp-port-range:

``dnsproxy-udp-port-range``
---------------------------

- String
- Default: `10000 60000`

If :ref:`setting-resolver` enables the DNS Proxy, this setting limits the
port range the DNS Proxy's UDP port is chosen from.

Default should be fine on most installs, but if you have conflicting local
services, you may choose to limit the range.

.. _setting-dnssec-key-cache-ttl:

``dnssec-key-cache-ttl``
Expand Down
3 changes: 2 additions & 1 deletion pdns/auth-main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ static void declareArguments()
::arg().set("receiver-threads", "Default number of receiver threads to start") = "1";
::arg().set("queue-limit", "Maximum number of milliseconds to queue a query") = "1500";
::arg().set("resolver", "Use this resolver for ALIAS and the internal stub resolver") = "no";
::arg().set("dnsproxy-udp-port-range", "Select DNS Proxy outgoing UDP port from given range (lower upper)") = "10000 60000";
::arg().set("udp-truncation-threshold", "Maximum UDP response size before we truncate") = "1232";

::arg().set("config-name", "Name of this virtual configuration - will rename the binary image") = "";
Expand Down Expand Up @@ -786,7 +787,7 @@ static void mainthread()
Utility::dropUserPrivs(newuid);

if (::arg().mustDo("resolver")) {
DP = std::make_unique<DNSProxy>(::arg()["resolver"]);
DP = std::make_unique<DNSProxy>(::arg()["resolver"], ::arg()["dnsproxy-udp-port-range"]);
DP->go();
}

Expand Down
22 changes: 19 additions & 3 deletions pdns/dnsproxy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@
#include "ednsoptions.hh"
#include "ednssubnet.hh"

#include <boost/uuid/uuid_io.hpp>

extern StatBag S;

DNSProxy::DNSProxy(const string& remote) :
DNSProxy::DNSProxy(const string& remote, const string& udpPortRange) :
d_xor(dns_random_uint16())
{
d_resanswers = S.getPointer("recursing-answers");
Expand All @@ -53,6 +55,20 @@ DNSProxy::DNSProxy(const string& remote) :
stringtok(addresses, remote, " ,\t");
d_remote = ComboAddress(addresses[0], 53);

vector<string> parts;
stringtok(parts, udpPortRange, " ");
if (parts.size() != 2) {
throw PDNSException("DNS Proxy UDP port range must contain exactly one lower and one upper bound");
}
unsigned long portRangeLow = std::stoul(parts.at(0));
unsigned long portRangeHigh = std::stoul(parts.at(1));
if (portRangeLow < 1 || portRangeHigh > 65535) {
throw PDNSException("DNS Proxy UDP port range values out of valid port bounds (1 to 65535)");
}
if (portRangeLow >= portRangeHigh) {
throw PDNSException("DNS Proxy UDP port range upper bound " + std::to_string(portRangeHigh) + " must be higher than lower bound (" + std::to_string(portRangeLow) + ")");
}

if ((d_sock = socket(d_remote.sin4.sin_family, SOCK_DGRAM, 0)) < 0) {
throw PDNSException(string("socket: ") + stringerror());
}
Expand All @@ -67,7 +83,7 @@ DNSProxy::DNSProxy(const string& remote) :

unsigned int attempts = 0;
for (; attempts < 10; attempts++) {
local.sin4.sin_port = htons(10000 + dns_random(50000));
local.sin4.sin_port = htons(portRangeLow + dns_random(portRangeHigh - portRangeLow));

if (::bind(d_sock, (struct sockaddr*)&local, local.getSocklen()) >= 0) { // NOLINT(cppcoreguidelines-pro-type-cstyle-cast)
break;
Expand All @@ -92,7 +108,7 @@ void DNSProxy::go()
proxythread.detach();
}

//! look up qname target with r->qtype, plonk it in the answer section of 'r' with name aname
//! look up qname 'target' with reply->qtype, plonk it in the answer section of 'reply' with name 'aname'
bool DNSProxy::completePacket(std::unique_ptr<DNSPacket>& reply, const DNSName& target, const DNSName& aname, const uint8_t scopeMask)
{
string ECSOptionStr;
Expand Down
2 changes: 1 addition & 1 deletion pdns/dnsproxy.hh
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ To fix: how to remove the stale entries that will surely accumulate
class DNSProxy
{
public:
DNSProxy(const string& remote); //!< creates socket
DNSProxy(const string& remote, const string& udpPortRange); //!< creates socket
~DNSProxy(); //<! dtor for DNSProxy
void go(); //!< launches the actual thread
bool completePacket(std::unique_ptr<DNSPacket>& reply, const DNSName& target, const DNSName& aname, uint8_t scopeMask);
Expand Down

0 comments on commit 7b76dcf

Please sign in to comment.