diff --git a/ChangeLog b/ChangeLog index 967f37e09a..1b46dd7a22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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. diff --git a/src/bin/d2/d2_process.cc b/src/bin/d2/d2_process.cc index ab12dd6dad..2eef4a3371 100644 --- a/src/bin/d2/d2_process.cc +++ b/src/bin/d2/d2_process.cc @@ -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. diff --git a/src/bin/d2/tests/d2_cfg_mgr_unittests.cc b/src/bin/d2/tests/d2_cfg_mgr_unittests.cc index 5e27ff8a5c..6699f1c7f9 100644 --- a/src/bin/d2/tests/d2_cfg_mgr_unittests.cc +++ b/src/bin/d2/tests/d2_cfg_mgr_unittests.cc @@ -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\" (:1:17)"); - - // Cannot use IPv6 ANY address - config = makeParamsConfigString ("::", 777, 333, "UDP", "JSON"); - LOGIC_ERROR(config, "IP address cannot be \"::\" (: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, ":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 diff --git a/src/lib/d2srv/d2_config.cc b/src/lib/d2srv/d2_config.cc index a5633f3ff3..c75281b5f6 100644 --- a/src/lib/d2srv/d2_config.cc +++ b/src/lib/d2srv/d2_config.cc @@ -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"); } diff --git a/src/lib/d2srv/d2_messages.cc b/src/lib/d2srv/d2_messages.cc index a35c63cd1c..9439876357 100644 --- a/src/lib/d2srv/d2_messages.cc +++ b/src/lib/d2srv/d2_messages.cc @@ -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.", diff --git a/src/lib/d2srv/d2_messages.h b/src/lib/d2srv/d2_messages.h index 2fcf224577..7c1d2740ad 100644 --- a/src/lib/d2srv/d2_messages.h +++ b/src/lib/d2srv/d2_messages.h @@ -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; diff --git a/src/lib/d2srv/d2_messages.mes b/src/lib/d2srv/d2_messages.mes index 53a7a32771..01c25926c5 100644 --- a/src/lib/d2srv/d2_messages.mes +++ b/src/lib/d2srv/d2_messages.mes @@ -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. diff --git a/src/lib/d2srv/d2_simple_parser.cc b/src/lib/d2srv/d2_simple_parser.cc index c24dfdcc9a..8be6376272 100644 --- a/src/lib/d2srv/d2_simple_parser.cc +++ b/src/lib/d2srv/d2_simple_parser.cc @@ -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");