|
|
[[_TOC_]]
|
|
|
|
|
|
## Problem
|
|
|
|
|
|
ISPs sometimes require limiting the number of leases handed by the Kea DHCP server to known customers.
|
|
|
Other times, a DHCP server is positioned in a topology facing clients that are unknown a priori, but are allowed to have leases.
|
|
|
In both cases, because of a predetermined contract, or because of the same client misbehaving and
|
|
|
not respecting exponential backoff and flooding the server, or because of multiple well behaved
|
|
|
clients oversoliciting the server, a need arises to limit set of clients, identifiable through various criteria, with regards to:
|
|
|
* the number of leases handed out, hereinafter referred to as **lease limiting**
|
|
|
* the rate of honored requests, hereinafter referred to as **rate limiting**
|
|
|
|
|
|
## Requested Use Cases
|
|
|
|
|
|
* [ ] U1. Limit the number of leases per user / per home gateway.
|
|
|
* [ ] U2. Limit the number of leases per set of clients identifiable by option values e.g. DHCPv6 option 18 Interface ID, DHCPv4 option 37 Remote ID.
|
|
|
* [ ] U3. Limit the number of leases per set of clients identifiable by relay-inserted options under option 82 e.g. RAI option 1 Circuit ID, RAI option 2 Remote ID, in DHCPv4.
|
|
|
* [ ] U4. Retain unleased addresses or prefixes through lease limiting.
|
|
|
* [ ] U5. Determine what clients were limited, or what set of clients was limited, from the logs.
|
|
|
* [ ] U6. Rate limit chatty clients.
|
|
|
|
|
|
## Class Spawning
|
|
|
|
|
|
Concept is borrowed from ISC DHCP. It is not necessarily required for lease limiting and rate
|
|
|
limiting, but it has good synergy with them by allowing to spread a single limit to a virtually
|
|
|
unlimited number of classes.
|
|
|
|
|
|
Helps in solving use cases U1-U6.
|
|
|
|
|
|
* [ ] K1. Implement class spawning. A spawning class would allow applying the limit granularly to each spawned class instead of applying it generally to a superset of all spawned classes, as it would have possible with traditional classes. This comes as part of addressing use case U1 and in the interest of configuration scalability.
|
|
|
* [ ] K1a. Configurable in file.
|
|
|
* [ ] K1b. Configurable in backend.
|
|
|
|
|
|
## Lease Limiting
|
|
|
|
|
|
Client classification is included because it is a flexible method of identifying packets. However,
|
|
|
limiting by subnet ID could also be a useful administrator tool, and it's an easy grab
|
|
|
implementation-wise because it does not require any memfile CSV header changes or any SQL schema
|
|
|
changes in the lease limiting case. The `subnet_id` column is already included with lease data, so
|
|
|
lease counting by subnet ID is already implemented.
|
|
|
|
|
|
Helps in solving use cases U1-U5.
|
|
|
|
|
|
* [ ] L1. Limit the number of leases at any one time.
|
|
|
* [ ] L1a. Per client class.
|
|
|
* [ ] L1b. Per spawned client class.
|
|
|
* [ ] L1c. Per subnet ID.
|
|
|
* [ ] L2. Prevent honoring of packets that go beyond the lease limit.
|
|
|
* [ ] L3. Log message when the lease limit is reached. Mention message type and the criteria that identified the client.
|
|
|
* [ ] L4. Take into consideration leases that were assigned before the latest Kea start.
|
|
|
|
|
|
## Rate Limiting
|
|
|
|
|
|
Helps in solving use case U6.
|
|
|
|
|
|
* [ ] R1. Aim to limit the rate of ingress packets.
|
|
|
* [ ] R1b. Per client class.
|
|
|
* [ ] R1c. Per spawned client class.
|
|
|
* [ ] R1d. Per subnet ID.
|
|
|
* [ ] R2. Prevent honoring packets that go beyond the rate limit.
|
|
|
* [ ] R3. Log message when the rate limit is reached. Mention message type and the criteria that identified the client.
|
|
|
|
|
|
## Automatic Detection of Chatty Clients
|
|
|
|
|
|
Helps in solving use case U6.
|
|
|
|
|
|
* [ ] C1. Implement special client class called `"CHATTY"` automatically assigned to ingress packets that abuse the sending rate.
|
|
|
|
|
|
## Implementation Details in ISC DHCP
|
|
|
|
|
|
Quote from `man dhcpd.conf`:
|
|
|
|
|
|
> PER-CLASS LIMITS ON DYNAMIC ADDRESS ALLOCATION
|
|
|
>
|
|
|
> You may specify a limit to the number of clients in a class that can be assigned leases. The effect of
|
|
|
> this will be to make it difficult for a new client in a class to get an address. Once a class with such a
|
|
|
> limit has reached its limit, the only way a new client in that class can get a lease is for an existing
|
|
|
> client to relinquish its lease, either by letting it expire, or by sending a DHCPRELEASE packet. Classes
|
|
|
> with lease limits are specified as follows:
|
|
|
>
|
|
|
> class "limited-1" {
|
|
|
> lease limit 4;
|
|
|
> }
|
|
|
>
|
|
|
> This will produce a class in which a maximum of four members may hold a lease at one time.
|
|
|
>
|
|
|
> SPAWNING CLASSES
|
|
|
>
|
|
|
> It is possible to declare a spawning class. A spawning class is a class that automatically produces sub‐
|
|
|
> classes based on what the client sends. The reason that spawning classes were created was to make it pos‐
|
|
|
> sible to create lease-limited classes on the fly. The envisioned application is a cable-modem environment
|
|
|
> where the ISP wishes to provide clients at a particular site with more than one IP address, but does not
|
|
|
> wish to provide such clients with their own subnet, nor give them an unlimited number of IP addresses from
|
|
|
> the network segment to which they are connected.
|
|
|
>
|
|
|
> Many cable modem head-end systems can be configured to add a Relay Agent Information option to DHCP packets
|
|
|
> when relaying them to the DHCP server. These systems typically add a circuit ID or remote ID option that
|
|
|
> uniquely identifies the customer site. To take advantage of this, you can write a class declaration as
|
|
|
> follows:
|
|
|
>
|
|
|
> class "customer" {
|
|
|
> spawn with option agent.circuit-id;
|
|
|
> lease limit 4;
|
|
|
> }
|
|
|
>
|
|
|
> Now whenever a request comes in from a customer site, the circuit ID option will be checked against the
|
|
|
> class's hash table. If a subclass is found that matches the circuit ID, the client will be classified in
|
|
|
> that subclass and treated accordingly. If no subclass is found matching the circuit ID, a new one will be
|
|
|
> created and logged in the dhcpd.leases file, and the client will be classified in this new class. Once the
|
|
|
> client has been classified, it will be treated according to the rules of the class, including, in this
|
|
|
> case, being subject to the per-site limit of four leases.
|
|
|
>
|
|
|
> The use of the subclass spawning mechanism is not restricted to relay agent options - this particular exam‐
|
|
|
> ple is given only because it is a fairly straightforward one.
|
|
|
|
|
|
## Substitute Implementations in Kea
|
|
|
|
|
|
As of Kea 1.4.0, lease limiting can be simulated by modelling pools to match the number of leases you want for a client class.
|
|
|
The following example limits client class `"user1"` to 4 address leases:
|
|
|
|
|
|
```json
|
|
|
{
|
|
|
"Dhcp4": {
|
|
|
"client-classes": [
|
|
|
{
|
|
|
"name": "user1",
|
|
|
"test": "hexstring(option[82].option[1].hex, ':') == '00:0c:01:02:03:04'"
|
|
|
}
|
|
|
],
|
|
|
"subnet4": [
|
|
|
{
|
|
|
"pools": [
|
|
|
{
|
|
|
"client-class": "user1",
|
|
|
"pool": "192.168.0.1 - 192.168.0.4"
|
|
|
}
|
|
|
],
|
|
|
"subnet": "192.168.0.0/24"
|
|
|
}
|
|
|
]
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
There is one restriction that has to be met for this to work. All sibling pools, i.e. under the same subnet, have to have classes attached to them so that clients from class `"user1"` don't get additional leases. It does, however, offer the flexibility of being able to have free-standing pools that clients can get leases from, in a first-come-first-served fashion. Free-standing pools seem unlikely to be a desired feature.
|
|
|
|
|
|
There is also a disadvantage to this approach. It is tedious to maintain so many classes and so many pools, at least if the limiting is done an per-user basis.
|
|
|
|
|
|
## Relevant RFCs
|
|
|
|
|
|
* RFC8415. Dynamic Host Configuration Protocol for IPv6 (DHCPv6)
|
|
|
|
|
|
> 18.2.10. Receipt of Reply Messages
|
|
|
>
|
|
|
> [...]
|
|
|
>
|
|
|
> If the client receives a Reply message with a status code of
|
|
|
> UnspecFail, the server is indicating that it was unable to process
|
|
|
> the client's message due to an unspecified failure condition. If the
|
|
|
> client retransmits the original message to the same server to retry
|
|
|
> the desired operation, the client MUST limit the rate at which it
|
|
|
> retransmits the message and limit the duration of the time during
|
|
|
> which it retransmits the message (see Section 14.1).
|
|
|
>
|
|
|
> [...]
|
|
|
>
|
|
|
> 14.1. Rate Limiting
|
|
|
>
|
|
|
> In order to avoid prolonged message bursts that may be caused by
|
|
|
> possible logic loops, a DHCP client MUST limit the rate of DHCP
|
|
|
> messages it transmits or retransmits. One example is that a client
|
|
|
> obtains an address or delegated prefix but does not like the
|
|
|
> response, so it reverts back to the Solicit procedure, discovers the
|
|
|
> same (sole) server, requests an address or delegated prefix, and gets
|
|
|
> the same address or delegated prefix as before (as the server has
|
|
|
> this previously requested lease assigned to this client). This loop
|
|
|
> can repeat infinitely if there is not a quit/stop mechanism.
|
|
|
> Therefore, a client must not initiate transmissions too frequently.
|
|
|
>
|
|
|
> A recommended method for implementing the rate-limiting function is a
|
|
|
> token bucket (see Appendix A of [RFC3290]), limiting the average rate
|
|
|
> of transmission to a certain number in a certain time interval. This
|
|
|
> method of bounding burstiness also guarantees that the long-term
|
|
|
> transmission rate will not be exceeded.
|
|
|
>
|
|
|
> A transmission rate limit SHOULD be configurable. A possible default
|
|
|
> could be 20 packets in 20 seconds.
|
|
|
>
|
|
|
> For a device that has multiple interfaces, the limit MUST be enforced
|
|
|
> on a per-interface basis.
|
|
|
>
|
|
|
> Rate limiting of forwarded DHCP messages and server-side messages is
|
|
|
> out of scope for this specification.
|
|
|
|
|
|
## Comments
|
|
|
|
|
|
* |