1.. _hooks-radius: 2 3radius: RADIUS Server Support 4============================= 5 6The RADIUS hooks library allows Kea to interact with two types of RADIUS 7servers: access and accounting. Although the most common DHCP and RADIUS 8integration is done on the DHCP relay-agent level (DHCP clients send 9DHCP packets to DHCP relays; those relays contact the RADIUS server and 10depending on the response either send the packet to the DHCP server or 11drop it), it does require DHCP relay hardware to support RADIUS 12communication. Also, even if the relay has the necessary support, it is 13often not flexible enough to send and receive additional RADIUS 14attributes. As such, the alternative looks more appealing: to extend the 15DHCP server to talk to RADIUS directly. That is the goal this library 16intends to fulfill. 17 18.. note:: 19 20 This library may only be loaded by the ``kea-dhcp4`` or the 21 ``kea-dhcp6`` process. 22 23The major feature of this hooks library is the ability to use RADIUS 24authorization. When a DHCP packet is received, the Kea server sends an 25Access-Request to the RADIUS server and waits for a response. The server 26then sends back either an Access-Accept with specific client attributes, 27or an Access-Reject. There are two cases supported here: first, the 28Access-Accept includes a Framed-IP-Address (for DHCPv4) or 29Framed-IPv6-Address (for DHCPv6), which will be interpreted by Kea as an 30instruction to assign that specified IPv4 or IPv6 address. This 31effectively means RADIUS can act as an address-reservation database. 32 33The second case supported is the ability to assign clients to specific 34pools based on a RADIUS response. In this case, the RADIUS server sends 35back an Access-Accept with a Framed-Pool (IPv4) or Framed-IPv6-Pool 36(IPv6). In both cases, Kea interprets those attributes as client 37classes. With the addition of the ability to limit access to pools to 38specific classes (see :ref:`classification-pools`), RADIUS can be 39used to force the client to be assigned a dynamic address from a 40specific pool. Furthermore, the same mechanism can be used to control 41what kind of options the client will get if there are DHCP options 42specified for a particular class. 43 44.. _hooks-radius-install: 45 46Compilation and Installation of the RADIUS Hook 47~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 48 49The following section describes how to compile and install the software 50on CentOS 7.0. Other systems may differ slightly. 51 52.. note:: 53 54 Starting with Kea 1.7.0, ISC now provides Kea software and hooks in convenient to use 55 native DEB and RPM packages. This includes the RADIUS hook and the required patched version 56 of the FreeRADIUS client library. The software compilation for RADIUS is complicated. unless 57 you have specific reasons to compile it yourself, you should seriously consider using 58 native packages. 59 60STEP 1: Install dependencies 61 62Several tools are needed to build the dependencies and Kea itself. The 63following commands should install them: 64 65.. code-block:: console 66 67 $ sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm 68 $ sudo yum install gcc-g++ openssl-devel log4cplus-devel wget git 69 70STEP 2: Install FreeRADIUS 71 72The Kea RADIUS hooks library uses the FreeRADIUS client library to 73conduct RADIUS communication. Unfortunately, the standard 1.1.7 release 74available from the project website https://freeradius.org/sub_projects/ 75has several serious deficiencies; ISC engineers observed a segmentation 76fault during testing. Also, the base version of the library does not 77offer asynchronous transmissions, which are essential for effective 78accounting implementation. Both of these issues were addressed by ISC 79engineers, and the changes have been reported to the FreeRADIUS client 80project. Acceptance of those changes is outside of ISC's control, so 81until those are processed, it is strongly recommended to use the 82FreeRADIUS client with ISC's patches. To download and compile this 83version, please use the following steps: 84 85.. code-block:: console 86 87 $ git clone https://github.com/fxdupont/freeradius-client.git 88 $ cd freeradius-client/ 89 $ git checkout iscdev 90 $ ./configure 91 $ make 92 $ sudo make install 93 94Additional parameters may be passed to the configure script, if needed. 95Once installed, the FreeRADIUS client will be installed in 96/usr/local. This is the default path where Kea will be looking for it. 97It can be installed in a different directory; if so, 98make sure to add that path to the configure script when compiling Kea. 99 100STEP 3: Install a recent BOOST version 101 102Kea requires a reasonably recent Boost version. Unfortunately, the 103version available in CentOS 7 is too old, so a newer Boost version is 104necessary. Furthermore, CentOS 7 has an old version of the g++ compiler 105that does not handle the latest Boost versions. Fortunately, Boost 1.65 106meets both requirements; it is both recent enough for Kea and able to be 107compiled using the g++ 4.8 version in CentOS. 108 109To download and compile Boost 1.65, please use the following commands: 110 111.. code-block:: console 112 113 $ wget -nd https://boostorg.jfrog.io/artifactory/main/release/1.65.1/source/boost_1_65_1.tar.gz 114 $ tar -zxvf boost_1_65_1.tar.gz 115 $ cd boost_1_65_1/ 116 $ ./bootstrap.sh 117 $ ./b2 --without-python 118 $ sudo ./b2 install 119 120Note that the b2 script may optionally take extra parameters; one of 121them specifies the destination path where the sources are to be 122compiled. 123 124Alternatively, some systems provide newer boost packages. For example, 125CentOS 7 provides ``boost169-devel``. If you install it with 126``yum install boost169-devel``, you will need to point Kea to it with: 127 128.. code-block:: console 129 130 $ ./configure --with-boost-include=/usr/include/boost169 --with-boost-lib-dir=/usr/lib64/boost169 131 132STEP 4: Compile and install Kea 133 134Obtain the Kea sources either by downloading them from the git 135repository or extracting the tarball. Use one of those commands 136to obtain the Kea sources. 137 138Choice 1: get from github 139 140.. code-block:: console 141 142 $ git clone https://github.com/isc-projects/kea.git 143 144Choice 2: get a tarball and extract it 145 146.. parsed-literal:: 147 148 $ tar -zxvf kea-|release|.tar.gz 149 150The next step is to extract the premium Kea package that contains the 151RADIUS repository into the Kea sources. After the tarball is extracted, 152the Kea sources should have a premium/ subdirectory. 153 154.. parsed-literal:: 155 156 $ cd kea 157 $ tar -zxvf ../kea-premium-radius-|release|.tar.gz 158 159Once this is done, verify that the Kea sources look similar to this: 160 161.. code-block:: console 162 163 $ ls -l 164 total 952 165 -rw-r--r-- 1 thomson staff 6192 Apr 25 17:38 AUTHORS 166 -rw-r--r-- 1 thomson staff 29227 Apr 25 17:38 COPYING 167 -rw-r--r-- 1 thomson staff 360298 Apr 25 20:00 ChangeLog 168 -rw-r--r-- 1 thomson staff 645 Apr 25 17:38 INSTALL 169 -rw-r--r-- 1 thomson staff 5015 Apr 25 17:38 Makefile.am 170 -rw-r--r-- 1 thomson staff 587 Apr 25 17:38 README 171 -rw-r--r-- 1 thomson staff 62323 Apr 25 17:38 configure.ac 172 drwxr-xr-x 12 thomson staff 408 Apr 26 19:04 doc 173 drwxr-xr-x 7 thomson staff 238 Apr 25 17:38 examples 174 drwxr-xr-x 5 thomson staff 170 Apr 26 19:04 ext 175 drwxr-xr-x 8 thomson staff 272 Apr 26 19:04 m4macros 176 drwxr-xr-x 20 thomson staff 680 Apr 26 11:22 premium 177 drwxr-xr-x 10 thomson staff 340 Apr 26 19:04 src 178 drwxr-xr-x 14 thomson staff 476 Apr 26 19:04 tools 179 180The makefiles must be regenerated using ``autoreconf``. 181 182The next step is to configure Kea, and there are several essential steps 183necessary here. Running ``autoreconf -if`` is necessary to compile the 184premium package that contains RADIUS. Also, the --with-freeradius option 185is necessary to tell Kea where the FreeRADIUS client sources can be 186found. Also, since the non-standard Boost is used, the path to it must 187be specified. 188 189.. code-block:: console 190 191 $ autoreconf -i 192 $ ./configure --with-freeradius=/path/to/freeradius --with-boost-include=/path/to/boost --with-boost-lib-dir=/path/to/boost/state/lib 193 194For example, assuming the FreeRADIUS client was installed in the default 195directory (/usr/local) and the Boost 1.65 sources were compiled in 196/home/thomson/devel/boost1_65_1, the configure path should look as 197follows: 198 199.. code-block:: console 200 201 $ ./configure --with-freeradius=/usr/local \ 202 --with-boost-include=/home/thomson/devel/boost_1_65_1 \ 203 --with-boost-lib-dir=/home/thomson/devel/boost_1_65_1/stage/lib 204 205After some checks, the configure script should print a report similar to 206the following: 207 208.. parsed-literal:: 209 210 Kea source configure results: 211 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 212 213 Package: 214 Name: kea 215 Version: |release| 216 Extended version: |release| (tarball) 217 OS Family: Linux 218 219 Hooks directory: /usr/local/lib/kea/hooks 220 Premium hooks: yes 221 Included Hooks: forensic_log flex_id host_cmds subnet_cmds radius host_cache 222 223 C++ Compiler: 224 CXX: g++ --std=c++11 225 CXX_VERSION: g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16) 226 CXX_STANDARD: 201103 227 DEFS: -DHAVE_CONFIG_H 228 CPPFLAGS: -DOS_LINUX -DBOOST_ASIO_HEADER_ONLY 229 CXXFLAGS: -g -O2 230 LDFLAGS: -lpthread 231 KEA_CXXFLAGS: -Wall -Wextra -Wnon-virtual-dtor -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -pthread -Wno-missing-field-initializers -fPIC 232 233 Python: 234 PYTHON_VERSION: not needed (because kea-shell is disabled) 235 236 Boost: 237 BOOST_VERSION: 1.65.1 238 BOOST_INCLUDES: -I/home/thomson/devel/boost_1_65_1 239 BOOST_LIBS: -L/home/thomson/devel/boost_1_65_1/stage/lib -lboost_system 240 241 OpenSSL: 242 CRYPTO_VERSION: OpenSSL 1.0.2k 26 Jan 2017 243 CRYPTO_CFLAGS: 244 CRYPTO_INCLUDES: 245 CRYPTO_LDFLAGS: 246 CRYPTO_LIBS: -lcrypto 247 248 Botan: no 249 250 Log4cplus: 251 LOG4CPLUS_VERSION: 1.1.3 252 LOG4CPLUS_INCLUDES: -I/usr/include 253 LOG4CPLUS_LIBS: -L/usr/lib -L/usr/lib64 -llog4cplus 254 255 Flex/bison: 256 FLEX: flex 257 BISON: bison -y 258 259 MySQL: 260 no 261 262 PostgreSQL: 263 no 264 265 Cassandra CQL: 266 no 267 Google Test: 268 no 269 Google Benchmark: 270 no 271 272 FreeRADIUS client: 273 FREERADIUS_INCLUDE: -I/usr/local/include 274 FREERADIUS_LIB: -L/usr/local/lib -lfreeradius-client 275 FREERADIUS_DICTIONARY: /usr/local/etc/radiusclient/dictionary 276 277 Developer: 278 Enable Debugging: no 279 Google Tests: no 280 Valgrind: not found 281 C++ Code Coverage: no 282 Logger checks: no 283 Generate Documentation: no 284 Parser Generation: no 285 Kea-shell: no 286 Perfdhcp: no 287 288Please make sure that the compilation includes the following: 289 290- RADIUS listed in Included Hooks; 291- FreeRADIUS client directories printed and pointing to the right 292 directories; 293- Boost version at least 1.65.1. The versions available in CentOS 7 294 (1.48 and 1.53) are too old. 295 296Once the configuration is complete, compile Kea using make. If the 297system has more than one core, using the "-j N" 298option is recommended to speed up the build. 299 300.. code-block:: console 301 302 $ make -j5 303 $ sudo make install 304 305.. _hooks-radius-config: 306 307RADIUS Hook Configuration 308~~~~~~~~~~~~~~~~~~~~~~~~~ 309 310The RADIUS hook is a library that has to be loaded by either DHCPv4 or 311DHCPv6 Kea servers. Unlike some other available hooks libraries, this one 312takes many parameters. For example, this configuration could be used: 313 314:: 315 316 "Dhcp4": { 317 318 # Your regular DHCPv4 configuration parameters here. 319 320 "hooks-libraries": [ 321 { 322 # Note that RADIUS requires host-cache for proper operation, 323 # so that library is loaded as well. 324 "library": "/usr/local/lib/kea/hooks/libdhcp_host_cache.so" 325 }, 326 { 327 "library": "/usr/local/lib/kea/hooks/libdhc_radius.so", 328 "parameters": { 329 330 # Specify where FreeRADIUS dictionary could be located 331 "dictionary": "/usr/local/etc/freeradius/dictionary", 332 333 # Specify which address to use to communicate with RADIUS servers 334 "bindaddr": "*", 335 336 # more RADIUS parameters here 337 } 338 } ] 339 340RADIUS is a complicated environment. As such, it is not feasible 341to provide a default configuration that works for everyone. 342However, we do have one example that showcases some of the more common 343features. Please see doc/examples/kea4/hooks-radius.json in the Kea 344sources. 345 346The RADIUS hook library supports the following global configuration 347flags, which correspond to FreeRADIUS client library options: 348 349- ``bindaddr`` (default "*") - specifies the address to be used by the 350 hooks library in communication with RADIUS servers. The "*" special 351 value tells the kernel to choose the address. 352 353- ``canonical-mac-address`` (default false) - specifies whether MAC 354 addresses in attributes follow the canonical RADIUS format (lowercase 355 pairs of hexadecimal digits separated by '-'). 356 357- ``client-id-pop0`` (default false) - used with flex-id, removes the 358 leading zero (or pair of zeroes in DHCPv6) type in client-id (aka 359 duid in DHCPv6). Implied by client-id-printable. 360 361- ``client-id-printable`` (default false) - checks whether the 362 client-id/duid content is printable and uses it as is instead of in 363 hexadecimal. Implies client-id-pop0 and extract-duid as 0 and 255 are 364 not printable. 365 366- ``deadtime`` (default 0) is a mechanism to try unresponsive servers 367 after responsive servers. Its value specifies the number of seconds 368 after which a server is considered not to have answered, so 0 369 disables the mechanism. As the asynchronous communication does not 370 use locks or atomics, it is recommended that you do not use this 371 feature when running in this mode. 372 373- ``dictionary`` (default set by configure at build time) - is the 374 attribute and value dictionary. Note that it is a critical parameter. You 375 may find dictionary examples in the FreeRADIUS repository under the etc 376 directory. 377 378- ``extract-duid`` (default true) - extracts the embedded duid from an 379 RFC 4361-compliant DHCPv4 client-id. Implied by client-id-printable. 380 381- ``identifier-type4`` (default client-id) - specifies the identifier 382 type to build the User-Name attribute. It should be the same as the 383 host identifier, and when the flex-id hook library is used the 384 replace-client-id must be set to true; client-id will be used with 385 client-id-pop0. 386 387- ``identifier-type6`` (default duid) - specifies the identifier type to 388 build the User-Name attribute. It should be the same as the host 389 identifier, and when the flex-id hook library is used the 390 replace-client-id must be set to true; duid will be used with 391 client-id-pop0. 392 393- ``realm`` (default "") - is the default realm. 394 395- ``reselect-subnet-address`` (default false) - uses the Kea reserved 396 address/RADIUS Framed-IP-Address or Framed-IPv6-Address to reselect 397 subnets where the address is not in the subnet range. 398 399- ``reselect-subnet-pool`` (default false) - uses the Kea 400 client-class/RADIUS Frame-Pool to reselect subnets where no available 401 pool can be found. 402 403- ``retries`` (default 3) - is the number of retries before trying the 404 next server. Note that it is not supported for asynchronous 405 communication. 406 407- ``session-history`` (default "") - is the name of the file providing 408 persistent storage for accounting session history. 409 410- ``timeout`` (default 10) - is the number of seconds during which a 411 response is awaited. 412 413When ``reselect-subnet-pool`` or ``reselect-subnet-address`` is set to 414true at the reception of RADIUS Access-Accept, the selected subnet is 415checked against the client-class name or the reserved address; if it 416does not match, another subnet is selected among matching subnets. 417 418Two services are supported: 419 420- ``access`` - the authentication service. 421 422- ``accounting`` - the accounting service. 423 424Configuration of services is divided into two parts: 425 426- Servers that define RADIUS servers that the library is expected to 427 contact. Each server may have the following items specified: 428 429 - ``name`` - specifies the IP address of the server (it is 430 possible to use a name which will be resolved, but it is not 431 recommended). 432 433 - ``port`` (default RADIUS authentication or accounting service) - 434 specifies the UDP port of the server. Note that the 435 FreeRADIUS client library by default uses ports 1812 436 (authorization) and 1813 (accounting). Some server implementations 437 use 1645 (authorization) and 1646 (accounting). The 438 "port" parameter may be used to adjust as needed. 439 440 - ``secret`` - authenticates messages. 441 442 There may be up to eight servers. Note that when no server is 443 specified, the service is disabled. 444 445- Attributes which define additional information that the Kea server 446 will send to a RADIUS server. The parameter must be identified either 447 by a name or type. Its value can be specified in one of three 448 possible ways: data (which defines a plain text value), raw (which 449 defines the value in hex), or expr (which defines an expression, 450 which will be evaluated for each incoming packet independently). 451 452 - ``name`` - the name of the attribute. 453 454 - ``type`` - the type of the attribute. Either the type or the name must be 455 provided, and the attribute must be defined in the dictionary. 456 457 - ``data`` - the first of three ways to specify the attribute 458 content. The data entry is parsed by the FreeRADIUS library, so 459 values defined in the dictionary of the attribute may be used. 460 461 - ``raw`` - the second of three ways to specify the attribute 462 content; it specifies the content in hexadecimal. Note that it 463 does not work with integer-content attributes (date, integer, and 464 IPv4 address); a string-content attribute (string, IPv6 address, 465 and IPv6 prefix) is required. 466 467 - ``expr`` - the last way to specify the attribute content. It 468 specifies an evaluation expression which must return a not-empty 469 string when evaluated with the DHCP query packet. Currently this 470 is restricted to the access service. 471 472For example, to specify a single access server available on localhost 473that uses "xyz123" as a secret, and tell Kea to send three additional 474attributes (Password, Connect-Info, and Configuration-Token), the 475following snippet could be used: 476 477:: 478 479 "parameters": { 480 481 # Other RADIUS parameters here 482 483 "access": { 484 485 # This starts the list of access servers 486 "servers": [ 487 { 488 # These are parameters for the first (and only) access server 489 "name": "127.0.0.1", 490 "port": 1812, 491 "secret": "xyz123" 492 } 493 # Additional access servers could be specified here 494 ], 495 496 # This defines a list of additional attributes Kea will send to each 497 # access server in Access-Request. 498 "attributes": [ 499 { 500 # This attribute is identified by name (must be present in the 501 # dictionary) and has static value (i.e. the same value will be 502 # sent to every server for every packet) 503 "name": "Password", 504 "data": "mysecretpassword" 505 }, 506 { 507 # It is also possible to specify an attribute using its type, 508 # rather than a name. 77 is Connect-Info. The value is specified 509 # using hex. Again, this is a static value. It will be sent the 510 # same for every packet and to every server. 511 "type": 77, 512 "raw": "65666a6a71" 513 }, 514 { 515 # This example shows how an expression can be used to send dynamic 516 # value. The expression (see Section 13) may take any value from 517 # the incoming packet or even its metadata (e.g. the interface 518 # it was received over from) 519 "name": "Configuration-Token", 520 "expr": "hexstring(pkt4.mac,':')" 521 } 522 ] # End of attributes 523 }, # End of access 524 525 # Accounting parameters. 526 "accounting": { 527 # This starts the list of accounting servers 528 "servers": [ 529 { 530 # These are parameters for the first (and only) accounting server 531 "name": "127.0.0.1", 532 "port": 1813, 533 "secret": "sekret" 534 } 535 # Additional accounting servers could be specified here 536 ] 537 } 538 539 } 540 541Customization is sometimes required for certain attributes by devices belonging 542to various vendors. This is a great way to leverage the expression evaluation 543mechanism. For example, MAC addresses which you might use as a convenience 544value for the User-Name attribute most likely will appear in colon-hexadecimal 545notation ``de:ad:be:ef:ca:fe``, but it might need to be expressed in: 546 547* hyphen-hexadecimal notation ``de-ad-be-ef-ca-fe`` 548 549.. code-block:: json 550 551 { 552 "parameters": { 553 "access": { 554 "attributes": [ 555 { 556 "name": "User-Name", 557 "expr": "hexstring(pkt4.mac, '-')" 558 } 559 ] 560 } 561 } 562 } 563 564* period-separated hexadecimal notation ``dead.beef.cafe``, preferred by Cisco devices 565 566.. code-block:: json 567 568 { 569 "parameters": { 570 "access": { 571 "attributes": [ 572 { 573 "name": "User-Name", 574 "expr": "concat(concat(concat(substring(hexstring(pkt4.mac, ''), 0, 4), '.'), concat(substring(hexstring(pkt4.mac, ''), 4, 4), '.'), concat(substring(hexstring(pkt4.mac, ''), 8, 4), '.'))" 575 } 576 ] 577 } 578 } 579 } 580 581 582For the RADIUS hooks library to operate properly in DHCPv4, 583the Host Cache hooks library must also be loaded. The reason for this 584is somewhat complex. In a typical deployment, the DHCP clients send 585their packets via DHCP relay which inserts certain Relay Agent 586Information options, such as circuit-id or remote-id. The values of 587those options are then used by the Kea DHCP server to formulate the 588necessary attributes in the Access-Request message sent to the RADIUS 589server. However, once the DHCP client gets its address, it then renews 590by sending packets directly to the DHCP server. As a result, the relays 591are not able to insert their RAI options, and the DHCP server cannot send 592the Access-Request queries to the RADIUS server by using just the 593information from incoming packets. Kea needs to keep the information 594received during the initial Discover/Offer exchanges and use it again 595later when sending accounting messages. 596 597This mechanism is implemented based on user context in host 598reservations. (See :ref:`user-context` and :ref:`user-context-hooks` for 599details.) The host cache mechanism allows the information retrieved by 600RADIUS to be stored and later used for sending accounting and access 601queries to the RADIUS server. In other words, the host-cache mechanism 602is mandatory, unless administrators do not want RADIUS communication for messages 603other than Discover and the first Request from each client. 604