mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 05:27:55 +00:00
[trac4101] Add classify.xml file
Add the chapter about classification
This commit is contained in:
parent
192e415b74
commit
e7e89d34b7
309
doc/guide/classify.xml
Normal file
309
doc/guide/classify.xml
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
<?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 "—" >
|
||||||
|
]>
|
||||||
|
|
||||||
|
<chapter id="classify">
|
||||||
|
<title>Client Classification</title>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Client Classification Overview</title>
|
||||||
|
<para>
|
||||||
|
In certain cases it is useful to differentiate between different
|
||||||
|
types of clients and treat them differently. There are many reasons
|
||||||
|
why one might want to treat clients different some common reasons
|
||||||
|
include:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para>
|
||||||
|
The clients represent different pieces of topology, for example a cable
|
||||||
|
modem vs the clients behind that modem.
|
||||||
|
</para></listitem>
|
||||||
|
<listitem><para>
|
||||||
|
The clients have different behavior, for example a smart phone vs a lapttop
|
||||||
|
vs a desktop.
|
||||||
|
</para></listitem>
|
||||||
|
<listitem><para>
|
||||||
|
The clients require different values for some options, for example a docsis3.0
|
||||||
|
cable modem vs a docsis2.0 cable modem.
|
||||||
|
</para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
It is envisaged that client classification will be used for changing the
|
||||||
|
behavior of almost any part of the DHCP message processing, including assigning
|
||||||
|
leases from different pools, assigning different options (or different values of
|
||||||
|
the same options) etc. For now, there are only two mechanisms that take
|
||||||
|
advantage of client classification: subnet selection and assigning different
|
||||||
|
options. For cable modems there are specific options for use with the TFTP
|
||||||
|
server address and the boot file field.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The process of doing classification is conducted in three steps. The first step
|
||||||
|
is to assess an incoming packet and assign it to zero or more classes. The
|
||||||
|
second step is to choose a subnet, possibly based on the class information.
|
||||||
|
The third step is to assign options again possibly based on the class
|
||||||
|
information.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Options will be included from all of the assigned classes. In the case two
|
||||||
|
or more classes include an option the value from the first class will be used.
|
||||||
|
Similarly if two or more classes are associated with a subnet the first subnet
|
||||||
|
will be used. In the future the processing order of the various classes may
|
||||||
|
be specified but for now it is being left unspecified and may change in
|
||||||
|
future releases.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
There are two methods of doing classification. The first is automatic and relies
|
||||||
|
on examining the values in the vendor class options. Information from these
|
||||||
|
options is extracted and a class name is constructed from it and added to
|
||||||
|
the class list for the packet. The second allows you to specify an expression
|
||||||
|
that is evaluated for each packet. If the result is true the packet is
|
||||||
|
a member of the class.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
The power of the expressions in the classification step is deliberately
|
||||||
|
limited in order to minimize the amount of time required to process each
|
||||||
|
expression. The expression for each class must be executed on each packet,
|
||||||
|
if they are overly complex or time consuming they may impact the performance
|
||||||
|
of the server. If you require complex or time consuming expressions you
|
||||||
|
should write a hook to perform the necessary work.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
Care should be taken with client classification as it is easy for
|
||||||
|
clients that do not meet class criteria to be denied any service altogether.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="classification-using-vendor">
|
||||||
|
<title>Using Vendor Class Information In Classification</title>
|
||||||
|
<para>
|
||||||
|
The server checks whether an incoming DHCPv4 packet includes
|
||||||
|
the vendor class identifier option (60) or an incoming DHCPv6 packet
|
||||||
|
includes the vendor class option (16). If it does, the content of that
|
||||||
|
option is prepended with "VENDOR_CLASS_" then it is interpreted
|
||||||
|
as a class. For example, modern cable modems will send this option with
|
||||||
|
value "docsis3.0" and as a result the packet will belong to
|
||||||
|
class "VENDOR_CLASS_docsis3.0".
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="classification-using-expressions">
|
||||||
|
<title>Using Expressions In Classification</title>
|
||||||
|
<para>
|
||||||
|
The expression portion of classification contains operators and values.
|
||||||
|
Values are currently strings and operators take a string or strings and
|
||||||
|
return another string. When all the operations have completed
|
||||||
|
the result should be a value of "true" or "false".
|
||||||
|
The packet belongs to
|
||||||
|
the class (and the class name is added to the list of classes) if the result
|
||||||
|
is "true". Expressions are written in standard format and can be nested.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Expressions are pre-processed during the parsing of the configuration file
|
||||||
|
and converted to an internal representation. This allows certain types of
|
||||||
|
errors (such as incorrect syntax) to be caught and logged. Other errors
|
||||||
|
(for example mistakes when setting up the values for a substring) won't be
|
||||||
|
caught and may affect the classification. In general if an expression has
|
||||||
|
a problem a log message will be emitted at the debug level and the result
|
||||||
|
will be an empty string.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The expressions are a work in progress and the supported operators and
|
||||||
|
values are limited. The expectation is that additional operators and values
|
||||||
|
will be added over time, however it is expected the basic mechanisms will
|
||||||
|
remain the same.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<table frame="all" id="classification-values-list">
|
||||||
|
<title>List of Classification Values</title>
|
||||||
|
<tgroup cols='3'>
|
||||||
|
<colspec colname='name' />
|
||||||
|
<colspec colname='example' />
|
||||||
|
<colspec colname='description' />
|
||||||
|
<thead>
|
||||||
|
<row>
|
||||||
|
<entry>Name</entry>
|
||||||
|
<entry>Example</entry>
|
||||||
|
<entry>Description</entry>
|
||||||
|
</row>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<row><entry>String</entry><entry>'example'</entry><entry>A string</entry></row>
|
||||||
|
<row><entry>Hex String</entry><entry>'0XABCD'</entry><entry>A hexadecimal string</entry></row>
|
||||||
|
<row><entry>Option</entry><entry>option[code]</entry><entry>The value of the option with code "code" from the packet</entry></row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</table>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Hex Strings are converted into a string as expected. The starting "0X" or
|
||||||
|
"0x" is removed and if the string is an odd number of characters a
|
||||||
|
"0" is prepended to it.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Option extracts the value of the given option from the incoming packet. If the
|
||||||
|
packet doesn't contain the option it returns an empty string.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<table frame="all" id="classification-expressions-list">
|
||||||
|
<title>List of Classification Expressions</title>
|
||||||
|
<tgroup cols='3'>
|
||||||
|
<colspec colname='name' />
|
||||||
|
<colspec colname='example' />
|
||||||
|
<colspec colname='description' />
|
||||||
|
<thead>
|
||||||
|
<row>
|
||||||
|
<entry>Name</entry>
|
||||||
|
<entry>Example</entry>
|
||||||
|
<entry>Description</entry>
|
||||||
|
</row>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<row><entry>Equal</entry> <entry>'foo' == 'bar'</entry><entry>Compare the two values and return "true" or "false"</entry></row>
|
||||||
|
<row><entry>Substring</entry><entry>substring('foobar',0,3)</entry><entry>Return the requested substring</entry></row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</table>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The substring operator substring(value, start, length) accepts both positive and
|
||||||
|
negative values for the starting position and the length. For start a value of
|
||||||
|
0 is the first byte in the string while -1 is the last byte. If the starting
|
||||||
|
point is outside of the original string an empty string is returned. Length
|
||||||
|
is the number of bytes to extract. A negative number means to count towards
|
||||||
|
the beginning of the string but doesn't include the byte pointed to by start.
|
||||||
|
The special value "all" means to return all bytes from start to the end of the
|
||||||
|
string. If length is longer than the remaining portion of the string then
|
||||||
|
the entire remaining portion is returned.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="classification-configuring">
|
||||||
|
<title>Configuring Classes</title>
|
||||||
|
<para>
|
||||||
|
A class contains three items: a name, a test expression and option data.
|
||||||
|
The name must exist and must be unique amongst all classes. The test
|
||||||
|
expression and option data are optional.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The test expression is a string containing the logical expression used to
|
||||||
|
determine membership in the class. The entire expression is in double
|
||||||
|
quotes.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The option data is a list which defines any options that should be assigned
|
||||||
|
to members of this class.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<screen>
|
||||||
|
"Dhcp4": {
|
||||||
|
"subnet4": [
|
||||||
|
{
|
||||||
|
"subnet": "192.0.2.0/24",
|
||||||
|
"pools": [ { "pool": "192.0.2.10 - 192.0.2.20" } ],
|
||||||
|
"client-class": "Client_foo"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"client-class": [
|
||||||
|
<userinput>
|
||||||
|
{
|
||||||
|
"name": "Client_foo",
|
||||||
|
"test": "substring(option[61],0,3) == 'foo'",
|
||||||
|
"option-data": [
|
||||||
|
{
|
||||||
|
"name": "doamin-name-servers",
|
||||||
|
"code": 6,
|
||||||
|
"space": "dhcp4",
|
||||||
|
"csv-format": true,
|
||||||
|
"data": "192.0.2.1, 192.0.2.2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</userinput>
|
||||||
|
...
|
||||||
|
}</screen>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
In this example the class named "Client_foo" is defined. It is comprised
|
||||||
|
of all clients who's client ids (option 61) start with the string "foo".
|
||||||
|
They will be given an address from 192.0.2.10 to 192.0.2.20 and 192.0.2.1
|
||||||
|
and 192.0.2.2 as their domain name servers.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="classification-subnets">
|
||||||
|
<title>Configuring Subnets With Class Information</title>
|
||||||
|
<para>
|
||||||
|
In certain cases it beneficial to restrict access to certain subnets
|
||||||
|
only to clients that belong to a given subnet. For details on client
|
||||||
|
classes, see <xref linkend="classification-using-vendor"/> and
|
||||||
|
<xref linkend="classification-using-expressions"/>
|
||||||
|
Let's assume that the server is connected to a network segment that uses
|
||||||
|
the 192.0.2.0/24 prefix. The Administrator of that network has decided
|
||||||
|
that addresses from range 192.0.2.10 to 192.0.2.20 are going to be
|
||||||
|
managed by the DHCP4 server. Only clients belonging to client class
|
||||||
|
example_class are allowed to use this subnet. Such a
|
||||||
|
configuration can be achieved in the following way:
|
||||||
|
<screen>
|
||||||
|
"Dhcp4": {
|
||||||
|
"subnet4": [
|
||||||
|
{
|
||||||
|
<userinput>"subnet": "192.0.2.0/24",
|
||||||
|
"pools": [ { "pool": "192.0.2.10 - 192.0.2.20" } ],
|
||||||
|
"client-class": "example_class"</userinput>
|
||||||
|
}
|
||||||
|
],
|
||||||
|
...
|
||||||
|
}</screen>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Using Classes</title>
|
||||||
|
<para>
|
||||||
|
Currently classes can be used for two functions. They can supply options
|
||||||
|
to the members class and they can choose a subnet for the members of the class.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
When supplying options class options defined as part of the class definition
|
||||||
|
are considred "class globals". They will override any global options that
|
||||||
|
may be defined and in turn will be overridden by any options defined for an
|
||||||
|
individual subnet.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Classes and Hooks</title>
|
||||||
|
<para>
|
||||||
|
You may use a hook to classify your packets. This may be useful if the
|
||||||
|
expression would either be complex or time consuming and be easier or
|
||||||
|
better to write as code. Once the hook has added the proper class name
|
||||||
|
to the packet the rest of the classification system will work as normal
|
||||||
|
in choosing a subnet and selecting options.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</chapter>
|
Loading…
x
Reference in New Issue
Block a user