classify.xml 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
  3. "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
  4. <!ENTITY mdash "&#x2014;" >
  5. ]>
  6. <chapter id="classify">
  7. <title>Client Classification</title>
  8. <section>
  9. <title>Client Classification Overview</title>
  10. <para>
  11. In certain cases it is useful to differentiate between different
  12. types of clients and treat them accordingly. Common reasons include:
  13. <itemizedlist>
  14. <listitem><para>
  15. The clients represent different pieces of topology, e.g. a cable
  16. modem is different to the clients behind that modem.
  17. </para></listitem>
  18. <listitem><para>
  19. The clients have different behavior, e.g. a smart phone behaves
  20. differently to a laptop.
  21. </para></listitem>
  22. <listitem><para>
  23. The clients require different values for some options, e.g. a docsis3.0
  24. cable modem requires different settings to docsis2.0 cable modem.
  25. </para></listitem>
  26. </itemizedlist>
  27. </para>
  28. <para>
  29. It is envisaged that client classification will be used for changing the
  30. behavior of almost any part of the DHCP message processing, including the assignment of
  31. leases from different pools, the assignment of different options (or different values of
  32. the same options) etc. In the current release of the software however, there are
  33. only three mechanisms that take
  34. advantage of client classification: subnet selection, assignment of different
  35. options and, for DHCPv4 cable modems, the setting of specific options for use with
  36. the TFTP server address and the boot file field.
  37. </para>
  38. <para>
  39. The process of doing classification is conducted in three steps:
  40. <orderedlist>
  41. <listitem><para>
  42. Assess an incoming packet and assign it to zero or more classes.
  43. </para></listitem>
  44. <listitem><para>
  45. Choose a subnet, possibly based on the class information.
  46. </para></listitem>
  47. <listitem><para>
  48. Assign options, again possibly based on the class information.
  49. </para></listitem>
  50. </orderedlist>
  51. </para>
  52. <para>
  53. When determining which options to include in the response the server will examine
  54. the union of options from all of the assigned classes. In the case two or more
  55. classes include the same option, the value from the first class examined will
  56. be used. When choosing a subnet the server will iterate over all of the
  57. subnets that are feasible given the information found in the packet (client address,
  58. relay address etc). It will use the first subnet it finds that either doesn't
  59. have a class associated with it or that has a class which matches one of
  60. the packet's classes. In the future the processing order of the
  61. various classes may be specified but for now it is being left unspecified and
  62. may change in future releases.
  63. </para>
  64. <para>
  65. As an example, imagine two classes. Class "foo" defines values for an NTP server
  66. (option 42 in DHCPv4) and an SMTP server (option 69 in DHCPv4) while class
  67. "bar" defines values for an NTP server and a POP3 server (option 70 in DHCPv4).
  68. The server will examine the three options NTP, SMTP and POP3 and return any
  69. of them that the client requested. As the NTP server was defined twice the
  70. server will choose only one of the values for the reply: the class from which the
  71. value is obtained is unspecified.
  72. </para>
  73. <para>
  74. There are two methods of doing classification. The first is automatic and relies
  75. on examining the values in the vendor class options. Information from these
  76. options is extracted and a class name is constructed from it and added to
  77. the class list for the packet. The second allows you to specify an expression
  78. that is evaluated for each packet. If the result is true, the packet is
  79. a member of the class.
  80. </para>
  81. <note>
  82. <para>
  83. Care should be taken with client classification as it is easy for
  84. clients that do not meet class criteria to be denied any service altogether.
  85. </para>
  86. </note>
  87. </section>
  88. <section id="classification-using-vendor">
  89. <title>Using Vendor Class Information In Classification</title>
  90. <para>
  91. The server checks whether an incoming DHCPv4 packet includes
  92. the vendor class identifier option (60) or an incoming DHCPv6 packet
  93. includes the vendor class option (16). If it does, the content of that
  94. option is prepended with &quot;VENDOR_CLASS_&quot; and the result is interpreted
  95. as a class. For example, modern cable modems will send this option with
  96. value &quot;docsis3.0&quot; and so the packet will belong to
  97. class &quot;VENDOR_CLASS_docsis3.0&quot;.
  98. </para>
  99. </section>
  100. <section id="classification-using-expressions">
  101. <title>Using Expressions In Classification</title>
  102. <para>
  103. The expression portion of classification contains operators and values.
  104. All values are currently strings and operators take a string or strings and
  105. return another string. When all the operations have completed
  106. the result should be a value of &quot;true&quot; or &quot;false&quot;.
  107. The packet belongs to
  108. the class (and the class name is added to the list of classes) if the result
  109. is &quot;true&quot;. Expressions are written in standard format and can be nested.
  110. </para>
  111. <para>
  112. Expressions are pre-processed during the parsing of the configuration file
  113. and converted to an internal representation. This allows certain types of
  114. errors to be caught and logged during parsing. Examples of these errors
  115. include incorrect number or types of arguments to an operator. The
  116. evaluation code will also check for this class of error and generally
  117. throw an exception, though they should not occur in a normally functioning
  118. system.
  119. </para>
  120. <para>
  121. Other issues, for example the starting position of a substring being
  122. outside of the substring or an option not existing in the packet, result
  123. in the operator returning an empty string.
  124. </para>
  125. <para>
  126. Expressions are a work in progress and the supported operators and
  127. values are limited. The expectation is that additional operators and values
  128. will be added over time, however it is expected the basic mechanisms will
  129. remain the same.
  130. </para>
  131. <para>
  132. <table frame="all" id="classification-values-list">
  133. <title>List of Classification Values</title>
  134. <tgroup cols='3'>
  135. <colspec colname='name' />
  136. <colspec colname='example' />
  137. <colspec colname='description' />
  138. <thead>
  139. <row>
  140. <entry>Name</entry>
  141. <entry>Example expression</entry>
  142. <entry>Example value</entry>
  143. <entry>Description</entry>
  144. </row>
  145. </thead>
  146. <tbody>
  147. <row>
  148. <entry>String literal</entry>
  149. <entry>'example'</entry>
  150. <entry>'example'</entry>
  151. <entry>A string</entry>
  152. </row>
  153. <row>
  154. <entry>Hexadecimal string literal</entry>
  155. <entry>0x5a7d</entry>
  156. <entry>'Z}'</entry>
  157. <entry>A hexadecimal string</entry>
  158. </row>
  159. <row>
  160. <entry>IP address literal</entry>
  161. <entry>10.0.0.1</entry>
  162. <entry>0x0a000001</entry>
  163. <entry>An IP address</entry>
  164. </row>
  165. <row>
  166. <entry>Integer literal</entry>
  167. <entry>123</entry>
  168. <entry>'123'</entry>
  169. <entry>An integer value</entry>
  170. </row>
  171. <row></row>
  172. <row>
  173. <entry>Binary content of the option</entry>
  174. <entry>option[123].hex</entry>
  175. <entry>'(content of the option)'</entry>
  176. <entry>The value of the option with given code from the
  177. packet as hex</entry>
  178. </row>
  179. <!-- Text option not fully defined yet, leave it out
  180. <row>
  181. <entry>Option Text</entry>
  182. <entry>option[123].text</entry>
  183. <entry>'foobar'</entry>
  184. <entry>The value of the option with given code from the
  185. packet as text</entry>
  186. </row>
  187. -->
  188. <row>
  189. <entry>Option existence</entry>
  190. <entry>option[123].exist</entry>
  191. <entry>'true'</entry>
  192. <entry>If the option with given code is present in the
  193. packet "true" else "false"</entry>
  194. </row>
  195. <row>
  196. <entry>DHCPv4 relay agent sub-option</entry>
  197. <entry>relay4[123].hex</entry>
  198. <entry>'(content of the RAI sub-option)'</entry>
  199. <entry>The value of sub-option with given code from the
  200. DHCPv4 Relay Agent Information option (option 82)</entry>
  201. </row>
  202. <row>
  203. <entry>Hardware address in DHCPv4 packet</entry>
  204. <entry>pkt4.mac</entry>
  205. <entry>0x010203040506</entry>
  206. <entry>The value of the chaddr field of the DHCPv4 packet on hlen bytes</entry>
  207. </row>
  208. <row>
  209. <entry>Hardware length in DHCPv4 packet</entry>
  210. <entry>pkt4.hlen</entry>
  211. <entry>0x00000006</entry>
  212. <entry>The value of the hlen field of the DHCPv4 packet padded to 4 bytes</entry>
  213. </row>
  214. <row>
  215. <entry>Hardware type in DHCPv4 packet</entry>
  216. <entry>pkt4.htype</entry>
  217. <entry>0x0000007b</entry>
  218. <entry>The value of the htype field of the DHCPv4 packet padded to 4 bytes</entry>
  219. </row>
  220. <row>
  221. <entry>ciaddr field in DHCPv4 packet</entry>
  222. <entry>pkt4.ciaddr</entry>
  223. <entry>192.0.2.1</entry>
  224. <entry>The value of the ciaddr field of the DHCPv4 packet (IPv4 address on 4 bytes)</entry>
  225. </row>
  226. <row>
  227. <entry>giaddr field in DHCPv4 packet</entry>
  228. <entry>pkt4.giaddr</entry>
  229. <entry>192.0.2.1</entry>
  230. <entry>The value of the giaddr field of the DHCPv4 packet (IPv4 address on 4 bytes)</entry>
  231. </row>
  232. <row>
  233. <entry>yiaddr field in DHCPv4 packet</entry>
  234. <entry>pkt4.yiaddr</entry>
  235. <entry>192.0.2.1</entry>
  236. <entry>The value of the yiaddr field of the DHCPv4 packet (IPv4 address on 4 bytes)</entry>
  237. </row>
  238. <row>
  239. <entry>siaddr field in DHCPv4 packet</entry>
  240. <entry>pkt4.siaddr</entry>
  241. <entry>192.0.2.1</entry>
  242. <entry>The value of the siaddr field of the DHCPv4 packet (IPv4 address on 4 bytes)</entry>
  243. </row>
  244. </tbody>
  245. </tgroup>
  246. </table>
  247. Hex Strings are converted into a string as expected. The starting &quot;0X&quot; or
  248. &quot;0x&quot; is removed and if the string is an odd number of characters a
  249. &quot;0&quot; is prepended to it.
  250. </para>
  251. <para>
  252. IP addresses are converted into strings of length 4 or 16. IPv4, IPv6,
  253. and IPv4 embedded IPv6 (e.g., IPv4 mapped IPv6) addresses are supported.
  254. </para>
  255. <para>
  256. Integers in the expression are converted to strings
  257. when the expression is read into Kea.
  258. </para>
  259. <para>
  260. "option[code].hex" extracts the value of the option with the code "code"
  261. from the incoming packet. If the packet doesn't contain the option, it
  262. returns the empty string. The string is presented as a byte string of
  263. the option payload without the type code or length fields.
  264. </para>
  265. <para>
  266. "option[code].exist" checks if an option with the code "code" is present
  267. in the incoming packet. It can be used with empty options.
  268. </para>
  269. <para>
  270. "relay4[code].hex" attempts to extract the value of the sub-option
  271. "code" from the option inserted as the DHCPv4 Relay Agent Information
  272. (82) option. If the packet doesn't contain a RAI option, or the RAI
  273. option doesn't contain the requested sub-option, the expression returns
  274. an empty string. The string is presented as a byte string of the
  275. option payload without the type code or length fields. This
  276. expression is allowed in DHCPv4 only.
  277. </para>
  278. <para>
  279. "relay4" shares the same representation types than "option", for
  280. instance "relay4[code].exists" is supported.
  281. </para>
  282. <para>
  283. Expressions starting with pkt4 can be used only in DHCPv4.
  284. </para>
  285. <para>
  286. <table frame="all" id="classification-expressions-list">
  287. <title>List of Classification Expressions</title>
  288. <tgroup cols='3'>
  289. <colspec colname='name' />
  290. <colspec colname='example' />
  291. <colspec colname='description' />
  292. <thead>
  293. <row>
  294. <entry>Name</entry>
  295. <entry>Example</entry>
  296. <entry>Description</entry>
  297. </row>
  298. </thead>
  299. <tbody>
  300. <row><entry>Equal</entry> <entry>'foo' == 'bar'</entry><entry>Compare the two values and return "true" or "false"</entry></row>
  301. <row><entry>Not</entry> <entry>not ('foo' == 'bar')</entry><entry>Logical negation</entry></row>
  302. <row><entry>And</entry> <entry>('foo' == 'bar') and ('bar' == 'foo')</entry><entry>Logical and</entry></row>
  303. <row><entry>Or</entry> <entry>('foo' == 'bar') or ('bar' == 'foo')</entry><entry>Logical or</entry></row>
  304. <row><entry>Substring</entry><entry>substring('foobar',0,3)</entry><entry>Return the requested substring</entry></row>
  305. <row><entry>Concat</entry><entry>concat('foo','bar')</entry><entry>Return the concatenation of the strings</entry></row>
  306. </tbody>
  307. </tgroup>
  308. </table>
  309. </para>
  310. <section>
  311. <title>Logical operators</title>
  312. The Not, And and Or logical operators are the common operators. Not
  313. has the highest precedence, Or the lowest. And and Or are (left)
  314. associative, parentheses around a logical expression can be used
  315. to enforce a specific grouping, for instance in "A and (B or C)"
  316. (without parentheses "A and B or C" means "(A and B) or C").
  317. </section>
  318. <section>
  319. <title>Substring</title>
  320. The substring operator "substring(value, start, length)" accepts both positive and
  321. negative values for the starting position and the length. For "start", a value of
  322. 0 is the first byte in the string while -1 is the last byte. If the starting
  323. point is outside of the original string an empty string is returned. "length"
  324. is the number of bytes to extract. A negative number means to count towards
  325. the beginning of the string but doesn't include the byte pointed to by "start".
  326. The special value "all" means to return all bytes from start to the end of the
  327. string. If length is longer than the remaining portion of the string then
  328. the entire remaining portion is returned. Some examples may be helpful:
  329. <screen>
  330. substring('foobar', 0, 6) == 'foobar'
  331. substring('foobar', 3, 3) == 'bar'
  332. substring('foobar', 3, all) == 'bar'
  333. substring('foobar', 1, 4) == 'ooba'
  334. substring('foobar', -5, 4) == 'ooba'
  335. substring('foobar', -1, -3) == 'oba'
  336. substring('foobar', 4, -2) == 'ob'
  337. substring('foobar', 10, 2) == ''
  338. </screen>
  339. </section>
  340. <section>
  341. <title>Concat</title>
  342. The concat function "concat(string1, string2)" returns the
  343. concatenation of its two arguments. For instance:
  344. <screen>
  345. concat('foo', 'bar') == 'foobar'
  346. </screen>
  347. </section>
  348. </section>
  349. <note>
  350. <para>
  351. The expression for each class is executed on each packet received.
  352. If the expressions are overly complex, the time taken to execute
  353. them may impact the performance of the server. If you need
  354. complex or time consuming expressions you should write a <link
  355. linkend='hooks-libraries'>hook</link> to perform the necessary work.
  356. </para> </note>
  357. <section id="classification-configuring">
  358. <title>Configuring Classes</title>
  359. <para>
  360. A class contains three items: a name, a test expression and option data.
  361. The name must exist and must be unique amongst all classes. The test
  362. expression and option data are optional.
  363. </para>
  364. <para>
  365. The test expression is a string containing the logical expression used to
  366. determine membership in the class. The entire expression is in double
  367. quotes.
  368. </para>
  369. <para>
  370. The option data is a list which defines any options that should be assigned
  371. to members of this class.
  372. </para>
  373. <para>
  374. In the following example the class named &quot;Client_foo&quot; is defined.
  375. It is comprised of all clients who's client ids (option 61) start with the
  376. string &quot;foo&quot;. Members of this class will be given 192.0.2.1 and
  377. 192.0.2.2 as their domain name servers.
  378. <screen>
  379. "Dhcp4": {
  380. "client-classes": [<userinput>
  381. {
  382. "name": "Client_foo",
  383. "test": "substring(option[61].hex,0,3) == 'foo'",
  384. "option-data": [
  385. {
  386. "name": "domain-name-servers",
  387. "code": 6,
  388. "space": "dhcp4",
  389. "csv-format": true,
  390. "data": "192.0.2.1, 192.0.2.2"
  391. }
  392. ]
  393. },
  394. ...
  395. ],</userinput>
  396. ...
  397. }</screen>
  398. </para>
  399. <para>
  400. This example shows a client class being defined for use by the DHCPv6 server.
  401. In it the class named &quot;Client_enterprise&quot; is defined. It is comprised
  402. of all clients who's client identifiers start with the given hex string (which
  403. would indicate a DUID based on an enterprise id of 0xAABBCCDD). Members of this
  404. class will be given an 2001:db8:0::1 and 2001:db8:2::1 as their domain name servers.
  405. <screen>
  406. "Dhcp6": {
  407. "client-classes": [<userinput>
  408. {
  409. "name": "Client_enterprise",
  410. "test": "substring(option[1].hex,0,6) == 0x0002AABBCCDD'",
  411. "option-data": [
  412. {
  413. "name": "dns-servers",
  414. "code": 23,
  415. "space": "dhcp6",
  416. "csv-format": true,
  417. "data": "2001:db8:0::1, 2001:db8:2::1"
  418. }
  419. ]
  420. },
  421. ...
  422. ],</userinput>
  423. ...
  424. }</screen>
  425. </para>
  426. </section>
  427. <section id="classification-subnets">
  428. <title>Configuring Subnets With Class Information</title>
  429. <para>
  430. In certain cases it beneficial to restrict access to certain subnets
  431. only to clients that belong to a given class using the "client-class"
  432. keyword when defining the subnet.
  433. </para>
  434. <para>
  435. Let's assume that the server is connected to a network segment that uses
  436. the 192.0.2.0/24 prefix. The Administrator of that network has decided
  437. that addresses from range 192.0.2.10 to 192.0.2.20 are going to be
  438. managed by the DHCP4 server. Only clients belonging to client class
  439. Client_foo are allowed to use this subnet. Such a
  440. configuration can be achieved in the following way:
  441. <screen>
  442. "Dhcp4": {
  443. "client-classes": [
  444. {
  445. "name": "Client_foo",
  446. "test": "substring(option[61].hex,0,3) == 'foo'",
  447. "option-data": [
  448. {
  449. "name": "domain-name-servers",
  450. "code": 6,
  451. "space": "dhcp4",
  452. "csv-format": true,
  453. "data": "192.0.2.1, 192.0.2.2"
  454. }
  455. ]
  456. },
  457. ...
  458. ],<userinput>
  459. "subnet4": [
  460. {
  461. "subnet": "192.0.2.0/24",
  462. "pools": [ { "pool": "192.0.2.10 - 192.0.2.20" } ],
  463. "client-class": "Client_foo"
  464. },
  465. ...
  466. ],</userinput>,
  467. ...
  468. }</screen>
  469. </para>
  470. <para>
  471. The following example shows restricting access to a DHCPv6 subnet. This
  472. configuration will restrict use of the addresses 2001:db8:1::1 to
  473. 2001:db8:1::FFFF to members of the "Client_enterprise" class.
  474. <screen>
  475. "Dhcp6": {
  476. "client-classes": [
  477. {
  478. "name": "Client_enterprise",
  479. "test": "substring(option[1].hex,0,6) == 0x0002AABBCCDD'",
  480. "option-data": [
  481. {
  482. "name": "dns-servers",
  483. "code": 23,
  484. "space": "dhcp6",
  485. "csv-format": true,
  486. "data": "2001:db8:0::1, 2001:db8:2::1"
  487. }
  488. ]
  489. },
  490. ...
  491. ], <userinput>
  492. "subnet6": [
  493. {
  494. "subnet": "2001:db8:1::/64",
  495. "pools": [ { "pool": "2001:db8:1::-2001:db8:1::ffff" } ],
  496. "client-class": "Client_enterprise"
  497. }
  498. ],</userinput>
  499. ...
  500. }</screen>
  501. </para>
  502. </section>
  503. <section>
  504. <title>Using Classes</title>
  505. <para>
  506. Currently classes can be used for two functions. They can supply options
  507. to the members of the class and they can be used to choose a subnet from which an
  508. address will be assigned to the class member.
  509. </para>
  510. <para>
  511. When supplying options, options defined as part of the class definition
  512. are considered &quot;class globals&quot;. They will override any global options that
  513. may be defined and in turn will be overridden by any options defined for an
  514. individual subnet.
  515. </para>
  516. </section>
  517. <section>
  518. <title>Classes and Hooks</title>
  519. <para>
  520. You may use a hook to classify your packets. This may be useful if the
  521. expression would either be complex or time consuming and be easier or
  522. better to write as code. Once the hook has added the proper class name
  523. to the packet the rest of the classification system will work as normal
  524. in choosing a subnet and selecting options. For a description of the
  525. hooks see <xref linkend="hooks-libraries"/>, for a description on
  526. configuring he classes see <xref linkend="classification-configuring"/>
  527. and <xref linkend="classification-subnets"/>.
  528. </para>
  529. </section>
  530. </chapter>