From: Francis Dupont Date: Fri, 12 Feb 2021 18:26:16 +0000 (+0100) Subject: [#1662] Addressed comments X-Git-Tag: Kea-1.9.5~95 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2a5e5e8b4c508576aa0ddc3c595dd58d18396db9;p=thirdparty%2Fkea.git [#1662] Addressed comments --- diff --git a/ChangeLog b/ChangeLog index 378a00fb9d..099169c2bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +1864. [func] fdupont + New parameters to handle upcoming TLS support added in + Control Agent config: "trust-anchor", "cert-file", + "key-file" and "cert-required". They can be configured, + but their values are not used yet. This will be + implemented in a future ticket. + (Gitlab #1662) + 1863. [func] andrei The perfdhcp tool now supports the -x l option that exports the assigned leases to stdout in CSV format. This new capability is diff --git a/doc/Makefile.am b/doc/Makefile.am index 89d5e0fad1..56a91d3cbf 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -3,6 +3,7 @@ SUBDIRS = sphinx devel EXTRA_DIST = images/kea-logo-100x70.png nobase_dist_doc_DATA = examples/agent/comments.json +nobase_dist_doc_DATA += examples/agent/https.json nobase_dist_doc_DATA += examples/agent/simple.json nobase_dist_doc_DATA += examples/ddns/comments.json nobase_dist_doc_DATA += examples/ddns/sample1.json diff --git a/doc/examples/agent/https.json b/doc/examples/agent/https.json new file mode 100644 index 0000000000..c36269d5e7 --- /dev/null +++ b/doc/examples/agent/https.json @@ -0,0 +1,28 @@ +// This is an example of a configuration for Control-Agent (CA) HTTPS i.e. +// HTTP over TLS. +{ + "Control-agent": + { + // We need to specify where the agent should listen to incoming HTTP + // queries. Note that agent does not provide SSL or TLS protection + // on its own, so limiting the traffic to localhost is a good idea. + "http-host": "127.0.0.1", + + // Another mandatory parameter is the HTTP port. + "http-port": 8000, + + // TLS trust anchor (Certificate Authority). This is a file name or + // (for OpenSSL only) a directory path. + "trust-anchor": "my-ca", + + // TLS server certificate file name. + "cert-file": "my-cert", + + // TLS server private key file name. + "key-file": "my-key", + + // TLS require client certificates flag. Default is true and means + // require client certificates. False means they are optional. + "cert-required": true + } +} diff --git a/doc/examples/agent/simple.json b/doc/examples/agent/simple.json index 3822807379..7aa741d33d 100644 --- a/doc/examples/agent/simple.json +++ b/doc/examples/agent/simple.json @@ -11,20 +11,6 @@ // Another mandatory parameter is the HTTP port. "http-port": 8000, - // TLS trust anchor aka Certificate Authority. A file name or - // with OpenSSL a directory path. - "trust-anchor": "my-ca", - - // TLS server certificate file name. - "cert-file": "my-cert", - - // TLS server private key file name. - "key-file": "my-key", - - // TLS require client certificates flag. Default is true and means - // require client certificates. False means they are optional. - "cert-required": true, - // Optional authentication. "authentication": { diff --git a/doc/sphinx/arm/agent.rst b/doc/sphinx/arm/agent.rst index 03097a60ae..8420cedbbd 100644 --- a/doc/sphinx/arm/agent.rst +++ b/doc/sphinx/arm/agent.rst @@ -50,6 +50,10 @@ The following example demonstrates the basic CA configuration. "Control-agent": { "http-host": "10.20.30.40", "http-port": 8000, + "trust-anchor": "/path/to/the/ca-cert.pem", + "cert-file": "/path/to/the/agent-cert.pem", + "key-file": "/path/to/the/agent-key.pem", + "cert-required": true, "authentication": { "type": "basic", "realm": "kea-control-agent", @@ -95,9 +99,13 @@ The following example demonstrates the basic CA configuration. The ``http-host`` and ``http-port`` parameters specify an IP address and port to which HTTP service will be bound. In the example configuration provided above, the RESTful service will be available under the URL of -``http://10.20.30.40:8000/``. If these parameters are not specified, the +``https://10.20.30.40:8000/``. If these parameters are not specified, the default URL is ``http://127.0.0.1:8000/``. +The ``trust-anchor``, ``cert-file``, ```key-file`` and ``cert-required`` +parameters specify the TLS setup for HTTP i.e. HTTPS. If these parameters +are not specified HTTP is used. + As mentioned in :ref:`agent-overview`, the CA can forward received commands to the Kea servers for processing. For example, ``config-get`` is sent to retrieve the configuration of one of the Kea @@ -179,11 +187,13 @@ the example above. .. _agent-secure-connection: -Secure Connections -================== +Secure Connections (version before 1.9.5) +========================================= The Control Agent does not natively support secure HTTP connections like -SSL or TLS. In order to setup a secure connection, please use one of the +SSL or TLS before version 1.9.5. + +In order to setup a secure connection, please use one of the available third-party HTTP servers and configure it to run as a reverse proxy to the Control Agent. Kea has been tested with two major HTTP server implementations working as a reverse proxy: Apache2 and nginx. @@ -287,6 +297,50 @@ can use an HTTP/HTTPS translator such as stunnel in client mode. A sample configuration is provided in the ``doc/examples/https/shell/`` directory. +Secure Connections (since version 1.9.5) +======================================== + +Since the Kea version 1.9.5 the Control Agent natively supports secure +HTTP connections using TLS. This allows a protection against users from +the node where the agent runs, something that a reverse proxy cannot +provide. + +TLS is configured using three string parameters giving file names and +a boolean parameter: + +- The ``trust-anchor`` specifies the Certificate Authority file name or + with OpenSSL backend directory path. + +- The ``cert-file`` specifies the server certificate file name. + +- The ``key-file`` specifies the private key file name. The file must not + be encrypted. + +- The ``cert-required`` specifies whether client certificates are required + or optional. The default is to require them and to perform mutual + authentication. + +The file format is PEM. Either all the string parameters are specified and +HTTP over TLS aka HTTPS is used, or none is specified and plain HTTP is used. +Configuring only one or two string parameters is an error. + +.. note:: + + When client certificates are not required only the server side is + authenticated i.e. the communication is encrypted with an unknown client. + This protects only against passive attacks, active attacks as Man in the + Middle is still possible. + +.. note:: + + No standard HTTP authentication scheme cryptographically bind its end + entity with TLS. This means that the TLS client and server can be + mutually authenticated but there is no proof they are the same as + the HTTP authentication. To summary a Man in the Middle attack is + still possible when both HTTPS and HTTP authentication are used. + +Since the Kea version 1.9.5 the ``kea-shell`` tool supports TLS. + .. _agent-launch: Starting the Control Agent diff --git a/src/bin/agent/ca_cfg_mgr.h b/src/bin/agent/ca_cfg_mgr.h index 4e8a38615f..df4e0f6dc7 100644 --- a/src/bin/agent/ca_cfg_mgr.h +++ b/src/bin/agent/ca_cfg_mgr.h @@ -171,7 +171,7 @@ public: /// @brief Returns cert-required parameter /// /// @return True when client certificates are required, false when they - /// are optional, the default is to required them (true). + /// are optional, the default is to require them (true). bool getCertRequired() const { return (cert_required_); } diff --git a/src/bin/agent/simple_parser.cc b/src/bin/agent/simple_parser.cc index 43a6461c0f..47e302d2a0 100644 --- a/src/bin/agent/simple_parser.cc +++ b/src/bin/agent/simple_parser.cc @@ -105,24 +105,25 @@ AgentSimpleParser::checkTlsSetup(const isc::data::ConstElementPtr& config) { ConstElementPtr ca = config->get("trust-anchor"); ConstElementPtr cert = config->get("cert-file"); ConstElementPtr key = config->get("key-file"); - if (ca && !ca->stringValue().empty()) { - if (!cert || cert->stringValue().empty()) { - isc_throw(ConfigError, "trust-anchor is set but not cert-file:" - " all or none of TLS parameters must be set"); - } - if (!key || key->stringValue().empty()) { - isc_throw(ConfigError, "cert-file is set but not key-file:" - " all or none of TLS parameters must be set"); - } - } else { - if (cert && !cert->stringValue().empty()) { - isc_throw(ConfigError, "cert-file is set but not trust-anchor:" - " all or none of TLS parameters must be set"); - } - if (key && !key->stringValue().empty()) { - isc_throw(ConfigError, "key-file is set but not cert-file:" - " all or none of TLS parameters must be set"); - } + bool have_ca = (ca && !ca->stringValue().empty()); + bool have_cert = (cert && !cert->stringValue().empty()); + bool have_key = (key && !key->stringValue().empty()); + if (!have_ca && !have_cert && !have_key) { + // No TLS parameter so TLS is not used. + return; + } + // TLS is used: all 3 parameters are required. + if (!have_ca) { + isc_throw(ConfigError, "trust-anchor parameter is missing or empty:" + " all or none of TLS parameters must be set"); + } + if (!have_cert) { + isc_throw(ConfigError, "cert-file parameter is missing or empty:" + " all or none of TLS parameters must be set"); + } + if (!have_key) { + isc_throw(ConfigError, "key-file parameter is missing or empty:" + " all or none of TLS parameters must be set"); } } diff --git a/src/bin/agent/tests/get_config_unittest.cc b/src/bin/agent/tests/get_config_unittest.cc index 2d557294ed..45396ecaf1 100644 --- a/src/bin/agent/tests/get_config_unittest.cc +++ b/src/bin/agent/tests/get_config_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2017-2021 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2017-2020 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this diff --git a/src/bin/agent/tests/parser_unittests.cc b/src/bin/agent/tests/parser_unittests.cc index ce8176f265..fab8de357f 100644 --- a/src/bin/agent/tests/parser_unittests.cc +++ b/src/bin/agent/tests/parser_unittests.cc @@ -320,6 +320,7 @@ void testFile(const std::string& fname) { TEST(ParserTest, file) { vector configs; configs.push_back("comments.json"); + configs.push_back("https.json"); configs.push_back("simple.json"); for (int i = 0; i