hooks.xml 110 KB
Newer Older
1
2
3
4
5
6
7
<!--
 - Copyright (C) 2014-2018 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/.
-->
Tomek Mrugalski's avatar
Tomek Mrugalski committed
8

9
10
<!-- Converted by db4-upgrade version 1.1 -->
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="hooks-libraries">
11
12

    <title>Hooks Libraries</title>
13
    <section xml:id="hooks-libraries-introduction">
14
15
16
      <title>Introduction</title>
      <para>
      Although Kea offers a lot of flexibility, there may be cases where
Josh Soref's avatar
Josh Soref committed
17
      its behavior needs customization.  To accommodate this possibility,
18
19
20
21
22
23
24
25
26
27
28
29
30
31
      Kea includes the idea of "Hooks".  This feature lets Kea load one
      or more dynamically-linked libraries (known as "hooks libraries")
      and, at various points in its processing ("hook points"), call
      functions in them.  Those functions perform whatever custom
      processing is required.
      </para>
      <para>
      Hooks libraries are attached to individual Kea processes, not to
      Kea as a whole.  This means (for example) that it is possible
      to associate one set of libraries with the DHCP4 server and a
      different set to the DHCP6 server.
      </para>
      <para>
      Another point to note is that it is possible for a process to
32
33
34
35
36
37
      load multiple libraries.  When processing reaches a hook point,
      Kea calls the hooks library functions attached to it.  If multiple
      libraries have attached a function to a given hook point, Kea calls
      all of them, in the order in which the libraries are specified in
      the configuration file. The order may be important: consult the
      documentation of the libraries to see if this is the case.
38
39
40
41
      </para>
      <para>
      The next section describes how to configure hooks libraries. If you
      are interested in writing your own hooks library, information can be
42
43
      found in the <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://jenkins.isc.org/job/Fedora20_32_doxygen_doc/doxygen/">Kea
      Developer's Guide</link>.
44
45
46
47
48
49
50
51
52
      </para>
    </section> <!-- end Introduction -->
    <section>
      <title>Configuring Hooks Libraries</title>
      <para>
      The hooks libraries for a given process are configured using the
      <command>hooks-libraries</command> keyword in the
      configuration for that process. (Note that
      the word "hooks" is plural).  The value of the keyword
53
54
55
      is an array of map structures, each structure corresponding to a hooks
      library.  For example, to set up two hooks libraries for the DHCPv4
      server, the configuration would be:
56
57
58
59
<screen>
<userinput>"Dhcp4": {
    :
    "hooks-libraries": [
60
61
62
63
        {
            "library": "/opt/charging.so"
        },
        {
Tomek Mrugalski's avatar
Tomek Mrugalski committed
64
65
66
67
68
69
70
71
72
73
74
            "library": "/opt/local/notification.so",
            "parameters": {
                "mail": "spam@example.com",
                "floor": 13,
                "debug": false,
                "users": [ "alice", "bob", "charlie" ],
                "languages": {
                    "french": "bonjour",
                    "klingon": "yl'el"
                }
            }
75
        }
76
77
78
79
80
    ]
    :
}</userinput>
</screen>
      </para>
81

82
      <note><para>
83
84
        This is a change to the syntax used in Kea 0.9.2 and earlier, where
        hooks-libraries was a list of strings, each string being the name of
85
        a library.  The change was made in Kea 1.0 to facilitate the
86
        specification of library-specific parameters, a capability
87
        available in Kea 1.1.0 onwards. Libraries should allow a parameter
88
        entry where to put comments as it is done for many configuration
89
        scopes with comment and user context.
90
      </para></note>
Tomek Mrugalski's avatar
Tomek Mrugalski committed
91

92
93
        <note>
          <para>
Tomek Mrugalski's avatar
Tomek Mrugalski committed
94
95
96
97
          The library reloading behavior has changed in Kea 1.1. Libraries are
          reloaded, even if their list hasn't changed. Kea does that, because
          the parameters specified for the library (or the files those
          parameters point to) may have changed.
98
99
          </para>
        </note>
Tomek Mrugalski's avatar
Tomek Mrugalski committed
100
101
102
103
104
105
106
107
108
109
110

      <para>
        Libraries may have additional parameters. Those are not mandatory in the
        sense that there may be libraries that don't require them. However, for
        specific library there is often specific requirement for specify certain
        set of parameters. Please consult the documentation for your library
        for details. In the example above, the first library has no parameters.
        The second library has five parameters, specifying mail (string
        parameter), floor (integer parameter), debug (boolean parameter) and
        even lists (list of strings) and maps (containing strings). Nested
        parameters could be used if the library supports it. This topic is
111
112
        explained in detail in the Hooks Developer's Guide in the "Configuring
        Hooks Libraries" section.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
113
114
      </para>

115
116
      <para>
      Notes:
117
        <itemizedlist mark="bullet">
118
119
120
121
122
123
124
125
126
127
          <listitem><para>
          The full path to each library should be given.
          </para></listitem>
          <listitem><para>
          As noted above, order may be important - consult the documentation for
          each library.
          </para></listitem>
          <listitem><para>
          An empty list has the same effect as omitting the
          <command>hooks-libraries</command> configuration element all together.
Stephen Morris's avatar
Stephen Morris committed
128
129
130
131
132
133
134
135
136
137
138
139
          </para>
          <note><para>
          There is one case where this is not true: if Kea
          is running with a configuration that contains a
          <command>hooks-libraries</command> item, and that item is
          removed and the configuration reloaded, the removal will be
          ignored and the libraries remain loaded.  As a workaround,
          instead of removing the <command>hooks-libraries</command>
          item, change it to an empty list.  This will be fixed in a
          future version of Kea.
          </para></note>
          </listitem>
140
141
142
143
144
145
146
        </itemizedlist>
      </para>
      <para>
      At the present time, only the kea-dhcp4 and kea-dhcp6 processes support
      hooks libraries.
      </para>
    </section>
147
148
149
150

    <section>
      <title>Available Hooks Libraries</title>
      <para>
151
      As described above, the hooks functionality provides a way to customize
152
      a Kea server without modifying the core code.  ISC has chosen to take
153
154
155
      advantage of this feature to provide functions that may only be useful
      to a subset of Kea users.  To this end ISC has created some hooks
      libraries; these discussed in the following sections.
156
157
      </para>

158
159
      <note><para>
      Some of these libraries will be available with the base code while others
160
161
      will be shared with organizations supporting development of Kea
      , possibly as a 'benefit' or 'thank you' for helping to sustain
162
      the larger Kea project. If you would like to get access to those
163
      libraries, please consider taking out a support contract: this includes
164
      professional support, advance security notifications, input into our
165
      roadmap planning, and many other benefits, while helping
166
167
168
169
170
      making Kea sustainable in the long term.
      </para></note>

      <para>Currently the following libraries are available or planned from ISC:

171
        <table frame="all" xml:id="hook-libs">
172
          <title>List of available hooks libraries</title>
173
174
175
176
          <tgroup cols="3">
          <colspec colname="name"/>
          <colspec colname="avail"/>
          <colspec colname="description"/>
177
178
179
180
181
182
183
184
185
186
187
188
189
190
          <thead>
            <row>
              <entry>Name</entry>
              <entry>Availability</entry>
              <entry>Since</entry>
              <entry>Description</entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry>user_chk</entry>
              <entry>Kea sources</entry>
              <entry>Kea 0.8</entry>
191
192
              <entry>Reads known users list from a file. Unknown users
              will be assigned a
193
              lease from the last subnet defined in the configuration file,
194
195
196
197
              e.g. to redirect them a captive portal. This demonstrates how an
              external source of information can be used to influence the Kea
              allocation engine. This hook is part of the Kea source code and is
              available in the src/hooks/dhcp/user_chk directory.</entry>
198
199
200
201
202
            </row>
            <row>
              <entry>Forensic Logging</entry>
              <entry>Support customers</entry>
              <entry>Kea 1.1.0</entry>
203
              <entry>This library provides hooks that record a detailed log of
204
205
206
207
208
209
              lease assignments and renewals into a set of log files. In many
              legal jurisdictions companies, especially ISPs, must record
              information about the addresses they have leased to DHCP
              clients. This library is designed to help with that
              requirement. If the information that it records is sufficient it
              may be used directly. If your jurisdiction requires that you save
210
              a different set of information, you may use it as a template or
211
212
213
              example and create your own custom logging hooks.</entry>
            </row>
            <row>
Francis Dupont's avatar
Francis Dupont committed
214
              <entry>Flexible Identifier</entry>
