]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1662] Addressed comments
authorFrancis Dupont <fdupont@isc.org>
Fri, 12 Feb 2021 18:26:16 +0000 (19:26 +0100)
committerFrancis Dupont <fdupont@isc.org>
Wed, 17 Feb 2021 11:54:14 +0000 (12:54 +0100)
ChangeLog
doc/Makefile.am
doc/examples/agent/https.json [new file with mode: 0644]
doc/examples/agent/simple.json
doc/sphinx/arm/agent.rst
src/bin/agent/ca_cfg_mgr.h
src/bin/agent/simple_parser.cc
src/bin/agent/tests/get_config_unittest.cc
src/bin/agent/tests/parser_unittests.cc
src/bin/agent/tests/testdata/get_config.json

index 378a00fb9d159e30610ed54b08c827d76c2d22b3..099169c2bd4fd88ea79838ce5512c40b45b1fb7a 100644 (file)
--- 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
index 89d5e0fad10bcc71180ff88fc7eaf545ee9967f7..56a91d3cbf301ce1fb9f6744e6a84aa0da30e3cc 100644 (file)
@@ -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 (file)
index 0000000..c36269d
--- /dev/null
@@ -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
+    }
+}
index 382280737933615a0cfa513113abc5d123fd9cba..7aa741d33d8d50d253329b449544bf23d3938915 100644 (file)
         // 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":
         {
index 03097a60ae93211cc612a39d140ddd7086ceb35b..8420cedbbde84a4bb80245a510bce4f0aec509c3 100644 (file)
@@ -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
index 4e8a38615f85d92aa93f58eed41f6eef6370cd8b..df4e0f6dc7a521fc5026e03ffdaf8083c390f0b0 100644 (file)
@@ -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_);
     }
index 43a6461c0f714202e47cb26f91eb4c6007131f53..47e302d2a09e5c97e78a53eb380d053beace1cfb 100644 (file)
@@ -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");
     }
 }
 
index 2d557294edc44429e4fb80b3dac5758099751f18..45396ecaf13bf6505209a1322442666e9f0dc7cc 100644 (file)
@@ -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
index ce8176f2651a65a7d0812071bb8e70e909f70502..fab8de357f603b0121ab1025b2a1cf491863cf2e 100644 (file)
@@ -320,6 +320,7 @@ void testFile(const std::string& fname) {
 TEST(ParserTest, file) {
     vector<string> configs;
     configs.push_back("comments.json");
+    configs.push_back("https.json");
     configs.push_back("simple.json");
 
     for (int i = 0; i<configs.size(); i++) {
@@ -758,6 +759,7 @@ TEST(ParserTest, mapEntries) {
     string sample_dir(CFG_EXAMPLES);
     sample_dir += "/";
     ElementPtr sample_json = Element::createList();
+    loadFile(sample_dir + "https.json", sample_json);
     loadFile(sample_dir + "simple.json", sample_json);
     KeywordSet sample_keys;
     // Recursively extract keywords.
index 38a6d47fb5f32b0be34294e4f1fe795225581dbb..f60c521a53824cea46ba87c770bd78ebc19d5fc2 100644 (file)
@@ -13,8 +13,6 @@
             "realm": "kea-control-agent",
             "type": "basic"
         },
-        "cert-file": "my-cert",
-        "cert-required": true,
         "control-sockets": {
             "d2": {
                 "socket-name": "/tmp/kea-ddns-ctrl-socket",
@@ -44,8 +42,6 @@
             }
         ],
         "http-host": "127.0.0.1",
-        "http-port": 8000,
-        "key-file": "my-key",
-        "trust-anchor": "my-ca"
+        "http-port": 8000
     }
 }