Changes between Version 27 and Version 28 of RadiusDesign


Ignore:
Timestamp:
Aug 2, 2018, 8:58:42 PM (16 months ago)
Author:
vicky
Comment:

Reverted to version 26.

Legend:

Unmodified
Added
Removed
Modified
  • RadiusDesign

    v27 v28  
    1 https://gitlab.isc.org/isc-projects/kea/wikis/implemented-designs/radius-design
     1= RADIUS support in Kea MIGRATED TO GITLAB =
     2
     3This document describes a design to extend Kea capabilities with Radius support.
     4
     5== OVERALL GOALS ==
     6
     7The following goals are sought after in this design:
     8
     91. Assign specific static addresses to some clients as provided by Radius.
     102. Assign other clients to specific pools as provided by Radius.
     113. Retrieve client information from Radius using authentication mechanism (Access-Request and Access-Accept / Access-Reject messages).
     124. Support accounting using Radius accounting mechanism.
     135. Limit number of authentication exchanges with Radius to absolute minimum.
     146. Be able to handle multiple Radius servers (at least two for authentication and at least two for accounting).
     157. Due to business reasons, the initial focus is on IPv4. IPv6 support will be added at a later stage.
     168. The primary OSes used for this project are CentOS 7 and !RedHat 7. Testing on other systems may be done on best effort basis.
     17
     18== DESIGN REQUIREMENTS ==
     19
     201. '''Access control using Radius'''. The Kea DHCP server will be extended to allow contacting a RADIUS server every time a new packet comes in to determine whether or not to assign an address, and to get the IP address assignment or subnet to use from the RADIUS server, using the following algorithm:
     21
     22   a. Upon receiving a packet (e.g. DHCPDISCOVER) from a new client, Kea will send Access-Request to the Radius server including "remote-id" and/or "circuit-id" value provided in DHCP option 82. Note: Kea will allow via configuration to choose which AVP to send to the Radius Server, and allow, to add Static AVP.
     23
     24   b. Depending on the RADIUS server response, Kea will take one of three actions: a) pick a specific pool based on the Framed-Pool, b) use the Framed-IP-Address from the RADIUS response or reject assignment (if Access-Reject was received).
     25
     26   c. If Access-Accept contains a User-Class attribute Kea will conduct special processing explained below. If the User-Class attribute is not present or is empty, Kea will continue normal packet processing.
     27
     28   The User-Class attribute returning from the Radius server will contain 5 or 6 comma separated fields.
     29
     30      - BW = Information field
     31      - Pool-Name = The name of the client class assigned to the User (informational Field)
     32      - IP-Static = The IP assign to the user, if it static (informational field)
     33      - Subnet-Id = needed to assign to a static_ip, if the return attribute contain Static IP
     34      - VAS – Information field
     35   There may be two more mutually exclusive fields:
     36      - Framed-Pool – The same as the Pool-Name, uses to assign a MAC/Remote-ID to a specific class name.
     37      - Framed-IP-Address – The IP assign to the User, if there is no Framed-Pool attribute, combined with the Subnet-Id, allow the Kea to assign static IP -> insert into kea host table.
     38
     39   d. The Radius interface will be implemented as host data source. The information will be returned as Host reservation information. Host class will be extended to store additional information (“user context”) that will convey necessary Radius attributes that are returned in Access-Accept and are later needed when sending Accounting-request.
     40
     412. '''Accounting using Radius'''. Kea will notify RADIUS server about the address leases being assigned, renewed, released or expired. Upon receiving a DHCPREQUEST from a client requesting an assignment of a new lease (not a renewing or rebinding client), Kea will send Accounting-Request with Acct-Status-Type set to "Start" to the Radius server. If the DHCPREQUEST is received from the renewing (or rebinding) client, Kea will send Accounting-Request with Acct-Status-Type set to "Interim-Update" instead. Upon receiving a DHCPRELEASE from a client, Kea will send Accounting- Request with Acct-Status-Type set to "Stop" to the Radius server. Also, the same packet with the same Acct-Status-Type value will be sent when the lease is expired.
     42
     43   The accounting information will be sent as Accounting-Request message with the following information:
     44
     45   a. User-Name=value of DHCP option 82 (value inserted by the relay)
     46   b. Framed-IP-Address=IPv4 (IPv4 address assigned by Kea)
     47   c. User-Class=User-Class (value returned by RADIUS in Access-Accept message)
     48   d. Filter-ID=Filter-ID (value returned by RADIUS in Access-Accept message)
     49   e. Connect-Info=MAC address (value set by the client)
     50   f. Acct-Session-ID=MAC address;IPv4 address;value of DHCP option 82
     51
     523. '''Host caching'''. Radius communication has significant impact on performance, therefore Radius responses for Access-Request must be cached. In Kea terminology, the Radius interface will be implemented as host backend and will return Host objects. A new mechanism to cache Host objects will be developed. The mechanism will have the following properties:
     53
     54  a. It will be possible to configure Kea to use more than one host backends, with cache and Radius being two possible options. Kea will inspect the backends in order they are specified. If information is found in the first one (cache), the second one (Radius) is not looked up.
     55
     56  b. It will be possible to tell Kea to put Host objects returned by a backed into a cache. This way for a given client, the Radius will be contacted only once and the response will be cached.
     57
     58  c. To retain the cache information after server restart, the cache will be stored on disk in a text file. It is understood that the cache will be optimized for in-memory operation and reading large cache from disk may make the server start-up slower.
     59
     60  d. There will be a very basic mechanism to control maximum size of the cache, expressed in number of hosts. This control mechanism will be optional. It will be possible to disable it, so Kea would never drop anything from a cache. This will ensure the Radius communication be kept to absolute minimum. It is understood that when used improperly, this may cause Kea to use more memory, so a machine with sufficient memory will be required.
     61
     62  e. New commands will be implemented to manipulate the cache. At least the following commands will be implemented: cache-flush (removes all entries from the cache), cache-remove (removes a single entry from the cache).
     63
     64  The caching mechanism will ensure the Radius communication is kept to absolute minimum. However, if the information ever changes in Radius (e.g. a client has been promoted to from bronze to silver), Kea will continue using its outdated cache information. Cache-remove command will be used to notify Kea to discard obsolete cache information.
     65
     664. '''Multiple IP relays per subnet'''. Kea 1.3 allows specifying a single IP address for a relay agent for each given subnet. This mechanism will be extended to allow specifying one or more addresses. The subnet will be selected if the relay address matches any value specified on the list and any client- class, if defined.
     67
     685. '''Client-class on pools level'''. Kea 1.3 allows restricting access to subnets to specific client classes, but does not allow the same for pools. The code will be extended to allow restricting access to specific pools to packets belonging to specific user class.
     69
     706. '''Backends in hooks'''. Existing backends are either enabled or disabled at compilation time. This approach has proven inflexible and we need to improve it. We will develop a registration mechanism, where any code, either from base Kea code or from a hook library, will be able to register and unregister a new backend type.
     71
     727. '''Option defintions in hooks'''. Existing Kea 1.3 code provides support for many standard options and allows users to define additional option definitions as custom options. However, for a general purpose Radius hook, it will be useful to have option definitions defined in a hook. This means that the definitions should be honoured only when specific hook is loaded (otherwise the options should be treated as general, unknown option). This requires a change in how hooks are loaded when configuration is processed.
     73
     74== OPERATION ==
     75
     761. When a new device shows in a network, it sends a DHCPDISCOVER packet. Kea will then parse (unpack) the packet, select a subnet for it and then check if the host for this particular client is available in each of configured backends. The backends will be configured as: cache, radius. Therfore, the first check will be whether host information is in a cache. If it is, that cached information will be used without contacting Radius. If it isn't, Kea will send Access-Request to the Radius server with the content of remote-id and/or circuit-id. Exact parameters to be sent will be configurable.
     77
     782. Upon reception of Access-Accept, the backend will return Host object that contains specified address and/or pool. Other attributes received in Access-Accept will be stored in user context associated with this Host object. That returned Host object will be put in a cache. Any incoming packets coming with the same remote-id and/or circuit-id will use the cached information and will not involve Radius authorization exchanges.
     79
     80  All attributes returned in Access-Accept will be stored in user context. This ensures maximum flexibility.
     81
     823. A host object returned by the Radius (or any "slow") backend will be added to a cache. This mechanism will be generic and could by applied to any backend that has performance limitations (Radius, but also MySQL, Postgres, Cassandra, but also possibly LDAP in the future). This cache will keep any number of hosts that were previously retrieved from a slow database in memory. This ensures that any follow up activities for this particular client (like DHCPRENEW or DHCPRELEASE processing) will be done using cached copy and will not require contacting the actual Radius server.
     83
     844. Upon receiving DHCPREQUEST from a client requesting an assigned of a new lease (not a renewing or rebinding client), Kea will retrieve the Host stored in a cache and will use the Radius attributes stored in user context to send Accounting-Request with Acct-Status-Type set to "Start" to the Radius server. If this is a renewing or rebinding client, the Acct-Status-Type will be set to "Interim-Update" instead.
     85
     865. Upon receiving DHCPRELEASE from a client, Kea will retrieve host from a cache and will use the information stored in the user context to send Accounting-Request with the Acct-Status-Type set to "Stop".
     87
     88== DESIGN DETAILS: RADIUS HOOK ==
     89
     90'''Type of Radius communication'''. After the Radius backend is implemented, Kea will be able to retrieve per client information from Radius. This can be used for two things. First, the ability to use Radius as access control for the network. Depending on Kea configuration, the clients that are not accepted by Radius, will not get an address. Second, it will provide the ability to provision specific addresses and/or pools on a per client basis. The client will be identified by its MAC address and value of one or more sub-options in option 82.
     91
     92These two aspects or Radius communication have radically different characteristic. authentication is bidirectional, i.e. Kea will use the responses and change its behavior depending on its content. As such, this will be done in synchronous manner (or could use the new parking mechanism feature, but in general remain its synchronicity in the sense that the processing of a packet will not continue until  a response comes in). Accounting is uni-directional, which means that Kea informs Radius about certain changes, but does not expect to get anything back. As such, this could be done asynchronously.
     93
     94'''Storing Radius info in User Context'''. Information returned by the Radius server in Access-Accept message must be retained to be later used for sending Accounting-request messages. This information will be retained in Host objects. To ensure maximum flexibility, the additional information stored in hosts will be using the user context concept, already available in subnets and pools in Kea. The concept assumes that certain configuration elements may contain additional generic pieces of information. This can be anything as long as it is in JSON format. The Radius backend will store all attributes retrieved in Access-accept in the user context that will be attached to a Host object returned.
     95
     96'''Configuration'''. The authentication and accounting features will be enabled/disabled independently. It will be possible to define which options and fields from the client package should be sent in either Access-Request. In particular, it will be possible to tell the library to use remote-id and/or circuit-id.
     97
     98Details are TBD.
     99
     100== DESIGN DETAILS: CACHE ==
     101
     102'''Multiple host data sources'''. As of Kea 1.3, it is possible to specify a single host data source, abeit the internal implementation always provides memory host data source to keep in memory host reservations that were defined in configuration file. This mechanism will be extended to support more than one host data source.
     103
     104'''Host caching'''. A new mechanism will be developed to store in memory the hosts returned by any host data source. There will be a cache in memory that will keep host information about hosts retrieved from the actual host data source, such as Radius. If host information is available in the cache, the actual host data source (such as Radius) will not be contacted and the cached information will be used instead.
     105
     106In many other software systems the information stored in a cache will be in general discarded during server shutdown. After restart, the cache is then slowly filled up again. However, in the Radius case, there is a significant complication. The original information sent by the relay agent (that includes circuit-id and/or remote-id may not be available, as client will send the renew messages directly to the server. As such, there is no easy way to query the Radius server again and refill the cache. Even if implemented a mechanism to store the relay information with leases, this would cause a spike of Radius queries after Kea restart. Obviously, we want to avoid that. Therefore it is necessary to have an ability to cache host information between restarts.
     107
     108'''Caching control'''. Using cache mechanism improves host backend performance, but introduces some limitations. Without caching any changes to the actual host data source (e.g. Radius or MySQL) are immediately picked up by Kea, without any need for restarts or any notifications. If the information is cached and it is later updated in the backend, Kea will continue using its cached version and the updated information will be ignored. To avoid this problem, several new mechanisms will be implemented:
     109
     110  '''hr-cache-flush''' command - this command will discard existing cache completely, thus ensuring that the cache is populated with new updated information. After the cache is flushed, Kea will start sending Access-Request messages for new clients and will repopulate the cache. This command is useful if many changes were made in the Radius backend and the cached information should be discarded entirely.
     111
     112  '''hr-cache-delete''' command - this command will discard an information about a single client.  This command is useful when a single client (or a small number of clients) have been updated. Other than those few, the other cached information is still valid.
     113
     114Both commands will be available over REST interface, similar to other commands.
     115
     116Cache will be enabled and disabled as a configuration parameter. Some users will prefer to keep the cache disabled to ensure that Kea always use the actual information. Others will prefer to have cache enabled to omit repeated calls to the Radius (or SQL) backend. Enabling or disabling cache will require Kea reconfiguration.
     117
     118The cache will be implemented as additional !HostContainer field that will be dedicated to caching.
     119
     120There will be a simple FIFO list with a maximum cache size specified. When additional new host is being added to the cache, the oldest one is being removed. It will be possible to set this number to infinite, thus effectively removing cache removal.
     121
     122One of the major problems to solve here is the problem of a disappearing cache after Kea shutdown/restart. If the cache content is lost after server restart, returning clients will send a DHCPSOLICIT(renew) packets that are unicasted directly to the server. This means they didn't pass through relay, so it's impossible to extract remote-id or circuit-id from option 82. The cache would need to write its content to a file and load content of that file upon start.
     123
     124Details are TBD.
     125
     126== DESIGN: Registration of Host Backend Types ==
     127
     128Details are TBD.
     129
     130== RADIUS OPTIONS (optional) ==
     131
     132In a typical deployment, it is the relay agent, not the server, who is communicating with Radius (see [[https://tools.ietf.org/html/rfc4014 | RFC40414]] or [[https://tools.ietf.org/html/rfc7037 | RFC7037]]). As such, it is useful for the Kea server to be able to interpret Radius DHCP options as inserted by relays. Nevertheless, it is also useful for the Radius hook to be able to translate Radius responses into DHCP options. This way there would be an unification to some degree regarding how Radius is handled in relay and server scenarios. Since this scenario is not strictly required by the primary user of this hook, it is considered low priority and marked as optional.
     133
     134This should cover encoding RAI sub-option 7 (see RFC4014) for DHCPv4 and option 81 (see RFC7037) for DHCPv6.
     135
     136== CONFIGURATION EXAMPLE ==
     137
     138This is still a work in progress.
     139
     140An example configuration of the Radius backend will look as follows:
     141
     142{{{
     143#!javascript
     144    "hosts-databases": [
     145        {
     146            "type": "radius",
     147            "auth": [
     148                {
     149                    ...
     150                    // parameters to contact the first auth server
     151                },
     152                {
     153                    ...
     154                    // parameters to contact the second auth server
     155                }
     156            ],
     157            "accounting": [
     158                {
     159                    ...
     160                    // parameters to contact the first accounting server
     161                },
     162                {
     163                    ...
     164                    // parameters to contact the second accounting server
     165                }
     166            ]
     167        },
     168    ],
     169
     170  "hooks-libraries": [
     171     {
     172         "library": "/opt/lib/radius.so",
     173         "parameters": {
     174
     175             // This specifies whether the library should do the
     176             // access control using Radius authentication.
     177             "auth": true,
     178
     179             // This specifies whether the library should do
     180             // accounting.
     181             "acct": true,
     182
     183             // This specifies what kind of values should be taken from
     184             // the incoming DHCP packet and sent to Radius in the
     185             // Access-Request. This is an array, so multiple fields
     186             // can be used. The "value" field specifies an expression.
     187             // See Kea User's Guide (http://kea.isc.org/docs/kea-guide
     188             // .html#classification-using-expressions for details.
     189             "auth-attributes": [
     190                 {
     191                     // Take value of option 82 (RAI), take suboption 1
     192                     // (circuit-id)...
     193                     "value": "option[82].option[1].hex"
     194
     195                     // ... and send it using attribute named Filter-id.
     196                     "attribute": "Filter-id"
     197                 }
     198             ],
     199
     200             // Once the Access-Accept message comes back from the Radius
     201             // server, Kea will store all of its content (all attributes).
     202             // This list governs which fields should be sent back to the
     203             // Radius server when sending Accounting-Request.
     204             "acct-attributes": [
     205                 "send": [
     206                     { "attribute": "Filter-id" },
     207                     { "attribute": "BW" },
     208                     { "attribute": "VAS" }
     209                 ]
     210             ]
     211         }
     212     }
     213  ]
     214}}}
     215
     216== Questions & Feedback ==
     217Q: One user commented: we sometimes need to reserve a user-class without subnetID. This is not possible with the current host reservation via mysql or postgres.
     218
     219A: Radius doesn't have any specific concept of subnet-ids. We will leverage the usual host backend interface. The code in the backend will take the subnet-id and remember it, send the Access-Request, receive Access-Accept and then later add the remembered subnet-id.
     220
     221Another user commented:
     222
     223- the client's MAC address should be available at least as 'Calling-Station-Id' or even better as 'User-Name' attribute (or both)
     224- for the 'NAS-IP-Address' I would suggest the DHCP relay address (giaddr) 
     225- the Acct-Session-Id really has to be unique, it might include MAC/IP/Option-82, but that's not yet unique for 2 sessions for the same device with the same IP
     226- it would be good to be able to build any RADIUS attribute based on an expression that incorporated lease configuration specific values. My use case is to build the 'NAS-Identifier' based on either the Option82.remote-id or if not available on the subnet's name (named pools or a name  attribute for a pool  in the KEA configuration would also be a good idea).
     227
     228C: Implementor comment: in Radius the DHCP subnet-ID is the NAS port (SHOULD be in requests).
     229
     230C: Should be attributes limited to types present in the dictionary? This introduces a hard constraint on the dictionary which is an external element, at the other hand there is nothing useful which can be done with an unknown attribute...
     231
     232== Tickets ==
     233
     234This work is being split into tickets that represent specific tasks. A great majority of them is expected to be completed in Kea 1.4 timeframe. A small number of non-critical tasks may be postponed to some later milestones.
     235
     236Radius:
     237- #5524: Create stub Radius library - the library has to be created, configure.ac needs to be aware of !FreeRadius. The makefiles should disable the lib if !FreeRadius is not detected.
     238- #5525: Implement configuration storage and parsers - once the stub lib is created, we need to implement parser that will handle the configuration and store it in internal structures. No specific Radius interaction is needed.
     239- #5526: Implement Radius communication
     240- #5527: Host backend using Radius (use Frame-IP-Address attribute)
     241- #5529: Ability to classify packet based on Radius response (use Framed-Pool attribute)
     242- #5528: Mechanism for registering host data sources from a hook
     243- #5530: Radius accounting
     244
     245Caching:
     246- #5531: Multiple host backends
     247- #5532: Caching host backend
     248- #5533: Use caching host backend to actually cache hosts
     249- #5534: cache-remove, cache-flush commands
     250
     251Optional features:
     252- #5536: Radius option defintions
     253- #5537: Insert DHCP options based on Radius responses
     254- #5516: mechanism to define options in hook libraries
     255
     256Misc:
     257- #5425: Class restrictions on pool level
     258- #5535: Multiple relay IP addresses per subnet
     259- #5538: Documentation for users (with config examples)
     260- #5539: Documentation for developers
     261
     262Outstanding issues:
     263- #5605: RADIUS library prints out RADIUS_ACCESS_NO_HOST_CACHE
     264- #5608: There should be a way to send Password in all Access-Requests
     265- 3: RADIUS: Print out list of access and accounting servers, similar to MySQL
     266- 4: FLEX-ID not available when SUBNET4_SELECT is called
     267
     268 
     269
     270