215
              <entry>Support customers</entry>
216
              <entry>Kea 1.2.0</entry>
217
218
219
220
              <entry>Kea software provides a way to handle host reservations
              that include addresses, prefixes, options, client classes and
              other features. The reservation can be based on hardware address,
              DUID, circuit-id or client-id in DHCPv4 and using hardware address
221
              or DUID in DHCPv6. However, there are sometimes scenarios where the
222
223
224
              reservation is more complex, e.g. uses other options that
              mentioned above, uses part of specific options or perhaps even a
              combination of several options and fields to uniquely identify a
Tomek Mrugalski's avatar
Tomek Mrugalski committed
225
              client. Those scenarios are addressed by the Flexible Identifiers
226
              hook application. It allows defining an expression, similar to
Francis Dupont's avatar
Francis Dupont committed
227
              the one used in client classification,
228
229
230
              e.g. substring(relay6[0].option[37],0,6). Each incoming packet is
              evaluated against that expression and its value is then searched
              in the reservations database.
231
232
              </entry>
            </row>
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
            <row>
              <entry>Host Commands</entry>
              <entry>Support customers</entry>
              <entry>Kea 1.2.0</entry>
              <entry>Kea provides a way to store host reservations in a
              database. In many larger deployments it is useful to be able to
              manage that information while the server is running. This library
              provides management commands for adding, querying and deleting
              host reservations in a safe way without restarting the server.
              In particular, it validates the parameters, so an attempt to
              insert incorrect data, e.g. add a host with conflicting identifier
              in the same subnet will be rejected. Those commands are
              exposed via command channel (JSON over unix sockets) and Control
              Agent (JSON over RESTful interface). Additional commands and
              capabilities related to host reservations will be added in the
              future.</entry>
            </row>
250
251
252
253
            <row>
              <entry>Subnet Commands</entry>
              <entry>Support customers</entry>
              <entry>Kea 1.3.0</entry>
254
255
256
              <entry>In deployments in which subnet configuration needs to
              be frequently updated, it is a hard requirement that such updates be
              performed without the need for a full DHCP server reconfiguration
257
              or restart. This hooks library allows for incremental changes
258
              to the subnet configuration such as: adding a subnet, removing
259
260
261
262
263
264
              a subnet. It also allows for listing all available subnets and
              fetching detailed information about a selected subnet. The
              commands exposed by this library do not affect other subnets
              or configuration parameters currently used by the server.
              </entry>
            </row>
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
            <row>
              <entry>High Availability</entry>
              <entry>Support customers</entry>
              <entry>Kea 1.4.0</entry>
              <entry>Minimizing a risk of DHCP service unavailability is achieved
              by setting up multiple instances of the DHCP servers in a network.
              Each server can serve selected group of clients in this network
              (load balancing) or all clients, if it detects that its partner has
              crashed or cannot be providing DHCP service for any other reason.
              It is also possible to designate one server to serve all DHCP clients,
              and leave another server as "standby". This server will activate its
              DHCP function when it detects that its partner is not available.
              Such cooperation between the DHCP servers requires that these
              servers constantly communicate with each other to send updates about
              allocated leases and to periodically test whether their partners are still
              operational. The "libdhcp_ha" library provides such functionality for
              Kea DHCP.
              </entry>
            </row>
284
285
286
287
288
          </tbody>
          </tgroup>
          </table>

      </para>
289
      <para>
290
        ISC hopes to see more hooks libraries become available as time
291
        progresses, both developed internally and externally. Since
292
        this list may evolve dynamically, we decided to keep it on a
293
        wiki page, available at this link: <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://kea.isc.org/wiki/Hooks">http://kea.isc.org/wiki/Hooks</link>.
294
295
        If you are a developer or are aware of any hooks libraries not
        listed there, please send a note to the kea-users or kea-dev
296
        mailing lists and someone will update it.
297
      </para>
298
      <section>
299
        <title>user_chk: Checking User Access</title>
300
        <para>
301
          The user_chk library is the first hooks library published by ISC. It
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
          attempts to serve several purposes:

          <itemizedlist>
            <listitem>
              <para>To assign "new" or "unregistered" users to a
              restricted subnet, while "known" or "registered" users are assigned
              to unrestricted subnets.</para>
            </listitem>
            <listitem>
              <para>To allow DHCP response options or vendor option
              values to be customized based upon user identity. </para>
            </listitem>
            <listitem>
              <para>To provide a real time record of the user registration
              activity which can be sampled by an external consumer.</para>
            </listitem>
            <listitem>
              <para> To serve as a demonstration of various capabilities
320
              possible using the hooks interface.</para>
321
322
323
324
            </listitem>
          </itemizedlist>
        </para>
        <para>
Francis Dupont's avatar
Francis Dupont committed
325
          Once loaded, the library allows segregating incoming requests into
326
327
328
329
330
331
332
333
          known and unknown clients. For known clients, the packets are
          processed mostly as usual, except it is possible to override certain
          options being sent. That can be done on a per host basis. Clients
          that are not on the known hosts list will be treated as unknown and
          will be assigned to the last subnet defined in the configuration file.
        </para>

        <para>
334
          As an example of use, this behavior may be used to put unknown users into a
335
336
          separate subnet that leads to a walled garden, where they can only
          access a registration portal. Once they fill in necessary data, their
337
          details are added to the known clients file and they get a proper
338
339
340
          address after their device is restarted.
        </para>

341
342
343
344
        <note><para>This library was developed several years before the host
        reservation mechanism has become available. Currently host reservation is
        much more
        powerful and flexible, but nevertheless the user_chk capability to consult
345
        and external source of information about clients and alter Kea's
346
        behavior is useful and remains of educational value.
347
348
349
350
        </para></note>

        <para>
          The library reads the /tmp/user_chk_registry.txt file while being
351
          loaded and each time an incoming packet is processed. The file is expected
352
353
354
355
          to have each line contain a self-contained JSON snippet which must
          have the following two entries:

          <itemizedlist>
356
357
358
359
            <listitem><para><command>type</command>, whose value
            is "HW_ADDR" for IPv4 users or "DUID" for IPv6
            users</para></listitem>
            <listitem><para><command>id</command>, whose value is
Francis Dupont's avatar
Francis Dupont committed
360
            either the hardware address or the DUID from the request
361
362
            formatted as a string of hex digits, with or without
            ":" delimiters.</para></listitem>
363
364
365
366
367
          </itemizedlist>

and may have the zero or more of the following entries:

          <itemizedlist>
368
369
370
371
372
            <listitem><para><command>bootfile</command> whose value
            is the pathname of the desired file</para></listitem>
            <listitem><para><command>tftp_server</command> whose
            value is the hostname or IP address of the desired
            server</para></listitem>
373
374
          </itemizedlist>

375
          A sample user registry file is shown below:
376
377
378
379
380
381
382
383

<screen>{ "type" : "HW_ADDR", "id" : "0c:0e:0a:01:ff:04", "bootfile" : "/tmp/v4bootfile" }
{ "type" : "HW_ADDR", "id" : "0c:0e:0a:01:ff:06", "tftp_server" : "tftp.v4.example.com" }
{ "type" : "DUID", "id" : "00:01:00:01:19:ef:e6:3b:00:0c:01:02:03:04", "bootfile" : "/tmp/v6bootfile" }
{ "type" : "DUID", "id" : "00:01:00:01:19:ef:e6:3b:00:0c:01:02:03:06", "tftp_server" : "tftp.v6.example.com" }</screen>

        </para>

384
        <para>As with any other hooks libraries provided by ISC, internals of the
385
        user_chk code are well documented. You can take a look at the  <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://jenkins.isc.org/job/Fedora20_32_doxygen_doc/doxygen/d8/db2/libdhcp_user_chk.html">Kea Developer's Guide section dedicated to the user_chk library</link>
386
        that discusses how the code works internally. That, together with
387
388
        our general entries in <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://jenkins.isc.org/job/Fedora20_32_doxygen_doc/doxygen/">Hooks
        Framework section</link> should give you some pointers how to extend
389
390
        this library and perhaps even write your own from scratch.</para>

391
      </section>
392
      <section>
393
        <title>legal_log: Forensic Logging Hooks</title>
394
        <para>
395
        This section describes the forensic log hooks library. This library
Francis Dupont's avatar
Francis Dupont committed
396
        provides hooks that record a detailed log of lease assignments
397
        and renewals into a set of log files.  Currently this library
398
        is only available to ISC customers with a support contract.
399
400
401
402
403
404
405
406
407
408
        </para>
        <para>
        In many legal jurisdictions companies, especially ISPs, must record
        information about the addresses they have leased to DHCP clients.
        This library is designed to help with that requirement.  If the
        information that it records is sufficient it may be used directly.
        If your jurisdiction requires that you save a different set of
        information you may use it as a template or example and create your
        own custom logging hooks.
        </para>
409
410
411
412
413
414
415
        <para>
        This logging is done as a set of hooks to allow it to be customized
        to any particular need.  Modifying a hooks library is easier and
        safer than updating the core code.  In addition by using the hooks
        features those users who don't need to log this information can
        leave it out and avoid any performance penalties.
        </para>
416
417
418
419
420
421
422
423
424
        <section>
        <title>Log File Naming</title>
          <para>
          The names for the log files have the following form:
          </para>
<screen>
path/base-name.CCYYMMDD.txt
</screen>
          <para>
425
          The "path" and "base-name" are supplied in the
426
          configuration as described below see
427
          <xref linkend="forensic-log-configuration"/>.  The next part of the name is
428
429
430
431
432
          the date the log file was started, with four digits for year, two digits
          for month and two digits for day.  The file is rotated on a daily basis.
          </para>
          <note><para>
          When running Kea servers for both DHCPv4 and DHCPv6 the log names must
433
          be distinct.  See the examples in <xref linkend="forensic-log-configuration"/>.
434
435
436
437
438
439
440
441
442
443
          </para></note>
        </section>
        <section>
        <title>DHCPv4 Log Entries</title>
          <para>
          For DHCPv4 the library creates entries based on DHCPREQUEST messages
          and corresponding DHCPv4 leases intercepted by lease4_select
          (for new leases) and lease4_renew (for renewed leases) hooks.
          </para>
          <para>
Francis Dupont's avatar
Francis Dupont committed
444
445
          An entry is a single string with no embedded end-of-line markers,
          a prepended timestamp and has the following sections:
446
<screen>
Francis Dupont's avatar
Francis Dupont committed
447
timestamp address duration device-id {client-info} {relay-info}
448
449
450
451
452
</screen>
          </para>
          <para>
          Where:
          <itemizedlist>
Francis Dupont's avatar
Francis Dupont committed
453
454
455
456
457
            <listitem><para>
            timestamp - the current date and time the log entry was written
            in "%Y-%m-%d %H:%M:%S %Z" strftime format ("%Z" is the time zone
            name).
            </para></listitem>
458
459
460
461
462
463
464
            <listitem><para>
            address - the leased IPv4 address given out and whether it was
            assigned or renewed.
            </para></listitem>
            <listitem><para>
            duration - the lease lifetime expressed in days (if present),
            hours, minutes and seconds.  A lease lifetime of 0xFFFFFFFF will be
465
            denoted with the text "infinite duration".
466
467
468
469
470
471
472
473
474
475
            </para></listitem>
            <listitem><para>
            device-id - the client's hardware address shown as numerical type
            and hex digit string.
            </para></listitem>
            <listitem><para>
            client-info - the DHCP client id option (61) if present, shown as
            a hex string.
            </para></listitem>
            <listitem><para>
Tomek Mrugalski's avatar
Tomek Mrugalski committed
476
477
478
            relay-info - for relayed packets the giaddr and the RAI circuit-id,
            remote-id and subscriber-id options (option 82 sub
            options: 1, 2 and 6) if present.
479
480
481
482
483
484
485
486
            The circuit id and remote id are presented as hex strings
            </para></listitem>
          </itemizedlist>
          </para>
          <para>
          For instance (line breaks added for readability, they would not
          be present in the log file).
<screen>
Francis Dupont's avatar
Francis Dupont committed
487
2018-01-06 01:02:03 CET Address: 192.2.1.100 has been renewed for 1 hrs 52 min 15 secs to a device with hardware address: hwtype=1 08:00:2b:02:3f:4e, client-id: 17:34:e2:ff:09:92:54 connected via relay at address: 192.2.16.33, identified by circuit-id: 68:6f:77:64:79 and remote-id: 87:f6:79:77:ef
488
</screen>
489
490
491
492
493
494
495
496
497
498
499
        </para>
        <para>
        In addition to logging lease activity driven by DHCPv4 client traffic, it also
        logs entries for the following lease management control channel commands:
        lease4-add, lease4-update, and lease4-del.  Each entry is a single string
        with no embedded end-of-line markers and they will typically have the following
        forms:
        </para>
        <para>
        <command>lease4-add:</command>
<screen>
Francis Dupont's avatar
Francis Dupont committed
500
*timestamp* Administrator added a lease of address: *address* to a device with hardware address: *device-id*
501
502
503
504
505
506
507
</screen>
        Dependent on the arguments of the add command, it may also include the
        client-id and duration.
        </para>
        <para>
        Example:
<screen>
Francis Dupont's avatar
Francis Dupont committed
508
2018-01-06 01:02:03 CET Administrator added a lease of address: 192.0.2.202 to a device with hardware address: 1a:1b:1c:1d:1e:1f for 1 days 0 hrs 0 mins 0 secs
509
510
511
512
513
</screen>
        </para>
        <para>
        <command>lease4-update:</command>
<screen>
Francis Dupont's avatar
Francis Dupont committed
514
*timestamp* Administrator updated information on the lease of address: *address* to a device with hardware address: *device-id*
515
516
517
518
519
520
521
</screen>
        Dependent on the arguments of the update command, it may also include the
        client-id and lease duration.
        </para>
        <para>
        Example:
<screen>
Francis Dupont's avatar
Francis Dupont committed
522
2018-01-06 01:02:03 CET Administrator updated information on the lease of address: 192.0.2.202 to a device with hardware address: 1a:1b:1c:1d:1e:1f, client-id: 1234567890
523
524
525
526
527
528
</screen>
        </para>
        <para>
        <command>lease4-del:</command>
        Deletes have two forms, one by address and one by identifier and identifier type:
<screen>
Francis Dupont's avatar
Francis Dupont committed
529
*timestamp* Administrator deleted the lease for address: *address*
530
531
532
</screen>
        or
<screen>
Francis Dupont's avatar
Francis Dupont committed
533
*timestamp* Administrator deleted a lease for a device identified by: *identifier-type* of *identifier*
534
535
536
537
538
539
</screen>
        Currently only a type of @b hw-address (hardware address) is supported.
        </para>
        <para>
        Examples:
<screen>
Francis Dupont's avatar
Francis Dupont committed
540
2018-01-06 01:02:03 CET Administrator deleted the lease for address: 192.0.2.202
541

Francis Dupont's avatar
Francis Dupont committed
542
2018-01-06 01:02:12 CET Administrator deleted a lease for a device identified by: hw-address of 1a:1b:1c:1d:1e:1f
543
544
</screen>
        </para>
545
        </section>
546

547
548
549
550
551
552
553
554
        <section>
        <title>DHCPv6 Log Entries</title>
          <para>
          For DHCPv6 the library creates entries based on lease management
          actions intercepted by the lease6_select (for new leases), lease6_renew
          (for renewed leases) and lease6_rebind (for rebound leases).
          </para>
          <para>
Francis Dupont's avatar
Francis Dupont committed
555
556
          An entry is a single string with no embedded end-of-line markers,
          a prepended timestamp and has the following sections:
557
<screen>
Francis Dupont's avatar
Francis Dupont committed
558
timestamp address duration device-id {relay-info}*
559
560
561
562
563
</screen>
          </para>
          <para>
          Where:
          <itemizedlist>
Francis Dupont's avatar
Francis Dupont committed
564
565
566
567
568
            <listitem><para>
            timestamp - the current date and time the log entry was written
            in "%Y-%m-%d %H:%M:%S %Z" strftime format ("%Z" is the time zone
            name).
            </para></listitem>
569
570
571
572
573
574
575
576
577
578
579
580
581
582
            <listitem><para>
            address - the leased IPv6 address or prefix given out and whether
            it was assigned or renewed.
            </para></listitem>
            <listitem><para>
            duration - the lease lifetime expressed in days (if present),
            hours, minutes and seconds.  A lease lifetime of 0xFFFFFFFF will be
            denoted with the text "infinite duration".
            </para></listitem>
            <listitem><para>
            device-id - the client's DUID and hardware address (if present).
            </para></listitem>
            <listitem><para>
            relay-info - for relayed packets the content of relay agent
Tomek Mrugalski's avatar
Tomek Mrugalski committed
583
584
585
586
587
588
589
            messages, remote-id (code 37), subscriber-id (code 38) and
            interface-id (code 18) options if present. Note that
            interface-id option, if present, identifies the whole interface the
            relay agent received the message on. This typically translates to a
            single link in your network, but it depends on your specific network
            topology. Nevertheless, this is useful information to better scope
            down the location of the device, so it is being recorded, if present.
590
591
592
593
594
595
596
            </para></listitem>
          </itemizedlist>
          </para>
          <para>
          For instance (line breaks added for readability, they would not
          be present in the log file).
<screen>
Francis Dupont's avatar
Francis Dupont committed
597
2018-01-06 01:02:03 PST Address:2001:db8:1:: has been assigned for 0 hrs 11 mins 53 secs to a device with DUID: 17:34:e2:ff:09:92:54 and hardware address: hwtype=1 08:00:2b:02:3f:4e (from Raw Socket) connected via relay at address: fe80::abcd for client on link address: 3001::1, hop count: 1, identified by remote-id: 01:02:03:04:0a:0b:0c:0d:0e:0f and subscriber-id: 1a:2b:3c:4d:5e:6f
598
</screen>
599
600
601
602
603
604
605
606
607
608
609
        </para>
        <para>
        In addition to logging lease activity driven by DHCPv6 client traffic, it also
        logs entries for the following lease management control channel commands:
        lease6-add, lease6-update, and lease6-del.  Each entry is a single string
        with no embedded end-of-line markers and they will typically have the following
        forms:
        </para>
        <para>
        <command>lease6-add:</command>
<screen>
Francis Dupont's avatar
Francis Dupont committed
610
*timestamp* Administrator added a lease of address: *address* to a device with DUID: *DUID*
611
612
613
614
615
616
</screen>
        Dependent on the arguments of the add command, it may also include the hardware address and duration.
        </para>
        <para>
        Example:
<screen>
Francis Dupont's avatar
Francis Dupont committed
617
2018-01-06 01:02:03 PST Administrator added a lease of address: 2001:db8::3 to a device with DUID: 1a:1b:1c:1d:1e:1f:20:21:22:23:24 for 1 days 0 hrs 0 mins 0 secs
618
619
620
621
622
</screen>
        </para>
        <para>
        <command>lease6-update:</command>
<screen>
Francis Dupont's avatar
Francis Dupont committed
623
*timestamp* Administrator updated information on the lease of address: *address* to a device with DUID: *DUID*
624
625
626
627
628
629
</screen>
        Dependent on the arguments of the update command, it may also include the hardware address and lease duration.
        </para>
        <para>
        Example:
<screen>
Francis Dupont's avatar
Francis Dupont committed
630
2018-01-06 01:02:03 PST Administrator updated information on the lease of address: 2001:db8::3 to a device with DUID: 1a:1b:1c:1d:1e:1f:20:21:22:23:24, hardware address: 1a:1b:1c:1d:1e:1f
631
632
633
634
635
636
</screen>
        </para>
        <para>
        <command>lease6-del:</command>
        Deletes have two forms, one by address and one by identifier and identifier type:
<screen>
Francis Dupont's avatar
Francis Dupont committed
637
*timestamp* Administrator deleted the lease for address: *address*
638
639
640
</screen>
        or
<screen>
Francis Dupont's avatar
Francis Dupont committed
641
*timestamp* Administrator deleted a lease for a device identified by: *identifier-type* of *identifier*
642
643
644
645
646
647
</screen>
        Currently only a type of DUID is supported.
        </para>
        <para>
Examples:
<screen>
Francis Dupont's avatar
Francis Dupont committed
648
2018-01-06 01:02:03 PST Administrator deleted the lease for address: 2001:db8::3
649

Francis Dupont's avatar
Francis Dupont committed
650
2018-01-06 01:02:11 PST Administrator deleted a lease for a device identified by: duid of 1a:1b:1c:1d:1e:1f:20:21:22:23:24
651
652
</screen>
        </para>
653
        </section>
654
        <section xml:id="forensic-log-configuration">
655
        <title>Configuring the Forensic Log Hooks</title>
656
657
658
659
660
661
          <para>
          To use this functionality the hook library must be included in the
          configuration of the desired DHCP server modules. The legal_log
          library is installed alongside the Kea libraries in
          <filename>[kea-install-dir]/lib</filename> where
          <filename>kea-install-dir</filename> is determined by the
662
          "--prefix" option of the configure script.  It defaults to
663
664
665
666
667
          <filename>/usr/local</filename>.  Assuming the
          default value then, configuring kea-dhcp4 to load the legal_log
          library could be done with the following Kea4 configuration:
<screen>
"Dhcp4": { <userinput>
668
669
670
671
672
673
674
675
    "hooks-libraries": [
        {
            "library": "/usr/local/lib/libdhcp_legal_log.so",
            "parameters": {
                "path": "/var/kea/var",
                "base-name": "kea-forensic4"
            }
        },
676
677
678
679
680
681
682
683
684
        ...
    ] </userinput>
}
</screen>
          </para>
          <para>
          To configure it for kea-dhcp6, the commands are simply as shown below:
<screen>
"Dhcp6": { <userinput>
685
686
687
688
689
690
691
692
    "hooks-libraries": [
        {
            "library": "/usr/local/lib/libdhcp_legal_log.so",
            "parameters": {
                "path": "/var/kea/var",
                "base-name": "kea-forensic6"
            }
        },
693
694
695
696
697
698
699
700
701
        ...
    ] </userinput>
}
</screen>
          </para>
          <para>
          Two Hook Library parameters are supported:
          <itemizedlist>
            <listitem><para>
702
            path - the directory in which the forensic file(s) will be written.  The
703
704
705
706
707
            default value is
            <filename>[prefix]/kea/var</filename>.  The directory must exist.
            </para></listitem>
            <listitem><para>
            base-name - an arbitrary value which is used in conjunction with
Francis Dupont's avatar
Francis Dupont committed
708
            the current system date to form the current forensic file name.  It defaults
709
710
711
712
            to <filename>kea-legal</filename>.
            </para></listitem>
          </itemizedlist>
          </para>
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765

          <para>
            If it is desired to restrict forensic logging to certain subnets, the
            "legal-logging" boolean parameter can be specified within a user context of
            these subnets. For example:
<screen>
"Dhcpv4" {
    "subnet4": [
        {
            "subnet": "192.0.2.0/24",
            "pools": [
                {
                     "pool": "192.0.2.1 - 192.0.2.200"
                }
            ],
            <userinput>"user-context": {
                "legal-logging": false
            }</userinput>
        }
    ]
}
</screen>
              disables legal logging for the subnet "192.0.2.0/24". If this parameter
              is not specified, it defaults to 'true', which enables legal logging for
              the subnet.
          </para>

          <para>
            The following example demonstrates how to selectively disable legal logging
            for an IPv6 subnet.
<screen>
"Dhcpv6": {
    "subnet6": [
        {
            "subnet": "2001:db8:1::/64",
            "pools": [
                 {
                     "pool": "2001:db8:1::1-2001:db8:1::ffff"
                 }
            ],
            <userinput>"user-context": {
                "legal-logging": false
            }</userinput>
        }
    ]
}
</screen>
          </para>

          <para>
            See <xref linkend="dhcp4-user-contexts"/> and <xref linkend="dhcp6-user-contexts"/>
            to learn more about user contexts in Kea configuration.
          </para>
766
        </section>
Francis Dupont's avatar
Francis Dupont committed
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799

        <section id="forensic-log-database">
        <title>Database backend</title>
          <para>
          Log entries can be inserted into a database when Kea is configured
          with database backend support: a table named 'logs' is used with a
          timestamp (timeuuid for Cassandra CQL) generated by the database
          software and a text log with the same format than for files
          without the timestamp.
          </para>
          <para>
          Please refer to <xref linkend="mysql-database"/> for MySQL,
          to <xref linkend="pgsql-database"/> for PostgreSQL or
          to <xref linkend="cql-database"/> for Cassandra CQL.
          Scripts are in
          <filename><replaceable>path-to-kea</replaceable>/share/kea/legal_log/scripts</filename> directory, for instance the PostgreSQL create schema
          command is:
<screen>
$ <userinput>psql -d <replaceable>database-name</replaceable> -U <replaceable>user-name</replaceable> -f <replaceable>path-to-kea</replaceable>/share/kea/legal_log/scripts/pgsql/legldb_create.pgsql</userinput>
Password for user <replaceable>user-name</replaceable>:
START TRANSACTION
CREATE TABLE
CREATE INDEX
CREATE TABLE
INSERT 0 1
COMMIT
$
</screen>
          </para>
          <para>
          Configuration parameters are extended by standard lease database
          parameters as defined in <xref linkend="database-configuration4"/>.
          The "type" parameter should be "mysql", "postgresql",  "cql" or
800
          be "logfile". When it is absent or set to "logfile" files are
Francis Dupont's avatar
Francis Dupont committed
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
          used.
          </para>
          <para>
          This database feature is experimental and will be likely
          improved, for instance to add an address / prefix index (currently
          the only index is the timestamp). No specific tools is provided
          to operate the database but standard tools are applicable,
          for instance to dump the logs table from a CQL database:
<screen>
$ <userinput>echo 'SELECT dateOf(timeuuid), log FROM logs;' | cqlsh -k <replaceable>database-name</replaceable></userinput>

 system.dateof(timeuuid)         | log
---------------------------------+---------------------------------------
 2018-01-06 01:02:03.227000+0000 | Address: 192.2.1.100 has been renewed ...
 ...
(12 rows)
$
</screen>
          </para>
        </section>
821
      </section>
822

823
      <section xml:id="flex-id">
824
825
        <title>flex_id: Flexible Identifiers for Host Reservations</title>
        <para>
Tomek Mrugalski's avatar
Tomek Mrugalski committed
826
827
828
829
830
831
          This section describes a hook application dedicated to generate
          flexible identifiers for host reservation. Kea software provides a way
          to handle host reservations that include addresses, prefixes, options,
          client classes and other features. The reservation can be based on
          hardware address, DUID, circuit-id or client-id in DHCPv4 and using
          hardware address or DUID in DHCPv6. However, there are sometimes
832
          scenarios where the reservation is more complex, e.g. uses other
Tomek Mrugalski's avatar
Tomek Mrugalski committed
833
834
835
          options that mentioned above, uses part of specific options or perhaps
          even a combination of several options and fields to uniquely identify
          a client. Those scenarios are addressed by the Flexible Identifiers
836
837
838
839
840
        hook application.</para>

        <para>Currently this library is only available to ISC customers with a
        support contract.</para>

841
        <para>The library allows for defining an expression, using notation
842
        initially used for client classification only. See <xref linkend="classification-using-expressions"/> for detailed description
843
844
845
846
847
848
849
850
851
852
853
854
855
        of the syntax available. One notable difference is that for client
        classification the expression currently has to evaluate to either true
        or false, while the flexible identifier expression is expected to
        evaluate to a string that will be used as identifier. It is a valid case
        for the expression to evaluate to empty string (e.g. in cases where a
        client does not sent specific options). This expression is then
        evaluated for each incoming packet. This evaluation generates an
        identifier that is used to identify the client. In particular, there may
        be host reservations that are tied to specific values of the flexible
        identifier.</para>

        <para>
          The library can be loaded in similar way as other hook libraries. It
856
857
          takes a mandatory parameter identifier-expression and optional
          boolean parameter replace-client-id:
Tomek Mrugalski's avatar
Tomek Mrugalski committed
858
859
860
861
862
863
<screen>
"Dhcp6": { <userinput>
    "hooks-libraries": [
        {
            "library": "/path/libdhcp_flex_id.so",
            "parameters": {
864
865
                "identifier-expression": "<userinput>expression</userinput>",
                "replace-client-id": "<userinput>false</userinput>"
Tomek Mrugalski's avatar
Tomek Mrugalski committed
866
867
868
869
870
871
            }
        },
        ...
    ] </userinput>
}
</screen>
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
        </para>

        <para>
          The flexible identifier library supports both DHCPv4 and DHCPv6.
        </para>

        <para>
          EXAMPLE: Let's consider a case of an IPv6 network that has an
          independent interface for each of the connected customers. Customers
          are able to plug in whatever device they want, so any type of
          identifier (e.g. a client-id) is unreliable. Therefore the operator
          may decide to use an option inserted by a relay agent to differentiate
          between clients. In this particular deployment, the operator verified
          that the interface-id is unique for each customer facing
          interface. Therefore it is suitable for usage as reservation. However,
          only the first 6 bytes of the interface-id are interesting, because
          remaining bytes are either randomly changed or not unique between
          devices. Therefore the customer decided to use first 6 bytes of the
890
891
892
          interface-id option inserted by the relay agent. After adding "flex-id"
          host-reservation-identifiers goal can be achieved by using the
          following configuration:
Tomek Mrugalski's avatar
Tomek Mrugalski committed
893
894
895
896
897
898
899
900
<screen>
"Dhcp6": {
    "subnet6": [{ ..., // subnet definition starts here
    "reservations": [
        <userinput>"flex-id": "'port1234'"</userinput>, // value of the first 8 bytes of the interface-id
        "ip-addresses": [ "2001:db8::1" ]
    ],
    }], // end of subnet definitions
901
    "host-reservation-identifiers": ["duid", "flex-id"], // add "flex-id" to reservation identifiers
Tomek Mrugalski's avatar
Tomek Mrugalski committed
902
903
904
905
    "hooks-libraries": [
        {
            "library": "/path/libdhcp_flex_id.so",
            "parameters": {
906
                "identifier-expression": "<userinput>substring(relay6[0].option[18].hex,0,8)</userinput>"
Tomek Mrugalski's avatar
Tomek Mrugalski committed
907
908
909
910
911
912
            }
        },
        ...
    ]
}
</screen>
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
        </para>

        <para>
          NOTE: Care should be taken when adjusting the expression. If the
          expression changes, then all the flex-id values may change, possibly
          rendering all reservations based on flex-id unusable until they're
          manually updated. Therefore it is strongly recommended to start with
          the expression and a handful reservations, adjust the expression as
          needed and only after it was confirmed the expression does exactly
          what is expected out of it go forward with host reservations on any
          broader scale.
        </para>

        <para>
          flex-id values in host reservations can be specified in two
          ways. First, they can be expressed as hex string, e.g. bar string
          can be represented as 626174. Alternatively, it can be expressed
          as quoted value (using double and single quotes), e.g. "'bar'".
          The former is more convenient for printable characters, while hex
          string values are more convenient for non-printable characters.
        </para>
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
<screen>
"Dhcp6": {
    "subnet6": [{ ..., // subnet definition starts here
    "reservations": [
        <userinput>"flex-id": "01:02:03:04:05:06"</userinput>, // value of the first 8 bytes of the interface-id
        "ip-addresses": [ "2001:db8::1" ]
    ],
    }], // end of subnet definitions
    "host-reservation-identifiers": ["duid", "flex-id"], // add "flex-id" to reservation identifiers
    "hooks-libraries": [
        {
            "library": "/path/libdhcp_flex_id.so",
            "parameters": {
                "identifier-expression": "<userinput>vendor[4491].option[1026].hex</userinput>"
            }
        },
        ...
    ]
}
</screen>
954
955
956
957
958

        <para>
          When "replace-client-id" is set to false (which is the default setting),
          the flex-id hook library uses evaluated flexible identifier solely for
          identifying host reservations, i.e. searching for reservations within a
959
960
961
962
          database. This is a functional equivalent of other identifiers,
          similar to hardware address or circuit-id. However,
          this mode of operation has an implication that if a client device is
          replaced, it may cause a conflict between an existing lease (allocated
963
964
965
966
967
          for old device) and the new lease being allocated for the new device. The
          conflict arises because the same flexible identifier is computed for the
          replaced device and the server will try to allocate the same lease. The
          mismatch between client identifiers sent by new device and old device causes
          the server to refuse this new allocation until the old lease expires.
968
969
970
971
972
          A manifestation of this problem is dependant on specific expression
          used as flexible identifier and is likely to appear if you only use options
          and other parameters that are identifying where the device is
          connected (e.g. circuit-id), rather than the device identification
          itself (e.g. MAC address).
973
974
975
976
977
978
979
980
        </para>

        <para>
          The flex-id library offers a way to overcome the problem with lease conflicts
          by dynamically replacing client identifier (or DUID in DHCPv6 case) with a
          value derived from flexible identifier. The server processes the client's
          query as if flexible identifier was sent in the client identifier (or DUID)
          option. This guarantees that returning client (for which the same flexible
981
          identifier is evaluated) will be assigned the same lease despite the client
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
          identifier and/or MAC address change.
        </para>

        <para>
          The following is a stub configuration that enables this behavior:
<screen>
"Dhcp4": { <userinput>
    "hooks-libraries": [
        {
            "library": "/path/libdhcp_flex_id.so",
            "parameters": {
                "identifier-expression": "<userinput>expression</userinput>",
                "replace-client-id": "<userinput>true</userinput>"
            }
        },
        ...
    ] </userinput>
}
</screen>
        </para>

