RFC 9132
Distributed Denial-of-Service Open Threat Signaling (DOTS) Signal Channel Specification
RFC 9132 🎀 Distributed Denial-of-Service Open Threat Signaling (DOTS) Signal Channel Specification
Okay bestie, let's start with the basics 💅. This is RFC 9132, published by the IETF in September 2021 ✨. It's a Standards Track document, which means it's an actual Internet standard and not just a suggestion 🙈. The lead editor is M. Boucadair (Orange), and J. Shallow and T. Reddy.K (Akamai) co-wrote it with them 🫶. The ISSN is 2070-1721 🌸. It obsoletes RFC 8782, so it replaces that one 💀.
Abstract ✨
So this doc specs the DOTS signal channel 🦋. It's a protocol for telling a server that you need protection from Distributed Denial-of-Service (DDoS) attacks 🛡️. The server is the one that can turn on network traffic mitigation for the client who asked for it 👑.
A companion document defines the DOTS data channel, which is a separate reliable communication layer for DOTS management and configuration purposes 💜.
This document obsoletes RFC 8782 💅, so that one is officially retired.
Status of This Memo 📜
This is an Internet Standards Track document 🎀.
It's a product of the Internet Engineering Task Force (IETF), so it represents the consensus of the IETF community 🌈. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG) ✅. If you want more info on Internet Standards, check out Section 2 of RFC 7841 💖.
For the current status of this document, any errata, and how to send feedback, go to https://www.rfc-editor.org/info/rfc9132 🧚.
Copyright Notice ⚖️
Copyright (c) 2021 IETF Trust and the persons identified as the document authors. All rights reserved 💜.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info), as they stood on the date this document was published. Please read these carefully, because they spell out your rights and restrictions for this document 🫶. Code components extracted from this document must include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions. They're also provided without warranty, as described in the Simplified BSD License ⚠️.
Table of Contents 🗂️
1. Introduction
2. Terminology
3. Design Overview
3.1. Backward Compatibility Considerations
4. DOTS Signal Channel: Messages & Behaviors
4.1. DOTS Server(s) Discovery
4.2. CoAP URIs
4.3. Happy Eyeballs for DOTS Signal Channel
4.4. DOTS Mitigation Methods
4.4.1. Request Mitigation
4.4.1.1. Building Mitigation Requests
4.4.1.2. Server-Domain DOTS Gateways
4.4.1.3. Processing Mitigation Requests
4.4.2. Retrieve Information Related to a Mitigation
4.4.2.1. DOTS Servers Sending Mitigation Status
4.4.2.2. DOTS Clients Polling for Mitigation Status
4.4.3. Efficacy Update from DOTS Clients
4.4.4. Withdraw a Mitigation
4.5. DOTS Signal Channel Session Configuration
4.5.1. Discover Configuration Parameters
4.5.2. Convey DOTS Signal Channel Session Configuration
4.5.3. Configuration Freshness and Notifications
4.5.4. Delete DOTS Signal Channel Session Configuration
4.6. Redirected Signaling
4.7. Heartbeat Mechanism
5. DOTS Signal Channel YANG Modules
5.1. Tree Structure
5.2. IANA DOTS Signal Channel YANG Module
5.3. IETF DOTS Signal Channel YANG Module
6. YANG/JSON Mapping Parameters to CBOR
7. (D)TLS Protocol Profile and Performance Considerations
7.1. (D)TLS Protocol Profile
7.2. (D)TLS 1.3 Considerations
7.3. DTLS MTU and Fragmentation
8. Mutual Authentication of DOTS Agents & Authorization of DOTS
Clients
9. Error Handling
10. IANA Considerations
10.1. DOTS Signal Channel UDP and TCP Port Number
10.2. Well-Known 'dots' URI
10.3. Media Type Registration
10.4. CoAP Content-Formats Registration
10.5. CBOR Tag Registration
10.6. DOTS Signal Channel Protocol Registry
10.6.1. DOTS Signal Channel CBOR Key Values Subregistry
10.6.1.1. Registration Template
10.6.1.2. Update Subregistry Content
10.6.2. Status Codes Subregistry
10.6.3. Conflict Status Codes Subregistry
10.6.4. Conflict Cause Codes Subregistry
10.6.5. Attack Status Codes Subregistry
10.7. DOTS Signal Channel YANG Modules
11. Security Considerations
12. References
12.1. Normative References
12.2. Informative References
Appendix A. Summary of Changes From RFC 8782
Appendix B. CUID Generation
Appendix C. Summary of Protocol Recommended/Default Values
Acknowledgements
Contributors
Authors' Addresses
1. Introduction ✨
Picture this 🙈: a Distributed Denial-of-Service (DDoS) attack is a distributed attempt to make machines or network resources unavailable to their intended users. Usually, you can get enough scale for an effective attack by compromising enough end hosts and then using those infected hosts to carry out and amplify the attack. The victim can be an application server, a host, a router, a firewall, or an entire network 💀.
Network applications have finite resources, like CPU cycles, the number of processes or threads they can create and use, the maximum number of simultaneous connections they can handle, the resources assigned to the control plane, and so on. When they process network traffic, these apps are supposed to use those resources to provide their intended functionality in the most efficient way 💅. But a DDoS attacker may be able to stop an app from doing its job by making it exhaust those finite resources 😭.
A TCP DDoS SYN flood [RFC4987], for example, is a memory-exhausting attack, while an ACK flood is a CPU-exhausting attack 🔥. Attacks on the link work by sending so much traffic that the link gets congested, which can cause packet loss for legitimate traffic too. Stateful firewalls can get attacked as well. Attack traffic can make the firewall maintain an excessive number of states, which may jeopardize its overall operation, on top of likely performance impacts. The firewall then runs out of memory and can no longer instantiate the states it needs to process legitimate flows 🥲. Other possible DDoS attacks are discussed in [RFC4732].
In many cases, network administrators can't determine what caused an attack. They might just notice that certain resources seem to be under attack 🫠. This document defines a lightweight protocol that lets a DOTS client request mitigation from one or more DOTS servers for protection against detected, suspected, or anticipated attacks 🎀. This protocol enables cooperation between DOTS agents, so you get a highly automated network defense that is robust, reliable, and secure ✨. Note that "secure" means the support of the features defined in Section 2.4 of [RFC8612] 🔐.
In typical deployments, the DOTS client belongs to a different administrative domain than the DOTS server 🌸. For example, the DOTS client is embedded in a firewall-protected service that a customer owns and operates, while the DOTS server is owned and operated by a different administrative entity (typically a service provider) that provides DDoS mitigation services. That latter entity might or might not provide connectivity services to the network hosting the DOTS client 🧚.
The DOTS server may or may not be co-located with the DOTS mitigator. In typical deployments, the DOTS server belongs to the same administrative domain as the mitigator 🦋. The DOTS client can talk directly to a DOTS server, or indirectly through a DOTS gateway 💜.
Here's an example of a network diagram showing a deployment of DOTS agents, in Figure 1 👀. In this example, a DOTS server runs on the access network. The DOTS client sits on the Local Area Network (LAN), and a DOTS gateway is embedded in the Customer Premises Equipment (CPE) 🏠.
Network
Resource CPE Router Access Network __________
+-------------+ +--------------+ +-------------+ / \
| | | | | | | Internet |
| DOTS Client +---+ DOTS Gateway +---+ DOTS Server +----+ |
| | | | | | | |
+-------------+ +--------------+ +-------------+ \__________/
Figure 1: Sample DOTS Deployment (1)
DOTS servers can also be reachable over the Internet, as shown in Figure 2 🌐.
Network DDoS Mitigation
Resource CPE Router _________ Service
+-------------+ +--------------+ / \ +-------------+
| | | | | | | |
| DOTS Client +---+ DOTS Gateway +---+ Internet +---+ DOTS Server |
| | | | | | | |
+-------------+ +--------------+ \_________/ +-------------+
Figure 2: Sample DOTS Deployment (2)
This document adheres to the DOTS architecture [RFC8811] 🏗️. The requirements for the DOTS signal channel protocol are documented in [RFC8612]. This document satisfies all the use cases discussed in [RFC8903] 🎉.
This document focuses on the DOTS signal channel. It's a companion to the DOTS data channel specification [RFC8783], which defines a configuration and bulk data exchange mechanism that supports the DOTS signal channel 💖.
Backward compatibility (including upgrade) considerations are discussed in Section 3.1 🫶.
2. Terminology 💅
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here 📖.
(D)TLS is used for statements that apply to both Transport Layer Security [RFC5246] [RFC8446] and Datagram Transport Layer Security [RFC6347]. Specific terms are used for any statement that applies to either protocol alone 🔒.
The reader should be familiar with the terms defined in [RFC8612] and [RFC7252] 🧠.
The meaning of the symbols in YANG tree diagrams is defined in [RFC8340] and [RFC8791] 🌳.
3. Design Overview ✨
Okay so bestie, this is where DOTS gets its whole personality 💅 The DOTS signal channel is built on top of the Constrained Application Protocol (CoAP) [RFC7252], which was originally made for tiny constrained devices and networks 🦋 CoAP is giving everything: it expects packet loss, supports asynchronous Non-confirmable messaging, has congestion control, keeps message overhead small so fragmentation isn't a big deal, uses minimal resources, and supports (D)TLS. Literally the perfect base to build the DOTS signaling mechanism on 🫶
DOTS clients and servers behave as CoAP endpoints. By default, a DOTS client acts as a CoAP client and a DOTS server acts as a CoAP server. BUT, a DOTS client (or server) can flip roles and act as a CoAP server (or client) for specific operations, like DOTS heartbeat operations (Section 4.7). Role-switching, iykyk 🔄✨
The DOTS signal channel is layered on existing standards (see Figure 3) 🎀
+---------------------+
| DOTS Signal Channel |
+---------------------+
| CoAP |
+----------+----------+
| TLS | DTLS |
+----------+----------+
| TCP | UDP |
+----------+----------+
| IP |
+---------------------+
Figure 3: Abstract Layering of DOTS Signal Channel over CoAP over
(D)TLS
In some cases, a DOTS client and server may have a mutual agreement to use a specific port number, such as through explicit configuration or dynamic discovery [RFC8973]. Absent that mutual agreement, the DOTS signal channel MUST run over port number 4646, as defined in Section 10.1, for both UDP and TCP (so the DOTS server listens on port number 4646) 🌸 If you want a distinct port number (instead of 4646), DOTS clients and servers SHOULD support a configurable parameter to supply the port number to use.
Note: The rationale for not using the default port number 5684 ((D)TLS CoAP) is to avoid the discovery of services and resources discussed in [RFC7252] and to allow for differentiated behaviors in environments where both a DOTS gateway and an Internet of Things (IoT) gateway (e.g., Figure 3 of [RFC7452]) are co-located. Particularly, the default port number is meant to simplify DOTS deployment in scenarios where no explicit IP address configuration is required. For example, using the default router as the DOTS server eases DOTS deployment within LANs (where CPEs embed a DOTS gateway, as illustrated in Figures 1 and 2) without needing a sophisticated discovery method and configuration tasks within the LAN. It is also possible to use anycast addresses for DOTS servers to simplify DOTS client configuration, including service discovery. In such an anycast-based scenario, a DOTS client initiating a DOTS session to the DOTS server anycast address may, for example, be (1) redirected to the DOTS server unicast address to be used by the DOTS client following the procedure discussed in Section 4.6 or (2) relayed to a unicast DOTS server. 🧚
The signal channel uses the "coaps" URI scheme defined in Section 6 of [RFC7252] and the "coaps+tcp" URI scheme defined in Section 8.2 of [RFC8323] to identify DOTS server resources that are accessible using CoAP over UDP secured with DTLS and CoAP over TCP secured with TLS, respectively 🔐
The DOTS signal channel can be established between two DOTS agents prior to or during an attack 🚨 It's initiated by the DOTS client, which can then negotiate, configure, and retrieve the signal channel session behavior with its DOTS peer (Section 4.5). Once the channel is up, the DOTS agents may periodically send heartbeats to keep it active (Section 4.7). At any time, the DOTS client may send a mitigation request message (Section 4.4) to a DOTS server over the active signal channel. While mitigation is active (because packet loss is way more likely during a DDoS attack), the DOTS server periodically sends status messages to the client, including basic mitigation feedback details 📊 Mitigation stays active until the DOTS client explicitly terminates it or the mitigation lifetime expires. Also, the DOTS server may rely on signal channel session loss to trigger mitigation for preconfigured mitigation requests (if any) 💜
DOTS signaling can use DTLS over UDP and TLS over TCP. Likewise, DOTS requests may be sent using IPv4 or IPv6 transfer capabilities. A Happy Eyeballs procedure for the DOTS signal channel is specified in Section 4.3 🙈
A DOTS client is entitled to access only the resources it creates. In particular, a DOTS client cannot retrieve data related to mitigation requests created by other DOTS clients of the same DOTS client domain. No peeking at your bestie's stuff 🚫👀
Messages exchanged between DOTS agents are serialized using Concise Binary Object Representation (CBOR) [RFC8949], a binary encoding scheme designed for small code and message size 🍓 CBOR-encoded payloads carry signal-channel-specific payload messages that convey request parameters and response information, such as errors. To allow data models to be reused across protocols, [RFC7951] specifies the JavaScript Object Notation (JSON) encoding of YANG-modeled data. A similar effort for CBOR is defined in [CORE-YANG-CBOR] ✨
DOTS agents determine that a CBOR data structure is a DOTS signal channel object from the application context, such as the port number assigned to the DOTS signal channel. The other method DOTS agents use to indicate that a CBOR data structure is a DOTS signal channel object is the "application/dots+cbor" content type (Section 10.3) 🎀
This document specifies a YANG module for representing DOTS mitigation scopes, DOTS signal channel session configuration data, and DOTS redirected signaling (Section 5). All parameters in the payload of the DOTS signal channel are mapped to CBOR types, as specified in Table 5 (Section 6) 💖
In order to prevent fragmentation, DOTS agents must follow the recommendations documented in Section 4.6 of [RFC7252]. Refer to Section 7.3 for more details 🌈
DOTS agents MUST support GET, PUT, and DELETE CoAP methods. The payload included in CoAP responses with 2.xx Response Codes MUST be of content type "application/dots+cbor". CoAP responses with 4.xx and 5.xx error Response Codes MUST include a diagnostic payload (Section 5.5.2 of [RFC7252]). The diagnostic payload may contain additional information to aid troubleshooting 🛠️
In deployments where multiple DOTS clients are enabled in a single network and administrative domain (called a DOTS client domain), the DOTS server may detect conflicting mitigation requests from these clients. This document does not aim to list every condition under which a DOTS server will treat two mitigation requests from distinct DOTS clients as conflicting, nor does it recommend a DOTS server behavior for processing conflicting mitigation requests. Those considerations are implementation and deployment specific. That said, this document specifies the mechanisms to notify DOTS clients when conflicts occur, including the conflict cause (Section 4.4.1.3) ⚔️
In deployments where one or more translators (e.g., Traditional NAT [RFC3022], CGN [RFC6888], NAT64 [RFC6146], NPTv6 [RFC6296]) are enabled between the client's network and the DOTS server, any DOTS signal channel messages forwarded to a DOTS server MUST NOT include internal IP addresses/prefixes and/or port numbers. Instead, the external addresses/prefixes and/or port numbers assigned by the translator MUST be used. This document does not make any recommendations about possible translator discovery mechanisms. Here are some (non-exhaustive) deployment examples that may be considered:
- Port Control Protocol (PCP) [RFC6887] or Session Traversal Utilities for NAT (STUN) [RFC8489] may be used by the client to retrieve the external addresses/prefixes and/or port numbers. Information retrieved by means of PCP or STUN will be used to feed the DOTS signal channel messages that will be sent to a DOTS server.
- A DOTS gateway may be co-located with the translator. The DOTS gateway will need to update the DOTS messages based upon the local translator's binding table.
3.1. Backward Compatibility Considerations 🔁
The main changes to [RFC8782] are listed in Appendix A. These modifications are made with the constraint of avoiding changes to the mapping table defined in Table 5 of [RFC8782] (see also Section 6 of the present document).
For both legacy [RFC8782] and implementations that follow the present specification, a DOTS signal channel attribute will thus have the same CBOR key value and CBOR major type. The only upgrade that is required to [RFC8782] implementations is to handle the CBOR key value range "128-255" as comprehension-optional instead of comprehension-required. Note that this range is anticipated to be used by the DOTS telemetry [DOTS-TELEMETRY], in which the following means are used to prevent message processing failure of a DOTS signal channel message enriched with telemetry data: (1) DOTS agents use dedicated (new) path suffixes (Section 5 of [DOTS-TELEMETRY]) and (2) a DOTS server won't include telemetry attributes in its responses unless it is explicitly told to do so by a DOTS client (Section 6.1.2 of [DOTS-TELEMETRY]) 📡
Future DOTS extensions that request a CBOR value in the range "128-255" MUST support means similar to the aforementioned DOTS telemetry ones 🧠
4. DOTS Signal Channel: Messages & Behaviors 📨
4.1. DOTS Server(s) Discovery 🔎
This document assumes that DOTS clients are provisioned with the reachability information of their DOTS server(s) using any of a variety of means (e.g., local configuration or dynamic means, such as DHCP [RFC8973]). The description of such means is out of scope for this document.
Likewise, it is out of scope for this document to specify the behavior a DOTS client should follow in order to send DOTS requests when multiple DOTS servers are provisioned (e.g., contact all DOTS servers, or select one DOTS server among the list). Such behavior is specified in other documents (e.g., [DOTS-MULTIHOMING]) 🥰
4.2. CoAP URIs ✨
okay so the DOTS server MUST support the path prefix of /.well-known/ as defined in [RFC8615] and the registered name of dots 🎀. Every DOTS operation gets its own path suffix that tells you what it's for 💅. You tack the operation path from Table 1 onto that prefix and boom, that's the URI your CoAP request uses 🦋
+=======================+================+=============+
| Operation | Operation Path | Details |
+=======================+================+=============+
| Mitigation | /mitigate | Section 4.4 |
+-----------------------+----------------+-------------+
| Session configuration | /config | Section 4.5 |
+-----------------------+----------------+-------------+
| Heartbeat | /hb | Section 4.7 |
+-----------------------+----------------+-------------+
Table 1: Operations and Corresponding URIs
4.3. Happy Eyeballs for DOTS Signal Channel 🌸
[RFC8612] says DOTS agents have to support both connectionless and connection-oriented protocols, so it's giving two-option energy 💜. The DOTS signal channel works over DTLS over UDP and over TLS over TCP. A DOTS client might get a list of IPv4 and IPv6 addresses (Section 4.1), and each one can be used to reach the DOTS server over UDP and TCP 🧚. If there's no list of IPv4 and IPv6 addresses configured (or discovered) to contact the DOTS server, the DOTS client adds the IPv4/IPv6 addresses of its default router to the candidate list 🫶.
Here's the procedure for picking the address family and transport protocol when sending DOTS signal channel messages 👑.
Why bother? Because nobody wants long connection delays 😭. If an IPv4 path to a DOTS server works but the IPv6 path is broken, a dual-stack DOTS client can end up waiting way longer than an IPv4-only DOTS client on the same network 💀. Also, if a middlebox between them is set up to block UDP traffic, the DOTS client can't establish a DTLS association with the DOTS server, so it has to fall back to TLS over TCP, and that adds significant connection delays too 🙈.
So to fix all this, the DOTS client tries to connect to its DOTS server(s) over both IPv6 and IPv4, and it tries both DTLS over UDP and TLS over TCP, following a DOTS Happy Eyeballs approach ✨. This is kind of similar to the Happy Eyeballs mechanism defined in [RFC8305] 💖. The connection attempts happen when the DOTS client initializes or, more generally, whenever it has to pick an address family and transport to contact its DOTS server. The DOTS client then uses the results for its later messages to the DOTS server 🎀. These are the ways it differs from the Happy Eyeballs mechanism in [RFC8305]:
- The order of preference for the DOTS signal channel address family and transport protocol (most preferred first) is: UDP over IPv6, UDP over IPv4, TCP over IPv6, and finally TCP over IPv4. This order follows the address preference order specified in [RFC6724] and the DOTS signal channel preference for UDP over TCP (to avoid TCP's head of line blocking) 🦋.
- After successfully establishing a connection, the DOTS client MUST cache information about the outcome of each connection attempt for a specific time period, and it uses that info to avoid thrashing the network with more attempts 🧠. The cached info gets flushed when its age goes past a specific time period on the order of a few minutes (e.g., 10 min). Typically, if the DOTS client has to reconnect to the same DOTS server within a few seconds after Happy Eyeballs finishes, caching stops the network from thrashing, especially when DDoS attack traffic is around 🚨.
- If a DOTS signal channel session is established with TLS (but DTLS failed), the DOTS client periodically repeats the mechanism to find out whether DOTS signal channel messages with DTLS over UDP become available from the DOTS server. That way it can migrate the DOTS signal channel from TCP to UDP 🌈. Such probing SHOULD NOT be done more frequently than every 24 hours, and MUST NOT be done more frequently than every 5 minutes ⏰.
When connection attempts happen during an attack, the DOTS client SHOULD use a "Connection Attempt Delay" [RFC8305] set to 100 ms 🫶.
In Figure 4, the DOTS client moves ahead with the connection attempts following the rules in [RFC8305] 🎀. In this example, the IPv6 path is broken and a middlebox drops UDP traffic, but that doesn't hurt the DOTS client much, since there isn't a long delay before it uses IPv4 and TCP 💅.
+-----------+ +-----------+
|DOTS Client| |DOTS Server|
+-----------+ +-----------+
| |
T0 |--DTLS ClientHello, IPv6 ---->X |
T1 |--DTLS ClientHello, IPv4 ---->X |
T2 |--TCP SYN, IPv6-------------->X |
T3 |--TCP SYN, IPv4------------------------------------->|
|<-TCP SYNACK-----------------------------------------|
|--TCP ACK------------------------------------------->|
|<------------Establish TLS Session------------------>|
|----------------DOTS signal------------------------->|
| |
Note:
* Retransmission messages are not shown.
* T1-T0=T2-T1=T3-T2= Connection Attempt Delay.
Figure 4: DOTS Happy Eyeballs (Sample Flow)
A single DOTS signal channel between DOTS agents can carry multiple DOTS signal messages 💜. To cut down the workload on both the DOTS client and the DOTS server, DOTS clients SHOULD reuse the (D)TLS session 🌸.
4.4. DOTS Mitigation Methods 🛡️
These are the methods a DOTS client uses to request, retrieve, or withdraw the status of mitigation requests 💖:
- PUT: DOTS clients use the PUT method to request mitigation from a DOTS server (Section 4.4.1). During active mitigation, DOTS clients may use PUT requests to carry mitigation efficacy updates to the DOTS server (Section 4.4.3).
- GET: DOTS clients may use the GET method to retrieve the list of its mitigations maintained by a DOTS server (Section 4.4.2) or to receive asynchronous DOTS server status messages (Section 4.4.2.1).
- DELETE: DOTS clients use the DELETE method to withdraw a request for mitigation from a DOTS server (Section 4.4.4).
Mitigation request and response messages are marked as Non-confirmable messages (Section 2.2 of [RFC7252]) 🦋.
DOTS agents MUST NOT send more than one UDP datagram per round-trip time (RTT) to the peer DOTS agent on average, following the data transmission guidelines in Section 3.1.3 of [RFC8085] 🧠.
Requests the DOTS client marks as Non-confirmable messages are sent at regular intervals until a response comes back from the DOTS server 🔁. If the DOTS client can't maintain an RTT estimate, it MUST NOT send more than one Non-confirmable request every 3 seconds, and it SHOULD use an even less aggressive rate whenever possible (case 2 in Section 3.1.3 of [RFC8085]) 🐢. Mitigation requests MUST NOT be delayed because of checks on probing rate (Section 4.7 of [RFC7252]) 🚫.
JSON encoding of YANG-modeled data [RFC7951] is used to illustrate the various methods in the subsections below ✨. The examples also use the Labels defined in Sections 10.6.2, 10.6.3, 10.6.4, and 10.6.5 🏷️.
The DOTS client MUST authenticate itself to the DOTS server (Section 8) 🔐. The DOTS server MAY use the algorithm presented in Section 7 of [RFC7589] to derive the DOTS client identity or username from the client certificate 🪪. That DOTS client identity lets the DOTS server accept mitigation requests with scopes the DOTS client is authorized to manage 👑.
4.4.1. Request Mitigation 🚀
4.4.1.1. Building Mitigation Requests 🧱
When a DOTS client needs mitigation for some reason, it uses the CoAP PUT method to send a mitigation request to its DOTS server(s) (Figures 5 and 6) 💌.
If a DOTS client is entitled to solicit the DOTS service, the DOTS server enables mitigation on its behalf. It does this by passing the DOTS client's request along to a mitigator (which may be co-located with the DOTS server) and then relaying the feedback of the thus-selected mitigator back to the requesting DOTS client 🫶.
Header: PUT (Code=0.03)
Uri-Path: ".well-known"
Uri-Path: "dots"
Uri-Path: "mitigate"
Uri-Path: "cuid=dz6pHjaADkaFTbjr0JGBpw"
Uri-Path: "mid=123"
Content-Format: "application/dots+cbor"
{
...
}
Figure 5: PUT to Convey DOTS Mitigation Requests
The order of the Uri-Path options matters, since it defines the CoAP resource 🧩. In particular, 'mid' MUST follow 'cuid' 🎀.
The extra Uri-Path parameters on top of the ones defined in Section 4.2 are:
- cuid: Stands for Client Unique Identifier 🪪. It's a globally unique identifier meant to prevent collisions among DOTS clients, especially ones from the same domain. It MUST be generated by DOTS clients.
For the reasons discussed in Appendix B, implementations SHOULD set 'cuid' using the following procedure 📜. First, the DOTS client feeds one of the following into the SHA-256 [RFC6234] cryptographic hash: the DER-encoded ASN.1 representation of the Subject Public Key Info (SPKI) of its X.509 certificate [RFC5280], its raw public key [RFC7250], the "Pre-Shared Key (PSK) identity" it uses in the TLS 1.2 ClientKeyExchange message, or the "identity" it uses in the "pre_shared_key" TLS 1.3 extension. Then the output of the hash is truncated to 16 bytes, and truncation is done by stripping off the final 16 bytes ✂️. The truncated output is base64url encoded (Section 5 of [RFC4648]) with the two trailing "=" removed from the encoding, and that resulting value becomes the 'cuid' 🌟.
The 'cuid' is meant to stay stable when communicating with a given DOTS server, so the 'cuid' used by a DOTS client SHOULD NOT change over time 🔒. Distinct 'cuid' values MAY be used by a single DOTS client per DOTS server 🦋.
If a DOTS client has to change its 'cuid' for some reason, it MUST NOT do that while mitigations are still active for the old 'cuid' ⚠️. The 'cuid' SHOULD be 22 characters to avoid DOTS signal message fragmentation over UDP 📏. Also, if that DOTS client created aliases and filtering entries at the DOTS server through the DOTS data channel, it MUST delete all the entries bound to the old 'cuid' and reinstall them using the new 'cuid' 🧹💖.
bestie, DOTS servers MUST return the 4.09 (Conflict) error code to a DOTS peer to say the 'cuid' is already in use by another DOTS client 🙈. When that error lands, a new 'cuid' MUST be generated by the DOTS peer (e.g., using [RFC4122]). Fresh start, no tears 🌸
Client-domain DOTS gateways MUST handle 'cuid' collision directly, and it is RECOMMENDED that 'cuid' collision is handled directly by server-domain DOTS gateways. So the client-side gateways are obligated and the server-side ones are strongly encouraged 🫶
DOTS gateways MAY rewrite the 'cuid' used by peer DOTS clients. What triggers that rewriting is out of scope 🧚 This is a mandatory Uri-Path parameter 👑
mid: this is the identifier for the mitigation request, and it's an integer 🦋 It MUST be unique for each mitigation request bound to the DOTS client. Put another way, the 'mid' value needs to be unique (per 'cuid' and DOTS server) compared to the 'mid' values of active mitigation requests sent from the DOTS client to the DOTS server 💜
To handle out-of-order delivery of mitigation requests, 'mid' values MUST increase monotonically 📈
If the 'mid' value has reached 3/4 of (2^(32) - 1) (i.e., 3221225471) and no attack is detected, the DOTS client MUST reset 'mid' to 0 to handle 'mid' rollover. If the DOTS client maintains mitigation requests with preconfigured scopes, it MUST recreate them with the 'mid' restarting at 0 🔄
This identifier MUST be generated by the DOTS client. This is a mandatory Uri-Path parameter ✨
'cuid' and 'mid' MUST NOT appear in the PUT request message body (Figure 6). The schema in Figure 6 uses the types defined in Section 6. Note that this figure (and other similar figures depicting a schema) are non-normative sketches of the structure of the message 📝
{
"ietf-dots-signal-channel:mitigation-scope": {
"scope": [
{
"target-prefix": [
"string"
],
"target-port-range": [
{
"lower-port": number,
"upper-port": number
}
],
"target-protocol": [
number
],
"target-fqdn": [
"string"
],
"target-uri": [
"string"
],
"alias-name": [
"string"
],
"lifetime": number,
"trigger-mitigation": true|false
}
]
}
}
Figure 6: PUT to Convey DOTS Mitigation Requests (Message Body
Schema)
The parameters in the CBOR body (Figure 6) of the PUT request are described below 💖
target-prefix: a list of prefixes identifying resources under attack 🎯 Prefixes are represented using Classless Inter-Domain Routing (CIDR) notation [RFC4632].
The prefix length must be less than or equal to 32 for IPv4 and 128 for IPv6.
The prefix list MUST NOT include broadcast, loopback, or multicast addresses. These addresses are considered to be invalid values. Also, the DOTS server MUST validate that target prefixes are within the scope of the DOTS client domain. Other validation checks may be supported by DOTS servers 🙅♀️
This is an optional attribute.
target-port-range: a list of port numbers bound to resources under attack 🔌
A port range is defined by two bounds: a lower port number ('lower-port') and an upper port number ('upper-port'). When only 'lower-port' is present, it represents a single port number.
For TCP, UDP, Stream Control Transmission Protocol (SCTP) [RFC4960], or Datagram Congestion Control Protocol (DCCP) [RFC4340], a range of ports can be, for example, 0-1023, 1024-65535, or 1024-49151 🌈
This is an optional attribute.
target-protocol: a list of protocols involved in an attack. Values are integers in the range of 0 to 255. See [IANA-Proto] for common values 🧩
If 'target-protocol' is not specified, then the request applies to any protocol.
This is an optional attribute.
target-fqdn: a list of Fully Qualified Domain Names (FQDNs) identifying resources under attack [RFC8499] 🌐
How a name is passed to an underlying name resolution library is implementation and deployment specific. Nevertheless, once the name is resolved into one or multiple IP addresses, DOTS servers MUST apply the same validation checks as those for 'target-prefix'. These validation checks are reiterated by DOTS servers each time a name is passed to an underlying name resolution library (e.g., upon expiry of DNS TTL) ⏰
The use of FQDNs may be suboptimal because:
- It induces both an extra load and increased delays on the DOTS server to handle and manage DNS resolution requests.
- It does not guarantee that the DOTS server will resolve a name to the same IP addresses that the DOTS client does.
This is an optional attribute.
target-uri: a list of URIs [RFC3986] identifying resources under attack 🔗
The same validation checks used for 'target-fqdn' MUST be followed by DOTS servers to validate a target URI.
This is an optional attribute.
alias-name: a list of aliases of resources for which the mitigation is requested 🎀 Aliases can be created using the DOTS data channel (Section 6.1 of [RFC8783]), direct configuration, or other means.
An alias is used in subsequent signal channel exchanges to refer more efficiently to the resources under attack ⭐
This is an optional attribute.
lifetime: the lifetime of the mitigation request in seconds ⏳ The RECOMMENDED lifetime of a mitigation request is 3600 seconds. This value was chosen to be long enough so that refreshing is not typically a burden on the DOTS client, while still making the request expire in a timely manner when the client has unexpectedly quit 🥹 DOTS clients MUST include this parameter in their mitigation requests.
A lifetime of '0' in a mitigation request is an invalid value 🚫
A lifetime of negative one (-1) indicates indefinite lifetime for the mitigation request. The DOTS server MAY refuse an indefinite lifetime, for policy reasons; the granted lifetime value is returned in the response. DOTS clients MUST be prepared to not be granted mitigations with indefinite lifetimes 🙃
The DOTS server MUST always indicate the actual lifetime in the response and the remaining lifetime in status messages sent to the DOTS client 📊
Upon the expiry of the negotiated lifetime (i.e., the remaining lifetime reaches '0'), and if the request is not refreshed by the DOTS client, the mitigation request is removed by the DOTS server. The request can be refreshed by sending the same request again 🔁
This is a mandatory attribute.
trigger-mitigation: if the parameter value is set to 'false', DDoS mitigation will not be triggered for the mitigation request unless the DOTS signal channel session is lost 🚦
If the DOTS client ceases to respond to heartbeat messages, the DOTS server can detect that the DOTS signal channel session is lost. More details are discussed in Section 4.7 💓
The default value of the parameter is 'true' (that is, the mitigation starts immediately). If 'trigger-mitigation' is not present in a request, this is equivalent to receiving a request with 'trigger-mitigation' set to 'true' 🚀
This is an optional attribute.
Because of the complexity of handling partial failure cases, this specification does not allow the inclusion of multiple mitigation requests in the same PUT request. Concretely, a DOTS client MUST NOT include multiple entries in the 'scope' array of the same PUT request 🛑
FQDN and URI mitigation scopes may be thought of as a form of scope alias, in which the addresses associated with the domain name or URI (as resolved by the DOTS server) represent the scope of the mitigation. Particularly, the IP addresses to which the host subcomponent of authority component of a URI resolves represent the 'target-prefix', the URI scheme represents the 'target-protocol', and the port subcomponent of authority component of a URI represents the 'target-port-range'. If the optional port information is not present in the authority component, the default port defined for the URI scheme represents the 'target-port' 🧠
In the PUT request, at least one of the attributes 'target-prefix', 'target-fqdn','target-uri', or 'alias-name' MUST be present ✅
Attributes and Uri-Path parameters with empty values MUST NOT be present in a request, as an empty value will render the entire request invalid 💀
Figure 7 shows a PUT request example to signal that servers 2001:db8:6401::1 and 2001:db8:6401::2 are receiving attack traffic on TCP port numbers 80, 8080, and 443. The presence of 'cdid' indicates that a server-domain DOTS gateway has modified the initial PUT request sent by the DOTS client. Note that 'cdid' MUST NOT appear in the PUT request message body 🎬
Header: PUT (Code=0.03)
Uri-Path: ".well-known"
Uri-Path: "dots"
Uri-Path: "mitigate"
Uri-Path: "cdid=7eeaf349529eb55ed50113"
Uri-Path: "cuid=dz6pHjaADkaFTbjr0JGBpw"
Uri-Path: "mid=123"
Content-Format: "application/dots+cbor"
{
"ietf-dots-signal-channel:mitigation-scope": {
"scope": [
{
"target-prefix": [
"2001:db8:6401::1/128",
"2001:db8:6401::2/128"
],
"target-port-range": [
{
"lower-port": 80
},
{
"lower-port": 443
},
{
"lower-port": 8080
}
],
"target-protocol": [
6
],
"lifetime": 3600
}
]
}
}
Figure 7: PUT for DOTS Mitigation Request (An Example)
The corresponding CBOR encoding format for the payload is shown in Figure 8 🫧
Figure 8 Continued 🎀
A1 # map(1)
01 # unsigned(1)
A1 # map(1)
02 # unsigned(2)
81 # array(1)
A4 # map(4)
06 # unsigned(6)
82 # array(2)
74 # text(20)
323030313A6462383A363430313A3A312F313238
74 # text(20)
323030313A6462383A363430313A3A322F313238
07 # unsigned(7)
83 # array(3)
A1 # map(1)
08 # unsigned(8)
18 50 # unsigned(80)
A1 # map(1)
08 # unsigned(8)
19 01BB # unsigned(443)
A1 # map(1)
08 # unsigned(8)
19 1F90 # unsigned(8080)
0A # unsigned(10)
81 # array(1)
06 # unsigned(6)
0E # unsigned(14)
19 0E10 # unsigned(3600)
Figure 8: PUT for DOTS Mitigation Request (CBOR)
4.4.1.2. Server-Domain DOTS Gateways ✨
okay so in deployments where server-domain DOTS gateways are enabled, the identity info about the origin source client domain (cdid) SHOULD be propagated to the DOTS server 🫶 why? it helps the server enforce policies like grouping DOTS clients that belong to the same DOTS domain, limiting how many DOTS requests come in, and figuring out the mitigation scope 💅 these policies can be enforced per client, per client domain, or both 🦋 and the identity info can also be used for auditing and debugging, which is literally so important 😭
Figure 9 is giving an example of a request relayed by a server-domain DOTS gateway 💖
Header: PUT (Code=0.03)
Uri-Path: ".well-known"
Uri-Path: "dots"
Uri-Path: "mitigate"
Uri-Path: "cdid=7eeaf349529eb55ed50113"
Uri-Path: "cuid=dz6pHjaADkaFTbjr0JGBpw"
Uri-Path: "mid=123"
Content-Format: "application/dots+cbor"
{
...
}
Figure 9: PUT for DOTS Mitigation Request as Relayed by a DOTS
Gateway
A server-domain DOTS gateway SHOULD add the following Uri-Path parameter:
cdid 🌸 stands for Client Domain Identifier! the gateway uses it to pass the source domain identity from its client-facing side to its server-facing side, and then from the server-facing side on to the DOTS server 🧚 the final DOTS server can use cdid for policy-enforcement stuff, like enforcing a quota on filtering rules. those policies are deployment specific, so the deployment gets to decide what they look like 👑
Server-domain DOTS gateways SHOULD support a configuration option to tell them whether the cdid parameter is inserted 🎀
okay this next part is the big one 🔥 server-domain DOTS gateways that are instructed to insert the cdid parameter MUST supply the SPKI hash of the DOTS client X.509 certificate, the DOTS client raw public key, or the hash of the "PSK identity" in the cdid. they follow the same rules for generating the hash that's conveyed in cuid, and then the ultimate DOTS server uses it to figure out the client's domain. so to support per-client policies, per-client domain policies, or a mix of both, this is the move ✨ the cdid a gateway generates is likely to be the same as the cuid, except when the DOTS message was relayed by a client-domain DOTS gateway or when the cuid was generated by a rogue DOTS client 🙈
if a DOTS client is provisioned with, for example, distinct certificates to peer with distinct server-domain DOTS gateways that peer to the same DOTS server, then distinct cdid values may be supplied by those gateways to the server 🦋 the ultimate DOTS server MUST treat those cdid values as equivalent. no cap, that's the rule 💅
The cdid attribute MUST NOT be generated and included by DOTS clients. DOTS clients are not allowed to make their own cdid 🙅
DOTS servers MUST ignore cdid attributes that are directly supplied by source DOTS clients or client-domain DOTS gateways. this implies that first server-domain DOTS gateways MUST strip cdid attributes supplied by DOTS clients. DOTS servers SHOULD support a configuration parameter to identify DOTS gateways that are trusted to supply cdid attributes 🫶
only single-valued cdid values are defined in this document. that means only the first on-path server-domain DOTS gateway can insert a cdid value. this spec does not allow multiple server-domain DOTS gateways in the path to each insert a cdid value for each server-domain gateway 🌈
this is an optional Uri-Path, btw 🧚 when it's present, cdid MUST be positioned before cuid ✨
A DOTS gateway SHOULD add the CoAP Hop-Limit Option [RFC8768]. 💖
4.4.1.3. Processing Mitigation Requests 🦋
the DOTS server couples the DOTS signal and data channel sessions using the DOTS client identity and optionally the cdid parameter value. that way the DOTS server can validate whether the aliases conveyed in the mitigation request were actually created by the same DOTS client using the DOTS data channel session 👀 if the aliases weren't created by the DOTS client, the DOTS server MUST return 4.00 (Bad Request) in the response. big oops, bestie 💀
the DOTS server also couples the DOTS signal channel sessions using the DOTS client identity and optionally the cdid parameter value. it uses the mid and cuid Uri-Path parameter values to detect duplicate mitigation requests 🔍 if the mitigation request contains the alias-name and other parameters that identify the target resources (like target-prefix, target-port-range, target-fqdn, or target-uri), the DOTS server appends the parameter values associated with the alias-name to the corresponding values in target-prefix, target-port-range, target-fqdn, or target-uri 🌸
the DOTS server tells you how the PUT request went using CoAP Response Codes. CoAP 2.xx codes mean success 🎉 CoAP 4.xx codes are some sort of invalid request (client error) 🙃 and CoAP 5.xx codes come back when the DOTS server is in an error state or is currently unavailable to provide mitigation for the request 😭
Figure 10 shows an example response to a PUT request that the DOTS server processed successfully (aka CoAP 2.xx Response Codes). this version forbids cuid and cdid (if used) from showing up in a response message body 🙅
{
"ietf-dots-signal-channel:mitigation-scope": {
"scope": [
{
"mid": 123,
"lifetime": 3600
}
]
}
}
Figure 10: 2.xx Response Body
if the request is missing a mandatory attribute, doesn't include the cuid or mid Uri-Path options, includes multiple scope parameters, or contains invalid or unknown parameters, the DOTS server MUST reply with 4.00 (Bad Request) 🚫 DOTS agents can safely ignore comprehension-optional parameters they don't understand (Section 10.6.1.1) 🫶
a DOTS server that gets a mitigation request with a lifetime set to 0 MUST reply with a 4.00 (Bad Request) 🙅
if the DOTS server doesn't find the mid parameter value from the PUT request in its configuration data, it MAY accept the mitigation request by sending back a 2.01 (Created) response to the DOTS client. the DOTS server will then try to mitigate the attack 🛡️ a DOTS server MAY reject mitigation requests when it's near capacity or needs to rate-limit a particular client, for example 🌈
the relative order of two mitigation requests with the same trigger-mitigation type from a DOTS client is determined by comparing their mid values. if two mitigation requests with the same trigger-mitigation type have overlapping mitigation scopes, the one with the highest numeric mid value overrides the other 👑 two mitigation requests from a DOTS client have overlapping scopes if there's a common IP address, IP prefix, FQDN, URI, or alias. to avoid keeping a long list of overlapping mitigation requests (same trigger-mitigation type and overlapping scopes) from a DOTS client, and to avoid error-prone provisioning, the overlapped lower numeric mid MUST be automatically deleted and no longer available at the DOTS server 🧹 for example, if the DOTS server gets a mitigation request that overlaps with an existing mitigation with a higher numeric mid, the DOTS server rejects the request by returning 4.09 (Conflict) to the DOTS client 🥺 the response MUST include enough information for the DOTS client to recognize the source of the conflict, as described in the conflict-information subtree (Section 5.1), with only the relevant nodes listed:
- conflict-information: indicates that a mitigation request is conflicting with another mitigation request. this attribute has the following structure:
- conflict-cause: indicates the cause of the conflict. the following value MUST be returned:
1: Overlapping targets.conflict-scopeprovides more details about the conflicting target clauses.
- conflict-scope: characterizes the exact conflict scope. it may include a list of IP addresses, a list of prefixes, a list of target protocols, a list of FQDNs, a list of URIs, a list of aliases, or a
mid. a list of port numbers may also be included if there's a common IP address, IP prefix, FQDN, URI, or alias 🔥
- conflict-cause: indicates the cause of the conflict. the following value MUST be returned:
if the DOTS server receives a mitigation request that overlaps with an active mitigation request, but both have distinct trigger-mitigation types, the DOTS server SHOULD deactivate (absent explicit policy/configuration otherwise) the mitigation request with trigger-mitigation set to false 🌸 particularly, if the mitigation request with trigger-mitigation set to false is active, the DOTS server withdraws it (status code is set to 7 as defined in Table 3) and transitions its status to 8 💜
Okay so, if a DOTS signal channel session with a peer DOTS client drops, the DOTS server SHOULD withdraw any active mitigation requests that overlap with mitigation requests from that client having 'trigger-mitigation' set to 'false' 🥺. This only applies unless there's explicit policy or configuration saying otherwise. Why? Because losing the session basically flips on those preconfigured mitigations, and they take precedence 👑. Also, the active-but-terminating period is not observed for mitigations withdrawn at the DOTS server's own initiative. No waiting around, bestie ✨
DOTS clients can totally be strategic about setting the scopes of immediate and preconfigured mitigation requests so they don't fight each other 💅. For example, a DOTS client can tweak its preconfigured scopes so that the scope of any overlapping immediate mitigation request is a subset of the preconfigured scopes. Another move: if an immediate mitigation request overlaps with any preconfigured scopes, the DOTS client sets the immediate one to be a subset of those preconfigured scopes. That way you get a broad mitigation when the DOTS signal channel collapses, and you maximize the chance of recovery 🦋🫶
Now, if a request conflicts with an existing mitigation request from a different DOTS client, the DOTS server may return 2.01 (Created) or 4.09 (Conflict) to the requesting DOTS client 🌸. If the DOTS server decides to maintain the new mitigation request, it returns 2.01 (Created). If it decides to reject the new mitigation request, it returns 4.09 (Conflict). For both 2.01 (Created) and 4.09 (Conflict) responses, the response MUST include enough information for the DOTS client to recognize the source of the conflict, and here's how that info is structured 🔍
conflict-information indicates that a mitigation request is conflicting with another mitigation request(s) from other DOTS client(s). It has the following structure:
conflict-status indicates the status of a conflicting mitigation request. The following values are defined:
- 1: DOTS server has detected conflicting mitigation requests from different DOTS clients. This mitigation request is currently inactive until the conflicts are resolved. Another mitigation request is active.
- 2: DOTS server has detected conflicting mitigation requests from different DOTS clients. This mitigation request is currently active.
- 3: DOTS server has detected conflicting mitigation requests from different DOTS clients. All conflicting mitigation requests are inactive.
conflict-cause indicates the cause of the conflict. The following values are defined:
- 1: Overlapping targets.
conflict-scopeprovides more details about the conflicting target clauses. - 2: Conflicts with an existing accept-list. This code is returned when the DDoS mitigation detects source addresses/prefixes in the accept-listed Access Control Lists (ACLs) are attacking the target.
- 3: CUID Collision. This code is returned when a DOTS client uses a
cuidthat is already used by another DOTS client. It's an indication that the request has been rejected, and a new request with a newcuidis to be re-sent by the DOTS client (see the example shown in Figure 11). Note thatconflict-status,conflict-scope, andretry-timerMUST NOT be returned in the error response. Big reminder, no sneaking those in 🙅♀️
conflict-scope characterizes the exact conflict scope. It may include a list of IP addresses, a list of prefixes, a list of target protocols, a list of FQDNs, a list of URIs, a list of aliases, or references to conflicting ACLs (by an acl-name, typically [RFC8783]). A list of port numbers may also be included if there is a common IP address, IP prefix, FQDN, URI, or alias.
retry-timer indicates, in seconds, the time after which the DOTS client may reissue the same request. The DOTS server returns retry-timer only to DOTS client(s) for which a mitigation request is deactivated. Any retransmission of the same mitigation request before this timer expires is likely to be rejected by the DOTS server for the same reasons, so hold up 🛑
The retry-timer SHOULD be equal to the lifetime of the active mitigation request that resulted in the deactivation of the conflicting mitigation request. ⏳
If the DOTS server decides to maintain a state for the deactivated mitigation request, it updates the lifetime of the deactivated mitigation request to retry-timer + 45 seconds (that is, this mitigation request remains deactivated for the entire duration of retry-timer + 45 seconds). This way, the DOTS client can refresh the deactivated mitigation request after retry-timer seconds, but before the lifetime expires, and check whether the conflict is resolved 🧚
Here's the cuid collision example, bestie 📸
(1) Request with a conflicting 'cuid'
Header: PUT (Code=0.03)
Uri-Path: ".well-known"
Uri-Path: "dots"
Uri-Path: "mitigate"
Uri-Path: "cuid=dz6pHjaADkaFTbjr0JGBpw"
Uri-Path: "mid=12"
(2) Message body of the 4.09 (Conflict) response from the DOTS server
{
"ietf-dots-signal-channel:mitigation-scope": {
"scope": [
{
"conflict-information": {
"conflict-cause": "cuid-collision"
}
}
]
}
}
(3) Request with a new 'cuid'
Header: PUT (Code=0.03)
Uri-Path: ".well-known"
Uri-Path: "dots"
Uri-Path: "mitigate"
Uri-Path: "cuid=f30d281ce6b64fc5a0b91e"
Uri-Path: "mid=12"
Figure 11: Example of Generating a New 'cuid'
As an active attack evolves, DOTS clients can adjust the scope of requested mitigation as needed 🎯 by refining the scope of resources requiring mitigation. This can be done by sending a PUT request with a new 'mid' value, which overrides the existing one with overlapping mitigation scopes. Main character glow-up energy ✨
Now, for a mitigation request to keep going beyond its initial negotiated lifetime, the DOTS client has to refresh the current mitigation request by sending a new PUT request. This PUT request MUST use the same 'mid' value, and it MUST repeat all the other parameters as sent in the original mitigation request, apart from a possible change to the 'lifetime' parameter value. In that case, the DOTS server MAY update the mitigation request by setting the remaining lifetime to the newly negotiated lifetime, and a 2.04 (Changed) response is returned to indicate a successful update of the mitigation request 🥳. If that's not the case, the DOTS server MUST reject the request with a 4.00 (Bad Request) 💀
4.4.2. Retrieve Information Related to a Mitigation 🦋
Okay bestie, so a GET request is how a DOTS client peeks at the info (including status) about its DOTS mitigations living on a DOTS server 👀✨
'cuid' is a mandatory Uri-Path parameter for GET requests 💖
Uri-Path parameters with empty values MUST NOT be present in a request. No empty Uri-Path vibes allowed 🙅♀️
The same considerations for manipulating the 'cdid' parameter by server-domain DOTS gateways specified in Section 4.4.1 MUST be followed for GET requests. So if you're a gateway, you know the drill from 4.4.1 💅
The 'c' Uri-Query option is used to control selection of configuration and non-configuration data nodes. Basically, the 'c' (content) parameter and its permitted values from Table 2 of [CORE-COMI] can be used to grab non-configuration data (attack mitigation status), configuration data, or both 🎀 The DOTS server MAY support this optional filtering capability. It can safely ignore it if it isn't supported, no drama 🌸 If the DOTS client supports the optional filtering capability, it SHOULD use "c=n" query (to get back only the dynamically changing data) or "c=c" query (to get back the static configuration values) when the DDoS attack is active, so the response stays small 🧚
+=======+=====================================================+
| Value | Description |
+=======+=====================================================+
| c | Return only configuration descendant data nodes |
+-------+-----------------------------------------------------+
| n | Return only non-configuration descendant data nodes |
+-------+-----------------------------------------------------+
| a | Return all descendant data nodes |
+-------+-----------------------------------------------------+
Table 2: Permitted Values of the 'c' Parameter
The DOTS client can use block-wise transfer [RFC7959] to get the list of all its mitigations maintained by a DOTS server 🍓 It can send a Block2 Option in a GET request with NUM = 0 to help keep the response size in check. If the representation of all the active mitigation requests associated with the DOTS client does not fit within a single datagram, the DOTS server MUST use the Block2 Option with NUM = 0 in the GET response 😭 The Size2 Option may be conveyed in the response to indicate the total size of the resource representation. The DOTS client then grabs the rest of the representation by sending additional GET requests with Block2 Options containing NUM values greater than zero. The DOTS client MUST adhere to the block size preferences indicated by the DOTS server in the response, no going rogue 👑
If the DOTS server uses the Block2 Option in the GET response, and the response is for a dynamically changing resource (e.g., "c=n" or "c=a" query), the DOTS server MUST include the ETag Option in the response. Then the DOTS client MUST include the same ETag value in subsequent GET requests to retrieve the rest of the representation. ETag energy, fr fr 🔥
The following examples illustrate how a DOTS client retrieves active mitigation requests from a DOTS server. In particular:
- Figure 12 shows the example of a GET request to retrieve all DOTS mitigation requests signaled by a DOTS client.
- Figure 13 shows the example of a GET request to retrieve a specific DOTS mitigation request signaled by a DOTS client. The configuration data to be reported in the response is formatted in the same order as it was processed by the DOTS server in the original mitigation request.
These two examples assume the default of "c=a"; that is, the DOTS client asks for all data to be reported by the DOTS server 🌈
Header: GET (Code=0.01)
Uri-Path: ".well-known"
Uri-Path: "dots"
Uri-Path: "mitigate"
Uri-Path: "cuid=dz6pHjaADkaFTbjr0JGBpw"
Observe: 0
Figure 12: GET to Retrieve All DOTS Mitigation Requests
Header: GET (Code=0.01)
Uri-Path: ".well-known"
Uri-Path: "dots"
Uri-Path: "mitigate"
Uri-Path: "cuid=dz6pHjaADkaFTbjr0JGBpw"
Uri-Path: "mid=12332"
Observe: 0
Figure 13: GET to Retrieve a Specific DOTS Mitigation Request
If the DOTS server does not find the 'mid' Uri-Path value conveyed in the GET request in its configuration data for the requesting DOTS client, it MUST respond with a 4.04 (Not Found) error Response Code. 🙈 Likewise, the same error MUST be returned as a response to a request to retrieve all mitigation records (i.e., 'mid' Uri-Path is not defined) of a given DOTS client if the DOTS server does not find any mitigation record for that DOTS client. Quick reminder: a DOTS client is identified by its identity (e.g., client certificate, 'cuid') and optionally the 'cdid' 🫶
Figure 14 shows a response example of all active mitigation requests associated with the DOTS client, as maintained by the DOTS server. The response indicates the mitigation status of each mitigation request 💜
{
"ietf-dots-signal-channel:mitigation-scope": {
"scope": [
{
"mid": 12332,
"mitigation-start": "1507818434",
"target-prefix": [
"2001:db8:6401::1/128",
"2001:db8:6401::2/128"
],
"target-protocol": [
17
],
"lifetime": 1756,
"status": "attack-successfully-mitigated",
"bytes-dropped": "134334555",
"bps-dropped": "43344",
"pkts-dropped": "333334444",
"pps-dropped": "432432"
},
{
"mid": 12333,
"mitigation-start": "1507818393",
"target-prefix": [
"2001:db8:6401::1/128",
"2001:db8:6401::2/128"
],
"target-protocol": [
6
],
"lifetime": 1755,
"status": "attack-stopped",
"bytes-dropped": "0",
"bps-dropped": "0",
"pkts-dropped": "0",
"pps-dropped": "0"
}
]
}
}
Figure 14: Response Body to a GET Request
The mitigation status parameters are described below, and they're giving a lot of detail ✨
- mitigation-start: Mitigation start time is expressed in seconds relative to 1970-01-01T00:00Z in UTC time (Section 3.4.1 of [RFC8949]). The CBOR encoding is modified so that the leading tag 1 (epoch-based date/time) MUST be omitted. This is a mandatory attribute when an attack mitigation is active. Particularly, 'mitigation-start' is not returned for a mitigation with 'status' code set to 8.
- lifetime: The remaining lifetime of the mitigation request, in seconds. This is a mandatory attribute.
- status: Status of attack mitigation. The various possible values of 'status' parameter are explained in Table 3. This is a mandatory attribute.
- bytes-dropped: The total dropped byte count for the mitigation request since the attack mitigation was triggered. The count wraps around when it reaches the maximum value of unsigned integer64. This is an optional attribute.
- bps-dropped: The average number of dropped bytes per second for the mitigation request since the attack mitigation was triggered. This average SHOULD be over five-minute intervals (that is, measuring bytes into five-minute buckets and then averaging these buckets over the time since the mitigation was triggered). This is an optional attribute.
- pkts-dropped: The total number of dropped packet count for the mitigation request since the attack mitigation was triggered. The count wraps around when it reaches the maximum value of unsigned integer64. This is an optional attribute.
- pps-dropped: The average number of dropped packets per second for the mitigation request since the attack mitigation was triggered. This average SHOULD be over five-minute intervals (that is, measuring packets into five-minute buckets and then averaging these buckets over the time since the mitigation was triggered). This is an optional attribute.
+===========+====================================================+
| Parameter | Description |
| Value | |
+===========+====================================================+
| 1 | Attack mitigation setup is in progress (e.g., |
| | changing the network path to redirect the inbound |
| | traffic to a DOTS mitigator). |
+-----------+----------------------------------------------------+
| 2 | Attack is being successfully mitigated (e.g., |
| | traffic is redirected to a DDoS mitigator and |
| | attack traffic is dropped). |
+-----------+----------------------------------------------------+
| 3 | Attack has stopped and the DOTS client can |
| | withdraw the mitigation request. This status code |
| | will be transmitted for immediate mitigation |
| | requests till the mitigation is withdrawn or the |
| | lifetime expires. For mitigation requests with |
| | preconfigured scopes (i.e., 'trigger-mitigation' |
| | set to 'false'), this status code will be |
| | transmitted four times and then transition to '8'. |
+-----------+----------------------------------------------------+
| 4 | Attack has exceeded the mitigation provider |
| | capability. |
+-----------+----------------------------------------------------+
| 5 | DOTS client has withdrawn the mitigation request |
| | and the mitigation is active but terminating. |
+-----------+----------------------------------------------------+
| 6 | Attack mitigation is now terminated. |
+-----------+----------------------------------------------------+
| 7 | Attack mitigation is withdrawn (by the DOTS |
| | server). If a mitigation request with 'trigger- |
| | mitigation' set to 'false' is withdrawn because it |
| | overlaps with an immediate mitigation request, |
| | this status code will be transmitted four times |
| | and then transition to '8' for the mitigation |
| | request with preconfigured scopes. |
+-----------+----------------------------------------------------+
| 8 | Attack mitigation will be triggered for the |
| | mitigation request only when the DOTS signal |
| | channel session is lost. |
+-----------+----------------------------------------------------+
Table 3: Values of 'status' Parameter 🌈✨ that's the whole status table, bestie ✨🌈
4.4.2.1. DOTS Servers Sending Mitigation Status
Okay so the Observe Option from [RFC7641] gives CoAP a glow-up 💖 It lets a CoAP client "observe" a resource on a CoAP server: the client grabs a representation of the resource and asks the server to keep it updated for as long as the client cares about it ✨. DOTS implementations MUST support the Observe Option for both 'mitigate' and 'config' (Section 4.2) 🫶
A DOTS client sets the Observe Option to '0' in its GET request so it can get asynchronous notifications of attack mitigation status from the DOTS server 🦋
Unidirectional mitigation notifications inside the bidirectional signal channel are what make async updates possible between the agents 🌸 [RFC7641] says that (1) a notification can go out in a Confirmable or a Non-confirmable message, and (2) the message type is usually application dependent and can be picked by the server for each notification one at a time 💅 For the DOTS server application, the message type MUST always be set to Non-confirmable, even if the underlying CoAP library would normally send a notification in a Confirmable message. This overrides the behavior in Section 4.5 of [RFC7641], which sends a Confirmable message instead of a Non-confirmable one at least every 24 hours 🙈 Why? Two reasons, bestie. First, the DOTS signal channel already uses a heartbeat mechanism to check if the DOTS client is alive 💜 Second, Confirmable messages are not suitable during an attack 💀
Due to the higher likelihood of packet loss during a DDoS attack, the DOTS server periodically sends attack mitigation status to the DOTS client, and it also notifies the DOTS client whenever the status of the attack mitigation changes 🌈 If the DOTS server cannot maintain an RTT estimate, it MUST NOT send more than one asynchronous notification every 3 seconds, and it SHOULD use an even less aggressive rate whenever possible (case 2 in Section 3.1.3 of [RFC8085]) 🍓
When conflicting requests show up, the DOTS server enforces the matching policy (for example: accept all requests, reject all requests, or accept only one request and reject all the others) 👑 It's assumed that this policy is supplied by the DOTS server administrator, or that it's a default behavior of the DOTS server implementation. Then the DOTS server sends notification message(s) to the DOTS client(s) at the origin of the conflict (refer to the conflict parameters defined in Section 4.4.1) 🔥 A conflict notification message includes info about the conflict cause, scope, and the status of the mitigation request(s). For example:
- A notification message with 'status' code set to '7 (Attack mitigation is withdrawn)' and 'conflict-status' set to '1' is sent to a DOTS client to indicate that an active mitigation request is deactivated because a conflict is detected 😭
- A notification message with 'status' code set to '1 (Attack mitigation is in progress)' and 'conflict-status' set to '2' is sent to a DOTS client to indicate that this mitigation request is in progress, but a conflict is detected 🧚
Upon receipt of a conflict notification message saying a mitigation request got deactivated because of a conflict, a DOTS client MUST NOT resend the same mitigation request before the expiry of 'retry-timer' 🛑 It's also recommended that DOTS clients support ways to alert administrators about mitigation conflicts 📣
A DOTS client that no longer wants notifications from the DOTS server can simply "forget" the observation 🙃 When the DOTS server sends the next notification, the DOTS client won't recognize the token in the message, so it will return a Reset message. That causes the DOTS server to remove the associated entry 🧹 Or, the DOTS client can explicitly de-register by issuing a GET request with the Token field set to the token of the observation to be canceled, and including an Observe Option with the value set to '1' (de-register). The latter is more deterministic, and that's why it is RECOMMENDED 💅
Figure 15 shows a DOTS client asking a DOTS server to send notifications about a mitigation request 📸 Note that for mitigations with preconfigured scopes (i.e., 'trigger-mitigation' set to 'false'), the state will need to transition from '3' (attack-stopped) to '8' (attack-mitigation-signal-loss) 🎀
+-----------+ +-----------+
|DOTS Client| |DOTS Server|
+-----------+ +-----------+
| |
| GET /<mid> |
| Token: 0x4a | Registration
| Observe: 0 |
+----------------------------------------->|
| |
| 2.05 Content |
| Token: 0x4a | Notification of
| Observe: 12 | the current state
| status: "attack-mitigation-in-progress" |
|<-----------------------------------------+
| |
| 2.05 Content |
| Token: 0x4a | Notification upon
| Observe: 44 | a state change
| status: "attack-successfully-mitigated" |
|<-----------------------------------------+
| |
| 2.05 Content |
| Token: 0x4a | Notification upon
| Observe: 60 | a state change
| status: "attack-stopped" |
|<-----------------------------------------+
| |
...
Figure 15: Notifications of Attack Mitigation Status
4.4.2.2. DOTS Clients Polling for Mitigation Status
Here's the vibe: the DOTS client can send GET requests at frequent intervals without the Observe Option to fetch the configuration data of the mitigation request and the non-configuration data (aka the attack status) 🧁 DOTS clients MAY be configured with a policy that sets how often they poll DOTS servers for mitigation status 🕰️ That frequency MUST NOT be more than one UDP datagram per RTT, as discussed in Section 3.1.3 of [RFC8085] 🛡️
If the DOTS server has mitigated the attack and the attack has stopped, the DOTS server says so in the status 🥳 Then the DOTS client withdraws the mitigation request by issuing a DELETE request for it (Section 4.4.4) 👋
A DOTS client SHOULD react to the attack status based on what the DOTS server tells it, rather than doing its own detection that the attack has been mitigated 🧠 This keeps the DOTS client from withdrawing a mitigation request too early. The DOTS client might not sense the DDoS attack on its resources, while the DOTS server could still be actively mitigating it because the attack isn't completely averted 😤
4.4.3. Efficacy Update from DOTS Clients
While DDoS mitigation is in progress, and because packet loss is likely, a DOTS client MAY periodically send DOTS mitigation efficacy updates to the relevant DOTS server 📬 A PUT request carries the mitigation efficacy update to the DOTS server, and this PUT request is treated as a refresh of the current mitigation 🔄
The 'attack-status' parameter is a mandatory attribute when performing an efficacy update 📝 The possible values of 'attack-status' are described in Table 4 🌷
+===========+=====================================+
| Parameter | Description |
| Value | |
+===========+=====================================+
| 1 | The DOTS client determines that it |
| | is still under attack. |
+-----------+-------------------------------------+
| 2 | The DOTS client determines that the |
| | attack is successfully mitigated |
| | (e.g., attack traffic is not seen). |
+-----------+-------------------------------------+
Table 4: Values of 'attack-status' Parameter
The PUT request used for the efficacy update MUST include all the parameters used in the PUT request that carried the DOTS mitigation request (Section 4.4.1), unchanged apart from the 'lifetime' parameter value 🎯 If that's not the case, the DOTS server MUST reject the request with a 4.00 (Bad Request) 🙅♀️
The If-Match Option (Section 5.10.8.1 of [RFC7252]) with an empty value is used to make the PUT request conditional on the current existence of the mitigation request 🧩 If UDP is the transport, CoAP requests can arrive out of order 🌀 For example, the DOTS client might send a PUT request to convey an efficacy update to the DOTS server, followed by a DELETE request to withdraw the mitigation request, but the DELETE request arrives at the DOTS server before the PUT request. To handle out-of-order delivery, if an If-Match Option is present in the PUT request and the 'mid' in the request matches a mitigation request from that DOTS client, the request is processed by the DOTS server. If no match is found, the DOTS server silently ignores the PUT request 🙈
An example efficacy update message, which includes an If-Match Option with an empty value, is shown in Figure 16 🎀
Header: PUT (Code=0.03)
Uri-Path: ".well-known"
Uri-Path: "dots"
Uri-Path: "mitigate"
Uri-Path: "cuid=dz6pHjaADkaFTbjr0JGBpw"
Uri-Path: "mid=123"
If-Match:
Content-Format: "application/dots+cbor"
{
"ietf-dots-signal-channel:mitigation-scope": {
"scope": [
{
"target-prefix": [
"2001:db8:6401::1/128",
"2001:db8:6401::2/128"
],
"target-port-range": [
{
"lower-port": 80
},
{
"lower-port": 443
},
{
"lower-port": 8080
}
],
"target-protocol": [
6
],
"attack-status": "under-attack"
}
]
}
}
Figure 16: An Example of Efficacy Update
The DOTS server reports the result of processing a PUT request using CoAP Response Codes 📊 The Response Code 2.04 (Changed) is returned if the DOTS server has accepted the mitigation efficacy update ✅ The error Response Code 5.03 (Service Unavailable) is returned if the DOTS server has erred or is incapable of performing the mitigation 🥺 As specified in [RFC7252], 5.03 uses the Max-Age Option to indicate the number of seconds after which to retry ⏳
4.4.4. Withdraw a Mitigation 🧹✨
okay so this is the part where the client says "bye bye, mitigation" 👋💅 and it does that with DELETE requests. Figure 17 shows what one looks like. 🎀
cuid and mid are mandatory Uri-Path parameters for DELETE requests. 🫶 The same rules for handling the cdid parameter that DOTS gateways follow, as laid out in Section 4.4.1, MUST be followed for DELETE requests too. And Uri-Path parameters with empty values MUST NOT be present in a request. No empty params, bestie 🙅♀️
Header: DELETE (Code=0.04)
Uri-Path: ".well-known"
Uri-Path: "dots"
Uri-Path: "mitigate"
Uri-Path: "cuid=dz6pHjaADkaFTbjr0JGBpw"
Uri-Path: "mid=123"
Figure 17: Withdraw a DOTS Mitigation 🦋
If the DELETE request doesn't have cuid and mid in it, the DOTS server MUST reply with a 4.00 (Bad Request). Not a vibe 💀
Once the request is validated, the DOTS server immediately acknowledges the withdrawal with a 2.02 (Deleted) Response Code and no response payload. Honestly iconic of it 🍓 It does this even if the mid value in the DELETE doesn't exist in its configuration data beforehand. So no drama, just a clean "okay, noted" ✨
Now the fun part. If the DOTS server does find that mid value in its configuration data for that DOTS client, it MAY keep the mitigation going for a limited period after it acknowledges the withdrawal. Why? To protect against route or DNS flapping that could happen if a DOTS client keeps rapidly removing and re-adding a mitigation, and to dampen the effect of oscillating attacks. Smart, right? 🧠👑 While this is happening, the DOTS server status messages SHOULD indicate that mitigation is active but terminating (Section 4.4.2). 🌈
The initial active-but-terminating period SHOULD be long enough to soak up the latency from route propagation. By default, it SHOULD be set to 120 seconds ⏱️ If the client asks for mitigation again before that initial period runs out, the DOTS server MAY exponentially increase the period (the base of the exponent is 2), capped at a maximum of 300 seconds (5 minutes). Exponential growth, but make it capped 📈
Once the active-but-terminating period is over, the DOTS server MUST treat the mitigation as terminated. That's the end of that era 🥀
One more thing 👀 If a mitigation was triggered by a signal channel loss, the DOTS server depends on the usual triggers to stop it. Those are typically a valid DELETE request, the mitigation lifetime expiring, or the traffic to the attack target getting scrubbed. And here's the important bit: the DOTS server MUST NOT count the signal channel coming back as a reason to stop the mitigation. Recovering the connection does NOT end the mitigation, periodt 🚫✋
4.5. DOTS Signal Channel Session Configuration 🎛️💖
A DOTS client can negotiate, configure, and retrieve the DOTS signal channel session behavior with its DOTS peers. 💜 The DOTS signal channel can be used to configure things like these:
a. Heartbeat interval (heartbeat-interval): DOTS agents regularly send heartbeats to each other once mutual authentication is successfully completed, so the DOTS signal channel stays open 💓 Heartbeat messages go out every heartbeat-interval seconds to check the current status of the DOTS signal channel session.
b. Missing heartbeats allowed (missing-hb-allowed): This variable is the maximum number of consecutive heartbeat messages a DOTS agent can send without getting a response before it decides the session is disconnected or defunct. Ghosted, basically 👻
c. Acceptable probing rate (probing-rate): This parameter is the average data rate that must not be exceeded by a DOTS agent when it's sending to a peer DOTS agent that isn't responding. Don't spam the ghost 🙅♀️
d. Acceptable signal loss ratio: Maximum retransmissions (max-retransmit), retransmission timeout value (ack-timeout), and other message transmission parameters for Confirmable messages over the DOTS signal channel. 🔁
When the DOTS signal channel runs over a reliable transport (e.g., TCP), there's no need for the reliability stuff CoAP brings over UDP, because TCP already handles retransmissions and deduplication [RFC8323]. 🫠 CoAP over reliable transports doesn't support Confirmable or Non-confirmable message types. So the transmission-related parameters (missing-hb-allowed and the acceptable signal loss ratio) are only negotiated for DOTS over unreliable transports. Main character logic: TCP has its own back-up plan 😤
The same or different configuration sets can be used when a mitigation is active (mitigating-config) and when no mitigation is active (idle-config). This is super handy for DOTS servers that want to lower heartbeat frequency or stop heartbeats entirely when an active DOTS client hasn't asked for mitigation. 💤 If distinct configurations are used, DOTS agents MUST follow the set that matches the mitigation activity. So if no mitigation request is active (also called 'idle' time), the idle-config values have to be followed. On top of that, DOTS agents MUST automatically switch to the other configuration whenever the mitigation activity changes. Example: an attack mitigation launches after an 'idle' stretch, so the agent switches from idle-config values to mitigating-config values. Seamless transition, no cap 🔄⚡
CoAP requests and responses are marked as Confirmable messages when reliable delivery is needed. DOTS signal channel session configuration requests and responses are marked as Confirmable messages too. As explained in Section 2.1 of [RFC7252], a Confirmable message gets retransmitted using a default timeout and exponential backoff between retransmissions, until the DOTS server sends an Acknowledgement message (ACK) carrying the same Message ID the DOTS client used. 📬
Message transmission parameters are defined in Section 4.8 of [RFC7252]. The DOTS server can piggyback the response in the Acknowledgement message. If it can't respond right away to a request sent in a Confirmable message, it can just send an Empty Acknowledgement message so the DOTS client stops retransmitting. Empty Acknowledgement messages are explained in Section 2.2 of [RFC7252]. Once the response is ready, the server sends it in a new Confirmable message, which then needs to be acknowledged by the DOTS client (see Sections 5.2.1 and 5.2.2 of [RFC7252]). Requests and responses exchanged during 'idle' time, except heartbeat messages, are marked as Confirmable messages. 🧾✨
Implementation Note: A DOTS client that gets a response in a Confirmable message may want to clean up its message state right after sending the ACK. But if that ACK gets lost, the DOTS server retransmits the Confirmable message, and the client may no longer have any state to match it to. From the client's point of view, that retransmission is unexpected. So the DOTS client sends a Reset message, which stops any further retransmissions. This is normal behavior and NOT an error (see Section 5.3.2 of [RFC7252] for more details). Not a bug, just the protocol being extra 🙈💅
4.5.1. Discover Configuration Parameters ✨
okay bestie, so a GET request is how a DOTS client asks its DOTS server what settings it's cool with, like the minimum and maximum values (for example), plus what's currently set 💅 this only happens between a DOTS client and its immediate peer DOTS server, so this GET request MUST NOT be relayed by a DOTS gateway 🙈 no gateway hopping for this one!
Figure 18 shows how to grab the configuration parameters the DOTS server will find acceptable 🎀
Header: GET (Code=0.01)
Uri-Path: ".well-known"
Uri-Path: "dots"
Uri-Path: "config"
Figure 18: GET to Retrieve Configuration
the DOTS server sends back a 2.05 (Content) response that spills the current, minimum, and maximum attribute values it finds acceptable (Figure 19) 🦋
{
"ietf-dots-signal-channel:signal-config": {
"mitigating-config": {
"heartbeat-interval": {
"max-value": number,
"min-value": number,
"current-value": number
},
"missing-hb-allowed": {
"max-value": number,
"min-value": number,
"current-value": number
},
"probing-rate": {
"max-value": number,
"min-value": number,
"current-value": number
},
"max-retransmit": {
"max-value": number,
"min-value": number,
"current-value": number
},
"ack-timeout": {
"max-value-decimal": "string",
"min-value-decimal": "string",
"current-value-decimal": "string"
},
"ack-random-factor": {
"max-value-decimal": "string",
"min-value-decimal": "string",
"current-value-decimal": "string"
}
},
"idle-config": {
"heartbeat-interval": {
"max-value": number,
"min-value": number,
"current-value": number
},
"missing-hb-allowed": {
"max-value": number,
"min-value": number,
"current-value": number
},
"probing-rate": {
"max-value": number,
"min-value": number,
"current-value": number
},
"max-retransmit": {
"max-value": number,
"min-value": number,
"current-value": number
},
"ack-timeout": {
"max-value-decimal": "string",
"min-value-decimal": "string",
"current-value-decimal": "string"
},
"ack-random-factor": {
"max-value-decimal": "string",
"min-value-decimal": "string",
"current-value-decimal": "string"
}
}
}
}
Figure 19: GET Configuration Response Body Schema
here's the tea on each parameter in Figure 19 🍓
- mitigating-config: the set of configuration parameters to use when a mitigation is active. The following parameters may be included:
- heartbeat-interval: time interval in seconds between two consecutive heartbeat messages.
'0'is used to disable the heartbeat mechanism.- This is an optional attribute.
- missing-hb-allowed: maximum number of consecutive heartbeat messages for which the DOTS agent did not receive a response before concluding that the session is disconnected.
- This is an optional attribute.
- probing-rate: the average data rate, in bytes/second, that must not be exceeded by a DOTS agent in sending to a peer DOTS agent that does not respond (referred to as PROBING_RATE parameter in CoAP).
- This is an optional attribute.
- max-retransmit: maximum number of retransmissions for a message (referred to as MAX_RETRANSMIT parameter in CoAP).
- This is an optional attribute.
- ack-timeout: timeout value in seconds used to calculate the initial retransmission timeout value (referred to as ACK_TIMEOUT parameter in CoAP).
- This is an optional attribute.
- ack-random-factor: random factor used to influence the timing of retransmissions (referred to as ACK_RANDOM_FACTOR parameter in CoAP).
- This is an optional attribute.
- heartbeat-interval: time interval in seconds between two consecutive heartbeat messages.
- idle-config: the set of configuration parameters to use when no mitigation is active. This attribute has the same structure as
mitigating-config.
Figure 20 shows an example of acceptable and current configuration parameters on a DOTS server for DOTS signal channel session configuration. The same acceptable configuration is used during mitigation and idle times 💜
{
"ietf-dots-signal-channel:signal-config": {
"mitigating-config": {
"heartbeat-interval": {
"max-value": 240,
"min-value": 15,
"current-value": 30
},
"missing-hb-allowed": {
"max-value": 20,
"min-value": 3,
"current-value": 15
},
"probing-rate": {
"max-value": 20,
"min-value": 5,
"current-value": 15
},
"max-retransmit": {
"max-value": 15,
"min-value": 2,
"current-value": 3
},
"ack-timeout": {
"max-value-decimal": "30.00",
"min-value-decimal": "1.00",
"current-value-decimal": "2.00"
},
"ack-random-factor": {
"max-value-decimal": "4.00",
"min-value-decimal": "1.10",
"current-value-decimal": "1.50"
}
},
"idle-config": {
"heartbeat-interval": {
"max-value": 240,
"min-value": 15,
"current-value": 30
},
"missing-hb-allowed": {
"max-value": 20,
"min-value": 3,
"current-value": 15
},
"probing-rate": {
"max-value": 20,
"min-value": 5,
"current-value": 15
},
"max-retransmit": {
"max-value": 15,
"min-value": 2,
"current-value": 3
},
"ack-timeout": {
"max-value-decimal": "30.00",
"min-value-decimal": "1.00",
"current-value-decimal": "2.00"
},
"ack-random-factor": {
"max-value-decimal": "4.00",
"min-value-decimal": "1.10",
"current-value-decimal": "1.50"
}
}
}
}
Figure 20: Example of a Configuration Response Body
4.5.2. Convey DOTS Signal Channel Session Configuration 🎀
okay so a PUT request (Figures 21 and 22) is how you send your signal channel config over 💌 stuff like the heartbeat interval and max retransmissions (e.g., heartbeat interval, maximum retransmissions). CoAP's transmission parameters are defined in Section 4.8 of [RFC7252] 🧚 The RECOMMENDED values for those are ack-timeout (2 seconds), max-retransmit (3), and ack-random-factor (1.5) 💖 On top of those, the RECOMMENDED DOTS-specific values are heartbeat-interval (30 seconds) and missing-hb-allowed (15) 🫶
Note: this part is the tea 🍵heartbeat-intervalshould also be tweaked to help DOTS messages survive NAT traversal (SIG-011 of [RFC8612]). According to [RFC8085], heartbeat messages must not be sent more frequently than once every 15 seconds and should use longer intervals when possible. [RFC4787] recommends that NATs use a state timeout of 2 minutes or longer, but experience shows that sending packets every 15 to 30 seconds is necessary to stop most middleboxes from losing state for UDP flows. So the RECOMMENDED minimumheartbeat-intervalis 15 seconds and the RECOMMENDED maximumheartbeat-intervalis 240 seconds. The recommended value of 30 seconds is picked to get ahead of NAT state expiring 🙈 Aheartbeat-intervalof 30 seconds may be considered too chatty in some deployments 😭 For those, DOTS agents may negotiate longerheartbeat-intervalvalues so the network doesn't get flooded with too-frequent heartbeats. You can define different heartbeat intervals formitigating-configandidle-configso you're not being too chatty during quiet times 🦋 If there's an on-path translator between the DOTS client (standalone or part of a DOTS gateway) and the DOTS server, themitigating-configheartbeat-intervalhas to be smaller than the translator session timeout. It is recommended that theidle-configheartbeat-intervalalso be smaller than the translator session timeout to avoid translator traversal issues, or that it be disabled entirely. Means to discover the lifetime assigned by a translator are out of scope. Since the heartbeat request can't be bigger than (heartbeat-interval*probing-rate) bytes,probing-rateshould be set appropriately so heartbeat exchanges don't slow down 🌸 For example,probing-ratemay be set to2 * ("size of encrypted DOTS heartbeat request"/'heartbeat-interval')or(("size of encrypted DOTS heartbeat request" + "average size of an encrypted mitigation request")/'heartbeat-interval'). Unless there's explicit configuration or theprobing-ratecan't be dynamically adjusted (Section 4.8.1 of [RFC7252]), DOTS agents use 5 bytes/second as the defaultprobing-ratevalue ✨
If the DOTS agent wants to change the default message transmission parameters, it SHOULD follow the guidance in Section 4.8.1 of [RFC7252] 💅 The DOTS agents MUST use the negotiated values for message transmission parameters, and default values for the non-negotiated ones.
The signal channel session config only applies to one DOTS signal channel session between DOTS agents, so the cuid Uri-Path MUST NOT be used 🙅♀️
Header: PUT (Code=0.03)
Uri-Path: ".well-known"
Uri-Path: "dots"
Uri-Path: "config"
Uri-Path: "sid=123"
Content-Format: "application/dots+cbor"
{
...
}
Figure 21: PUT to Convey the DOTS Signal Channel Session
Configuration Data
The extra Uri-Path parameter on top of the ones in Table 1 looks like this:
sid: Session Identifier is an identifier for the DOTS signal channel session configuration data, represented as an integer. This identifier MUST be generated by DOTS clients.sidvalues MUST increase monotonically (when a new PUT is generated by a DOTS client to convey the configuration parameters for the signal channel).
This is a mandatory attribute. 🧸
{
"ietf-dots-signal-channel:signal-config": {
"mitigating-config": {
"heartbeat-interval": {
"current-value": number
},
"missing-hb-allowed": {
"current-value": number
},
"probing-rate": {
"current-value": number
},
"max-retransmit": {
"current-value": number
},
"ack-timeout": {
"current-value-decimal": "string"
},
"ack-random-factor": {
"current-value-decimal": "string"
}
},
"idle-config": {
"heartbeat-interval": {
"current-value": number
},
"missing-hb-allowed": {
"current-value": number
},
"probing-rate": {
"current-value": number
},
"max-retransmit": {
"current-value": number
},
"ack-timeout": {
"current-value-decimal": "string"
},
"ack-random-factor": {
"current-value-decimal": "string"
}
}
}
}
Figure 22: PUT to Convey the DOTS Signal Channel Session
Configuration Data (Message Body Schema)
The meaning of the parameters in the CBOR body (Figure 22) is defined in Section 4.5.1 🧠
At least one of the attributes heartbeat-interval, missing-hb-allowed, probing-rate, max-retransmit, ack-timeout, and ack-random-factor MUST be present in the PUT request. Those attributes, if present, don't need to be given for both mitigating-config and idle-config in a PUT request. A request also doesn't need to include both mitigating-config and idle-config attributes 💜
A PUT request with a higher numeric sid value overrides the DOTS signal channel session config installed by a PUT with a lower numeric sid value. So the parameters in the higher-sid PUT get used instead of the DOTS server's defaults 👑 To avoid keeping a giant list of sid requests from a DOTS client, the lower numeric sid MUST be automatically deleted and no longer available at the DOTS server 🧹
Figure 23 is a PUT example for the signal channel config. In this one, the heartbeat is disabled when no mitigation is active, and the heartbeat interval is set to '30' when a mitigation is active 🍓
Header: PUT (Code=0.03)
Uri-Path: ".well-known"
Uri-Path: "dots"
Uri-Path: "config"
Uri-Path: "sid=123"
Content-Format: "application/dots+cbor"
{
"ietf-dots-signal-channel:signal-config": {
"mitigating-config": {
"heartbeat-interval": {
"current-value": 30
},
"missing-hb-allowed": {
"current-value": 15
},
"probing-rate": {
"current-value": 15
},
"max-retransmit": {
"current-value": 3
},
"ack-timeout": {
"current-value-decimal": "2.00"
},
"ack-random-factor": {
"current-value-decimal": "1.50"
}
},
"idle-config": {
"heartbeat-interval": {
"current-value": 0
},
"max-retransmit": {
"current-value": 3
},
"ack-timeout": {
"current-value-decimal": "2.00"
},
"ack-random-factor": {
"current-value-decimal": "1.50"
}
}
}
}
Figure 23: PUT to Convey the Configuration Parameters
The DOTS server tells you how the PUT went using CoAP Response Codes 📬
- If the request is missing a mandatory attribute, doesn't include a
sidUri-Path, or has one or more invalid or unknown parameters, 4.00 (Bad Request) MUST be returned in the response 🙃 - If the DOTS server doesn't find the
sidparameter value from the PUT in its config data, and it has accepted the config parameters, then Response Code 2.01 (Created) MUST be returned in the response 🥳 - If the DOTS server does find the
sidparameter value from the PUT in its config data, and it has accepted the updated config parameters, 2.04 (Changed) MUST be returned in the response ✨ - If any of the
heartbeat-interval,missing-hb-allowed,probing-rate,max-retransmit,target-protocol,ack-timeout, andack-random-factorattribute values aren't acceptable to the DOTS server, 4.22 (Unprocessable Entity) MUST be returned in the response. When the DOTS client gets this error code, it SHOULD retrieve the maximum and minimum attribute values the DOTS server accepts (Section 4.5.1).
The DOTS client may retry and send the PUT request with updated attribute values that the DOTS server accepts 🔁
A DOTS client may send a GET for config with a sid Uri-Path parameter to retrieve the negotiated config 🦋 The response does not need to include sid in its message body.
4.5.3. Configuration Freshness and Notifications ✨
Okay bestie, so the Max-Age Option (Section 5.10.5 of [RFC7252]) SHOULD be returned by a DOTS server to give a configuration it sends a validity time ⏰. This is the part that makes the client go grab the updated config whenever something changes on the server side. Like, the new config might tell a DOTS client to stop heartbeats or send them less often 💅.
It is NOT RECOMMENDED to return a Max-Age Option set to 0 🙅♀️.
Returning a Max-Age Option set to 2^(32)-1 is the same as giving the config an infinite lifetime ♾️.
If a DOTS client receives a non-zero Max-Age Option value, it MUST issue a GET request with a 'sid' Uri-Path parameter to retrieve the current and acceptable configuration before that value expires 🏃♀️. The client and the server both treat this request as a way to refresh the signal channel's configuration parameters. Now the big rule: when a DDoS attack is active, DOTS clients MUST NOT send refresh requests 🚫, and the DOTS server MUST NOT terminate the (D)TLS session once the Max-Age value runs out 🔒. Don't touch the connection mid-attack, periodt 💀.
If a response doesn't include a Max-Age Option, the DOTS client sends GET requests to refresh the configuration parameters every 60 seconds (Section 5.10.5 of [RFC7252]) ⏱️. To prevent that overload, it is RECOMMENDED that DOTS servers return a Max-Age Option in GET responses 🙏. Which value to use and how to set it are implementation and deployment specific, so that's up to you 🤷♀️.
If an Observe Option set to 0 is included in the configuration request, the DOTS server sends notifications of any configuration change (Section 4.2 of [RFC7641]) 🔔. Notifications are giving main character energy 🎀.
If a DOTS server notices that a misbehaving DOTS client hasn't contacted it after Max-Age expired to retrieve the signal channel configuration data, it MAY terminate the (D)TLS session 👋. A (D)TLS session gets terminated when an authenticated message closes the connection, for example a fatal alert (Section 6 of [RFC8446]) ☠️.
4.5.4. Delete DOTS Signal Channel Session Configuration 🧹
A DELETE request is used to delete the installed DOTS signal channel session configuration data (Figure 24) 🗑️.
Header: DELETE (Code=0.04)
Uri-Path: ".well-known"
Uri-Path: "dots"
Uri-Path: "config"
Uri-Path: "sid=123"
Figure 24: Delete Configuration
The DOTS server resets the DOTS signal channel session configuration back to the default values ♻️. Then it acknowledges the DOTS client's request to remove the configuration with a 2.02 (Deleted) Response Code ✅.
Upon bootstrapping or reboot, a DOTS client MAY send a DELETE request to set the configuration parameters back to default values 🔄. Such a request doesn't include any 'sid'.
4.6. Redirected Signaling 🦋
Redirected DOTS signaling is discussed in detail in Section 3.2.2 of [RFC8811] 📖.
To redirect a DOTS client to an alternative DOTS server, the DOTS server can return the error Response Code 5.03 (Service Unavailable) in response to a request from the DOTS client, or convey the error Response Code 5.03 in a unidirectional notification response to the client 👉.
In the CBOR body (Figure 25), the DOTS server puts the alternate DOTS server's FQDN and the alternate DOTS server's IP address(es) in the error response 📦.
{
"ietf-dots-signal-channel:redirected-signal": {
"alt-server": "string",
"alt-server-record": [
"string"
]
}
}
Figure 25: Redirected Server Error Response Body Schema
The parameters work like this:
alt-server: FQDN of an alternate DOTS server. This is a mandatory attribute 📛.
alt-server-record: A list of IP addresses of an alternate DOTS server. This is an optional attribute 🧩.
The DOTS server returns the Time to Live (TTL) of the alternate DOTS server in a Max-Age Option ⏳. That's the time interval the alternate DOTS server may be cached for use by a DOTS client. A Max-Age Option set to 2^(32)-1 means an infinite TTL ♾️. That value means the alternate DOTS server is used until it redirects traffic with another 5.03 response that conveys an alternate server's FQDN 🔁.
A Max-Age Option set to '0' may be returned for redirecting mitigation requests 🧐. That value means the redirection only applies to the mitigation request in progress. Returning a short TTL in a Max-Age Option may adversely impact DOTS clients on slow links 🐌. Returning short values should be avoided under such conditions.
If the alternate DOTS server TTL has expired, the DOTS client MUST use the DOTS server(s) that were provisioned using the means discussed in Section 4.1 🔙. This fallback kicks in immediately when the TTL expires, except when a DDoS attack is active ⚔️.
Requests from misbehaving DOTS clients that don't honor the TTL conveyed in the Max-Age Option, or that don't react to explicit redirect messages, MAY be rejected by DOTS servers 🚪.
Figure 26 shows a 5.03 response example conveying the DOTS alternate server 'alt-server.example', together with its IP addresses 2001:db8:6401::1 and 2001:db8:6401::2 🌸.
{
"ietf-dots-signal-channel:redirected-signal": {
"alt-server": "alt-server.example",
"alt-server-record": [
"2001:db8:6401::1",
"2001:db8:6401::2"
]
}
}
Figure 26: Example of Redirected Server Error Response Body
When the DOTS client receives a 5.03 response with an alternate server included, it considers the current request to have failed 😤. It SHOULD still try resending the request to the alternate DOTS server 🔁. During a DDoS attack, the DNS server may be the target of another DDoS attack 😭. That's why the alternate DOTS server's IP addresses in the 5.03 response are so useful: they help the DOTS client skip the DNS lookup of the alternate DOTS server. The trade-off is that the client has to trust the first DOTS server to provide accurate information 🫣.
The DOTS client can then try to establish a UDP or a TCP session with the alternate DOTS server (Section 4.3) 🤝. Note that state synchronization (for example signal session configuration and aliases) is assumed to be in place between the original and alternate DOTS servers. Those synchronization means are out of scope 🙅♀️.
If session configuration refresh is needed while redirection is in place, the DOTS client follows the procedure defined in Section 4.5.3 🔄. In 'idle' time, and under some conditions (for example an infinite configuration lifetime, an infinite redirection TTL, and a failed configuration refresh), the DOTS client follows the procedure defined in Section 4.5.2 to negotiate the DOTS signal channel session configuration with the alternate server 🤓.
The DOTS client MAY implement a method to construct IPv4-embedded IPv6 addresses [RFC6052] 🧮. This is required to handle the scenario where an IPv6-only DOTS client communicates with an IPv4-only alternate DOTS server 🌈.
If the DOTS client has been redirected to a DOTS server it has already communicated with in the last five (5) minutes, it MUST ignore the redirection 🙅♀️. Instead, it has to try contacting other DOTS servers listed in the local configuration or discovered using dynamic means, such as DHCP or SRV procedures [RFC8973] 🔍. It is RECOMMENDED that DOTS clients support the means to alert administrators about redirect loops 🚨. Loops are not it, bestie 💜.
4.7. Heartbeat Mechanism 💖
Okay, so the heartbeat is how a DOTS agent says "hey, I'm still here, don't ghost me" 👻. It keeps its half of the signal channel alive, which means an idle channel doesn't get confused with one that's disconnected or defunct 💅. The heartbeat also lines up with the "consents" recommendation in Section 6 of [RFC8085] 🫶. Each DOTS agent expects a heartbeat from its peer too, and it may decide a session is over if the peer's heartbeats stop for a long time 💀. In practice, when the two agents aren't talking, the DOTS client pokes the DOTS server to make sure the server still has its cryptographic state, and the server does the same back ✨. These little probes can also keep firewall and stateful translator bindings alive 🌸. Bonus: it means the client doesn't have to start a brand-new handshake every time it needs to send a DOTS signal 🦋.
Implementation Note: Since CoAP roles can be multiplexed over the same session, as discussed in [RFC7252], and CoAP implementations already support this, both the DOTS client and the DOTS server can send DOTS heartbeat requests 🧚.
The DOTS heartbeat uses Non-confirmable PUT requests (Figure 27) and expects a 2.04 (Changed) Response Code back (Figure 28) 🎀. This happens between a DOTS agent and its immediate peer, so this PUT request MUST NOT be relayed by a DOTS gateway 🙅♀️. Also, the PUT request used for the DOTS heartbeat MUST NOT have a 'cuid', 'cdid', or 'mid' Uri-Path 🚫.
Header: PUT (Code=0.03)
Uri-Path: ".well-known"
Uri-Path: "dots"
Uri-Path: "hb"
Content-Format: "application/dots+cbor"
{
"ietf-dots-signal-channel:heartbeat": {
"peer-hb-status": true
}
}
Figure 27: PUT to Check Peer DOTS Agent Is Responding
The mandatory peer-hb-status attribute gets set to true or false 🍓. true means the agent IS getting heartbeats from its peer within the last (2 * heartbeat-interval) period, and false means it ISN'T 😭. This is super useful because the peer can use it to spot or confirm connectivity drama and respond to it 🔥. For example, if a DOTS client gets a 2.04 for its heartbeats but never gets any server-initiated heartbeats, it sets peer-hb-status to false in its next heartbeat 🙈. When the DOTS server gets that, it has to try a different strategy for sending heartbeats, like adjusting the heartbeat interval or sending a server-initiated heartbeat right after it gets a client-initiated one 💜.
Header: (Code=2.04)
Figure 28: Response to a DOTS Heartbeat Request (with an Empty Body)
DOTS servers MAY trigger their own heartbeat requests right after getting heartbeat probes from peer DOTS clients 🌈. Meanwhile, DOTS clients are responsible for making sure on-path translators and firewalls keep a binding, so the same external IP address and/or port number is kept for the DOTS signal channel session 🔐.
Under normal traffic (aka no attack going on), if a DOTS agent gets no response from its peer for missing-hb-allowed consecutive heartbeat messages, it concludes the DOTS signal channel session is disconnected 💔. The DOTS client MUST then try to reestablish the session, preferably by resuming the (D)TLS session 🔄.
Note: If a new DOTS signal channel session can't be established, the DOTS client SHOULD NOT retry more often than every 300 seconds (5 minutes), and it MUST NOT retry more often than every 60 seconds (1 minute) ⏰. It is recommended that DOTS clients support ways to alert administrators when a (D)TLS session fails to be established 📣.
Now, the scary part: a massive DDoS attack has saturated the incoming link(s) to the DOTS client 😱. In that case, most traffic from the DOTS server to the DOTS client will likely get dropped, even though the DOTS server still receives heartbeat requests along with the DOTS messages from the client 🥲. So DOTS clients MUST behave differently to handle message transmission and session liveliness during link saturation 🫠:
- The DOTS client MUST NOT consider the session terminated, even after the maximum
missing-hb-allowedthreshold is reached. It SHOULD keep using the current session to send heartbeat requests, so the DOTS server knows the client didn't hang up on it 💖. - Once the maximum
missing-hb-allowedthreshold is reached, the DOTS client SHOULD try to establish a new DOTS signal channel session 🆕. It SHOULD send mitigation requests over the current session and, at the same time, send them over the new session too 🏃♀️. This could be handled by resuming the (D)TLS session, or by using 0-RTT mode in DTLS 1.3 to piggyback the mitigation request in the ClientHello message ✨. - As soon as the link is no longer saturated, if traffic from the DOTS server reaches the DOTS client over the current session, the DOTS client can stop the new session attempt. Or, if the new session was already successful, it can disconnect the current one 🎉.
If the DOTS server gets traffic from the peer DOTS client (like peer DOTS client-initiated heartbeats) but the maximum missing-hb-allowed threshold has still been reached, the DOTS server MUST NOT consider the session disconnected 🙅♀️. It MUST keep using the current session so the DOTS client can send mitigation requests over it 💅. In this case, the DOTS server can tell that the DOTS client is under attack and that the inbound link to the DOTS client (domain) is saturated 🚨. Also, if the DOTS server doesn't get a mitigation request from the DOTS client, that means the client hasn't detected the attack, or, if a mitigation is already in progress, that the DDoS mitigation actions applied so far aren't yet effectively handling the attack volume 🤔.
If the DOTS server doesn't receive any traffic from the peer DOTS client during the time it takes to exhaust the maximum missing-hb-allowed threshold, the DOTS server concludes the session is disconnected 🥀. It can then trigger preconfigured mitigation requests for this DOTS client, if there are any 🛡️.
In DOTS over TCP, the sender of a DOTS heartbeat message has to allow up to heartbeat-interval seconds when waiting for a heartbeat reply ⏳. When a DOTS client detects a failure, it goes ahead with session recovery, using the same approach as for unreliable transports 🔁.
5. DOTS Signal Channel YANG Modules 🎀
This document defines a YANG module [RFC7950] for DOTS mitigation scope, DOTS signal channel session configuration data, DOTS redirection signaling, and DOTS heartbeats 📜.
This YANG module is NOT intended to be used via NETCONF/RESTCONF for DOTS server management purposes, since that kind of module is out of scope for this document 🙅♀️. It only exists to provide abstract data structures 🧩. This document uses the "structure" extension specified in [RFC8791] ✨.
A companion YANG module is defined to include a collection of types defined by IANA: "iana-dots-signal-channel" (Section 5.2) 🦋.
5.1. Tree Structure ✨
okay so this section is where the YANG module gets its whole shape 🎀 the module is called "ietf-dots-signal-channel", and bestie, it's giving main character energy because one DOTS signal message can be a mitigation, a configuration, a redirect, or a heartbeat message 💅 which is literally four jobs in one 🫶
ngl the tree below is the full layout, so scroll through it like you're checking out a fit 👀
module: ietf-dots-signal-channel
structure dots-signal:
+-- (message-type)?
+--:(mitigation-scope)
| +-- scope* []
| +-- target-prefix* inet:ip-prefix
| +-- target-port-range* [lower-port]
| | +-- lower-port inet:port-number
| | +-- upper-port? inet:port-number
| +-- target-protocol* uint8
| +-- target-fqdn* inet:domain-name
| +-- target-uri* inet:uri
| +-- alias-name* string
| +-- lifetime? union
| +-- trigger-mitigation? boolean
| +-- (direction)?
| +--:(server-to-client-only)
| | +-- mid? uint32
| | +-- mitigation-start? uint64
| | +-- status?
| | | iana-dots-signal:status
| | +-- conflict-information
| | | +-- conflict-status?
| | | | iana-dots-signal:conflict-status
| | | +-- conflict-cause?
| | | | iana-dots-signal:conflict-cause
| | | +-- retry-timer? uint32
| | | +-- conflict-scope
| | | +-- target-prefix* inet:ip-prefix
| | | +-- target-port-range* [lower-port]
| | | | +-- lower-port inet:port-number
| | | | +-- upper-port? inet:port-number
| | | +-- target-protocol* uint8
| | | +-- target-fqdn* inet:domain-name
| | | +-- target-uri* inet:uri
| | | +-- alias-name* string
| | | +-- acl-list* [acl-name]
| | | | +-- acl-name leafref
| | | | +-- acl-type? leafref
| | | +-- mid? uint32
| | +-- bytes-dropped?
| | | yang:zero-based-counter64
| | +-- bps-dropped? yang:gauge64
| | +-- pkts-dropped?
| | | yang:zero-based-counter64
| | +-- pps-dropped? yang:gauge64
| +--:(client-to-server-only)
| +-- attack-status?
| iana-dots-signal:attack-status
+--:(signal-config)
| +-- mitigating-config
| | +-- heartbeat-interval
| | | +-- (direction)?
| | | | +--:(server-to-client-only)
| | | | +-- max-value? uint16
| | | | +-- min-value? uint16
| | | +-- current-value? uint16
| | +-- missing-hb-allowed
| | | +-- (direction)?
| | | | +--:(server-to-client-only)
| | | | +-- max-value? uint16
| | | | +-- min-value? uint16
| | | +-- current-value? uint16
| | +-- probing-rate
| | | +-- (direction)?
| | | | +--:(server-to-client-only)
| | | | +-- max-value? uint16
| | | | +-- min-value? uint16
| | | +-- current-value? uint16
| | +-- max-retransmit
| | | +-- (direction)?
| | | | +--:(server-to-client-only)
| | | | +-- max-value? uint16
| | | | +-- min-value? uint16
| | | +-- current-value? uint16
| | +-- ack-timeout
| | | +-- (direction)?
| | | | +--:(server-to-client-only)
| | | | +-- max-value-decimal? decimal64
| | | | +-- min-value-decimal? decimal64
| | | +-- current-value-decimal? decimal64
| | +-- ack-random-factor
| | +-- (direction)?
| | | +--:(server-to-client-only)
| | | +-- max-value-decimal? decimal64
| | | +-- min-value-decimal? decimal64
| | +-- current-value-decimal? decimal64
| +-- idle-config
| +-- heartbeat-interval
| | +-- (direction)?
| | | +--:(server-to-client-only)
| | | +-- max-value? uint16
| | | +-- min-value? uint16
| | +-- current-value? uint16
| +-- missing-hb-allowed
| | +-- (direction)?
| | | +--:(server-to-client-only)
| | | +-- max-value? uint16
| | | +-- min-value? uint16
| | +-- current-value? uint16
| +-- probing-rate
| | +-- (direction)?
| | | +--:(server-to-client-only)
| | | +-- max-value? uint16
| | | +-- min-value? uint16
| | +-- current-value? uint16
| +-- max-retransmit
| | +-- (direction)?
| | | +--:(server-to-client-only)
| | | +-- max-value? uint16
| | | +-- min-value? uint16
| | +-- current-value? uint16
| +-- ack-timeout
| | +-- (direction)?
| | | +--:(server-to-client-only)
| | | +-- max-value-decimal? decimal64
| | | +-- min-value-decimal? decimal64
| | +-- current-value-decimal? decimal64
| +-- ack-random-factor
| +-- (direction)?
| | +--:(server-to-client-only)
| | +-- max-value-decimal? decimal64
| | +-- min-value-decimal? decimal64
| +-- current-value-decimal? decimal64
+--:(redirected-signal)
| +-- (direction)?
| +--:(server-to-client-only)
| +-- alt-server inet:domain-name
| +-- alt-server-record* inet:ip-address
+--:(heartbeat)
+-- peer-hb-status boolean
This tree structure obsoletes the one described in Section 5.1 of [RFC8782]. 🦋 so if you were still using that older layout, it's officially been replaced, no cap 💀✨
5.2. IANA DOTS Signal Channel YANG Module ✨
okay bestie, this version officially obsoletes the one from Section 5.2 of [RFC8782], so it's the glow-up 💅🌸 Here's the IANA module, which holds the DOTS signal channel's YANG data types that IANA maintains 🎀
<CODE BEGINS> file "iana-dots-signal-channel@2021-09-02.yang"
module iana-dots-signal-channel {
yang-version 1.1;
namespace "urn:ietf:params:xml:ns:yang:iana-dots-signal-channel";
prefix iana-dots-signal;
organization
"IANA";
contact
"Internet Assigned Numbers Authority
Postal: ICANN
12025 Waterfront Drive, Suite 300
Los Angeles, CA 90094-2536
United States of America
Tel: +1 310 301 5800
<mailto:iana@iana.org>";
description
"This module contains a collection of YANG data types defined
by IANA and used for DOTS signal channel protocol.
Copyright (c) 2021 IETF Trust and the persons identified as
authors of the code. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Simplified BSD License
set forth in Section 4.c of the IETF Trust's Legal Provisions
Relating to IETF Documents
(http://trustee.ietf.org/license-info).
This version of this YANG module is part of RFC 9132; see
the RFC itself for full legal notices.";
revision 2021-09-02 {
description
"Updated the prefix used for the module.";
reference
"RFC 9132: Distributed Denial-of-Service Open Threat Signaling
(DOTS) Signal Channel Specification";
}
revision 2020-05-28 {
description
"Initial revision.";
reference
"RFC 8782: Distributed Denial-of-Service Open Threat Signaling
(DOTS) Signal Channel Specification";
}
typedef status {
type enumeration {
enum attack-mitigation-in-progress {
value 1;
description
"Attack mitigation setup is in progress (e.g., changing
the network path to reroute the inbound traffic
to DOTS mitigator).";
}
enum attack-successfully-mitigated {
value 2;
description
"Attack is being successfully mitigated (e.g., traffic
is redirected to a DDoS mitigator and attack
traffic is dropped).";
}
enum attack-stopped {
value 3;
description
"Attack has stopped and the DOTS client can
withdraw the mitigation request.";
}
enum attack-exceeded-capability {
value 4;
description
"Attack has exceeded the mitigation provider
capability.";
}
enum dots-client-withdrawn-mitigation {
value 5;
description
"DOTS client has withdrawn the mitigation
request and the mitigation is active but
terminating.";
}
enum attack-mitigation-terminated {
value 6;
description
"Attack mitigation is now terminated.";
}
enum attack-mitigation-withdrawn {
value 7;
description
"Attack mitigation is withdrawn.";
}
enum attack-mitigation-signal-loss {
value 8;
description
"Attack mitigation will be triggered
for the mitigation request only when
the DOTS signal channel session is lost.";
}
}
description
"Enumeration for status reported by the DOTS server.";
}
typedef conflict-status {
type enumeration {
enum request-inactive-other-active {
value 1;
description
"DOTS server has detected conflicting mitigation
requests from different DOTS clients.
This mitigation request is currently inactive
until the conflicts are resolved. Another
mitigation request is active.";
}
enum request-active {
value 2;
description
"DOTS server has detected conflicting mitigation
requests from different DOTS clients.
This mitigation request is currently active.";
}
enum all-requests-inactive {
value 3;
description
"DOTS server has detected conflicting mitigation
requests from different DOTS clients. All
conflicting mitigation requests are inactive.";
}
}
description
"Enumeration for conflict status.";
}
typedef conflict-cause {
type enumeration {
enum overlapping-targets {
value 1;
description
"Overlapping targets. conflict-scope provides
more details about the exact conflict.";
}
enum conflict-with-acceptlist {
value 2;
description
"Conflicts with an existing accept-list.
This code is returned when the DDoS mitigation
detects that some of the source addresses/prefixes
listed in the accept-list ACLs are actually
attacking the target.";
}
enum cuid-collision {
value 3;
description
"Conflicts with the cuid used by another
DOTS client.";
}
}
description
"Enumeration for conflict causes.";
}
typedef attack-status {
type enumeration {
enum under-attack {
value 1;
description
"The DOTS client determines that it is still under
attack.";
}
enum attack-successfully-mitigated {
value 2;
description
"The DOTS client determines that the attack is
successfully mitigated.";
}
}
description
"Enumeration for attack status codes.";
}
}
<CODE ENDS>
5.3. IETF DOTS Signal Channel YANG Module 🦋
this one is the main event 👑 It borrows the common YANG types from [RFC6991] and some types from [RFC8783], so it's basically a collab of all three specs 🤝
This version obsoletes the version described in Section 5.3 of [RFC8782], so it's the new and improved version 💖
<CODE BEGINS> file "ietf-dots-signal-channel@2021-09-02.yang"
module ietf-dots-signal-channel {
yang-version 1.1;
namespace "urn:ietf:params:xml:ns:yang:ietf-dots-signal-channel";
prefix dots-signal;
import ietf-inet-types {
prefix inet;
reference
"Section 4 of RFC 6991";
}
import ietf-yang-types {
prefix yang;
reference
"Section 3 of RFC 6991";
}
import ietf-dots-data-channel {
prefix data-channel;
reference
"RFC 8783: Distributed Denial-of-Service Open Threat Signaling
(DOTS) Data Channel Specification";
}
import iana-dots-signal-channel {
prefix iana-dots-signal;
reference
"RFC 9132: Distributed Denial-of-Service Open Threat Signaling
(DOTS) Signal Channel Specification";
}
import ietf-yang-structure-ext {
prefix sx;
reference
"RFC 8791: YANG Data Structure Extensions";
}
organization
"IETF DDoS Open Threat Signaling (DOTS) Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/dots/>
WG List: <mailto:dots@ietf.org>
Editor: Mohamed Boucadair
<mailto:mohamed.boucadair@orange.com>
Editor: Jon Shallow
<mailto:supjps-ietf@jpshallow.com>
Author: Konda, Tirumaleswar Reddy.K
<mailto:kondtir@gmail.com>
Author: Prashanth Patil
<mailto:praspati@cisco.com>
Author: Andrew Mortensen
<mailto:amortensen@arbor.net>
Author: Nik Teague
<mailto:nteague@ironmountain.co.uk>";
description
"This module contains YANG definition for the signaling
messages exchanged between a DOTS client and a DOTS server.
Copyright (c) 2021 IETF Trust and the persons identified as
authors of the code. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Simplified BSD License
set forth in Section 4.c of the IETF Trust's Legal Provisions
Relating to IETF Documents
(http://trustee.ietf.org/license-info).
This version of this YANG module is part of RFC 9132; see
the RFC itself for full legal notices.";
revision 2021-09-02 {
description
"Updated revision to comply with RFC 8791.
This version is not backward compatible with the version
published in RFC 8782.";
reference
"RFC 9132: Distributed Denial-of-Service Open Threat
Signaling (DOTS) Signal Channel Specification";
}
revision 2020-05-28 {
description
"Initial revision.";
reference
"RFC 8782: Distributed Denial-of-Service Open Threat
Signaling (DOTS) Signal Channel Specification";
}
/*
* Groupings
*/
grouping mitigation-scope {
description
"Specifies the scope of the mitigation request.";
list scope {
description
"The scope of the request.";
uses data-channel:target;
leaf-list alias-name {
type string;
description
"An alias name that points to a resource.";
}
leaf lifetime {
type union {
type uint32;
type int32 {
range "-1";
}
}
units "seconds";
default "3600";
description
"Indicates the lifetime of the mitigation request.
A lifetime of '0' in a mitigation request is an
invalid value.
A lifetime of negative one (-1) indicates indefinite
lifetime for the mitigation request.
Lifetime is mandatory in a mitigation request.
The DOTS server must always indicate the actual lifetime
in the response to an accepted mitigation request and the
remaining lifetime in status messages sent to the
DOTS client.";
}
leaf trigger-mitigation {
type boolean;
default "true";
description
"If set to 'false', DDoS mitigation will not be
triggered unless the DOTS signal channel
session is lost.";
}
choice direction {
description
"Indicates the communication direction in which the
data nodes can be included.";
case server-to-client-only {
description
"These data nodes appear only in a mitigation message
sent from the server to the client.";
leaf mid {
type uint32;
description
"Mitigation request identifier.
This identifier must be unique for each mitigation
request bound to the DOTS client.";
}
leaf mitigation-start {
type uint64;
description
"Mitigation start time is represented in seconds
relative to 1970-01-01T00:00:00Z in UTC time.
Okay bestie, the YANG code stays exactly as written 💅🫶
This is a mandatory attribute when an attack
mitigation is active. It must not be returned for
a mitigation with 'status' code set to 8.";
}
leaf status {
type iana-dots-signal:status;
description
"Indicates the status of a mitigation request.
It must be included in responses only.
This is a mandatory attribute if a mitigation
request is accepted and processed by the server.";
}
container conflict-information {
description
"Indicates that a conflict is detected.";
leaf conflict-status {
type iana-dots-signal:conflict-status;
description
"Indicates the conflict status.";
}
leaf conflict-cause {
type iana-dots-signal:conflict-cause;
description
"Indicates the cause of the conflict.";
}
leaf retry-timer {
type uint32;
units "seconds";
description
"The DOTS client must not resend the
same request that has a conflict before the expiry
of this timer.";
}
container conflict-scope {
description
"Provides more information about the conflict
scope.";
uses data-channel:target {
when "/dots-signal/scope/conflict-information/"
+ "conflict-cause = 'overlapping-targets'";
}
leaf-list alias-name {
when "../../conflict-cause = 'overlapping-targets'";
type string;
description
"Conflicting alias-name.";
}
list acl-list {
when "../../conflict-cause ="
+ " 'conflict-with-acceptlist'";
key "acl-name";
description
"List of conflicting ACLs, as defined in the DOTS
data channel. These ACLs are uniquely defined by
cuid and acl-name.";
leaf acl-name {
type leafref {
path "/data-channel:dots-data"
+ "/data-channel:dots-client"
+ "/data-channel:acls"
+ "/data-channel:acl/data-channel:name";
}
description
"Reference to the conflicting ACL name bound to
a DOTS client.";
}
leaf acl-type {
type leafref {
path "/data-channel:dots-data"
+ "/data-channel:dots-client"
+ "/data-channel:acls"
+ "/data-channel:acl/data-channel:type";
}
description
"Reference to the conflicting ACL type bound to
a DOTS client.";
}
}
leaf mid {
when "../../conflict-cause = 'overlapping-targets'";
type uint32;
description
"Reference to the conflicting 'mid' bound to
the same DOTS client.";
}
}
}
leaf bytes-dropped {
type yang:zero-based-counter64;
units "bytes";
description
"The total dropped byte count for the mitigation
request since the attack mitigation was triggered.
The count wraps around when it reaches the maximum
value of counter64 for dropped bytes.";
}
leaf bps-dropped {
type yang:gauge64;
units "bytes per second";
description
"The average number of dropped bytes per second for
the mitigation request since the attack
mitigation was triggered. This should be over
five-minute intervals (that is, measuring bytes
into five-minute buckets and then averaging these
buckets over the time since the mitigation was
triggered).";
}
leaf pkts-dropped {
type yang:zero-based-counter64;
description
"The total number of dropped packet count for the
mitigation request since the attack mitigation was
triggered. The count wraps around when it reaches
the maximum value of counter64 for dropped packets.";
}
leaf pps-dropped {
type yang:gauge64;
units "packets per second";
description
"The average number of dropped packets per second
for the mitigation request since the attack
mitigation was triggered. This should be over
five-minute intervals (that is, measuring packets
into five-minute buckets and then averaging these
buckets over the time since the mitigation was
triggered).";
}
}
case client-to-server-only {
description
"These data nodes appear only in a mitigation message
sent from the client to the server.";
leaf attack-status {
type iana-dots-signal:attack-status;
description
"Indicates the status of an attack as seen by the
DOTS client.
This is a mandatory attribute when a client
performs an efficacy update.";
}
}
}
}
}
grouping config-parameters {
description
"Subset of DOTS signal channel session configuration.";
container heartbeat-interval {
description
"DOTS agents regularly send heartbeats to each other
after mutual authentication is successfully
completed in order to keep the DOTS signal channel
open.";
choice direction {
description
"Indicates the communication direction in which the
data nodes can be included.";
case server-to-client-only {
description
"These data nodes appear only in a mitigation message
sent from the server to the client.";
leaf max-value {
type uint16;
units "seconds";
description
"Maximum acceptable heartbeat-interval value.";
}
leaf min-value {
type uint16;
units "seconds";
description
"Minimum acceptable heartbeat-interval value.";
}
}
}
leaf current-value {
type uint16;
units "seconds";
default "30";
description
"Current heartbeat-interval value.
'0' means that heartbeat mechanism is deactivated.";
}
}
container missing-hb-allowed {
description
"Maximum number of missing heartbeats allowed.";
choice direction {
description
"Indicates the communication direction in which the
data nodes can be included.";
case server-to-client-only {
description
"These data nodes appear only in a mitigation message
sent from the server to the client.";
leaf max-value {
type uint16;
description
"Maximum acceptable missing-hb-allowed value.";
}
leaf min-value {
type uint16;
description
"Minimum acceptable missing-hb-allowed value.";
}
}
}
leaf current-value {
type uint16;
default "15";
description
"Current missing-hb-allowed value.";
}
}
container probing-rate {
description
"The limit for sending Non-confirmable messages with
no response.";
choice direction {
description
"Indicates the communication direction in which the
data nodes can be included.";
case server-to-client-only {
description
"These data nodes appear only in a mitigation message
sent from the server to the client.";
leaf max-value {
type uint16;
units "byte/second";
description
"Maximum acceptable probing-rate value.";
}
leaf min-value {
type uint16;
units "byte/second";
description
"Minimum acceptable probing-rate value.";
}
}
}
leaf current-value {
type uint16;
units "byte/second";
default "5";
description
"Current probing-rate value.";
}
}
container max-retransmit {
description
"Maximum number of retransmissions of a Confirmable
message.";
choice direction {
description
"Indicates the communication direction in which the
data nodes can be included.";
case server-to-client-only {
description
"These data nodes appear only in a mitigation message
sent from the server to the client.";
leaf max-value {
type uint16;
description
"Maximum acceptable max-retransmit value.";
}
leaf min-value {
type uint16;
description
"Minimum acceptable max-retransmit value.";
}
}
}
leaf current-value {
type uint16;
default "3";
description
"Current max-retransmit value.";
}
}
container ack-timeout {
description
"Initial retransmission timeout value.";
choice direction {
description
"Indicates the communication direction in which the
data nodes can be included.";
case server-to-client-only {
description
"These data nodes appear only in a mitigation message
sent from the server to the client.";
leaf max-value-decimal {
type decimal64 {
fraction-digits 2;
}
units "seconds";
description
"Maximum ack-timeout value.";
}
leaf min-value-decimal {
type decimal64 {
fraction-digits 2;
}
units "seconds";
description
"Minimum ack-timeout value.";
}
}
}
leaf current-value-decimal {
type decimal64 {
fraction-digits 2;
}
units "seconds";
default "2";
description
"Current ack-timeout value.";
}
}
container ack-random-factor {
description
"Random factor used to influence the timing of
retransmissions.";
choice direction {
description
"Indicates the communication direction in which the
data nodes can be included.";
case server-to-client-only {
description
"These data nodes appear only in a mitigation message
sent from the server to the client.";
leaf max-value-decimal {
type decimal64 {
fraction-digits 2;
}
description
"Maximum acceptable ack-random-factor value.";
}
leaf min-value-decimal {
type decimal64 {
fraction-digits 2;
}
description
"Minimum acceptable ack-random-factor value.";
}
}
}
leaf current-value-decimal {
type decimal64 {
fraction-digits 2;
}
default "1.5";
description
"Current ack-random-factor value.";
}
}
}
grouping signal-config {
description
"DOTS signal channel session configuration.";
container mitigating-config {
description
"Configuration parameters to use when a mitigation
is active.";
uses config-parameters;
}
container idle-config {
description
"Configuration parameters to use when no mitigation
is active.";
uses config-parameters;
}
}
grouping redirected-signal {
description
"Grouping for the redirected signaling.";
choice direction {
description
"Indicates the communication direction in which the
data nodes can be included.";
case server-to-client-only {
description
"These data nodes appear only in a mitigation message
sent from the server to the client.";
leaf alt-server {
type inet:domain-name;
mandatory true;
description
"FQDN of an alternate server.";
}
leaf-list alt-server-record {
type inet:ip-address;
description
"List of records for the alternate server.";
}
}
}
}
/*
* DOTS Signal Channel Structure
*/
sx:structure dots-signal {
description
"Main structure for DOTS signal message.
A DOTS signal message can be a mitigation, a configuration,
a redirected, or a heartbeat signal message.";
choice message-type {
description
"Can be a mitigation, a configuration, a redirect, or
a heartbeat message.";
case mitigation-scope {
description
"Mitigation scope of a mitigation message.";
uses mitigation-scope;
}
case signal-config {
description
"Configuration message.";
uses signal-config;
}
case redirected-signal {
description
"Redirected signaling.";
uses redirected-signal;
}
case heartbeat {
description
"DOTS heartbeats.";
leaf peer-hb-status {
type boolean;
mandatory true;
description
"Indicates whether a DOTS agent receives heartbeats
from its peer. The value is set to 'true' if the
DOTS agent is receiving heartbeat messages
from its peer.";
}
}
}
}
}
<CODE ENDS>
6. YANG/JSON Mapping Parameters to CBOR ✨
okay bestie, every single parameter in the DOTS signal channel payload MUST be mapped to a CBOR type, as shown in Table 5 💅, and each one gets an integer key so we don't waste any space 🎀
Note: Implementers must check that the mapping output provided by their YANG-to-CBOR encoding schemes is aligned with the content of Table 5. For example, some CBOR and JSON types for enumerations and the 64-bit quantities can differ depending on the encoder used. 🙈
ngl the CBOR key values come in two flavors: comprehension-required and comprehension-optional 🦋. DOTS agents can safely ignore comprehension-optional values they don't understand 🫶, but if a request has comprehension-required values that aren't understood, they cannot successfully process it 😭. The 4.00 response SHOULD include a diagnostic payload describing the unknown comprehension-required CBOR key values 💜. The initial set of CBOR key values defined in this specification is all comprehension-required 👑
Okay bestie, this is the big cheat sheet 📋✨ It's basically a translation guide: every parameter gets its CBOR key, its YANG type, its CBOR major type, and its JSON type, all lined up in one place 💜
+=====================+==============+======+=============+========+
| Parameter Name | YANG Type | CBOR | CBOR Major | JSON |
| | | Key | Type & | Type |
| | | | Information | |
+=====================+==============+======+=============+========+
| ietf-dots-signal- | container | 1 | 5 map | Object |
| channel:mitigation- | | | | |
| scope | | | | |
+---------------------+--------------+------+-------------+--------+
| scope | list | 2 | 4 array | Array |
+---------------------+--------------+------+-------------+--------+
| cdid | string | 3 | 3 text | String |
| | | | string | |
+---------------------+--------------+------+-------------+--------+
| cuid | string | 4 | 3 text | String |
| | | | string | |
+---------------------+--------------+------+-------------+--------+
| mid | uint32 | 5 | 0 unsigned | Number |
+---------------------+--------------+------+-------------+--------+
| target-prefix | leaf-list | 6 | 4 array | Array |
| +--------------+------+-------------+--------+
| | inet:ip- | | 3 text | String |
| | prefix | | string | |
+---------------------+--------------+------+-------------+--------+
| target-port-range | list | 7 | 4 array | Array |
+---------------------+--------------+------+-------------+--------+
| lower-port | inet:port- | 8 | 0 unsigned | Number |
| | number | | | |
+---------------------+--------------+------+-------------+--------+
| upper-port | inet:port- | 9 | 0 unsigned | Number |
| | number | | | |
+---------------------+--------------+------+-------------+--------+
| target-protocol | leaf-list | 10 | 4 array | Array |
| +--------------+------+-------------+--------+
| | uint8 | | 0 unsigned | Number |
+---------------------+--------------+------+-------------+--------+
| target-fqdn | leaf-list | 11 | 4 array | Array |
| +--------------+------+-------------+--------+
| | inet:domain- | | 3 text | String |
| | name | | string | |
+---------------------+--------------+------+-------------+--------+
| target-uri | leaf-list | 12 | 4 array | Array |
| +--------------+------+-------------+--------+
| | inet:uri | | 3 text | String |
| | | | string | |
+---------------------+--------------+------+-------------+--------+
| alias-name | leaf-list | 13 | 4 array | Array |
| +--------------+------+-------------+--------+
| | string | | 3 text | String |
| | | | string | |
+---------------------+--------------+------+-------------+--------+
| lifetime | union | 14 | 0 unsigned | Number |
| | | +-------------+--------+
| | | | 1 negative | Number |
+---------------------+--------------+------+-------------+--------+
| mitigation-start | uint64 | 15 | 0 unsigned | String |
+---------------------+--------------+------+-------------+--------+
| status | enumeration | 16 | 0 unsigned | String |
+---------------------+--------------+------+-------------+--------+
| conflict- | container | 17 | 5 map | Object |
| information | | | | |
+---------------------+--------------+------+-------------+--------+
| conflict-status | enumeration | 18 | 0 unsigned | String |
+---------------------+--------------+------+-------------+--------+
| conflict-cause | enumeration | 19 | 0 unsigned | String |
+---------------------+--------------+------+-------------+--------+
| retry-timer | uint32 | 20 | 0 unsigned | String |
+---------------------+--------------+------+-------------+--------+
| conflict-scope | container | 21 | 5 map | Object |
+---------------------+--------------+------+-------------+--------+
| acl-list | list | 22 | 4 array | Array |
+---------------------+--------------+------+-------------+--------+
| acl-name | leafref | 23 | 3 text | String |
| | | | string | |
+---------------------+--------------+------+-------------+--------+
| acl-type | leafref | 24 | 3 text | String |
| | | | string | |
+---------------------+--------------+------+-------------+--------+
| bytes-dropped | yang:zero- | 25 | 0 unsigned | String |
| | based- | | | |
| | counter64 | | | |
+---------------------+--------------+------+-------------+--------+
| bps-dropped | yang:gauge64 | 26 | 0 unsigned | String |
+---------------------+--------------+------+-------------+--------+
| pkts-dropped | yang:zero- | 27 | 0 unsigned | String |
| | based- | | | |
| | counter64 | | | |
+---------------------+--------------+------+-------------+--------+
| pps-dropped | yang:gauge64 | 28 | 0 unsigned | String |
+---------------------+--------------+------+-------------+--------+
| attack-status | enumeration | 29 | 0 unsigned | String |
+---------------------+--------------+------+-------------+--------+
| ietf-dots-signal- | container | 30 | 5 map | Object |
| channel:signal- | | | | |
| config | | | | |
+---------------------+--------------+------+-------------+--------+
| sid | uint32 | 31 | 0 unsigned | Number |
+---------------------+--------------+------+-------------+--------+
| mitigating-config | container | 32 | 5 map | Object |
+---------------------+--------------+------+-------------+--------+
| heartbeat-interval | container | 33 | 5 map | Object |
+---------------------+--------------+------+-------------+--------+
| max-value | uint16 | 34 | 0 unsigned | Number |
+---------------------+--------------+------+-------------+--------+
| min-value | uint16 | 35 | 0 unsigned | Number |
+---------------------+--------------+------+-------------+--------+
| current-value | uint16 | 36 | 0 unsigned | Number |
+---------------------+--------------+------+-------------+--------+
| missing-hb-allowed | container | 37 | 5 map | Object |
+---------------------+--------------+------+-------------+--------+
| max-retransmit | container | 38 | 5 map | Object |
+---------------------+--------------+------+-------------+--------+
| ack-timeout | container | 39 | 5 map | Object |
+---------------------+--------------+------+-------------+--------+
| ack-random-factor | container | 40 | 5 map | Object |
+---------------------+--------------+------+-------------+--------+
| max-value-decimal | decimal64 | 41 | 6 tag 4 | String |
| | | | [-2, | |
| | | | integer] | |
+---------------------+--------------+------+-------------+--------+
| min-value-decimal | decimal64 | 42 | 6 tag 4 | String |
| | | | [-2, | |
| | | | integer] | |
+---------------------+--------------+------+-------------+--------+
| current-value- | decimal64 | 43 | 6 tag 4 | String |
| decimal | | | [-2, | |
| | | | integer] | |
+---------------------+--------------+------+-------------+--------+
| idle-config | container | 44 | 5 map | Object |
+---------------------+--------------+------+-------------+--------+
| trigger-mitigation | boolean | 45 | 7 bits 20 | False |
| | | +-------------+--------+
| | | | 7 bits 21 | True |
+---------------------+--------------+------+-------------+--------+
| ietf-dots-signal- | container | 46 | 5 map | Object |
| channel:redirected- | | | | |
| signal | | | | |
+---------------------+--------------+------+-------------+--------+
| alt-server | inet:domain- | 47 | 3 text | String |
| | name | | string | |
+---------------------+--------------+------+-------------+--------+
| alt-server-record | leaf-list | 48 | 4 array | Array |
| +--------------+------+-------------+--------+
| | inet:ip- | | 3 text | String |
| | address | | string | |
+---------------------+--------------+------+-------------+--------+
| ietf-dots-signal- | container | 49 | 5 map | Object |
| channel:heartbeat | | | | |
+---------------------+--------------+------+-------------+--------+
| probing-rate | container | 50 | 5 map | Object |
+---------------------+--------------+------+-------------+--------+
| peer-hb-status | boolean | 51 | 7 bits 20 | False |
| | | +-------------+--------+
| | | | 7 bits 21 | True |
+---------------------+--------------+------+-------------+--------+
Table 5: CBOR Key Values Used in DOTS Signal Channel Messages &
Their Mappings to JSON and YANG
7. (D)TLS Protocol Profile and Performance Considerations ✨
7.1. (D)TLS Protocol Profile 🔐
okay bestie, this section is the (D)TLS protocol profile for the DOTS signal channel over (D)TLS and the DOTS data channel over TLS 💖
There are known attacks on (D)TLS, like man-in-the-middle and protocol downgrade attacks 😭 These are general attacks on (D)TLS, so they aren't specific to DOTS over (D)TLS. For the full discussion of these security issues, go read the (D)TLS RFCs. Also, DOTS agents MUST adhere to the (D)TLS implementation recommendations and security considerations of [RFC7525] except with respect to (D)TLS version. Since DOTS signal channel encryption relying on (D)TLS is basically a greenfield deployment, DOTS agents MUST implement only (D)TLS 1.2 or later 🌸
When a DOTS client is configured with a domain name of the DOTS server and connects to it, the server may present a PKIX certificate 🎀 To make sure authentication actually works, a DOTS client MUST verify the entire certification path per [RFC5280]. The DOTS client MUST also use [RFC6125] validation techniques to compare the domain name with the certificate provided. Certification authorities that issue DOTS server certificates SHOULD support the DNS-ID and SRV-ID identifier types. DOTS servers SHOULD prefer DNS-ID and SRV-ID over Common Name ID (CN-ID) identifier types in certificate requests (as described in Section 2.3 of [RFC6125]), and the wildcard character '*' SHOULD NOT be included in the presented identifier. DOTS doesn't use URI-IDs for server identity verification 🧚
Provisioning DOTS clients is a big deal, ngl 🥺 It includes distributing keying material so DOTS agents can do the mutual authentication they need. Enrollment over Secure Transport (EST) [RFC7030] is a method of certificate enrollment where domains running DOTS servers can give DOTS clients all the cryptographic keying material they need, including a private key and a certificate, so they can authenticate themselves. One deployment option is for DOTS clients to act as EST clients, enrolling with an EST server provisioned by the mitigation provider. This document doesn't specify which EST or other mechanism the DOTS client uses for initial enrollment 💅
The Server Name Indication (SNI) extension [RFC6066] lets a client tell a (D)TLS server the name of the server it wants to reach. This is super useful in hosting environments where multiple virtual servers live behind a single IP address ✨ The DOTS client may or may not know whether it's talking to a DOTS server in a virtual server-hosting environment, so the DOTS client SHOULD include the DOTS server FQDN in the SNI extension.
Implementations that comply with this profile MUST implement all of the following items:
- DTLS record replay detection (Section 3.3 of [RFC6347]) or an equivalent mechanism to protect against replay attacks.
- DTLS session resumption without server-side state, so a client can resume a session and convey the DOTS signal.
- At least one of raw public keys [RFC7250] or PSK handshake [RFC4279] with (EC)DHE key exchange. This shrinks the size of the ServerHello, and it can also be used by DOTS agents that can't obtain certificates 🦋
Implementations that comply with this profile SHOULD implement all of the following items to reduce the delay before a DOTS signal channel message gets delivered:
- TLS False Start [RFC7918], which cuts round trips by letting the TLS client's second flight of messages (ChangeCipherSpec) also carry the DOTS signal. TLS False Start is formally defined for TLS, but the same technique applies to DTLS too 🚀
- Cached Information Extension [RFC7924], which skips sending the server's certificate and certificate chain if the client already cached that information from a previous TLS handshake 🧠
Compared to UDP, DOTS signal channel over TCP needs an extra round-trip time (RTT) of latency to set up a TCP connection. DOTS implementations are encouraged to implement TCP Fast Open [RFC7413] to get rid of that RTT 💜
7.2. (D)TLS 1.3 Considerations 🌈
TLS 1.3 brings real latency improvements for connection establishment over TLS 1.2 ⭐ The DTLS 1.3 protocol [TLS-DTLS13] is based on the TLS 1.3 protocol and gives equivalent security guarantees. (D)TLS 1.3 has two basic handshake modes that the DOTS signal channel can take advantage of:
- A full handshake mode in which a DOTS client can send a DOTS mitigation request message after one round trip, and the DOTS server immediately responds with a DOTS mitigation response. This assumes no packet loss is experienced.
- 0-RTT mode, in which the DOTS client can authenticate itself and send DOTS mitigation request messages in the first message, which cuts handshake latency. 0-RTT only works if the DOTS client has previously communicated with that DOTS server, which is very likely with the DOTS signal channel 🔥
The DOTS client has to set up a (D)TLS session with the DOTS server during 'idle' time and share a PSK 🫶
During a DDoS attack, the DOTS client can use the (D)TLS session to convey the DOTS mitigation request message. If there's no response from the server after multiple retries, the DOTS client can resume the (D)TLS session in 0-RTT mode using PSK 😤
DOTS servers that support (D)TLS 1.3 MAY allow DOTS clients to send early data (0-RTT). DOTS clients MUST NOT send "CoAP Ping" as early data, and such messages MUST be rejected by DOTS servers 🙅♀️ Section 8 of [RFC8446] talks about mechanisms to implement to limit the impact of replay attacks on 0-RTT data. If the DOTS server accepts 0-RTT, it MUST implement one of these mechanisms to prevent replay at the TLS layer. A DOTS server can reject 0-RTT by sending a TLS HelloRetryRequest.
The DOTS signal channel messages that the DOTS client sends as early data are idempotent requests. As a reminder, the Message ID (Section 3 of [RFC7252]) changes every time a new CoAP request is sent, and the Token (Section 5.3.1 of [RFC7252]) is randomized in each CoAP request 🎀 The DOTS server(s) MUST use the Message ID and the Token in the DOTS signal channel message to detect replay of early data at the application layer, and accept 0-RTT data at most once from the same DOTS client. This anti-replay defense requires sharing the Message ID and the Token in the 0-RTT data between DOTS servers in the DOTS server domain. DOTS servers don't rely on transport coordinates to identify DOTS peers. As specified in Section 4.4.1, DOTS servers couple the DOTS signal channel sessions using the DOTS client identity and, optionally, the 'cdid' parameter value. Furthermore, the 'mid' value is monotonically increased by the DOTS client for each mitigation request, so attackers replaying mitigation requests with lower numeric 'mid' values and overlapping scopes with mitigation requests that have higher numeric 'mid' values will be rejected systematically by the DOTS server 👑 Likewise, the 'sid' value is monotonically increased by the DOTS client for each configuration request (Section 4.5.2). Attackers replaying configuration requests with lower numeric 'sid' values will be rejected by the DOTS server if it maintains a higher numeric 'sid' value for this DOTS client.
Thanks to all those protections, every DOTS signal channel request is safe to transmit in TLS 1.3 as early data 🧁 Refer to [DOTS-EARLYDATA] for more details.
A simplified TLS 1.3 handshake with a 0-RTT DOTS mitigation request message exchange is shown in Figure 29 ✨
DOTS Client DOTS Server
ClientHello
(0-RTT DOTS signal message)
-------->
ServerHello
{EncryptedExtensions}
{Finished}
<-------- [DOTS signal message]
(end_of_early_data)
{Finished} -------->
[DOTS signal message] <-------> [DOTS signal message]
Note that:
() Indicates messages protected 0-RTT keys
{} Indicates messages protected using handshake keys
[] Indicates messages protected using 1-RTT keys
Figure 29: A Simplified TLS 1.3 Handshake with 0-RTT
7.3. DTLS MTU and Fragmentation 🦋
To avoid DOTS signal message fragmentation (and the lower chance of the message getting delivered that comes with it), the DTLS records need to fit within a single datagram [RFC6347]. DTLS only handles fragmentation and reassembly for handshake messages, not for application data (Section 4.1.1 of [RFC6347]). If the Path MTU (PMTU) can't be discovered, DOTS agents MUST assume a PMTU of 1280 bytes, since IPv6 requires every link in the Internet to have an MTU of 1280 octets or greater, as specified in [RFC8200] 💖 If IPv4 support on legacy or otherwise unusual networks is a consideration and the PMTU is unknown, DOTS implementations MAY assume a PMTU of 576 bytes for IPv4 datagrams (see Section 3.3.3 of [RFC1122]).
The DOTS client must consider the amount of record expansion that DTLS processing expects when calculating the size of the CoAP message that fits within the PMTU. The PMTU MUST be greater than or equal to [CoAP message size + DTLS 1.2 overhead of 13 octets + authentication overhead of the negotiated DTLS cipher suite + block padding] (Section 4.1.1.1 of [RFC6347]). If the total request size exceeds the PMTU, the DOTS client MUST split the DOTS signal into separate messages. For example, the list of addresses in the 'target-prefix' parameter could be split into multiple lists, with each list conveyed in a new PUT request 🧩
🫶 Implementation note, bestie: DOTS choice of message size parameters works well with IPv6 and with most of today's IPv4 paths. With IPv4, though, it's harder to make sure there's no IP fragmentation. If the IPv4 PMTU is unknown, implementations may want to limit themselves to more conservative IPv4 datagram sizes, such as 576 bytes, per [RFC0791] 💅
8. Mutual Authentication of DOTS Agents & Authorization of DOTS Clients ✨
Okay so, (D)TLS with client certificates can be used for mutual authentication between DOTS agents 🔐. If there's a DOTS gateway in the mix, DOTS clients and DOTS gateways must perform mutual authentication, and only authorized DOTS clients are allowed to send DOTS signals to a DOTS gateway 💅. The DOTS gateway and the DOTS server must also perform mutual authentication. A DOTS server only accepts DOTS signal channel messages from an authorized DOTS gateway, which creates a two-link chain of transitive authentication between the DOTS client and the DOTS server 🦋.
The DOTS server should support certificate-based client authentication. The DOTS client should respond to the DOTS server's TLS CertificateRequest message with the PKIX certificate that the DOTS client holds 🎀. DOTS client certificate validation must be performed per [RFC5280], and the DOTS client certificate must conform to the [RFC5280] certificate profile. If a DOTS client doesn't support TLS client certificate authentication, it must support client authentication based on pre-shared key or raw public key 🌸.
+---------------------------------------------+
| example.com domain +---------+ |
| | AAA | |
| +---------------+ | Server | |
| | Application | +------+--+ |
| | server +<---------------+ ^ |
| | (DOTS client) | | | |
| +---------------+ | | |
| V V | example.net domain
| +-----+----+--+ | +---------------+
| +--------------+ | | | | |
| | Guest +<----x---->+ DOTS +<----->+ DOTS |
| | (DOTS client)| | gateway | | | server |
| +--------------+ | | | | |
| +----+--------+ | +---------------+
| ^ |
| | |
| +----------------+ | |
| | DDoS detector | | |
| | (DOTS client) +<-------------+ |
| +----------------+ |
+---------------------------------------------+
Figure 30: Example of Authentication and Authorization of DOTS Agents
In the example in Figure 30, the DOTS gateway and the DOTS clients inside the 'example.com' domain do mutual authentication 🤝. Once the DOTS gateway has checked who a DOTS client is, it talks to the Authentication, Authorization, and Accounting (AAA) server in the 'example.com' domain to find out if that DOTS client is allowed to request DDoS mitigation. If the DOTS client isn't authorized, a 4.01 (Unauthorized) comes back in the response to the DOTS client 🙅♀️. In this example, the DOTS gateway only lets the application server and the DDoS attack detector request DDoS mitigation. The user of type 'guest' doesn't get to request it, sorry guest 💀.
DOTS gateways and servers in different domains must also do mutual authentication (for example, using certificates) 🔏. A DOTS server will only let a DOTS gateway with a certificate for a particular domain request mitigation for that domain. Looking at Figure 30 again, the DOTS server only lets the DOTS gateway request mitigation for the 'example.com' domain, and not for any other domains 🚫.
9. Error Handling 🚨
This section is a summary of the Error Code responses that a DOTS server can return. These error responses must contain a CoAP 4.xx or 5.xx Response Code 💜.
In general, there may be an additional plain text diagnostic payload (Section 5.5.2 of [RFC7252]) in the body of the response to help with troubleshooting, unless it's detailed otherwise ✨.
Errors returned by a DOTS server fall into two categories: the ones tied to CoAP itself, and the ones that come up while the DOTS server validates the data it was given 🧐.
The list below has common CoAP errors that DOTS servers implement. It isn't exhaustive, so other errors defined by CoAP and its associated RFCs might apply too 📋.
4.00 (Bad Request)is returned by the DOTS server when the DOTS client has sent a request that violates the DOTS protocol (Section 4). Bestie, don't send bad requests 😭.4.01 (Unauthorized)is returned by the DOTS server when the DOTS client is not authorized to access the DOTS server (Section 4).4.02 (Bad Option)is returned by the DOTS server when one or more CoAP options are unknown or malformed by the CoAP layer [RFC7252].4.04 (Not Found)is returned by the DOTS server when the DOTS client requests a 'mid' or 'sid' that is not valid (Section 4).4.05 (Method Not Allowed)is returned by the DOTS server when the DOTS client requests a resource using a method (for example, GET) that the DOTS server doesn't support [RFC7252].4.08 (Request Entity Incomplete)is returned by the DOTS server if one or more blocks of a block transfer request are missing [RFC7959].4.09 (Conflict)is returned by the DOTS server if it detects that a request conflicts with a previous request. The response body is formatted using "application/dots+cbor" and contains the "conflict-clause" (Section 4.4.1.3) 🥊.4.13 (Request Entity Too Large)may be returned by the DOTS server during a block transfer request [RFC7959].4.15 (Unsupported Content-Format)is returned by the DOTS server when the Content-Format is used but the request is not formatted as "application/dots+cbor" (Section 4).4.22 (Unprocessable Entity)is returned by the DOTS server when one or more session configuration parameters are not valid (Section 4.5).5.03 (Service Unavailable)is returned by the DOTS server if it can't handle the request (Section 4). An example is when the DOTS server needs to redirect the DOTS client to use an alternate DOTS server (Section 4.6). The response body is formatted using "application/dots+cbor" and contains how to handle the 5.03 Response Code 🔁.5.08 (Hop Limit Reached)is returned by the DOTS server if there is a data path loop through upstream DOTS gateways. The response body is formatted using plain text and contains a list of servers that are in the data path loop [RFC8768] 🌀.
10. IANA Considerations 🌷
10.1. DOTS Signal Channel UDP and TCP Port Number
IANA has assigned the port number 4646 (the ASCII decimal value for ".." (DOTS)) to the DOTS signal channel protocol for both UDP and TCP, from the "Service Name and Transport Protocol Port Number Registry" available at https://www.iana.org/assignments/service-names-port-numbers/ 🔢.
IANA has updated these entries to refer to this document, and updated the Description as described below 📝:
Service Name: dots-signal
Port Number: 4646
Transport Protocol: TCP
Description: Distributed Denial-of-Service Open Threat Signaling
(DOTS) Signal Channel Protocol. The service name is used to
construct the SRV service names "_dots-signal._udp" and "_dots-
signal._tcp" for discovering DOTS servers used to establish DOTS
signal channel.
Assignee: IESG
Contact: IETF Chair
Registration Date: 2020-01-16
Reference: [RFC8973][RFC9132]
Service Name: dots-signal
Port Number: 4646
Transport Protocol: UDP
Description: Distributed Denial-of-Service Open Threat Signaling
(DOTS) Signal Channel Protocol. The service name is used to
construct the SRV service names "_dots-signal._udp" and "_dots-
signal._tcp" for discovering DOTS servers used to establish DOTS
signal channel.
Assignee: IESG
Contact: IETF Chair
Registration Date: 2020-01-16
Reference: [RFC8973][RFC9132]
10.2. Well-Known 'dots' URI
IANA has updated the 'dots' well-known URI (Table 6) entry in the "Well-Known URIs" registry [URI] as follows 🌈:
+============+============+===========+===========+=============+
| URI Suffix | Change | Reference | Status | Related |
| | Controller | | | information |
+============+============+===========+===========+=============+
| dots | IETF | [RFC9132] | permanent | None |
+------------+------------+-----------+-----------+-------------+
Table 6: 'dots' Well-Known URI
10.3. Media Type Registration
IANA has updated the "application/dots+cbor" media type in the "Media Types" registry [IANA-MediaTypes], following the manner described in [RFC6838]. It can be used to say that the content is a DOTS signal channel object 💖:
Type name: application
Subtype name: dots+cbor
Required parameters: N/A
Optional parameters: N/A
Encoding considerations: binary
Security considerations: See the Security Considerations section of
RFC 9132.
Interoperability considerations: N/A
Published specification: RFC 9132
Applications that use this media type: DOTS agents sending DOTS
messages over CoAP over (D)TLS.
Fragment identifier considerations: N/A
Additional information:
Deprecated alias names for this type: N/A
Magic number(s): N/A
File extension(s): N/A
Macintosh file type code(s): N/A
Person & email address to contact for further information:
IESG, iesg@ietf.org
Intended usage: COMMON
Restrictions on usage: none
Author: See Authors' Addresses section.
Change controller: IESG
Provisional registration? No
10.4. CoAP Content-Formats Registration
IANA has updated the "application/dots+cbor" media type in the "CoAP Content-Formats" registry [IANA-CoAP-Content-Formats] as follows 🧁:
Media Type: application/dots+cbor
Encoding: -
ID: 271
Reference: [RFC9132]
10.5. CBOR Tag Registration
This section defines the DOTS CBOR tag as another way for applications to declare that a CBOR data structure is a DOTS signal channel object 🏷️. Using it is optional, and it's meant for cases where this information wouldn't otherwise be known. The DOTS CBOR tag is not required for the DOTS signal channel protocol version specified in this document. If it's present, the DOTS tag MUST prefix a DOTS signal channel object 🔖.
IANA has updated the DOTS signal channel CBOR tag in the "CBOR Tags" registry [IANA-CBOR-Tags] as follows:
Tag: 271
Data Item: DDoS Open Threat Signaling (DOTS) signal channel object
Semantics: DDoS Open Threat Signaling (DOTS) signal channel object,
as defined in [RFC9132]
Reference: [RFC9132]
10.6. DOTS Signal Channel Protocol Registry
The following sections update the "Distributed Denial-of-Service Open Threat Signaling (DOTS) Signal Channel" subregistries [REG-DOTS] 📚.
10.6.1. DOTS Signal Channel CBOR Key Values Subregistry
The structure of this subregistry is provided in Section 10.6.1.1 🌟.
10.6.1.1. Registration Template ✨
okay so IANA has glowed up the allocation policy for the "DOTS Signal Channel CBOR Key Values" registry 💅 here's the tea:
- Parameter name: the parameter name, as used in the DOTS signal channel 🎀
- CBOR Key Value: the key value for the parameter. It's giving strict vibes because the key value MUST be an integer in the 1-65535 range 🔥
Here's the OLD allocation table (we're retiring it 😭):
+=============+=========================+========================+
| Range | Registration | Note |
| | Procedures | |
+=============+=========================+========================+
| 1-16383 | IETF Review | comprehension-required |
+-------------+-------------------------+------------------------+
| 16384-32767 | Specification | comprehension-optional |
| | Required | |
+-------------+-------------------------+------------------------+
| 32768-49151 | IETF Review | comprehension-optional |
+-------------+-------------------------+------------------------+
| 49152-65535 | Private Use | comprehension-optional |
+-------------+-------------------------+------------------------+
Table 7
And here's the NEW one, which is so much better 🦋:
+=============+=========================+========================+
| Range | Registration | Note |
| | Procedures | |
+=============+=========================+========================+
| 1-127 | IETF Review | comprehension-required |
+-------------+-------------------------+------------------------+
| 128-255 | IETF Review | comprehension-optional |
+-------------+-------------------------+------------------------+
| 256-16383 | IETF Review | comprehension-required |
+-------------+-------------------------+------------------------+
| 16384-32767 | Specification | comprehension-optional |
| | Required | |
+-------------+-------------------------+------------------------+
| 32768-49151 | IETF Review | comprehension-optional |
+-------------+-------------------------+------------------------+
| 49152-65535 | Private Use | comprehension-optional |
+-------------+-------------------------+------------------------+
Table 8
Now the spicy part 🌶️ Registration requests for the 16384-32767 range get evaluated after a three-week review period on the dots-signal-reg-review@ietf.org mailing list, with advice from one or more designated experts. BUT (the plot twist 👀) the designated experts can approve early to allow allocating values before publication, as long as they're satisfied that a specification will get published. New requests go by email to the review mailing list with a proper subject line, like Request to register CBOR Key Value for DOTS: example 💌 IANA will only accept new registrations from the designated experts, and it will check that review was requested on the mailing list the right way.
Within the review period, the designated experts will either approve or deny the request and tell the review list and IANA. Denials should include an explanation and, if applicable, suggestions for how to make the request work next time 🫶 If a request is still undetermined after more than 21 days, it can be brought to the IESG's attention (via the iesg@ietf.org mailing list) for resolution. Not a fun vibe, but it's a safety net 🧚
The designated experts should check a few things when deciding: whether the proposed registration duplicates existing functionality, whether it's likely to be generally applicable or only useful for one single use case, and whether the registration description is clear 💜 IANA must only accept registry updates to the 16384-32767 range from the designated experts, and should send all registration requests to the review mailing list. It's suggested that multiple designated experts get appointed. And if a decision could look like a conflict of interest for a particular expert, that expert should defer to the judgment of the other experts. Very mature, very iconic 👑
- CBOR Major Type: the CBOR major type and optional tag for the parameter 🍓
- Change Controller: for Standards Track RFCs, list the "IESG". For others, give the name of the responsible party. Other details (like an email address) may also be included 💅
- Specification Document(s): a reference to the document or documents that specify the parameter, preferably with URIs where people can grab copies. An indication of the relevant sections may also be included, but it's not required 🌸
10.6.1.2. Update Subregistry Content 🌈
IANA has updated entries in the "0-51" and "49152-65535" ranges from the "DOTS Signal Channel CBOR Key Values" registry to refer to this RFC. So if you're looking at those ranges, this is the doc you want ⭐
10.6.2. Status Codes Subregistry 🚦
IANA has updated the following entries from the "DOTS Signal Channel Status Codes" registry to refer to this RFC:
+==============+===============+======================+===========+
| Code | Label | Description | Reference |
+==============+===============+======================+===========+
| 0 | Reserved | | [RFC9132] |
+--------------+---------------+----------------------+-----------+
| 1 | attack- | Attack mitigation | [RFC9132] |
| | mitigation- | setup is in progress | |
| | in-progress | (e.g., changing the | |
| | | network path to | |
| | | redirect the inbound | |
| | | traffic to a DOTS | |
| | | mitigator). | |
+--------------+---------------+----------------------+-----------+
| 2 | attack- | Attack is being | [RFC9132] |
| | successfully- | successfully | |
| | mitigated | mitigated (e.g., | |
| | | traffic is | |
| | | redirected to a DDoS | |
| | | mitigator and attack | |
| | | traffic is dropped). | |
+--------------+---------------+----------------------+-----------+
| 3 | attack- | Attack has stopped | [RFC9132] |
| | stopped | and the DOTS client | |
| | | can withdraw the | |
| | | mitigation request. | |
+--------------+---------------+----------------------+-----------+
| 4 | attack- | Attack has exceeded | [RFC9132] |
| | exceeded- | the mitigation | |
| | capability | provider capability. | |
+--------------+---------------+----------------------+-----------+
| 5 | dots-client- | DOTS client has | [RFC9132] |
| | withdrawn- | withdrawn the | |
| | mitigation | mitigation request | |
| | | and the mitigation | |
| | | is active but | |
| | | terminating. | |
+--------------+---------------+----------------------+-----------+
| 6 | attack- | Attack mitigation is | [RFC9132] |
| | mitigation- | now terminated. | |
| | terminated | | |
+--------------+---------------+----------------------+-----------+
| 7 | attack- | Attack mitigation is | [RFC9132] |
| | mitigation- | withdrawn. | |
| | withdrawn | | |
+--------------+---------------+----------------------+-----------+
| 8 | attack- | Attack mitigation | [RFC9132] |
| | mitigation- | will be triggered | |
| | signal-loss | for the mitigation | |
| | | request only when | |
| | | the DOTS signal | |
| | | channel session is | |
| | | lost. | |
+--------------+---------------+----------------------+-----------+
| 9-2147483647 | Unassigned | | |
+--------------+---------------+----------------------+-----------+
Table 9: Initial DOTS Signal Channel Status Codes
New codes can be assigned via Standards Action [RFC8126]. Status code party time continues 🎉
10.6.3. Conflict Status Codes Subregistry 💅
okay bestie, IANA gave these entries in the "DOTS Signal Channel Conflict Status Codes" registry a glow-up, and they now point at this RFC ✨ Here's the table 🦋
+==============+===================+====================+===========+
| Code | Label | Description | Reference |
+==============+===================+====================+===========+
| 0 | Reserved | | [RFC9132] |
+--------------+-------------------+--------------------+-----------+
| 1 | request-inactive- | DOTS server | [RFC9132] |
| | other-active | has detected | |
| | | conflicting | |
| | | mitigation | |
| | | requests from | |
| | | different DOTS | |
| | | clients. This | |
| | | mitigation | |
| | | request is | |
| | | currently | |
| | | inactive until | |
| | | the conflicts | |
| | | are resolved. | |
| | | Another | |
| | | mitigation | |
| | | request is | |
| | | active. | |
+--------------+-------------------+--------------------+-----------+
| 2 | request-active | DOTS server | [RFC9132] |
| | | has detected | |
| | | conflicting | |
| | | mitigation | |
| | | requests from | |
| | | different DOTS | |
| | | clients. This | |
| | | mitigation | |
| | | request is | |
| | | currently | |
| | | active. | |
+--------------+-------------------+--------------------+-----------+
| 3 | all-requests- | DOTS server | [RFC9132] |
| | inactive | has detected | |
| | | conflicting | |
| | | mitigation | |
| | | requests from | |
| | | different DOTS | |
| | | clients. All | |
| | | conflicting | |
| | | mitigation | |
| | | requests are | |
| | | inactive. | |
+--------------+-------------------+--------------------+-----------+
| 4-2147483647 | Unassigned | | |
+--------------+-------------------+--------------------+-----------+
Table 10: Initial DOTS Signal Channel Conflict Status Codes
Want a brand-new code? That's allowed through Standards Action [RFC8126] 🫶
10.6.4. Conflict Cause Codes Subregistry 🎀
IANA also updated these entries in the "DOTS Signal Channel Conflict Cause Codes" registry so they refer to this document 🌸
+==============+=====================+================+===========+
| Code | Label | Description | Reference |
+==============+=====================+================+===========+
| 0 | Reserved | | [RFC9132] |
+--------------+---------------------+----------------+-----------+
| 1 | overlapping-targets | Overlapping | [RFC9132] |
| | | targets. | |
+--------------+---------------------+----------------+-----------+
| 2 | conflict-with- | Conflicts with | [RFC9132] |
| | acceptlist | an existing | |
| | | accept-list. | |
| | | This code is | |
| | | returned when | |
| | | the DDoS | |
| | | mitigation | |
| | | detects source | |
| | | addresses/ | |
| | | prefixes in | |
| | | the accept- | |
| | | listed ACLs | |
| | | are attacking | |
| | | the target. | |
+--------------+---------------------+----------------+-----------+
| 3 | cuid-collision | CUID | [RFC9132] |
| | | Collision. | |
| | | This code is | |
| | | returned when | |
| | | a DOTS client | |
| | | uses a 'cuid' | |
| | | that is | |
| | | already used | |
| | | by another | |
| | | DOTS client. | |
+--------------+---------------------+----------------+-----------+
| 4-2147483647 | Unassigned | | |
+--------------+---------------------+----------------+-----------+
Table 11: Initial DOTS Signal Channel Conflict Cause Codes
New codes can be assigned via Standards Action [RFC8126] 💖
10.6.5. Attack Status Codes Subregistry 🧚
same energy here: IANA updated these entries in the "DOTS Signal Channel Attack Status Codes" registry to refer to this RFC 🦋
+==============+======================+=================+===========+
| Code | Label | Description | Reference |
+==============+======================+=================+===========+
| 0 | Reserved | | [RFC9132] |
+--------------+----------------------+-----------------+-----------+
| 1 | under-attack | The DOTS | [RFC9132] |
| | | client | |
| | | determines | |
| | | that it is | |
| | | still under | |
| | | attack. | |
+--------------+----------------------+-----------------+-----------+
| 2 | attack-successfully- | The DOTS | [RFC9132] |
| | mitigated | client | |
| | | determines | |
| | | that the | |
| | | attack is | |
| | | successfully | |
| | | mitigated. | |
+--------------+----------------------+-----------------+-----------+
| 3-2147483647 | Unassigned | | |
+--------------+----------------------+-----------------+-----------+
Table 12: Initial DOTS Signal Channel Attack Status Codes
New codes can be assigned via Standards Action [RFC8126] 👑
10.7. DOTS Signal Channel YANG Modules 🌈
IANA registered the following URIs in the "ns" subregistry within the "IETF XML Registry" [RFC3688] ⭐
URI: urn:ietf:params:xml:ns:yang:ietf-dots-signal-channel
Registrant Contact: The IESG.
XML: N/A; the requested URI is an XML namespace.
URI: urn:ietf:params:xml:ns:yang:iana-dots-signal-channel
Registrant Contact: IANA.
XML: N/A; the requested URI is an XML namespace.
IANA also updated the following YANG module in the "YANG Module Names" subregistry [RFC6020] within the "YANG Parameters" registry 🧁
Name: iana-dots-signal-channel
Maintained by IANA: Y
Namespace: urn:ietf:params:xml:ns:yang:iana-dots-signal-channel
Prefix: iana-dots-signal
Reference: [RFC9132]
And IANA registered one more YANG module in the "YANG Module Names" subregistry [RFC6020] within the "YANG Parameters" registry. This one obsoletes the registration in [RFC8782] 🫶
Name: ietf-dots-signal-channel
Maintained by IANA: N
Namespace: urn:ietf:params:xml:ns:yang:ietf-dots-signal-channel
Prefix: dots-signal
Reference: [RFC9132]
⚠️ Plot twist: this document obsoletes the initial version of the IANA-maintained iana-dots-signal-channel YANG module (Section 5.2 of [RFC8782]). IANA is also requested to maintain this note 👀
Status, conflict status, conflict cause, and attack status
values must not be directly added to the iana-dots-signal-
channel YANG module. They must instead be respectively added to
the "DOTS Status Codes", "DOTS Conflict Status Codes", "DOTS
Conflict Cause Codes", and "DOTS Attack Status Codes"
registries.
So when a 'status', 'conflict-status', 'conflict-cause', or 'attack-status' value gets added to the "DOTS Status Codes", "DOTS Conflict Status Codes", "DOTS Conflict Cause Codes", or "DOTS Attack Status Codes" registry, a new "enum" statement has to be added to the iana-dots-signal-channel YANG module 🔥 The "enum" statement, plus its substatements, should be defined like this:
"enum": Replicates the label from the registry.
"value": Contains the IANA-assigned value corresponding to the
'status', 'conflict-status', 'conflict-cause', or
'attack-status'.
"description": Replicates the description from the registry.
"reference": Replicates the reference from the registry and adds
the title of the document.
And whenever the iana-dots-signal-channel YANG module gets updated, a new "revision" statement goes in front of the existing revision statements 🌸
Last glow-up: IANA has updated this note in the "DOTS Status Codes", "DOTS Conflict Status Codes", "DOTS Conflict Cause Codes", and "DOTS Attack Status Codes" registries:
When this registry is modified, the YANG module iana-dots-
signal-channel must be updated as defined in [RFC9132].
11. Security Considerations ✨
High-level DOTS security considerations are documented in [RFC8612] and [RFC8811]. Go read those too, bestie, they're the big-picture stuff 🧚
Authenticated encryption MUST be used for data confidentiality and message integrity. 🔒 The interaction between the DOTS agents requires Datagram Transport Layer Security (DTLS) or Transport Layer Security (TLS) with a cipher suite offering confidentiality protection, and the guidance given in [RFC7525] MUST be followed to avoid attacks on (D)TLS. The (D)TLS protocol profile used for the DOTS signal channel is specified in Section 7. 💜
If TCP is used between DOTS agents, an attacker may be able to inject RST packets, bogus application segments, etc., regardless of whether TLS authentication is used. 😭 Because the application data is TLS protected, this will not result in the application receiving bogus data, but it will constitute a DoS on the connection. This attack can be countered by using TCP Authentication Option (TCP-AO) [RFC5925]. Although not widely adopted, if TCP-AO is used, then any bogus packets injected by an attacker will be rejected by the TCP-AO integrity check and therefore will never reach the TLS layer. 🛡️✨
If the 'cuid' is guessable, a misbehaving DOTS client from within the client's domain can use the 'cuid' of another DOTS client of the domain to delete or alter active mitigations. 💀 For this attack to succeed, the misbehaving client's messages need to pass the security validation checks by the DOTS server and, if the communication involves a client-domain DOTS gateway, the security checks of that gateway.
A similar attack can be achieved by a compromised DOTS client that can sniff the TLS 1.2 handshake: use the client certificate to identify the 'cuid' used by another DOTS client. This attack is not possible if algorithms such as version 4 Universally Unique IDentifiers (UUIDs) in Section 4.4 of [RFC4122] are used to generate the 'cuid' because such UUIDs are not a deterministic function of the client certificate. Likewise, this attack is not possible with TLS 1.3 because most of the TLS handshake is encrypted and the client certificate is not visible to eavesdroppers. 🙈
A compromised DOTS client can collude with a DDoS attacker to send a mitigation request for a target resource, get the mitigation efficacy from the DOTS server, and convey the mitigation efficacy to the DDoS attacker to possibly change the DDoS attack strategy. Obviously, signaling an attack by the compromised DOTS client to the DOTS server will trigger attack mitigation. This attack can be prevented by monitoring and auditing DOTS clients to detect misbehavior and to deter misuse and by only authorizing the DOTS client to request mitigation for specific target resources (e.g., an application server is authorized to request mitigation for its IP addresses, but a DDoS mitigator can request mitigation for any target resource in the network). Furthermore, DOTS clients are typically co-located on network security services (e.g., firewall), and a compromised security service potentially can do a lot more damage to the network. 🔥
Rate-limiting DOTS requests, including those with new 'cuid' values, from the same DOTS client defend against DoS attacks that would result in varying the 'cuid' to exhaust DOTS server resources. Rate-limit policies SHOULD be enforced on DOTS gateways (if deployed) and DOTS servers. 🚦
In order to prevent leaking internal information outside a client's domain, DOTS gateways located in the client domain SHOULD NOT reveal the identification information that pertains to internal DOTS clients (e.g., source IP address, client's hostname) unless explicitly configured to do so. 🫶
DOTS servers MUST verify that requesting DOTS clients are entitled to trigger actions on a given IP prefix. A DOTS server MUST NOT authorize actions due to a DOTS client request unless those actions are limited to that DOTS client's domain IP resources. The exact mechanism for the DOTS servers to validate that the target prefixes are within the scope of the DOTS client domain is deployment specific. 👑
The presence of DOTS gateways may lead to infinite forwarding loops, which is undesirable. To prevent and detect such loops, this document uses the Hop-Limit Option. 🔁
When FQDNs are used as targets, the DOTS server MUST rely upon DNS privacy-enabling protocols (e.g., DNS over TLS [RFC7858] or DNS over HTTPS (DoH) [RFC8484]) to prevent eavesdroppers from possibly identifying the target resources protected by the DDoS mitigation service to ensure the target FQDN resolution is authentic (e.g., DNSSEC [RFC4034]). 🌸
CoAP-specific security considerations are discussed in Section 11 of [RFC7252], while CBOR-related security considerations are discussed in Section 10 of [RFC8949]. 🧚
This document defines YANG data structures that are meant to be used as an abstract representation of DOTS signal channel messages. As such, the "ietf-dots-signal-channel" module does not introduce any new vulnerabilities beyond those specified above. 💖
12. References 🦋
12.1. Normative References ✨
okay bestie, these are the normative references 💅 the docs this spec leans on so hard it's giving dependency 🫶
[RFC0791]Postel, J., "Internet Protocol", STD 5, RFC 791, DOI 10.17487/RFC0791, September 1981,https://www.rfc-editor.org/info/rfc791.[RFC1122]Braden, R., Ed., "Requirements for Internet Hosts - Communication Layers", STD 3, RFC 1122, DOI 10.17487/RFC1122, October 1989,https://www.rfc-editor.org/info/rfc1122.[RFC2119]Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997,https://www.rfc-editor.org/info/rfc2119.[RFC3688]Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688, DOI 10.17487/RFC3688, January 2004,https://www.rfc-editor.org/info/rfc3688.[RFC3986]Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005,https://www.rfc-editor.org/info/rfc3986.[RFC4279]Eronen, P., Ed. and H. Tschofenig, Ed., "Pre-Shared Key Ciphersuites for Transport Layer Security (TLS)", RFC 4279, DOI 10.17487/RFC4279, December 2005,https://www.rfc-editor.org/info/rfc4279.[RFC4632]Fuller, V. and T. Li, "Classless Inter-domain Routing (CIDR): The Internet Address Assignment and Aggregation Plan", BCP 122, RFC 4632, DOI 10.17487/RFC4632, August 2006,https://www.rfc-editor.org/info/rfc4632.[RFC4648]Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006,https://www.rfc-editor.org/info/rfc4648.[RFC5246]Dierks, T. and E. Rescorla, "The Transport Layer Security (TLS) Protocol Version 1.2", RFC 5246, DOI 10.17487/RFC5246, August 2008,https://www.rfc-editor.org/info/rfc5246.[RFC5280]Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., and W. Polk, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 5280, DOI 10.17487/RFC5280, May 2008,https://www.rfc-editor.org/info/rfc5280.[RFC6020]Bjorklund, M., Ed., "YANG - A Data Modeling Language for the Network Configuration Protocol (NETCONF)", RFC 6020, DOI 10.17487/RFC6020, October 2010,https://www.rfc-editor.org/info/rfc6020.[RFC6066]Eastlake 3rd, D., "Transport Layer Security (TLS) Extensions: Extension Definitions", RFC 6066, DOI 10.17487/RFC6066, January 2011,https://www.rfc-editor.org/info/rfc6066.[RFC6125]Saint-Andre, P. and J. Hodges, "Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS)", RFC 6125, DOI 10.17487/RFC6125, March 2011,https://www.rfc-editor.org/info/rfc6125.[RFC6347]Rescorla, E. and N. Modadugu, "Datagram Transport Layer Security Version 1.2", RFC 6347, DOI 10.17487/RFC6347, January 2012,https://www.rfc-editor.org/info/rfc6347.[RFC6991]Schoenwaelder, J., Ed., "Common YANG Data Types", RFC 6991, DOI 10.17487/RFC6991, July 2013,https://www.rfc-editor.org/info/rfc6991.[RFC7250]Wouters, P., Ed., Tschofenig, H., Ed., Gilmore, J., Weiler, S., and T. Kivinen, "Using Raw Public Keys in Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)", RFC 7250, DOI 10.17487/RFC7250, June 2014,https://www.rfc-editor.org/info/rfc7250.[RFC7252]Shelby, Z., Hartke, K., and C. Bormann, "The Constrained Application Protocol (CoAP)", RFC 7252, DOI 10.17487/RFC7252, June 2014,https://www.rfc-editor.org/info/rfc7252.[RFC7525]Sheffer, Y., Holz, R., and P. Saint-Andre, "Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)", BCP 195, RFC 7525, DOI 10.17487/RFC7525, May 2015,https://www.rfc-editor.org/info/rfc7525.[RFC7641]Hartke, K., "Observing Resources in the Constrained Application Protocol (CoAP)", RFC 7641, DOI 10.17487/RFC7641, September 2015,https://www.rfc-editor.org/info/rfc7641.[RFC7918]Langley, A., Modadugu, N., and B. Moeller, "Transport Layer Security (TLS) False Start", RFC 7918, DOI 10.17487/RFC7918, August 2016,https://www.rfc-editor.org/info/rfc7918.[RFC7924]Santesson, S. and H. Tschofenig, "Transport Layer Security (TLS) Cached Information Extension", RFC 7924, DOI 10.17487/RFC7924, July 2016,https://www.rfc-editor.org/info/rfc7924.[RFC7950]Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language", RFC 7950, DOI 10.17487/RFC7950, August 2016,https://www.rfc-editor.org/info/rfc7950.[RFC7959]Bormann, C. and Z. Shelby, Ed., "Block-Wise Transfers in the Constrained Application Protocol (CoAP)", RFC 7959, DOI 10.17487/RFC7959, August 2016,https://www.rfc-editor.org/info/rfc7959.[RFC8085]Eggert, L., Fairhurst, G., and G. Shepherd, "UDP Usage Guidelines", BCP 145, RFC 8085, DOI 10.17487/RFC8085, March 2017,https://www.rfc-editor.org/info/rfc8085.[RFC8126]Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017,https://www.rfc-editor.org/info/rfc8126.[RFC8174]Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017,https://www.rfc-editor.org/info/rfc8174.[RFC8200]Deering, S. and R. Hinden, "Internet Protocol, Version 6 (IPv6) Specification", STD 86, RFC 8200, DOI 10.17487/RFC8200, July 2017,https://www.rfc-editor.org/info/rfc8200.[RFC8305]Schinazi, D. and T. Pauly, "Happy Eyeballs Version 2: Better Connectivity Using Concurrency", RFC 8305, DOI 10.17487/RFC8305, December 2017,https://www.rfc-editor.org/info/rfc8305.[RFC8323]Bormann, C., Lemay, S., Tschofenig, H., Hartke, K., Silverajan, B., and B. Raymor, Ed., "CoAP (Constrained Application Protocol) over TCP, TLS, and WebSockets", RFC 8323, DOI 10.17487/RFC8323, February 2018,https://www.rfc-editor.org/info/rfc8323.[RFC8446]Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,https://www.rfc-editor.org/info/rfc8446.[RFC8615]Nottingham, M., "Well-Known Uniform Resource Identifiers (URIs)", RFC 8615, DOI 10.17487/RFC8615, May 2019,https://www.rfc-editor.org/info/rfc8615.[RFC8768]Boucadair, M., Reddy.K, T., and J. Shallow, "Constrained Application Protocol (CoAP) Hop-Limit Option", RFC 8768, DOI 10.17487/RFC8768, March 2020,https://www.rfc-editor.org/info/rfc8768.[RFC8783]Boucadair, M., Ed. and T. Reddy.K, Ed., "Distributed Denial-of-Service Open Threat Signaling (DOTS) Data Channel Specification", RFC 8783, DOI 10.17487/RFC8783, May 2020,https://www.rfc-editor.org/info/rfc8783.[RFC8791]Bierman, A., Björklund, M., and K. Watsen, "YANG Data Structure Extensions", RFC 8791, DOI 10.17487/RFC8791, June 2020,https://www.rfc-editor.org/info/rfc8791.[RFC8949]Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, December 2020,https://www.rfc-editor.org/info/rfc8949.
that's the whole normative list, bestie 🧚💜
12.2. Informative References
[CORE-COMI] Veillette, M., Ed., Stok, P., Ed., Pelov, A., Bierman, A., and I. Petrov, "CoAP Management Interface (CORECONF)", Work in Progress, Internet-Draft, draft-ietf-core-comi-11, 17 January 2021, <https://datatracker.ietf.org/doc/html/ draft-ietf-core-comi-11>.
Okay so this is the informative reference list, and bestie, it's where the spec points you to all the extra reading material 📚✨ Our first stop is the CoAP Management Interface (CORECONF) draft, which is still a work in progress, lowkey very cool 🦋
[CORE-YANG-CBOR] Veillette, M., Ed., Petrov, I., Ed., and A. Pelov, "CBOR Encoding of Data Modeled with YANG", Work in Progress, Internet-Draft, draft-ietf-core-yang-cbor-16, 25 January 2021, <https://datatracker.ietf.org/doc/html/draft-ietf- core-yang-cbor-16>.
Next up is the draft on CBOR encoding of YANG-modeled data 🎀 Still a draft, so it's a work in progress, no cap 💅
[DOTS-EARLYDATA] Boucadair, M. and T. Reddy.K, "Using Early Data in DOTS", Work in Progress, Internet-Draft, draft-boucadair-dots- earlydata-00, 29 January 2019, <https://datatracker.ietf.org/doc/html/draft-boucadair- dots-earlydata-00>.
This one's about using early data in DOTS 🌸 It's an Internet-Draft, so it's still in progress.
[DOTS-MULTIHOMING] Boucadair, M., Reddy.K, T., and W. Pan, "Multi-homing Deployment Considerations for Distributed-Denial-of- Service Open Threat Signaling (DOTS)", Work in Progress, Internet-Draft, draft-ietf-dots-multihoming-07, 6 July 2021, <https://datatracker.ietf.org/doc/html/draft-ietf- dots-multihoming-07>.
Multi-homing deployment considerations for DOTS are covered here 🌈 Also still a work in progress.
[DOTS-TELEMETRY] Boucadair, M., Ed., Reddy.K, T., Ed., Doron, E., Chen, M., and J. Shallow, "Distributed Denial-of-Service Open Threat Signaling (DOTS) Telemetry", Work in Progress, Internet- Draft, draft-ietf-dots-telemetry-16, 8 December 2020, <https://datatracker.ietf.org/doc/html/draft-ietf-dots- telemetry-16>.
And the DOTS Telemetry draft is here 📊💜 Work in progress, same as the rest.
[IANA-CBOR-Tags] IANA, "Concise Binary Object Representation (CBOR) Tags", <https://www.iana.org/assignments/cbor-tags>.
IANA keeps the CBOR Tags registry, so go look there if you need it 🧚
[IANA-CoAP-Content-Formats] IANA, "CoAP Content-Formats", <https://www.iana.org/assignments/core-parameters>.
The CoAP Content-Formats are listed on IANA's core-parameters page 🍓
[IANA-MediaTypes] IANA, "Media Types", <https://www.iana.org/assignments/media-types>.
Media Types live on IANA's registry too 💖
[IANA-Proto] IANA, "Protocol Numbers", <https://www.iana.org/assignments/protocol-numbers>.
Protocol Numbers, also from IANA 🔥
[REG-DOTS] IANA, "Distributed Denial-of-Service Open Threat Signaling (DOTS) Signal Channel", <https://www.iana.org/assignments/dots>.
The DOTS Signal Channel registry is over here 👑
[RFC3022] Srisuresh, P. and K. Egevang, "Traditional IP Network Address Translator (Traditional NAT)", RFC 3022, DOI 10.17487/RFC3022, January 2001, <https://www.rfc-editor.org/info/rfc3022>.
RFC 3022 is the one on Traditional NAT, and it's a classic 🦋
[RFC4034] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, "Resource Records for the DNS Security Extensions", RFC 4034, DOI 10.17487/RFC4034, March 2005, <https://www.rfc-editor.org/info/rfc4034>.
RFC 4034 covers DNS Security Extensions resource records 🌸
[RFC4122] Leach, P., Mealling, M., and R. Salz, "A Universally Unique IDentifier (UUID) URN Namespace", RFC 4122, DOI 10.17487/RFC4122, July 2005, <https://www.rfc-editor.org/info/rfc4122>.
RFC 4122 is the UUID URN namespace one, and UUIDs are iconic 🫶
[RFC4340] Kohler, E., Handley, M., and S. Floyd, "Datagram Congestion Control Protocol (DCCP)", RFC 4340, DOI 10.17487/RFC4340, March 2006, <https://www.rfc-editor.org/info/rfc4340>.
RFC 4340 is DCCP, the Datagram Congestion Control Protocol ✨
[RFC4732] Handley, M., Ed., Rescorla, E., Ed., and IAB, "Internet Denial-of-Service Considerations", RFC 4732, DOI 10.17487/RFC4732, December 2006, <https://www.rfc-editor.org/info/rfc4732>.
RFC 4732 is all about Internet Denial-of-Service Considerations, which is very on-theme for DOTS 💀
[RFC4787] Audet, F., Ed. and C. Jennings, "Network Address Translation (NAT) Behavioral Requirements for Unicast UDP", BCP 127, RFC 4787, DOI 10.17487/RFC4787, January 2007, <https://www.rfc-editor.org/info/rfc4787>.
RFC 4787 covers NAT behavioral requirements for unicast UDP, and it's BCP 127 🎀
[RFC4960] Stewart, R., Ed., "Stream Control Transmission Protocol", RFC 4960, DOI 10.17487/RFC4960, September 2007, <https://www.rfc-editor.org/info/rfc4960>.
RFC 4960 is the Stream Control Transmission Protocol (SCTP) 💜
[RFC4987] Eddy, W., "TCP SYN Flooding Attacks and Common Mitigations", RFC 4987, DOI 10.17487/RFC4987, August 2007, <https://www.rfc-editor.org/info/rfc4987>.
RFC 4987 is about TCP SYN flooding attacks and how to mitigate them 🙈
[RFC5925] Touch, J., Mankin, A., and R. Bonica, "The TCP Authentication Option", RFC 5925, DOI 10.17487/RFC5925, June 2010, <https://www.rfc-editor.org/info/rfc5925>.
RFC 5925 is the TCP Authentication Option 🔐
[RFC6052] Bao, C., Huitema, C., Bagnulo, M., Boucadair, M., and X. Li, "IPv6 Addressing of IPv4/IPv6 Translators", RFC 6052, DOI 10.17487/RFC6052, October 2010, <https://www.rfc-editor.org/info/rfc6052>.
RFC 6052 covers IPv6 addressing for IPv4/IPv6 translators 🧚
[RFC6146] Bagnulo, M., Matthews, P., and I. van Beijnum, "Stateful NAT64: Network Address and Protocol Translation from IPv6 Clients to IPv4 Servers", RFC 6146, DOI 10.17487/RFC6146, April 2011, <https://www.rfc-editor.org/info/rfc6146>.
RFC 6146 is Stateful NAT64, translating from IPv6 clients to IPv4 servers 🌈
[RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)", RFC 6234, DOI 10.17487/RFC6234, May 2011, <https://www.rfc-editor.org/info/rfc6234>.
RFC 6234 is the US Secure Hash Algorithms one, SHA and friends 🔥
[RFC6296] Wasserman, M. and F. Baker, "IPv6-to-IPv6 Network Prefix Translation", RFC 6296, DOI 10.17487/RFC6296, June 2011, <https://www.rfc-editor.org/info/rfc6296>.
RFC 6296 is IPv6-to-IPv6 Network Prefix Translation ⭐
[RFC6724] Thaler, D., Ed., Draves, R., Matsumoto, A., and T. Chown, "Default Address Selection for Internet Protocol Version 6 (IPv6)", RFC 6724, DOI 10.17487/RFC6724, September 2012, <https://www.rfc-editor.org/info/rfc6724>.
RFC 6724 is default address selection for IPv6 🦋
[RFC6838] Freed, N., Klensin, J., and T. Hansen, "Media Type Specifications and Registration Procedures", BCP 13, RFC 6838, DOI 10.17487/RFC6838, January 2013, <https://www.rfc-editor.org/info/rfc6838>.
RFC 6838 covers media type specifications and registration procedures, and it's BCP 13 💅
[RFC6887] Wing, D., Ed., Cheshire, S., Boucadair, M., Penno, R., and P. Selkirk, "Port Control Protocol (PCP)", RFC 6887, DOI 10.17487/RFC6887, April 2013, <https://www.rfc-editor.org/info/rfc6887>.
RFC 6887 is the Port Control Protocol 🎀
[RFC6888] Perreault, S., Ed., Yamagata, I., Miyakawa, S., Nakagawa, A., and H. Ashida, "Common Requirements for Carrier-Grade NATs (CGNs)", BCP 127, RFC 6888, DOI 10.17487/RFC6888, April 2013, <https://www.rfc-editor.org/info/rfc6888>.
RFC 6888 has the common requirements for Carrier-Grade NATs, and it's BCP 127 too 🌸
[RFC7030] Pritikin, M., Ed., Yee, P., Ed., and D. Harkins, Ed., "Enrollment over Secure Transport", RFC 7030, DOI 10.17487/RFC7030, October 2013, <https://www.rfc-editor.org/info/rfc7030>.
RFC 7030 is Enrollment over Secure Transport 🔐
[RFC7413] Cheng, Y., Chu, J., Radhakrishnan, S., and A. Jain, "TCP Fast Open", RFC 7413, DOI 10.17487/RFC7413, December 2014, <https://www.rfc-editor.org/info/rfc7413>.
RFC 7413 is TCP Fast Open 🚀
[RFC7452] Tschofenig, H., Arkko, J., Thaler, D., and D. McPherson, "Architectural Considerations in Smart Object Networking", RFC 7452, DOI 10.17487/RFC7452, March 2015, <https://www.rfc-editor.org/info/rfc7452>.
RFC 7452 covers architectural considerations in smart object networking 🧚
[RFC7589] Badra, M., Luchuk, A., and J. Schoenwaelder, "Using the NETCONF Protocol over Transport Layer Security (TLS) with Mutual X.509 Authentication", RFC 7589, DOI 10.17487/RFC7589, June 2015, <https://www.rfc-editor.org/info/rfc7589>.
RFC 7589 is about using NETCONF over TLS with mutual X.509 authentication 🌈
[RFC7858] Hu, Z., Zhu, L., Heidemann, J., Mankin, A., Wessels, D., and P. Hoffman, "Specification for DNS over Transport Layer Security (TLS)", RFC 7858, DOI 10.17487/RFC7858, May 2016, <https://www.rfc-editor.org/info/rfc7858>.
RFC 7858 is the DNS over TLS spec 🔒
[RFC7951] Lhotka, L., "JSON Encoding of Data Modeled with YANG", RFC 7951, DOI 10.17487/RFC7951, August 2016, <https://www.rfc-editor.org/info/rfc7951>.
RFC 7951 is the JSON encoding of YANG-modeled data ⭐
[RFC8340] Bjorklund, M. and L. Berger, Ed., "YANG Tree Diagrams", BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018, <https://www.rfc-editor.org/info/rfc8340>.
RFC 8340 is YANG Tree Diagrams, and it's BCP 215 🌳
[RFC8484] Hoffman, P. and P. McManus, "DNS Queries over HTTPS (DoH)", RFC 8484, DOI 10.17487/RFC8484, October 2018, <https://www.rfc-editor.org/info/rfc8484>.
RFC 8484 is DNS Queries over HTTPS, DoH 🦋
[RFC8489] Petit-Huguenin, M., Salgueiro, G., Rosenberg, J., Wing, D., Mahy, R., and P. Matthews, "Session Traversal Utilities for NAT (STUN)", RFC 8489, DOI 10.17487/RFC8489, February 2020, <https://www.rfc-editor.org/info/rfc8489>.
RFC 8489 is STUN, Session Traversal Utilities for NAT 💖
[RFC8499] Hoffman, P., Sullivan, A., and K. Fujiwara, "DNS Terminology", BCP 219, RFC 8499, DOI 10.17487/RFC8499, January 2019, <https://www.rfc-editor.org/info/rfc8499>.
RFC 8499 is DNS Terminology, and it's BCP 219 📖
[RFC8612] Mortensen, A., Reddy, T., and R. Moskowitz, "DDoS Open Threat Signaling (DOTS) Requirements", RFC 8612, DOI 10.17487/RFC8612, May 2019, <https://www.rfc-editor.org/info/rfc8612>.
RFC 8612 has the DOTS Requirements, which is very much our topic 💜
[RFC8782] Reddy.K, T., Ed., Boucadair, M., Ed., Patil, P., Mortensen, A., and N. Teague, "Distributed Denial-of- Service Open Threat Signaling (DOTS) Signal Channel Specification", RFC 8782, DOI 10.17487/RFC8782, May 2020, <https://www.rfc-editor.org/info/rfc8782>.
RFC 8782 is the DOTS Signal Channel Specification, the one we're already in the thick of 🔥
[RFC8811] Mortensen, A., Ed., Reddy.K, T., Ed., Andreasen, F., Teague, N., and R. Compton, "DDoS Open Threat Signaling (DOTS) Architecture", RFC 8811, DOI 10.17487/RFC8811, August 2020, <https://www.rfc-editor.org/info/rfc8811>.
RFC 8811 is the DOTS Architecture, the big picture doc 🌸
[RFC8903] Dobbins, R., Migault, D., Moskowitz, R., Teague, N., Xia, L., and K. Nishizuka, "Use Cases for DDoS Open Threat Signaling", RFC 8903, DOI 10.17487/RFC8903, May 2021, <https://www.rfc-editor.org/info/rfc8903>.
RFC 8903 has the use cases for DDoS Open Threat Signaling 🧚
[RFC8973] Boucadair, M. and T. Reddy.K, "DDoS Open Threat Signaling (DOTS) Agent Discovery", RFC 8973, DOI 10.17487/RFC8973, January 2021, <https://www.rfc-editor.org/info/rfc8973>.
RFC 8973 covers DOTS Agent Discovery 🫶
[TLS-DTLS13] Rescorla, E., Tschofenig, H., and N. Modadugu, "The Datagram Transport Layer Security (DTLS) Protocol Version 1.3", Work in Progress, Internet-Draft, draft-ietf-tls- dtls13-43, 30 April 2021, <https://datatracker.ietf.org/doc/html/draft-ietf-tls- dtls13-43>.
DTLS 1.3 is the last one on the list, and it's still a work in progress 🌈
[URI] IANA, "Well-Known URIs", <https://www.iana.org/assignments/well-known-uris>.
And last but not least, IANA's Well-Known URIs registry 🎀
Appendix A. Summary of Changes From RFC 8782 ✨
okay so here's the tea on what changed compared to [RFC8782] 💅
- Update the
ietf-dots-signal-channelYANG module (Section 5.3) and the tree structure (Section 5.1) to follow the new YANG data structure specified in [RFC8791]. In particular:- Add in
choiceto indicate the communication direction in which a data node applies. If nochoiceis indicated, a data node can appear in both directions (i.e., from DOTS clients to DOTS servers and vice versa). - Remove
configclauses. Note thatconfigstatements will be ignored (if present) anyway, according to Section 4 of [RFC8791]. This supersedes the references to the use ofroandrw, which are now covered bychoiceabove. - Remove
cuid,cdid, andsiddata nodes from the structure because these data nodes are included as Uri-Path options, not within the message body. - Remove the list keys for the mitigation scope message type (i.e.,
cuidandmid).midis not indicated as a key because it is included as a Uri-Path option for requests and in the message body for responses. Note that Section 4 of [RFC8791] specifies that a list does not require to have a key statement defined.
- Add in
- Add a new section with a summary of the error code responses that can be returned by a DOTS server (Section 9). 🙌
- Update the IANA section to allocate a new range for comprehension-optional attributes (Section 10.6.1.1). This change is motivated by the need to allow for compact DOTS signal messages that include a long list of comprehension-optional attributes, e.g., DOTS telemetry messages [DOTS-TELEMETRY]. 📡
- Add Appendix C to list recommended/default values of key DOTS signal channel parameters. 🌸
- Add subsections to Section 4.4.1 for better readability. 📖
Appendix B. CUID Generation 🦋
so the document recommends using SPKI to generate the cuid, and honestly the reasons are chef's kiss 🤌
- SPKI is globally unique. 🌍
- It is deterministic. 🎯
- It allows the avoidance of extra cycles that may be induced by
cuidcollision. 🔁 - DOTS clients do not need to store the
cuidin a persistent storage. 💾 - It allows the detection of compromised DOTS clients that do not adhere to the
cuidgeneration algorithm. 🕵️♀️
Appendix C. Summary of Protocol Recommended/Default Values 💜
bestie, here's the cheat sheet of the recommended and default values for the key protocol parameters. Screenshot this one 📸
+================================+===========================+
| Parameter | Recommended/Default Value |
+================================+===========================+
| Port number | 4646 (tcp/udp) |
+--------------------------------+---------------------------+
| lifetime | 3600 seconds |
+--------------------------------+---------------------------+
| active-but-terminating | 120 seconds |
+--------------------------------+---------------------------+
| maximum active-but-terminating | 300 seconds |
+--------------------------------+---------------------------+
| heartbeat-interval | 30 seconds |
+--------------------------------+---------------------------+
| minimum 'heartbeat-interval' | 15 seconds |
+--------------------------------+---------------------------+
| maximum 'heartbeat-interval' | 240 seconds |
+--------------------------------+---------------------------+
| missing-hb-allowed | 15 |
+--------------------------------+---------------------------+
| max-retransmit | 3 |
+--------------------------------+---------------------------+
| ack-timeout | 2 seconds |
+--------------------------------+---------------------------+
| ack-random-factor | 1.5 |
+--------------------------------+---------------------------+
| probing-rate | 5 bytes/second |
+--------------------------------+---------------------------+
| trigger-mitigation | true |
+--------------------------------+---------------------------+
Table 13
Acknowledgements 🫶
Many thanks to Martin Björklund for the suggestion to use [RFC8791]. 🙏
Thanks to Valery Smyslov for the comments, guidance, and support. 💖
Thanks to Ebben Aries for the yangdoctors review, Dan Romascanu for the opsdir review, Michael Tuexen for the tsv-art review, Dale Worley for the genart review, and Donald Eastlake 3rd for the secdir review. 🎀
Thanks to Benjamin Kaduk for the AD review. ✨
Thanks to Martin Duke, Lars Eggert, Erik Kline, Murray Kucherawy, Éric Vyncke, and Robert Wilton for the IESG review. 👑
Acknowledgements from RFC 8782 🌈
Thanks to Christian Jacquenet, Roland Dobbins, Roman Danyliw, Michael Richardson, Ehud Doron, Kaname Nishizuka, Dave Dolson, Liang Xia, Gilbert Clark, Xialiang Frank, Jim Schaad, Klaus Hartke, Nesredien Suleiman, Stephen Farrell, and Yoshifumi Nishida for the discussion and comments. 💬
The authors would like to give special thanks to Kaname Nishizuka and Jon Shallow for their efforts in implementing the protocol and performing interop testing at IETF Hackathons. 🧚
Thanks to the core WG for the recommendations on Hop-Limit and redirect signaling. 🍓
Special thanks to Benjamin Kaduk for the detailed AD review. 🌟
Thanks to Alexey Melnikov, Adam Roach, Suresh Krishnan, Mirja Kuehlewind, and Alissa Cooper for the review. 💅
Thanks to Carsten Bormann for his review of the DOTS heartbeat mechanism. 🦋
Contributors 💜
The authors of RFC 8782 are listed below:
Tirumaleswar Reddy.K (editor)
McAfee, Inc.
Embassy Golf Link Business Park
Bangalore 560071
Karnataka
India
Email: kondtir@gmail.com
Mohamed Boucadair (editor)
Orange
35000 Rennes
France
Email: mohamed.boucadair@orange.com
Prashanth Patil
Cisco Systems, Inc.
Email: praspati@cisco.com
Andrew Mortensen
Arbor Networks, Inc.
2727 S. State Street
Ann Arbor, MI 48104
United States of America
Email: andrew@moretension.com
Nik Teague
Iron Mountain Data Centers
United Kingdom
Email: nteague@ironmountain.co.uk
The following individuals have contributed to RFC 8782:
Jon Shallow
NCC Group
Email: jon.shallow@nccgroup.trust
Mike Geller
Cisco Systems, Inc.
FL 33309
United States of America
Email: mgeller@cisco.com
Robert Moskowitz
HTT Consulting
Oak Park, MI 42837
United States of America
Email: rgm@htt-consult.com
Authors' Addresses 🌸
Mohamed Boucadair (editor)
Orange
35000 Rennes
France
Email: mohamed.boucadair@orange.com
Jon Shallow
United Kingdom
Email: supjps-ietf@jpshallow.com
Tirumaleswar Reddy.K
Akamai
Embassy Golf Link Business Park
Bangalore 560071
Karnataka
India
Email: kondtir@gmail.com
📦 where this page comes from
- ietf: rfc9132 2021-09
- 💖 girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms