mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-22 09:57:41 +00:00
205 lines
7.9 KiB
ReStructuredText
205 lines
7.9 KiB
ReStructuredText
.. ischooklib:: libdhcp_limits.so
|
|
.. _hooks-limits:
|
|
|
|
``libdhcp_limits.so``: Limits to Manage Lease Allocation and Packet Processing
|
|
==============================================================================
|
|
|
|
This hook library enables two types of limits:
|
|
|
|
1. Lease limiting: allow a maximum of ``n`` leases assigned at any one time.
|
|
2. Rate limiting: allow a maximum of ``n`` packets per ``time_unit`` to receive a response.
|
|
|
|
.. note::
|
|
|
|
:ischooklib:`libdhcp_limits.so` is part of the open source code and is
|
|
available to every Kea user.
|
|
It was previously available only to ISC customers with a paid support contract.
|
|
|
|
.. _hooks-limits-configuration:
|
|
|
|
Configuration
|
|
~~~~~~~~~~~~~
|
|
|
|
The following examples are for :iscman:`kea-dhcp6`, but they apply equally to
|
|
:iscman:`kea-dhcp4`. The wildcards ``"<limit-type>"`` and ``"<limit-value>"`` need to be replaced
|
|
with the respective keys and values for each limit type described in the sections following this
|
|
one.
|
|
|
|
The library can be loaded by both :iscman:`kea-dhcp4` and :iscman:`kea-dhcp6` servers by adding its path in the
|
|
``"hooks-libraries"`` element of the server's configuration.
|
|
|
|
.. code-block:: json
|
|
|
|
{
|
|
"Dhcp6": {
|
|
"hooks-libraries": [
|
|
{
|
|
"library": "/usr/local/lib/libdhcp_limits.so"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
This alone does not limit anything. The desired limits are added to the user context in the
|
|
configuration portion of the element that identifies the clients to be limited: a client class or a
|
|
subnet. Upon reconfiguration, if Kea picked up on the configured limits, it logs one line for
|
|
each configured limit. The log message contains ``LIMITS_CONFIGURED`` in its identifier.
|
|
|
|
This is how a lease limit is defined for a client class:
|
|
|
|
.. code-block:: json
|
|
|
|
{
|
|
"Dhcp6": {
|
|
"client-classes": [
|
|
{
|
|
"name": "cable-modem-1",
|
|
"test": "option[123].hex == 0x000C4B1E",
|
|
"user-context": {
|
|
"limits": {
|
|
"<limit>": "<limit-value>"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
This is how a lease limit is defined for a global subnet:
|
|
|
|
.. code-block:: json
|
|
|
|
{
|
|
"Dhcp6": {
|
|
"subnet6": [
|
|
{
|
|
"id": 1,
|
|
"subnet": "2001:db8::/64",
|
|
"user-context": {
|
|
"limits": {
|
|
"<limit>": "<limit-value>"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
This is how a lease limit is defined for a subnet inside a shared network:
|
|
|
|
.. code-block:: json
|
|
|
|
{
|
|
"Dhcp6": {
|
|
"shared-networks": [
|
|
{
|
|
"subnet6": [
|
|
{
|
|
"id": 1,
|
|
"subnet": "2001:db8::/64",
|
|
"user-context": {
|
|
"limits": {
|
|
"<limit>": "<limit-value>"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
.. note::
|
|
|
|
The Limits hook library uses the class name to identify a client class and the subnet ID to
|
|
identify a subnet. Changing a test expression in a client class or the network range of a
|
|
subnet while leaving the name or ID unchanged does not reset the lease count for the
|
|
respective client class or subnet. To reset the lease count, change the client class name
|
|
or the subnet ID.
|
|
|
|
.. _hooks-limits-lease-limiting:
|
|
|
|
Lease Limiting
|
|
~~~~~~~~~~~~~~
|
|
|
|
It is possible to limit the number of leases that a group of clients can get from a Kea DHCP server
|
|
or from a set of collaborating Kea DHCP servers.
|
|
|
|
The value of a lease limit can be specified as an unsigned integer in 32 bits, i.e. between ``0`` and
|
|
``4,294,967,295``. Each lease type can be limited individually. IPv4 leases and IPv6 IA_NA leases
|
|
are limited through the ``"address-limit"`` configuration entry. IPv6 IA_PD leases are limited
|
|
through the ``"prefix-limit"`` configuration entry. Here are some examples:
|
|
|
|
* ``"address-limit": 4``
|
|
* ``"prefix-limit": 2``
|
|
|
|
For lease limiting, client classes and the associated lease counts - which are
|
|
checked against the configured limits - are updated for each lease in the following hook callouts:
|
|
|
|
* ``lease4_select``
|
|
* ``lease4_renew``
|
|
* ``lease6_select``
|
|
* ``lease6_renew``
|
|
* ``lease6_rebind``
|
|
|
|
As a result, classes for which ``"only-in-additional-list"`` is "true" cannot be lease-limited.
|
|
Please refer to :ref:`the classification steps <classify-classification-steps>` for more information on which
|
|
client classes can be used to limit the number of leases.
|
|
|
|
.. note::
|
|
|
|
Under load, a Kea DHCP server may allocate more leases than the limit strictly allows. This only has a chance of
|
|
happening during high traffic surges, coming from clients belonging to the same class or the
|
|
same subnet, depending on what is limited. Users may be interested in following the development of
|
|
`atomic lease limits <https://gitlab.isc.org/isc-projects/kea/-/issues/2449>`__ in ISC's GitLab instance.
|
|
|
|
.. _hooks-limits-rate-limiting:
|
|
|
|
Rate Limiting
|
|
~~~~~~~~~~~~~
|
|
|
|
It is possible to limit the frequency or rate at which inbound packets receive a response.
|
|
|
|
The value of a rate limit can be specified in the format ``"<p> packets per <time-unit>"``. ``<p>``
|
|
is any number that can be represented by an unsigned integer in 32 bits, i.e. between ``0`` and
|
|
``4,294,967,295``. ``<time-unit>`` can be any of ``second``, ``minute``, ``hour``, ``day``,
|
|
``week``, ``month``, or ``year``. A ``month`` is considered to be 30 days for
|
|
simplicity; similarly, a ``year`` is 365 days for limiting purposes. This syntax
|
|
covers a wide range of rates, from one lease per year to four billion leases per
|
|
second. This value is assigned to the ``"rate-limit"`` configuration entry.
|
|
Here are some examples:
|
|
|
|
* ``"rate-limit": 1 packet per second``
|
|
* ``"rate-limit": 4 packets per minute``
|
|
* ``"rate-limit": 16 packets per hour``
|
|
|
|
The configured value of ``0`` packets is a convenient way of disabling packet processing for certain
|
|
clients entirely. As such, it means its literal value and is not a special value for disabling
|
|
limiting altogether, as might be imagined. Disabling limiting entirely is achieved by removing
|
|
the ``"rate-limit"`` leaf configuration entry, the ``"limits"`` map or user context
|
|
around it, or the hook library configuration. The same applies to the value of ``0`` in lease
|
|
limiting. However, that use case is best achieved with rate limiting; it puts less computational
|
|
strain on Kea, since the action of dropping the request or sending a NAK is decided earlier.
|
|
|
|
In terms of rate limiting, client classes are evaluated at the ``pkt4_receive`` and the
|
|
``pkt6_receive`` callout, respectively, so that rate limits are checked as early as possible in the
|
|
packet-processing cycle. Thus, only those classes which are assigned to the packet solely via an
|
|
independent test expression can be used. Classes that depend on host reservations or the special
|
|
``BOOTP`` or ``KNOWN`` classes, and classes that are marked with ``"only-in-additional-list": true``,
|
|
cannot be rate limited. See :ref:`the classification steps <classify-classification-steps>` for
|
|
more details on which client classes can be used to limit the packet rate.
|
|
|
|
Rate limits based on subnet are enforced only on the initially selected subnet for a given packet.
|
|
If the selected subnet is subsequently changed, as may be the case for subnets in a
|
|
shared network or when reselection is enabled in libraries such as the RADIUS hook, rate
|
|
limits on the newly selected subnet are ignored. In other words, packets are gated only by
|
|
the rate limit on the original subnet.
|
|
|
|
.. note::
|
|
|
|
It may seem logical to think that assigning a rate limit of ``n`` packets per time unit results
|
|
in ``n`` DORA or ``n`` SARR exchanges. However, by default, all inbound packets are counted - meaning
|
|
that a full message exchange accounts for two packets. To achieve the effect of counting an
|
|
exchange only once, use client-class rate-limiting with a test expression that binds
|
|
``pkt4.msgtype`` to DHCPDISCOVER messages or ``pkt6.msgtype`` to SOLICIT messages.
|