1003
1004
1005
1006
1007
1008
        <para>
          In the DHCPv4 case, the value derived from the flexible identifier is formed
          by prepending 1 byte with a value of zero to flexible identifier. In the IPv6
          case, it is formed by prepanding two zero bytes before the flexible identifier.
        </para>

1009
1010
1011
        <para>
          Note that for this mechanism to take effect, the DHCPv4 server must be configured
          to respect the client identifier option value during lease allocation, i.e.
1012
          "match-client-id" must be set to true. See
1013
1014
1015
          <xref linkend="dhcp4-match-client-id"/> for details. No additional settings
          are required for DHCPv6.
        </para>
1016
1017
1018
1019
1020
        <para>
          If "replace-client-id" option is set to true, the value of "echo-client-id"
          parameter (that governs whether to send back a client-id option or
          not) is ignored.
        </para>
1021

1022
1023
1024
        <para>
          The <xref linkend="lease-cmds"/> section describes commands used to retrieve,
          update and delete leases using various identifiers, e.g. "hw-address",
Tomek Mrugalski's avatar
Tomek Mrugalski committed
1025
          "client-id". The lease_cmds library doesn't natively support querying for
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
          leases by flexible identifier. However, when "replace-client-id" is set to
          true, it makes it possible to query for leases using a value derived from
          the flexible identifier. In the DHCPv4 case, the query will look similar to this:
<screen>
{
    "command": "lease4-get",
    "arguments": {
        "identifier-type": "client-id",
        "identifier": "00:<userinput>54:64:45:66</userinput>",
        "subnet-id": 44
    }
}
</screen>

            where hexadecimal value of "54:64:45:66" is a flexible identifier computed
            for the client.
        </para>

        <para>
          In the DHCPv6 case, the corresponding query will look similar to this:
<screen>
{
    "command": "lease6-get",
    "arguments": {
        "identifier-type": "duid",
        "identifier": "00:00:<userinput>54:64:45:66</userinput>",
        "subnet-id": 10
    }
}</screen>

        </para>
1057
1058
      </section>

1059
      <section xml:id="host-cmds">
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
        <title>host_cmds: Host Commands</title>
        <para>
          This section describes a hook application that offers a number of new
          commands used to query and manipulate host reservations. Kea provides
          a way to store host reservations in a database. In many larger
          deployments it is useful to be able to manage that information while
          the server is running. This library provides management commands for
          adding, querying and deleting host reservations in a safe way without
          restarting the server.  In particular, it validates the parameters, so
          an attempt to insert incorrect data e.g. add a host with conflicting
          identifier in the same subnet will be rejected. Those commands are
          exposed via command channel (JSON over unix sockets) and Control Agent
          (JSON over RESTful interface). Additional commands and capabilities
          related to host reservations will be added in the future.
        </para>

        <para>Currently this library is only available to ISC customers with a
        support contract.</para>
1078

1079
1080
1081
1082
1083
1084
1085
1086
        <para>
          Currently three commands are supported: reservation-add (which adds
          new host reservation), reservation-get (which returns existing
          reservation if specified criteria are matched) and reservation-del
          (which attempts to delete a reservation matching specified
          criteria). To use commands that change the reservation information
          (currently these are reservation-add and reservation-del, but this
          rule applies to other commands that may be implemented in the future),
Francis Dupont's avatar
Francis Dupont committed
1087
1088
1089
          hosts database must be specified (see hosts-databases description in
          <xref linkend="hosts-databases-configuration4"/> and <xref linkend="hosts-databases-configuration6"/>) and it must not operate in
          read-only mode. If the hosts-databases are not specified or are running
1090
1091
1092
1093
1094
1095
1096
          in read-only mode, the host_cmds library will load, but any attempts
          to use reservation-add or reservation-del will fail.
        </para>

        <para>
          Additional host reservation commands are planned in the future. For
          a description of envisaged commands, see
1097
1098
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://kea.isc.org/wiki/ControlAPIRequirements">Control API
Requirements </link> document.</para>
1099
1100
1101
1102

        <para>
          All commands are using JSON syntax. They can be issued either using
          control channel (see <xref linkend="ctrl-channel"/>) or via Control
1103
          Agent (see <xref linkend="kea-ctrl-agent"/>).
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
        </para>

        <para>
          The library can be loaded in similar way as other hook libraries. It
          does not take any parameters. It supports both DHCPv4 and DHCPv6
          servers.
<screen>
"Dhcp6": { <userinput>
    "hooks-libraries": [
        {
            "library": "/path/libdhcp_host_cmds.so"
        }
        ...
    ] </userinput>
}
</screen>
        </para>

        <section>
          <title>reservation-add command</title>
        <para>
Tomek Mrugalski's avatar
Tomek Mrugalski committed
1125
          <command>reservation-add</command> allows for the insertion of a new host.  It
1126
1127
1128
          takes a set of arguments that vary depending on the nature of the host
          reservation. Any parameters allowed in the configuration file that
          pertain to host reservation are permitted here. For details regarding
1129
          IPv4 reservations, see <xref linkend="host-reservation-v4"/> and <xref linkend="host-reservation-v6"/>. There is one notable addition. A
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
          <command>subnet-id</command> must be specified.  This parameter is
          mandatory, because reservations specified in the configuration file
          are always defined within a subnet, so the subnet they belong to is
          clear. This is not the case with reservation-add, therefore the
          subnet-id must be specified explicitly. An example command can be as
          simple as:
<screen>{
    "command": "reservation-add",
    "arguments": {
        <userinput>"reservation": {
            "subnet-id": 1,
            "hw-address": "1a:1b:1c:1d:1e:1f",
            "ip-address": "192.0.2.202"
        }</userinput>
    }
}</screen> but can also take many more parameters, for example:

<screen>
{
    "command": "reservation-add",
    "arguments": {
1151
        <userinput>"reservation":
1152
            {
1153
                "subnet-id":1,
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
                "client-id": "01:0a:0b:0c:0d:0e:0f",
                "ip-address": "192.0.2.205",
                "next-server": "192.0.2.1",
                "server-hostname": "hal9000",
                "boot-file-name": "/dev/null",
                "option-data": [
                    {
                        "name": "domain-name-servers",
                        "data": "10.1.1.202,10.1.1.203"
                    }
                ],
                "client-classes": [ "special_snowflake", "office" ]
1166
            }</userinput>
1167
1168
    }
}</screen>
1169

1170
1171
1172
1173
1174
Here is an example of complex IPv6 reservation:
<screen>
{
    "command": "reservation-add",
    "arguments": {
1175
        <userinput>"reservation":
1176
            {
1177
                "subnet-id":1,
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
                "duid": "01:02:03:04:05:06:07:08:09:0A",
                "ip-addresses": [ "2001:db8:1:cafe::1" ],
                "prefixes": [ "2001:db8:2:abcd::/64" ],
                "hostname": "foo.example.com",
                "option-data": [
                    {
                        "name": "vendor-opts",
                        "data": "4491"
                    },
                    {
                        "name": "tftp-servers",
                        "space": "vendor-4491",
                        "data": "3000:1::234"
                    }
                ]
1193
            }</userinput>
1194
1195
    }
}</screen>
1196
        </para>
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207

        <para>
          The command returns a status that indicates either a success (result
          0) or a failure (result 1). Failed command always includes text
          parameter that explains the cause of failure. Example results:
          <screen>{ "result": 0, "text": "Host added." }</screen> Example failure:
          <screen>{ "result": 1, "text": "Mandatory 'subnet-id' parameter missing." }</screen>
        </para>

        <para>
          As <command>reservation-add</command> is expected to store the host,
Francis Dupont's avatar
Francis Dupont committed
1208
1209
          hosts-databases parameter must be specified in your configuration and
          databases must not run in read-only mode. In the future versions
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
          it will be possible to modify the reservations read from a
          configuration file. Please contact ISC if you are interested in this
          functionality.
        </para>
        </section>

        <section>
          <title>reservation-get command</title>
          <para><command>reservation-get</command> can be used to query the host
          database and retrieve existing reservations. There are two types of
          parameters this command supports: (subnet-id, address) or (subnet-id,
          identifier-type, identifier). The first type of query is used when the
          address (either IPv4 or IPv6) is known, but the details of the
          reservation aren't. One common use case of this type of query is to
          find out whether a given address is reserved or not. The second query
          uses identifiers. For maximum flexibility, Kea stores the host
          identifying information as a pair of values: type and the actual
          identifier. Currently supported identifiers are "hw-address", "duid",
          "circuit-id", "client-id" and "flex-id", but additional types may be
          added in the future. If any new identifier types are defined in the
          future, reservation-get command will support them
          automatically.</para>

          <para>
            An example command for getting a host reservation by (subnet-id,
            address) pair looks as follows:
