Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

auth dnsproxy: make local port range configurable #14591

Merged
merged 1 commit into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading