2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-09-04 07:55:18 +00:00

[#3116] Allow D2 to listen on ANY addresses

D2 now allows but warns when configured to listen
on 0.0.0.0 or ::

src/bin/d2/d2_process.cc
    D2Process::reconfigureQueueMgr() - emit new warning

src/bin/d2/tests/d2_cfg_mgr_unittests.cc
    TEST_F(D2CfgMgrTest, listenOnANYAddresses)  - new test

src/lib/d2srv/d2_config.cc
    D2Params::validateContents() - remove ANY address check

src/lib/d2srv/d2_messages.*
    DHCP_DDNS_LISTENING_ON_ALL_INTERFACES - new message

src/lib/d2srv/d2_simple_parser.cc
    D2SimpleParser::parse() - remove ANY address check

Added ChangeLog entry
This commit is contained in:
Thomas Markwalder
2023-10-19 11:02:14 -04:00
parent a81909de39
commit db87a3daf5
8 changed files with 55 additions and 26 deletions

View File

@@ -1,3 +1,10 @@
3116. [func] tmark
To facilitate use in containers the restriction from listening
on 0.0.0.0 or :: addresses has been removed from kea-dhcp-ddns.
The server will now issue a warning of configured to use either
address.
(Gitlab #3116)
2186. [bug] andrei
Fixed interface redetection which had stopped working since
Kea 2.3.6.

View File

@@ -408,8 +408,10 @@ D2Process::reconfigureQueueMgr() {
/// Warn the user if the server address is not the loopback.
/// @todo Remove this once we provide a secure mechanism.
std::string ip_address = d2_params->getIpAddress().toText();
if (ip_address != "127.0.0.1" && ip_address != "::1") {
LOG_WARN(d2_logger, DHCP_DDNS_NOT_ON_LOOPBACK).arg(ip_address);
if (ip_address == "0.0.0.0" || ip_address == "::") {
LOG_WARN(d2_logger, DHCP_DDNS_LISTENING_ON_ALL_INTERFACES).arg(ip_address);
} else if (ip_address != "127.0.0.1" && ip_address != "::1") {
LOG_WARN(d2_logger, DHCP_DDNS_NOT_ON_LOOPBACK).arg(ip_address);
}
// Instantiate the listener.

View File

@@ -404,17 +404,8 @@ TEST_F(D2CfgMgrTest, unsupportedTopLevelItems) {
/// -# ncr_protocol must be valid
/// -# ncr_format must be valid
TEST_F(D2CfgMgrTest, invalidEntry) {
// Cannot use IPv4 ANY address
std::string config = makeParamsConfigString ("0.0.0.0", 777, 333,
"UDP", "JSON");
LOGIC_ERROR(config, "IP address cannot be \"0.0.0.0\" (<string>:1:17)");
// Cannot use IPv6 ANY address
config = makeParamsConfigString ("::", 777, 333, "UDP", "JSON");
LOGIC_ERROR(config, "IP address cannot be \"::\" (<string>:1:17)");
// Cannot use port 0
config = makeParamsConfigString ("127.0.0.1", 0, 333, "UDP", "JSON");
std::string config = makeParamsConfigString ("127.0.0.1", 0, 333, "UDP", "JSON");
SYNTAX_ERROR(config, "<string>:1.40: port must be greater than zero but less than 65536");
// Cannot use dns server timeout of 0
@@ -1077,4 +1068,36 @@ TEST_F(D2CfgMgrTest, comments) {
EXPECT_EQ("1", srv_ctx->get("version")->str());
}
/// @brief Tests a basic valid configuration for D2Param.
TEST_F(D2CfgMgrTest, listenOnANYAddresses) {
// Verify that ip_address 0.0.0.0 is valid.
std::string config = makeParamsConfigString ("0.0.0.0", 777, 333,
"UDP", "JSON");
RUN_CONFIG_OK(config);
EXPECT_EQ(isc::asiolink::IOAddress("0.0.0.0"),
d2_params_->getIpAddress());
// Verify the configuration summary.
EXPECT_EQ("listening on 0.0.0.0, port 777, using UDP",
d2_params_->getConfigSummary());
EXPECT_EQ(777, d2_params_->getPort());
EXPECT_EQ(333, d2_params_->getDnsServerTimeout());
EXPECT_EQ(dhcp_ddns::NCR_UDP, d2_params_->getNcrProtocol());
EXPECT_EQ(dhcp_ddns::FMT_JSON, d2_params_->getNcrFormat());
// Verify that ip_address :: valid.
config = makeParamsConfigString ("::", 777, 333, "UDP", "JSON");
RUN_CONFIG_OK(config);
// Verify that the global scalars have the proper values.
EXPECT_EQ(isc::asiolink::IOAddress("::"),
d2_params_->getIpAddress());
// Verify the configuration summary.
EXPECT_EQ("listening on ::, port 777, using UDP",
d2_params_->getConfigSummary());
}
} // end of anonymous namespace

View File

@@ -52,11 +52,6 @@ D2Params::~D2Params(){};
void
D2Params::validateContents() {
if ((ip_address_.toText() == "0.0.0.0") || (ip_address_.toText() == "::")) {
isc_throw(D2CfgError,
"D2Params: IP address cannot be \"" << ip_address_ << "\"");
}
if (port_ == 0) {
isc_throw(D2CfgError, "D2Params: port cannot be 0");
}

View File

@@ -45,6 +45,7 @@ extern const isc::log::MessageID DHCP_DDNS_FORWARD_REPLACE_RESP_CORRUPT = "DHCP_
extern const isc::log::MessageID DHCP_DDNS_FORWARD_REPLACE_TIMEOUT = "DHCP_DDNS_FORWARD_REPLACE_TIMEOUT";
extern const isc::log::MessageID DHCP_DDNS_FWD_REQUEST_IGNORED = "DHCP_DDNS_FWD_REQUEST_IGNORED";
extern const isc::log::MessageID DHCP_DDNS_INVALID_RESPONSE = "DHCP_DDNS_INVALID_RESPONSE";
extern const isc::log::MessageID DHCP_DDNS_LISTENING_ON_ALL_INTERFACES = "DHCP_DDNS_LISTENING_ON_ALL_INTERFACES";
extern const isc::log::MessageID DHCP_DDNS_NOT_ON_LOOPBACK = "DHCP_DDNS_NOT_ON_LOOPBACK";
extern const isc::log::MessageID DHCP_DDNS_NO_ELIGIBLE_JOBS = "DHCP_DDNS_NO_ELIGIBLE_JOBS";
extern const isc::log::MessageID DHCP_DDNS_NO_FWD_MATCH_ERROR = "DHCP_DDNS_NO_FWD_MATCH_ERROR";
@@ -134,6 +135,7 @@ const char* values[] = {
"DHCP_DDNS_FORWARD_REPLACE_TIMEOUT", "DHCP_DDNS Request ID %1: timed out waiting for a response to forward mapping replace for FQDN %2 to DNS server %3",
"DHCP_DDNS_FWD_REQUEST_IGNORED", "Request ID %1: Forward updates are disabled, the forward portion of request will be ignored: %2",
"DHCP_DDNS_INVALID_RESPONSE", "received response to DNS Update message is malformed: %1",
"DHCP_DDNS_LISTENING_ON_ALL_INTERFACES", "the DHCP-DDNS server has been configured to listen on %1. This is an insecure configuration supported for testing purposes only",
"DHCP_DDNS_NOT_ON_LOOPBACK", "the DHCP-DDNS server has been configured to listen on %1 which is not the local loopback. This is an insecure configuration supported for testing purposes only",
"DHCP_DDNS_NO_ELIGIBLE_JOBS", "although there are queued requests, there are pending transactions for each, Queue count: %1 Transaction count: %2",
"DHCP_DDNS_NO_FWD_MATCH_ERROR", "Request ID %1: the configured list of forward DDNS domains does not contain a match for: %2 The request has been discarded.",

View File

@@ -46,6 +46,7 @@ extern const isc::log::MessageID DHCP_DDNS_FORWARD_REPLACE_RESP_CORRUPT;
extern const isc::log::MessageID DHCP_DDNS_FORWARD_REPLACE_TIMEOUT;
extern const isc::log::MessageID DHCP_DDNS_FWD_REQUEST_IGNORED;
extern const isc::log::MessageID DHCP_DDNS_INVALID_RESPONSE;
extern const isc::log::MessageID DHCP_DDNS_LISTENING_ON_ALL_INTERFACES;
extern const isc::log::MessageID DHCP_DDNS_NOT_ON_LOOPBACK;
extern const isc::log::MessageID DHCP_DDNS_NO_ELIGIBLE_JOBS;
extern const isc::log::MessageID DHCP_DDNS_NO_FWD_MATCH_ERROR;

View File

@@ -439,3 +439,11 @@ server.
% DHCP_DDNS_UPDATE_RESPONSE_RECEIVED Request ID %1: to server: %2 status: %3
This is a debug message issued when DHCP_DDNS receives sends a DNS update
response from a DNS server.
% DHCP_DDNS_LISTENING_ON_ALL_INTERFACES the DHCP-DDNS server has been configured to listen on %1. This is an insecure configuration supported for testing purposes only
This is a warning message issued when the DHCP-DDNS server is configured to
listen at either `0.0.0.0` or `::`. It is possible for a malicious attacker to send
bogus NameChangeRequests to it and change entries in the DNS. For this reason,
listening on all interfaces should only be used when deploying in containers
or for testing purposes. A future version of Kea will disable this ability by
default.

View File

@@ -237,16 +237,7 @@ void D2SimpleParser::parse(const D2CfgContextPtr& ctx,
dhcp_ddns::NameChangeFormat ncr_format = dhcp_ddns::FMT_JSON;
ip_address = SimpleParser::getAddress(config, "ip-address");
if ((ip_address.toText() == "0.0.0.0") ||
(ip_address.toText() == "::")) {
isc_throw(D2CfgError, "IP address cannot be \""
<< ip_address << "\""
<< " (" << config->get("ip-address")->getPosition() << ")");
}
port = SimpleParser::getUint32(config, "port");
dns_server_timeout = SimpleParser::getUint32(config, "dns-server-timeout");
ncr_protocol = getProtocol(config, "ncr-protocol");