<screen>
{
    "command": "reservation-get",
    "arguments": {
        "subnet-id": 1,
        "ip-address": "192.0.2.202"
    }
}</screen>

An example query by (subnet-id, identifier-type, identifier) looks as follows:
<screen>
{
    "command": "reservation-get",
    "arguments":
        "subnet-id": 4,
        "identifier-type": "hw-address",
        "identifier": "01:02:03:04:05:06"
    }
}</screen>

          </para>
          <para><command>reservation-get</command> typically returns result 0
          when the query was conducted properly. In particular, 0 is returned
          when the host was not found. If the query was successful a number
          of host parameters will be returned. An example of a query that
          did not find the host looks as follows:
<screen>{ "result": 0, "text": "Host not found." }</screen>

An example result returned when the host was found:
<screen>{
  "arguments": {
    "boot-file-name": "bootfile.efi",
    "client-classes": [
1269

1270
1271
1272
1273
1274
1275
    ],
    "hostname": "somehost.example.org",
    "hw-address": "01:02:03:04:05:06",
    "ip-address": "192.0.2.100",
    "next-server": "192.0.0.2",
    "option-data": [
1276

1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
    ],
    "server-hostname": "server-hostname.example.org"
  },
  "result": 0,
  "text": "Host found."
}</screen>

An example result returned when the query was malformed:<screen>
{ "result": 1, "text": "No 'ip-address' provided and 'identifier-type'
                        is either missing or not a string." }</screen>
</para>
1288

1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
        </section>

        <section>
          <title>reservation-del command</title>
          <para><command>reservation-del</command> can be used to delete a
          reservation from the host database. There are two types of parameters
          this command supports: (subnet-id, address) or (subnet-id,
          identifier-type, identifier). The first type of query is used when the
          address (either IPv4 or IPv6) is known, but the details of the
          reservation aren't. One common use case of this type of query is to
          remove a reservation (e.g. you want a specific address to no longer be
          reserved). The second query uses identifiers. For maximum flexibility,
          Kea stores the host identifying information as a pair of values: type
          and the actual identifier. Currently supported identifiers are
          "hw-address", "duid", "circuit-id", "client-id" and "flex-id", but
          additional types may be added in the future. If any new identifier
          types are defined in the future, reservation-get command will support
          them automatically.</para>

          <para>
            An example command for deleting a host reservation by (subnet-id,
            address) pair looks as follows:
<screen>
{
    "command": "reservation-del",
    "arguments": {
        "subnet-id": 1,
        "ip-address": "192.0.2.202"
    }
}</screen>

An example deletion by (subnet-id, identifier-type, identifier) looks as follows:
<screen>
{
    "command": "reservation-del",
    "arguments":
        "subnet-id": 4,
        "identifier-type": "hw-address",
        "identifier": "01:02:03:04:05:06"
    }
}</screen>
          </para>
          <para>
            <command>reservation-del</command> returns result 0 when the host
1333
            deletion was successful or 1 if it was not. A descriptive text is
1334
1335
1336
1337
1338
1339
1340
            provided in case of error. Example results look as follows:
<screen>
{
    "result": 1,
    "text": "Host not deleted (not found)."
}</screen>

1341
<screen>
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
{
    "result": 0,
    "text": "Host deleted."
}</screen>

<screen>
{
    "result": 1,
    "text": "Unable to delete a host because there is no hosts-database
             configured."
}</screen>
          </para>
        </section>
1355
1356
      </section>

1357
1358
1359
1360
      <!-- ================================================================= -->
      <!-- === lease_cmds ================================================== -->
      <!-- ================================================================= -->

1361
      <section xml:id="lease-cmds">
1362
1363
        <title>lease_cmds: Lease Commands</title>
        <para>
1364
          This section describes the hook library that offers a number of new
1365
1366
          commands used to manage leases. Kea provides a way to store lease
          information in several backends (memfile, MySQL, PostgreSQL and
1367
          Cassandra). This library provides a unified interface that can
1368
1369
1370
1371
1372
1373
          manipulate leases in an unified, safe way. In particular, it allows
          things previously impossible: manipulate leases in memfile while Kea
          is running, sanity check changes, check lease existence and remove all
          leases belonging to specific subnet. It can also catch more obscure
          errors, like adding a lease with subnet-id that does not exist in the
          configuration or configuring a lease to use an address that is outside
1374
          of the subnet to which it is supposed to belong.
1375
1376
1377
1378
        </para>

        <para>There are many use cases when an administrative command may be
        useful: during migration between servers (possibly even between
1379
        different vendors), when a certain network is being retired, when a
1380
        device has been disconnected and the sysadmin knows for sure that it
1381
        will not be coming back. The "get" queries may be useful for automating
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
        certain management and monitoring tasks. They can also act as
        preparatory steps for lease updates and removals.</para>

        <para>
          This library provides the following commands:
          <itemizedlist>
            <listitem>
              <para><command>lease4-add</command> - adds new IPv4 lease;</para>
            </listitem>
            <listitem>
              <para><command>lease6-add</command> - adds new IPv6 lease;</para>
            </listitem>
            <listitem>
1395
1396
              <para><command>lease4-get</command> - checks if an IPv4 lease with
              the specified parameters exists and returns it if it does;</para>
1397
            </listitem>
1398
1399
1400
1401
            <listitem>
              <para><command>lease6-get</command> - checks if an IPv6 lease with
              the specified parameters exists and returns it if it does;</para>
            </listitem>
1402
1403
1404
1405
            <listitem>
              <para><command>lease4-get-all</command> - returns all IPv4 leases
              or IPv4 leases for specified subnets;</para>
            </listitem>
1406
            <listitem>
1407
1408
              <para><command>lease6-get-all</command> - returns all IPv6 leases
              or IPv6 leases for specified subnets;</para>
1409
1410
1411
            </listitem>
            <listitem>
              <para><command>lease4-del</command> - attempts to delete an IPv4
1412
              lease with the specified parameters;</para>
1413
1414
1415
            </listitem>
            <listitem>
              <para><command>lease6-del</command> - attempts to delete an IPv6
1416
              lease with the specified parameters;</para>
1417
1418
1419
1420
1421
1422
1423
1424
1425
            </listitem>
            <listitem>
              <para><command>lease4-update</command> - updates an IPv4 lease;</para>
            </listitem>
            <listitem>
              <para><command>lease6-update</command> - updates an IPv6 lease;</para>
            </listitem>
            <listitem>
              <para><command>lease4-wipe</command> - removes all leases from a
Tomek Mrugalski's avatar
Tomek Mrugalski committed
1426
              specific IPv4 subnet or all subnets;</para>
1427
1428
1429
            </listitem>
            <listitem>
              <para><command>lease6-wipe</command> - removes all leases from a
Tomek Mrugalski's avatar
Tomek Mrugalski committed
1430
              specific IPv6 subnet or all subnets;</para>
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
            </listitem>
          </itemizedlist>

        </para>

        <para>Lease commands library is part of the open source code and is
        available to every Kea user.</para>

        <para>
          All commands are using JSON syntax. They can be issued either using
          control channel (see <xref linkend="ctrl-channel"/>) or via Control
          Agent (see <xref linkend="kea-ctrl-agent"/>).
        </para>

        <para>
1446
          The library can be loaded in the same way as other hook libraries. It
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
          does not take any parameters. It supports both DHCPv4 and DHCPv6
          servers.
<screen>
"Dhcp6": { <userinput>
    "hooks-libraries": [
        {
            "library": "/path/libdhcp_lease_cmds.so"
        }
        ...
    ] </userinput>
}
</screen>
        </para>

        <section>
          <title>lease4-add, lease6-add commands</title>
        <para>
          <command>lease4-add</command> and <command>lease6-add</command>
Tomek Mrugalski's avatar
Tomek Mrugalski committed
1465
          commands allow for the creation of a new lease. Typically Kea creates a lease
1466
1467
1468
          on its own, when it first sees a new device. However, sometimes it may
          be convenient to create the lease administratively. The
          <command>lease4-add</command> command requires at least three
