Commit abf7887a authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[master] Merge branch 'trac5175'

parents fdbb4c57 ab8a956b
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012-2017 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
......@@ -46,6 +46,7 @@
* - @subpage hooksdgDevelopersGuide
* - @subpage dhcpv4Hooks
* - @subpage dhcpv6Hooks
* - @subpage agentHooks
* - @subpage hooksComponentDeveloperGuide
* - @subpage hooksmgMaintenanceGuide
* - @subpage libdhcp_user_chk
......@@ -80,6 +81,11 @@
* - @subpage d2TransDetail
* - @subpage d2StateModel
* - @subpage d2TransExecExample
* - @subpage controlAgent
* - @subpage ctrlAgentHttp
* - @subpage ctrlAgentCreatingResponse
* - @subpage ctrlAgentCommandMgr
* - @subpage CtrlAgentSecurity
* - @subpage lfc
* - @subpage lfcProcessing
* - @subpage lfcFiles
......
......@@ -6,7 +6,7 @@
// 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": "localhost",
"http-host": "127.0.0.1",
// Another mandatory parameter is the HTTP port.
"http-port": 8000,
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY mdash "&#x2017;" >
]>
<chapter id="kea-ctrl-agent">
<title>Kea Control Agent</title>
<section id="agent-overview">
<title>Overview</title>
<para>Kea Control Agent (CA) is a daemon, first included in Kea 1.2, which
exposes a RESTful control interface for managing Kea servers. The daemon
can receive control commands over HTTP and either forward these commands
to the respective Kea servers or handle these commands on its own. The
determination whether the command should be handled by the CA or forwarded
is made by checking the value of the 'service' parameter which may be
included in the command from the controlling client. The details of the
supported commands as well as their structures are provided in
<xref linkend="ctrl-channel"/>.</para>
<para>Hook libraries can be attached to the CA to provide support for
additional commands or custom behavior of existing commands. Such hook
libraries must implement callouts for 'control_command_receive' hook point.
Details about creating new hook libraries and supported hook points can be
found in
<ulink url="https://jenkins.isc.org/job/Kea_doc/doxygen/">Kea Developer's Guide</ulink>.
</para>
<para>
The CA processes received commands according to the following algorithm:
<itemizedlist>
<listitem>
<simpara>
Pass command into any installed hooks (regardless of service value(s)).
If the command is handled by a hook, return the response.
</simpara>
</listitem>
<listitem>
<simpara>
If the service specifies one more or services, the CA will forward the
command to specified services and return the accumulated responses.
</simpara>
</listitem>
<listitem>
<simpara>
If service is not specified or is an empty list, the CA will handle
the command if it supports it.
</simpara>
</listitem>
</itemizedlist>
</para>
</section>
<section id="agent-configuration">
<title>Configuration</title>
<para>The following example demonstrates the basic CA configuration.</para>
<para>
<screen>
{
"Control-agent": {
"http-host": "10.20.30.40",
"http-port": 8080,
"control-sockets": {
"dhcp4-server": {
"socket-type": "unix",
"socket-name": "/path/to/the/unix/socket-v4"
},
"dhcp6-server": {
"socket-type": "unix",
"socket-name": "/path/to/the/unix/socket-v4"
}
},
"hooks-libraries": [
{
"library": "/opt/local/control-agent-commands.so",
"parameters": {
"param1": "foo"
}
} ]
},
"Logging": {
"loggers": [ {
"name": "kea-ctrl-agent",
"severity": "INFO"
} ]
}
}</screen>
</para>
<warning>
<simpara>
In the Kea 1.2 beta release the Control Agent configuration can't be
specified within the same configuration file as DHCPv4, DHCPv6 and D2
configuration. The default configuration file for the CA is installed
in the <filename>etc/kea/kea-ca.conf</filename>. In the Kea 1.2 final
release the CA configuration will be merged into the default
<filename>etc/kea/kea.conf.</filename>
</simpara>
</warning>
<para>
The <command>http-host</command> and <command>http-port</command>
specify an IP address and port to which HTTP service will be bound.
In case of the example configuration provided above, the RESTful
service will be available under the URL of
<command>http://10.20.30.40:8080/</command>. If these parameters
are not specified, the default URL is http://127.0.0.1:8000/
</para>
<para>
It has been mentioned in the <xref linkend="agent-overview"/> that
CA can forward received commands to the specific Kea servers for
processing. For example, <command>config-get</command> is sent to
retrieve configuration of one of the Kea services. When CA receives
this command, including a <command>service</command> parameter
indicating that the client desires to retrieve configuration of
the DHCPv4 server, the CA will forward this command to this server
and then pass the received response back to the client. More about
the <command>service</command> parameter and general structure of
the commands can be found in <xref linkend="ctrl-channel"/>.
</para>
<para>
The CA uses unix domain sockets to forward control commands and receive
responses from other Kea services. The <command>dhcp4-server</command>,
<command>dhcp6-server</command> and <command>d2-server</command> maps
specify the files to which unix domain sockets are bound. In case
of the configuration above, the CA will connect to the DHCPv4 server
via <filename>/path/to/the/unix/socket-v4</filename> to forward the
commands to it. Obviously, the DHCPv4 server must be configured to
listen to connections via this same socket. In other words, the command
socket configuration for the DHCPv4 server and CA (for this server)
must match. Consult the <xref linkend="dhcp4-ctrl-channel"/> and the
<xref linkend="dhcp6-ctrl-channel"/> to learn how the socket
configuration is specified for the DHCPv4 and DHCPv6 services.
</para>
<para>
Hooks libraries can be attached to the Control Agent just like to
DHCPv4 and DHCPv6 servers. It currently supports one hook point
'control_command_receive' which makes it possible to delegate
processing of some commands to the hooks library. The
<command>hooks-libraries</command> list contains the list of hooks
libraries that should be loaded by the CA, along with their configuration
information specified with <command>parameters</command>.
</para>
<para>
Please consult <xref linkend="logging"/> for the details how to
configure logging. The CA's root logger's name is
<command>kea-ctrl-agent</command> as given in the example above.
</para>
</section>
<section id="agent-secure-connection">
<title>Secure Connections</title>
<para>
Control Agent doesn't natively support secure HTTP connections like
SSL or TLS. In order to setup 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.
</para>
</section>
<section id="agent-limitations">
<title>Control Agent Limitations</title>
<para>
Control Agent is a new component, first released in Kea 1.2 beta. In
this release it comes with two notable limitations:
<itemizedlist>
<listitem>
<simpara>
CA configuration must be specified in a separate configuration file
from the configurations of other components. The default confirguation
file for CA is located in <filename>etc/kea/kea-ca.conf</filename>.
</simpara>
</listitem>
<listitem>
<simpara>
keactrl hasn't been updated to manage the Control Agent (start, stop
reload). As a result, the CA must be started directly as described in
<xref linkend="agent-launch"/>
</simpara>
</listitem>
</itemizedlist>
</para>
</section>
<section id="agent-launch">
<title>Starting Control Agent</title>
<para>
The CA is started by running its binary and specifying the configuration file
it should use. For example:
<screen>
$ ./kea-ctrl-agent -c /usr/local/etc/kea/kea-ca.conf
</screen>
</para>
</section>
</chapter>
......@@ -24,14 +24,40 @@
Both servers can be instructed to open control sockets, which
is a communication channel. The server is able to receive
commands on that channel, act on them and report back status.
While the set of commands in Kea 1.1.0 is limited,
While the set of commands in Kea 1.2.0 is limited,
the number is expected to grow over time.</para>
<para>Currently the only supported type of control channel
is UNIX stream socket. For details how to configure it, see
<xref linkend="dhcp4-ctrl-channel" /> and <xref
linkend="dhcp6-ctrl-channel" />. It is likely that support
for other control channel types will be added in the future.
<para>The DHCPv4 and DHCPv6 servers receive commands over the
unix domain sockets. The details how to configure these sockets,
see <xref linkend="dhcp4-ctrl-channel" /> and <xref
linkend="dhcp6-ctrl-channel" />. While it is possible control
the servers directly using unix domain sockets it requires that
the controlling client be running on the same machine as
the server. In order to connect remotely SSH is usually used to
connect to the controlled machine.</para>
<para>The network administrators usually prefer using some form
of a RESTful API to control the servers, rather than using unix
domain sockets directly. Therefore, as of Kea 1.2.0 release,
Kea includes a new component called Control Agent (or CA) which
exposes a RESTful API to the controlling clients and can forward
commands to the respective Kea services over the unix domain
sockets. The CA configuration has been described in
<xref linkend="agent-configuration"/>.</para>
<para>The HTTP requests received by the CA contain the control
commands encapsulated within HTTP requests. Simply speaking,
the CA is responsible for stripping the HTTP layer from the
received commands and forwarding the commands in a JSON format
over the unix domain sockets to respective services. Because the
CA receives commands for all services it requires additional
"forwarding" information to be included in the client's messages.
This "forwarding" information is carried within the
<command>service</command> parameter of the received command.
If the <command>service</command> parameter is not included or if
the parameter is a blank list the CA will assume that the control
command is targetted at the CA itself and will try to handle
it on its own.
</para>
<section id="ctrl-channel-syntax">
......@@ -44,6 +70,7 @@
<screen>
{
"command": "foo",
"service": [ "dhcp4" ]
"arguments": {
"param1": "value1",
"param2": "value2",
......@@ -52,13 +79,86 @@
}
</screen>
The same command sent over the RESTful interface to the CA will have
the following structure.
<screen>
POST / HTTP/1.1\r\n
Content-Type: application/json\r\n
Content-Length: 147\r\n\r\n
{
"command": "foo",
"service": [ "dhcp4" ]
"arguments": {
"param1": "value1",
"param2": "value2",
...
}
}
</screen>
<command>command</command> is the name of command to execute and
is mandatory. <command>arguments</command> is a map of parameters
required to carry out the given command. The exact content and
format of the map is command specific.</para>
<para>The server will process the incoming command and then send a
response of the form:
<para>
<command>service</command> is a list of the servers at which the control
command is targetted. In the example above, the control command is
targetted at the DHCPv4 server. In most cases, the CA will simply forward this
command to the DHCPv4 server for processing via unix domain socket.
Sometimes, the command including a service value may also be processed by the
CA, if the CA is running a hooks library which handles such command for the
given server. As an example, the hooks library attached to the CA
may perform some operations on the database (like adding host reservations,
modifying leases etc.). An advantage of performing DHCPv4 specific
administrative operations in the CA rather than forwarding it to
the DHCPv4 server is the ability to perform these operations without
disrupting the DHCPv4 service (DHCPv4 server doesn't have to stop
processing DHCP messages to apply changes to the database). Nevetheless,
these situations are rather rare and, in most cases, when the
<command>service</command> parameter contains a name of the service
the commands are simply forwarded by the CA. The forwarded command
includes the <command>service</command> parameter but this parameter
is ignored by the receiving server. This parameter is only meaningful
to the CA.
</para>
<para>
If the command received by the CA does not include a <command>service</command>
parameter or this list is empty, the CA will simply process this message
on its own. For example, the <command>config-get</command> command which
doesn't include service parameter will return Control Agent's own
configuration. The <command>config-get</command> including a service
value "dhcp4" will be forwarded to the DHCPv4 server and will return
DHCPv4 server's configuration and so on.
</para>
<para>
The following list contains a mapping of the values carried within the
<command>service</command> parameter to the servers to which the commands
are forwarded:
<itemizedlist>
<listitem>
<simpara><command>dhcp4</command> - the command is forwarded to the
<command>kea-dhcp4</command> server,</simpara>
</listitem>
<listitem>
<simpara><command>dhcp6</command> - the command is forwarded to the
<command>kea-dhcp6</command> server,</simpara>
</listitem>
<listitem>
<simpara><command>d2</command> - the command is forwarded to the
<command>kea-d2</command> server.</simpara>
</listitem>
</itemizedlist>
</para>
<para>The server processing the incoming command will send a response of
the form:
<screen>
{
"result": 0|1,
......@@ -79,23 +179,29 @@
<command>arguments</command> is a map of additional data values returned by
the server which is specific to the command issued. The map is always present, even
if it contains no data values.</para>
<note>
<simpara>
When sending commands via Control Agent, it is possible to specify
multiple services at which the command is targetted. CA will forward this
command to each service individually. Thus, the CA response to the
controlling client will contain an array of individual responses.
</simpara>
</note>
</section>
<section id="ctrl-channel-client">
<title>Using the Control Channel</title>
<para>Kea does not currently provide a client for using the control channel. The primary
reason for this is the expectation is that the entity using the control channel
is typically an IPAM or similar network management/monitoring software which
may have quite varied expectations regarding the client and is even likely to
be written in languages different than C or C++. Therefore only examples are provided to show
how one can take advantage of the API.</para>
<para>The easiest way is to use a tool called <command>socat</command>,
a tool available from <ulink url="http://www.dest-unreach.org/socat/">socat
homepage</ulink>, but it is also widely available in Linux and BSD
distributions. Once Kea is started, one could connect to the control
interface using the following command:
<para>Kea development team is actively working on providing client applications
which can be used to control the servers. These applications are, however, in the
early stages of development and as of Kea 1.2.0 release have certain limitatins.
The easiest way to start playing with the control API is to use common Unix/Linux tools
such as <command>socat</command> and <command>curl</command>.</para>
<para>In order to control the given Kea service via unix domain socket, use
<command>socat</command> as follows:
<screen>
$ socat UNIX:/path/to/the/kea/socket -
</screen>
......@@ -108,6 +214,16 @@ will be sent to Kea and the responses received from Kea printed to standard outp
such a simplistic client written in C is available in the Kea Developer's
Guide, chapter Control Channel Overview, section Using Control Channel.</para>
<para>In order to use Kea's RESTful API with <command>curl</command> try the
following:
<screen>
$ curl -X POST -H "Content-Type: application/json" -d '{ "command": "config-get", "service": [ "dhcp4" ] }' http://ca.example.org:8000/
</screen>
This assumes that the Control Agent is running on host
<filename>ca.example.org</filename> and runs RESTful service on port 8000.
</para>
</section>
<section id="commands-common">
......@@ -404,4 +520,36 @@ will be sent to Kea and the responses received from Kea printed to standard outp
</section> <!-- end of commands supported by both servers -->
<section id="agent-commands">
<title>Commands Supported by Control Agent</title>
<para>The following commands listed in <xref linkend="commands-common"/>
are also supported by the Control Agent, i.e. when the
<command>service</command> parameter is blank the commands are handled
by the CA and they relate to the CA process itself:
<itemizedlist>
<listitem>
<simpara>build-report</simpara>
</listitem>
<listitem>
<simpara>config-get</simpara>
</listitem>
<listitem>
<simpara>config-test</simpara>
</listitem>
<listitem>
<simpara>config-write</simpara>
</listitem>
<listitem>
<simpara>list-commands</simpara>
</listitem>
<listitem>
<simpara>shutdown</simpara>
</listitem>
<listitem>
<simpara>version-get</simpara>
</listitem>
</itemizedlist>
</para>
</section>
</chapter>
......@@ -64,6 +64,8 @@
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="keactrl.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="agent.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="dhcp4-srv.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="dhcp6-srv.xml" />
......
......@@ -181,6 +181,22 @@
Currently defined loggers are:
</para>
<itemizedlist>
<listitem>
<simpara>
<command>kea-ctrl-agent</command> - the root logger for the
Control Agent exposing RESTful control API. All components used
by the Control Agent inherit the settings from this logger.
</simpara>
</listitem>
<listitem>
<simpara>
<command>kea-ctrl-agent.http</command> - a logger which outputs
log messages related to receiving, parsing and sending HTTP
messages.
</simpara>
</listitem>
<listitem>
<simpara>
<command>kea-dhcp4</command> - the root logger for the DHCPv4
......
......@@ -14,6 +14,7 @@ CLEANFILES = *.gcno *.gcda ca_messages.h ca_messages.cc s-messages
man_MANS = kea-ctrl-agent.8
DISTCLEANFILES = $(man_MANS)
EXTRA_DIST = $(man_MANS) kea-ctrl-agent.xml
EXTRA_DIST += agent.dox agent_hooks.dox
if GENERATE_DOCS
kea-ctrl-agent.8: kea-ctrl-agent.xml
......
// Copyright (C) 2017 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
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
/**
@page controlAgent Control Agent Component
Kea 1.2 release has introduced the Control Agent component (CA), which
is started by the "kea-ctrl-agent" binary. The CA exposes a RESTful API
which is used by the administrators to manage Kea servers' instances.
In the most typical case, the CA forwards commands received over the
RESTful API to the respective Kea servers, e.g. DHCPv4 server, DHCPv6
server etc. The communication between the CA and other servers is
established with the use of unix domain sockets. This is possible because
the CA is running on the same system as other Kea services to which
messages are forwarded.
The CA can forward the same command to multiple Kea services and return
an aggregated response (from all services) over the RESTful API. The
"service" parameter included in the client's command can contain one
or more services at which the command is targeted. The CA will
iterate over this list and forward the command to each of them
individually.
In some cases, the commands containing the "service" value can be handled
directly by the CA. This is usually the case when the CA is running
with hooks libraries attached. The hooks libraries must implement
callouts for the "control_command_receive" hook point, which will be
invoked by the CA when the command is received. If the hooks libraries
set the 'skip' status, it is an indication to the CA that the command
has been processed by the CA and that it should return the response created
by the hooks libraries to the client. An example of the hooks library attached
to the CA and handling the commands for other services is a library which
stores or retrieves some data from the SQL database.
The "service" parameter is optional. If it is not included in the command
(or it is an empty list), this indicates that the command relates to the
CA and that the CA should handle it, e.g. return its own configuration in
response to a "config-get" command.
@section ctrlAgentHttp Receiving commands over HTTP
Control Agent uses libkea-http library to establish HTTP connections,
receive messages and send responses over HTTP. This library uses boost ASIO
for creating TCP connections and asynchronously receive and send the data
over the sockets.
The @ref isc::http::HttpListener provides an entry point to this library.
It is used by the CA to bind the acceptor to the specific address and
port. When the client connects to this address and port, the acceptor's
callback function is invoked which opens a new connection and starts
receiving data over that socket. The @ref isc::http::HttpConnection
implements the logic to read and parse received data. Each new TCP
connection is associated with unique instance of the @ref isc::http::HttpConnection
When a portion of data is received (asynchronously) over
the socket it is provided to the instance of the
@ref isc::http::HttpRequestParser object (unique per connection) and
data parsing is continued until the parser runs out of data or until
the entire HTTP request has been received. The
@ref isc::http::HttpRequestParser signals these events using the
@ref isc::http::HttpRequestParser::needData and
@ref isc::http::HttpRequestParser::httpParseOk respectively.
libkea-http is designed to handle processing messages carrying different
content types. The Control Agent uses "application/json" content
type which describes messages with JSON structures carried within the
message body. The JSON structures represent commands sent to the Kea
server(s) by controlling clients. libkea-http provides generic classes
(derived from @ref isc::http::HttpRequest) which facilitate validation of
messages holding various content types.
CA uses @ref isc::http::PostHttpRequestJson, which encapsulate messages
sent using HTTP POST and including JSON content, to represent received messages.
@section ctrlAgentCreatingResponse Creating HTTP responses
The @ref isc::http::HttpResponseCreatorFactory is an interface which should
be implemented by components using libkea-http to generate instances of
the HTTP responses of a desired type. The instance of the factory class is
provided to the @ref isc::http::HttpListener via its constructor. The listener
calls an implementation of the
@ref isc::http::HttpResponseCreatorFactory::create when a new HTTP
message has been received and parsed.
The CA component includes the @ref isc::agent::CtrlAgentResponseCreatorFactory
class. Its @c create() method implementation returns
an instance of the @ref isc::agent::CtrlAgentResponseCreator, which is a
derivation of the @ref isc::http::HttpResponseCreator. This creator creates
instances of the @ref isc::http::HttpResponseJson, holding responses to
the commands in the JSON format.
@section ctrlAgentCommandMgr Handling commands with Command Manager
The @ref isc::agent::CtrlAgentCommandMgr is a derivation of the
@ref isc::config::HookedCommandMgr which adds the capability to forward
commands received over HTTP to specific Kea servers. The
@ref isc::agent::CtrlAgentCommandMgr forwards commands over a Unix domain
socket, using @ref isc::asiolink::UnixDomainSocket class. All responses
to a particular command (possibly received from multiple Kea servers) are
aggregated within a JSON list and sent back to the controlling client over
HTTP.
In some cases the responses may be generated locally (without forwarding).
Typically, the command will be generated by the CA when the command sent
by the client lacks the "service" parameter, which indicates that the
command is targeted at the CA itself. In some cases the commands can also
be processed by the hooks libraries attached to the CA.
@section CtrlAgentSecurity Security considerations
The Control Agent doesn't provide any mechanisms to secure the communication
over the RESTful API. In the design of the CA we have considered including built-in
HTTPS solutions (HTTP + TLS), making use of crypto libraries supported by Kea.
It was eventually decided to not implement the secure layer within Kea for the following reasons:
- additional code complexity which requires maintenance, bug fixing and
monitoring for security vulnerabilities in the OpenSSL/Botan code,
- OpenSSL/Botan code may be awkward to use and it is likely we wouldn't
implement it right,
- need to support two crypto backends: OpenSSL and Botan which puts significant
burden on Kea maintenance.