1469
1470
          parameters: an IPv4 address, a subnet-id and an identifier: hardware
          (MAC) address. The simplest successful call might look as follows:
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
<screen>
{
    "command": "lease4-add",
    "arguments": {
        "subnet-id": 44,
        "ip-address": "192.0.2.202",
        "hw-address": "1a:1b:1c:1d:1e:1f"
    }
}
</screen>
        </para>

        <para><command>lease6-add</command> command requires four
1484
        parameters: an IPv6 address, a subnet-id, and IAID value
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
        (identity association identifier, a value sent by clients) and
        a DUID:
<screen>
{
    "command": "lease6-add",
    "arguments": {
        "subnet-id": 66,
        "ip-address": "2001:db8::3",
        "duid": "1a:1b:1c:1d:1e:1f:20:21:22:23:24",
        "iaid": 1234
    }
}</screen>

<command>lease6-add</command> can be also used to add leases for IPv6
prefixes. In this case there are two parameters that must be
1500
specified: type (set to value of "IA_PD") and a prefix
1501
1502
1503
1504
1505
1506
1507
1508
1509
length. The actual prefix is set using ip-address field. For example,
to configure a lease for prefix 2001:db8:abcd::/48, the following
command can be used:

<screen>
{
    "command": "lease6-add",
    "arguments": {
        "subnet-id": 66,
1510
        "type": "IA_PD",
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
        "ip-address": "2001:db8:abcd::",
        "prefix-len": 48,
        "duid": "1a:1b:1c:1d:1e:1f:20:21:22:23:24",
        "iaid": 1234
    }
}</screen>

The commands can take a number of additional optional parameters:
          <itemizedlist>
            <listitem>
1521
              <para><command>valid-lft</command> - specifies the lifetime of the
1522
              lease, expressed in seconds. If not specified, the value
1523
              configured in the subnet related to specified subnet-id is
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
              used.</para>
            </listitem>
            <listitem>
              <para><command>expire</command> - timestamp of the lease
              expiration time, expressed in unix format (seconds since 1 Jan
              1970). If not specified, the default value is now + valid
              lifetime.</para>
            </listitem>
            <listitem>
              <para><command>fqdn-fwd</command> - specifies whether the lease
              should be marked as if forward DNS update was conducted. Note this
              only affects the lease parameter and the actual DNS update will
1536
              not be conducted at the lease insertion time. If configured, a DNS
1537
1538
              update to remove the A or AAAA records will be conducted when the
              lease is removed due to expiration or being released by a
1539
              client. If not specified, the default value is false. Hostname
1540
1541
1542
1543
1544
1545
              parameter must be specified in fqdn-fwd is set to true.</para>
            </listitem>
            <listitem>
              <para><command>fqdn-rev</command> - specifies whether the lease
              should be marked as if reverse DNS update was conducted. Note this
              only affects the lease parameter and the actual DNS update will
1546
              not be conducted at the lease insertion time. If configured, a DNS
1547
1548
              update to remove the PTR record will be conducted when the lease
              is removed due to expiration or being released by a client. If not
1549
              specified, the default value is false. Hostname parameter must be
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
              specified in fqdn-fwd is set to true.</para>
            </listitem>
            <listitem>
              <para><command>hostname</command> - specifies the hostname to be
              associated with this lease. Its value must be non-empty if either
              fqdn-fwd or fwdn-rev are set to true. If not specified, the
              default value is an empty string.</para>
            </listitem>
            <listitem>
              <para><command>hw-address</command> - hardware (MAC) address can
              be optionally specified for IPv6 lease. It is mandatory parameter
              for IPv4 lease.</para>
            </listitem>
            <listitem>
              <para><command>client-id</command> - client identifier is an
              optional parameter that can be specified for IPv4 lease.</para>
            </listitem>
            <listitem>
              <para><command>preferred-lft</command> - Preferred lifetime is an
              optional parameter for IPv6 leases. If not specified, the value
1570
              configured for the subnet corresponding to the specified subnet-id
1571
1572
1573
1574
1575
              is used. This parameter is not used in IPv4.</para>
            </listitem>
          </itemizedlist>
        </para>

1576
        <para>Here's an example of more complex lease addition:
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614

<screen>
{
    "command": "lease6-add",
    "arguments": {
        "subnet-id": 66,
        "ip-address": "2001:db8::3",
        "duid": "01:02:03:04:05:06:07:08",
        "iaid": 1234,
        "hw-address": "1a:1b:1c:1d:1e:1f",
        "preferred-lft": 500,
        "valid-lft": 1000,
        "expire": 12345678,
        "fqdn-fwd": true,
        "fqdn-rev": true,
        "hostname": "urania.example.org"
    }
}
</screen>
        </para>

        <para>
          The command returns a status that indicates either a success (result
          0) or a failure (result 1). Failed command always includes text
          parameter that explains the cause of failure. Example results:
          <screen>{ "result": 0, "text": "Lease added." }</screen> Example failure:
          <screen>{ "result": 1, "text": "missing parameter 'ip-address' (&lt;string&gt;:3:19)" }</screen>
        </para>


        <section>
          <title>lease4-get, lease6-get commands</title>
          <para><command>lease4-get</command> or <command>lease6-get</command>
          can be used to query the lease database and retrieve existing
          leases. There are two types of parameters the
          <command>lease4-get</command> supports: (address) or (subnet-id,
          identifier-type, identifier). There are two types for
          <command>lease6-get</command>: (address,type) or (subnet-id,
1615
          identifier-type, identifier, IAID, type). The first type of query is
1616
1617
1618
          used when the address (either IPv4 or IPv6) is known, but the details
          of the lease aren't. One common use case of this type of query is to
          find out whether a given address is being used or not. The second
Tomek Mrugalski's avatar
Tomek Mrugalski committed
1619
          query uses identifiers. Currently supported identifiers for leases are:
1620
1621
          "hw-address" (IPv4 only), "client-id" (IPv4 only) and "duid" (IPv6 only).
          </para>
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647

          <para>
            An example <command>lease4-get</command> command for getting a lease
            by an IPv4 address looks as follows:
<screen>
{
    "command": "lease4-get",
    "arguments": {
        "ip-address": "192.0.2.1"
    }
}
</screen>
          </para>

          <para>An example of the <command>lease6-get</command> query
          looks as follows:
<screen>
{
  "command": "lease6-get",
  "arguments": {
    "ip-address": "2001:db8:1234:ab::",
    "type": "IA_PD"
  }
}</screen>
          </para>

1648
1649
          <para>An example query by "hw-address" for IPv4 lease looks
          as follows:
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
<screen>
{
    "command": "lease4-get",
    "arguments": {
        "identifier-type": "hw-address",
        "identifier": "08:08:08:08:08:08",
        "subnet-id": 44
    }
}</screen>

          </para>

1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
          <para>An example query by "client-id" for IPv4 lease looks
          as follows:
<screen>
{
    "command": "lease4-get",
    "arguments": {
        "identifier-type": "client-id",
        "identifier": "01:01:02:03:04:05:06",
        "subnet-id": 44
    }
}</screen>

          </para>

1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
          <para>An example query by (subnet-id, identifier-type,
          identifier, iaid, type) for IPv6 lease looks as follows:
<screen>
{
    "command": "lease4-get",
    "arguments": {
        "identifier-type": "duid",
        "identifier": "08:08:08:08:08:08",
        "iaid": 1234567,
        "type": "IA_NA",
        "subnet-id": 44
    }
}</screen>
The type is an optional parameter. Supported values are: IA_NA
(non-temporary address) and IA_PD (IPv6 prefix) are supported.
If not specified, IA_NA is assumed.
          </para>

          <para><command>leaseX-get</command> returns a result that indicates a
          result of the operation and lease details, if found. It has one of the
          following values: 0 (success), 1 (error) or 2 (empty). The empty
          result means that a query has been completed properly, but the object
          (a lease in this case) has not been found. The lease parameters, if
          found, are returned as arguments.
          </para>

          <para>
An example result returned when the host was found:
<screen>{
  "arguments": {
    "client-id": "42:42:42:42:42:42:42:42",
    "cltt": 12345678,
    "fqdn-fwd": false,
    "fqdn-rev": true,
    "hostname": "myhost.example.com.",
    "hw-address": "08:08:08:08:08:08",
    "ip-address": "192.0.2.1",
    "state": 0,
    "subnet-id": 44,
    "valid-lft": 3600
  },
  "result": 0,
  "text": "IPv4 lease found."
}</screen>
</para>

        </section>

1724
        <section>
1725
          <title>lease4-get-all, lease6-get-all commands</title>
1726
1727
          <para><command>lease4-get-all</command> and
          <command>