RFC 7499

Support of Fragmentation of RADIUS Packets

๐Ÿ“… published April 2015, from ietf

RFC 7499: Support of Fragmentation of RADIUS Packets โœจ (Part 1 of 8)

  • Number and series: RFC 7499, Internet Engineering Task Force (IETF) ๐ŸŽ€
  • Category: Experimental, ISSN 2070-1721 ๐Ÿงš
  • Date: April 2015 ๐Ÿ“…
  • Authors: A. Perez-Mendez (Ed.), R. Marin-Lopez, F. Pereniguez-Garcia, G. Lopez-Millan (University of Murcia), D. Lopez (Telefonica I+D), A. DeKok (Network RADIUS) ๐Ÿ’œ
  • Obsoletes / Updates: the title block doesn't list any RFCs this one obsoletes or updates ๐ŸŒธ

Abstract

okay so RADIUS can only handle packets up to 4096 bytes total ๐Ÿ™ˆ there's already a way to split up big authentication data across packets using Access-Challenge, but there's nothing like that for big authorization data ๐Ÿ’€ this document explains how to use the RADIUS stuff that already exists to make that work โœจ it's mostly compatible with what people already run, and it's designed to be invisible to proxies and "fail-safe" for legacy RADIUS Clients and Servers ๐Ÿซถ


Status of This Memo

this one is not an Internet Standards Track spec ๐Ÿ’… it's published so people can look at it, try implementing it, and evaluate it ๐Ÿ”ฅ

it defines an Experimental Protocol for the Internet community โœจ it's a product of the IETF and reflects the IETF community's consensus ๐Ÿ’– it went through public review and got approved for publication by the Internet Engineering Steering Group (IESG) ๐Ÿ‘‘ not every IESG-approved document qualifies for any level of Internet Standard, so see Section 2 of RFC 5741 for that ๐Ÿงš

for the latest status, any errata, and how to send feedback, check http://www.rfc-editor.org/info/rfc7499 ๐Ÿฆ‹


Copyright (c) 2015 IETF Trust and the people listed as document authors ๐ŸŒˆ all rights reserved ๐Ÿ’…

this document is covered by BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they stand on the publication date ๐Ÿ“œ please read these carefully, because they spell out your rights and restrictions for this document ๐Ÿ™ˆ

if you pull Code Components out of this document, they have to include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions ๐Ÿ”ฅ they come without warranty, as the Simplified BSD License describes ๐Ÿ’–


Table of Contents

   1. Introduction ....................................................4
      1.1. Requirements Language ......................................6
   2. Status of This Document .........................................6
   3. Scope of This Document ..........................................7
   4. Overview .......................................................10
   5. Fragmentation of Packets .......................................13
      5.1. Pre-Authorization .........................................14
      5.2. Post-Authorization ........................................18
   6. Chunk Size .....................................................21
   7. Allowed Large Packet Size ......................................22
   8. Handling Special Attributes ....................................23
      8.1. Proxy-State Attribute .....................................23
      8.2. State Attribute ...........................................24
      8.3. Service-Type Attribute ....................................25
      8.4. Rebuilding the Original Large Packet ......................25
   9. New T Flag for the Long Extended Type Attribute Definition .....26
   10. New Attribute Definition ......................................26
      10.1. Frag-Status Attribute ....................................27
      10.2. Proxy-State-Length Attribute .............................28
      10.3. Table of Attributes ......................................29
   11. Operation with Proxies ........................................29
      11.1. Legacy Proxies ...........................................29
      11.2. Updated Proxies ..........................................29
   12. General Considerations ........................................31
      12.1. T Flag ...................................................31
      12.2. Violation of RFC 2865 ....................................32
      12.3. Proxying Based on User-Name ..............................32
      12.4. Transport Behavior .......................................33
   13. Security Considerations .......................................33
   14. IANA Considerations ...........................................34
   15. References ....................................................35
      15.1. Normative References .....................................35
      15.2. Informative References ...................................35
   Acknowledgements ..................................................37
   Authors' Addresses ................................................37

1. Introduction ๐ŸŽ€

okay so the RADIUS [RFC2865] protocol carries authentication, authorization, and accounting info between a RADIUS Client and a RADIUS Server ๐Ÿ’– everything travels in RADIUS packets, and each one is a header plus zero or more attributes, capped at a maximum packet size of 4096 bytes ๐Ÿ“ฆ it's a request/response protocol, which is described in the operational model ([RFC6158], Section 3.1) โœจ

that 4096-byte cap was there to avoid UDP fragmentation as much as possible ๐Ÿงš back then, 4096 bytes seemed big enough for literally anything ๐Ÿ’€ but now there are new scenarios that need to exchange authorization info over that 4096-byte limit ๐Ÿ‘‘ for example, the Application Bridging for Federated Access Beyond web (ABFAB) IETF working group defines carrying Security Assertion Markup Language (SAML) statements from the RADIUS Server to the RADIUS Client [SAML-RADIUS] ๐Ÿฆ‹ that assertion is likely to be bigger than 4096 bytes ๐Ÿ™ˆ

so peers that want to send a lot of data have to split it across multiple packets ๐Ÿงฉ for instance, RADIUS-EAP [RFC3579] defines how an Extensible Authentication Protocol (EAP) exchange happens across multiple Access-Request / Access-Challenge sequences ๐Ÿซถ nothing like that exists for accounting or authorization data ๐Ÿ˜ญ [RFC6158], Section 3.1 suggests that sending big chunks of authorization data isn't needed in RADIUS, and that the data should be referenced by name instead ๐ŸŒธ that lets large policies get pre-provisioned and then referenced in an Access-Accept ๐Ÿ’… but sometimes the authorization data from the RADIUS Server is large and highly dynamic ๐ŸŒช๏ธ other times the RADIUS Client needs to send lots of authorization data to the RADIUS Server ๐Ÿ“ neither case is covered by the requirements in [RFC6158] ๐Ÿ’€ as that document notes, the practical limit on RADIUS packet sizes is set by the Path MTU (PMTU), which can be way smaller than 4096 bytes ๐Ÿ˜ญ put those two limits together and there's a pressing need for a way to send large amounts of authorization data between RADIUS Client and Server, and there's no solution for it yet ๐Ÿ”ฅ

[RFC6158], Section 3.1 recommends three approaches for sending large amounts of data within RADIUS ๐Ÿง  but they don't fit the problem this document is solving, for these reasons:

  • The first approach (utilization of a sequence of packets) doesn't cover large amounts of data sent from the RADIUS Client to a RADIUS Server ๐Ÿ™…โ€โ™€๏ธ using EAP (request/challenge) to send the data isn't feasible, because EAP already fills packets up to PMTU and not every authentication uses EAP ๐Ÿ’€ also, as noted for the NAS-Filter-Rule attribute ([RFC4849]), this approach doesn't fully solve sending large amounts of data from a RADIUS Server to a RADIUS Client, since lots of current RADIUS attributes aren't allowed in Access-Challenge packets ๐Ÿ˜ค
  • The second approach (utilization of names rather than values) isn't usable either ๐Ÿฅฒ names are hard to use when the data is highly dynamic (like a SAML statement or NAS-Filter-Rule attributes) ๐ŸŒ€ URLs could point to where the actual data lives, but they'd need to be (a) dynamically created and modified, (b) securely accessed, and (c) accessible from remote systems ๐ŸŒ meeting those constraints would mean changing several networking systems (like firewalls and web servers) ๐Ÿงฑ and you'd also need extra trust infrastructure, such as a Public Key Infrastructure (PKI), to securely retrieve the info from the web server ๐Ÿ”
  • PMTU discovery doesn't solve it, because it doesn't allow sending data bigger than the minimum of (PMTU or 4096) bytes ๐Ÿ“‰

this document gives RADIUS peers a mechanism to swap large amounts of authorization data beyond the 4096-byte limit by splitting it across several exchanges ๐Ÿฆ‹ the proposed solution doesn't add any new requirements for RADIUS system administrators (no firewall rule changes, no web server setup, no router configs, no app server changes) ๐Ÿ™Œ it stays compatible with intra-packet fragmentation mechanisms (like those in [RFC3579] or [RFC6929]) ๐Ÿซถ it's also transparent to existing RADIUS proxies, which don't implement this specification ๐Ÿงš the only systems that need to implement this RFC are the ones that either generate or consume the fragmented data being sent ๐Ÿ’– intermediate proxies just pass the packets along without changes ๐ŸŽ€ that said, if a proxy does support this specification, it may reassemble the data so it can examine and/or modify it โœจ

there's a different approach for RADIUS packets above the 4096-byte limit, described in [RADIUS-Larger-Pkts] ๐ŸŒˆ it proposes extending RADIUS over TCP by letting the Length field in the RADIUS header take values up to 65535 bytes ๐Ÿ“ that's simpler to operate, but the drawback is that every RADIUS proxy on the path between the RADIUS Client and the RADIUS Server has to implement that extension too ๐Ÿ˜ฌ

1.1. Requirements Language

the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119] ๐Ÿ“š when these words show up in lower case, they just have their normal natural-language meaning ๐Ÿซถ

to be continuedโ€ฆ part 2 is coming, bestie ๐Ÿ’œ๐Ÿฆ‹

2. Status of This Document โœจ

okay so this one is an Experimental RFC ๐Ÿงช It proposes a way to send and receive data bigger than the 4096-byte limit that [RFC2865] puts on RADIUS packets, and it does that without anyone having to modify the intermediary proxies ๐Ÿซถ

The experiment is basically checking whether this approach actually works in a huge, real-life environment. Like, are people picking it up, is it easy to use, and how does it behave when it's running in big real deployments? ๐Ÿ‘€ So far the main use case is carrying big SAML statements from the ABFAB architecture [ABFAB-Arch]. So if you're piloting an ABFAB deployment, you can test it right there ๐Ÿ’…

There's also a bunch of experimental features that need testing before this can even be considered for the Standards Track ๐Ÿ”ฅ

First up, this proposal wants to update [RFC2865] so it can relax the rule in Section 4.1 of that doc that says "An Access-Request MUST contain either a User-Password or a CHAP-Password or a State." ๐Ÿ˜ญ That means this spec might generate Access-Request packets with none of those attributes. The implementations out there are all living by "be liberal in what you accept," but we still need real operational experience to confirm that unmodified proxies don't drop these packets. More on this in Section 12.2 ๐ŸŒธ

Another experimental feature: this spec requires proxies to base their routing decisions on the value of the RADIUS User-Name attribute. From what they've seen, that's already the common behavior, so no issues are expected ๐Ÿฆ‹ But it has to be confirmed across different implementations of intermediate proxies. More on this in Section 12.3 โœจ

Then there are two minor updates to Standards Track documents ๐Ÿ‘‘ First, this doc changes the definition of the Reserved field of the Long Extended Type attribute [RFC6929] by adding a new flag called the T (Truncation) flag. No issues are expected from this, although some proxies might drop packets that don't have the Reserved field set to 0. More on this in Section 12.1 ๐ŸŽ€

The other Standards Track doc needing a minor update is [RFC6158]. It says "attribute designers SHOULD NOT assume that a RADIUS implementation can successfully process RADIUS packets larger than 4096 bytes," which stops being true if this document advances ๐Ÿ™ˆ

When and if the experiment succeeds and this doc gets reissued as a Standards Track document, a proper "Updates" clause will be added for all of these changes ๐Ÿงš


3. Scope of This Document ๐ŸŒˆ

okay this section is the "what is this even for" part and it's giving boundaries ๐Ÿ’…

This spec describes how a RADIUS Client and a RADIUS Server can swap data that goes past the 4096-byte limit of a single packet. BUT the mechanism here SHOULD NOT be used to exchange more than 100 kilobytes of data ๐Ÿ˜ญ Any more than that and RADIUS starts turning into a generic transport protocol like TCP or the Stream Control Transmission Protocol (SCTP), and that's undesirable ๐Ÿ’€ Experience has shown that trying to move bulk data across the Internet over UDP will inevitably fail, unless you rebuild all of TCP's behavior from scratch. RADIUS just doesn't have the retransmission policies or congestion control mechanisms that would let it compete with TCP ๐Ÿซ 

So RADIUS/UDP transport is, by design, unable to carry bulk data. Changing the protocol at this point is both undesirable and impossible ๐Ÿ™…โ€โ™€๏ธ This spec only exists so that more than 4096 bytes can get through existing RADIUS/UDP proxies. If someone's building a "green field" deployment that needs bulk data, other solutions such as RADIUS/TCP MUST be used ๐ŸŒธ

Section 7, below, goes deeper into what counts as a reasonable amount of data. It also recommends that administrators adjust data transfer limits based on what their existing systems can actually handle in terms of memory and processing power ๐Ÿง 

The scope is also limited to exchanging authorization data, because other exchanges don't need this mechanism ๐Ÿซถ Authentication exchanges already have ways around the limit (RADIUS-EAP, for example). And since authentication is the most critical part of a RADIUS conversation, it's preferable not to touch its operation in any way that could affect existing equipment ๐Ÿ”’

Accounting packets don't need fragmentation either ๐Ÿ’– Accounting can send lots of data, but that data is usually made of many small updates. There's no demonstrated need to send indivisible blocks bigger than 4 kilobytes. The need for huge amounts of data per session mostly comes from flow-based accounting, where the RADIUS Client might send accounting data for many thousands of flows, all tied to one user session. The existing Acct-Multi-Session-Id attribute defined in [RFC2866], Section 5.11 has been proven to work here โœจ

Same deal for Change-of-Authorization (CoA) [RFC5176] packets. There's no need to fragment them. Instead, according to [RFC5176], the CoA client sends a CoA-Request packet containing session identification attributes, along with Service-Type = Additional-Authorization and a State attribute ๐Ÿฆ‹ Implementations that don't support fragmentation respond with a CoA-NAK and an Error-Cause of Unsupported-Service ๐Ÿ™ˆ

The above requirement doesn't assume that the CoA client and the RADIUS Server are co-located. They could be running on totally separate parts of the infrastructure, or even run by separate administrators ๐ŸŒ There is however a requirement that the two can talk to each other. The CoA client needs session identification attributes to send CoA packets, and it can't know those a priori. They can only come from the RADIUS Server. So even when the two systems aren't co-located, they must be able to communicate in order to operate in unison. The alternative is the two systems having different views of the users' authorization parameters, and that would be a security disaster ๐Ÿšจ๐Ÿ˜ฑ

This spec doesn't allow fragmentation of CoA packets ๐Ÿ™…โ€โ™€๏ธ Allowing it would mean changing multiple parts of the RADIUS protocol, and those changes bring the risk of implementation issues, mistakes, and so on ๐Ÿฅด

Now, when CoA clients (i.e., RADIUS Servers) need to send large amounts of authorization data to a CoA server (i.e., RADIUS Client), they only need to send a minimal CoA-Request packet. It contains a Service-Type of Authorize Only, as per [RFC5176], plus session identification attributes ๐ŸŽ€ That CoA packet is just a signal to the RADIUS Client that the user's session needs re-authorization. Then, when the RADIUS Client re-authorizes the user via Access-Request, the RADIUS Server can do the fragmentation and send all that large authorization data to the RADIUS Client ๐Ÿ’œ

The assumption in this scenario is that the CoA client and RADIUS Server are co-located, or at least strongly coupled. The path from CoA client to CoA server SHOULD be the exact reverse of the path from RADIUS Client to RADIUS Server ๐Ÿ” This diagram should make the roles click:

                              +----------------+
                              | RADIUS   CoA   |
                              | Client  Server |
                              +----------------+
                                 |        ^
                 Access-Request  |        |   CoA-Request
                                 v        |
                              +----------------+
                              | RADIUS   CoA   |
                              | Server  Client |
                              +----------------+

And when there's a proxy involved:

                              +----------------+
                              | RADIUS   CoA   |
                              | Client  Server |
                              +----------------+
                                 |        ^
                 Access-Request  |        |   CoA-Request
                                 v        |
                              +----------------+
                              | RADIUS   CoA   |
                              | Proxy   Proxy  |
                              +----------------+
                                 |        ^
                 Access-Request  |        |   CoA-Request
                                 v        |
                              +----------------+
                              | RADIUS   CoA   |
                              | Server  Client |
                              +----------------+

So the RADIUS and CoA subsystems at each hop are strongly connected ๐Ÿ”— And if they aren't strongly connected, it'll be impossible to use CoA-Request packets to transport large amounts of authorization data ๐Ÿ˜ฌ

Is this design more complicated than just allowing fragmented CoA packets? Yes, ngl ๐Ÿฅฒ But the CoA client and the RADIUS Server have to communicate even when this spec isn't being used. The authors believe that standardizing that communication, and using one method for exchanging large data, beats unspecified communication methods and multiple ways of getting the same result ๐Ÿซถ Allowing fragmentation over CoA packets would make this spec a lot bigger and way more complex ๐Ÿ“š

The above requirement also solves a few issues. It clearly separates session identification from authorization โœ‚๏ธ Without that separation, it's hard to both identify a session and change its authorization using the same attribute. It also makes sure the authorization process is the same for initial authentication and for CoA ๐Ÿ‘‘

4. Overview ๐Ÿ’…

Okay so, authorization can happen before or after the end user finishes authenticating ๐Ÿซถ. A pre-authorization exchange lets a RADIUS Client tell the RADIUS Server stuff that MAY modify how the authentication process gets done. Like, it can affect which EAP method gets picked ๐Ÿฆ‹. A post-authorization exchange flips it: the RADIUS Server tells the RADIUS Client about the end user, the results of the authentication, and/or obligations to be enforced โœจ. In this spec, "pre-authorization" means authorization info going from the RADIUS Client to the RADIUS Server before end-user authentication has started, and "post-authorization" means the exchange going from the RADIUS Server to the RADIUS Client after that authentication process happens ๐Ÿ’œ.

Now the size limit ๐Ÿ“. That's the practical limit on RADIUS packet sizes, and it's the minimum of 4096 bytes and the current PMTU ๐ŸŒธ. The method we're defining uses Access-Request and Access-Accept to swap fragmented data around ๐Ÿ”ฅ. The RADIUS Client and Server trade a series of Access-Request / Access-Accept packets until all the fragmented data has been moved over ๐Ÿงš. Every packet has a Frag-Status attribute, which lets the other party know if fragmentation is desired, ongoing, or finished ๐Ÿ’…. A packet may also carry fragmented data, or it may just be an "ACK" for a previous fragment from the other party ๐Ÿซถ.

Every Access-Request has a User-Name attribute, so the packet can be proxied if necessary (see Section 11.1) ๐Ÿฆ‹. An Access-Request may also have a State attribute, which ties it to a previous Access-Accept ๐ŸŽ€. Every Access-Accept has a State attribute too, for the RADIUS Client to use in a later Access-Request ๐Ÿ’œ. Each Access-Accept also has a Service-Type attribute with the "Additional-Authorization" value ๐Ÿ‘‘. That means the service is part of a fragmented exchange, and the Access-Accept should not be read as giving the end user network access ๐Ÿ™ˆ.

When a RADIUS Client or RADIUS Server needs to send data that's over the size limit, this document's mechanism kicks in ๐ŸŒˆ. Instead of cramming everything into one giant RADIUS packet, we send a bunch of smaller RADIUS packets of the same type โœจ. Each little packet is called a "chunk" in this spec, so it doesn't get mixed up with traditional RADIUS packets ๐Ÿ“. The encoding process is a simple linear walk over the attributes being encoded, and this walk keeps the order of attributes of the same type, as required by [RFC2865] ๐ŸŽ€. How many attributes fit in one chunk depends on the size limit, the size of each attribute, the number of proxies between the RADIUS Client and RADIUS Server, and the overhead for fragmentation-signaling attributes ๐Ÿงฎ. Specific details are in Section 6 ๐Ÿ’–. A brand-new attribute called Frag-Status (Section 10.1) is what signals the fragmentation status ๐Ÿฆ‹.

Once the first chunk is encoded, it gets sent to the other party ๐Ÿ“จ. The packet is identified as a chunk via the Frag-Status attribute ๐Ÿ’œ. The other party then asks for more chunks, again using the Frag-Status attribute ๐Ÿซถ. This keeps going until every attribute has been sent from one party to the other ๐Ÿš€. When all the chunks have arrived, the original list of attributes is rebuilt and processed as if it had come in one packet ๐Ÿ‘‘.

Rebuilding is super simple: you just append all the chunks together ๐Ÿงฉ. Unlike IPv4 fragmentation, there's no Fragment Offset field ๐Ÿ™…โ€โ™€๏ธ. The chunks here are explicitly ordered, because RADIUS is a lock-step protocol, as noted in Section 12.4 ๐Ÿ”’. What that means is chunk N+1 can't be sent until every chunk up to and including N has been received and acknowledged ๐Ÿ’….

When multiple chunks are sent, something special can happen to Long Extended Type attributes as defined in [RFC6929] ๐Ÿ˜ญ. The fragmentation process might split a fragmented attribute across two or more chunks, and that's not permitted by that specification ๐Ÿ’€. To fix this, we use the newly defined T flag in the Reserved field of the Long Extended Type attribute format (see Section 9 for more on this flag) โœจ.

This last situation is expected to be the most common one in chunks ๐ŸŒธ. Usually, packet fragmentation happens because someone wants to send one or more large (and therefore fragmented) attributes ๐Ÿ“. The large attribute will most likely get split into two or more pieces ๐Ÿง. Where chunking doesn't split a fragmented attribute, no special treatment is needed ๐ŸŽ€.

Setting the T flag is the only case where the chunking process changes the content of an attribute ๐Ÿฆ‹. Even then, the Value fields of all attributes stay unchanged ๐Ÿ’œ. Any per-packet security attributes, such as Message-Authenticator, are calculated for each chunk independently ๐Ÿ”. Integrity checks and security checks are not performed on the "original" packet ๐Ÿ™ˆ.

Each RADIUS packet sent or received as part of the chunking process MUST be a valid packet, subject to all format and security requirements ๐Ÿ’–. This is what lets a "transparent" proxy that doesn't implement this specification still receive and send compliant packets ๐Ÿซถ. In other words, a proxy that just forwards packets, without looking inside or changing anything, will be able to proxy "chunks" ๐Ÿš€.


5. Fragmentation of Packets ๐Ÿงฉ

When the RADIUS Client or the RADIUS Server wants to send a packet that's over the size limit, it gets split into chunks and sent through multiple client/server exchanges ๐Ÿ“ฆ. The exchange is indicated by the Frag-Status attribute, which has the value More-Data-Pending for all but the last chunk in the series ๐Ÿ’ซ. The chunks are tied together with the State attribute ๐ŸŽ€.

Delivering a big fragmented RADIUS packet with authorization data can happen before or after the RADIUS Server has authenticated the end user ๐Ÿ”‘. We can split it into two phases, and either one can be skipped if there's no authorization data to send ๐ŸŒˆ:

  1. Pre-authorization. In this phase, the RADIUS Client MAY send a large packet with authorization information to the RADIUS Server before the end user is authenticated. Only the RADIUS Client is allowed to send authorization data during this phase ๐Ÿฆ‹.
  2. Post-authorization. In this phase, the RADIUS Server MAY send a large packet with authorization data to the RADIUS Client after the end user has been authenticated. Only the RADIUS Server is allowed to send authorization data during this phase ๐Ÿ‘‘.

The following subsections describe how to do fragmentation for packets in these two phases ๐Ÿ’…. We give the packet type, along with a RADIUS Identifier, to show that requests and responses are connected ๐Ÿ”—. Then we give a list of attributes ๐Ÿ“. We don't give values for most attributes, because we want to focus on the fragmentation behavior rather than the packet contents ๐Ÿ™ˆ. Attribute values are only given for attributes relevant to the fragmentation process ๐Ÿซถ. Where "long extended" attributes are used, we show the M (More) and T (Truncation) flags as optional square brackets after the attribute name ๐Ÿ“. Since no "long extended" attributes have been defined yet, we use example attributes named Example-Long-1, etc. โœจ For the sake of simplicity, the maximum chunk size is set in terms of the number of attributes (11) ๐Ÿ’–.

5.1. Pre-Authorization โœจ

okay so bestie, this is the chunking part ๐Ÿ’– When the RADIUS Client needs to send a huge amount of data to the RADIUS Server, it slices the data into chunks and sends them over multiple Access-Request / Access-Accept exchanges ๐Ÿฆ‹ Here's how that whole dance goes.

First up is the Access-Request the RADIUS Client wants to send ๐ŸŽ€ But between the PMTU, the big attributes, and everything else, it's way too much for one packet ๐Ÿ˜ญ

Access-Request
    User-Name
    NAS-Identifier
    Calling-Station-Id
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1
    Example-Long-2 [M]
    Example-Long-2 [M]
    Example-Long-2

Figure 1: Desired Access-Request

So the RADIUS Client has to send those attributes in a series of chunks ๐Ÿงš The first chunk holds eight (8) attributes from the original Access-Request, plus a Frag-Status attribute. The last attribute is "Example-Long-1" with the M flag set, so the chunking process also sets the T flag on that attribute ๐Ÿ’… This Access-Request gets a RADIUS Identifier field with value 23. The Frag-Status attribute has value More-Data-Pending, which basically says "hey, I've got more coming in a later Access-Request" ๐ŸŒธ The client also adds a Service-Type attribute to show this packet is part of the chunking process. Then it gets signed with the Message-Authenticator attribute, and that fills up the maximum of eleven (11) attributes ๐Ÿ™ˆ

Access-Request (ID = 23)
    User-Name
    NAS-Identifier
    Calling-Station-Id
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [MT]
    Frag-Status = More-Data-Pending
    Service-Type = Additional-Authorization
    Message-Authenticator

Figure 2: Access-Request (Chunk 1)

Compliant RADIUS Servers (i.e., servers implementing fragmentation) receiving this packet will see the Frag-Status attribute and will postpone all authorization and authentication handling until all of the chunks have been received. This postponement also applies to the verification that the Access-Request packet contains some kind of authentication attribute (e.g., User-Password, CHAP-Password, State, or other future attribute), as required by [RFC2865] (see Section 12.2 for more information on this). ๐Ÿฆ‹

Non-compliant servers (the ones that don't do fragmentation) are a whole different story ๐Ÿ’€ Non-compliant RADIUS Servers (i.e., servers not implementing fragmentation) should also see the Service-Type requesting provisioning for an unknown service and return Access-Reject. Other non-compliant RADIUS Servers may return an Access-Reject or Access-Challenge, or they may return an Access-Accept with a particular Service-Type other than Additional-Authorization. Compliant RADIUS Client implementations MUST treat these responses as if they had received Access-Reject instead. So even the weird responses get treated as a reject, periodt ๐Ÿ‘‘

Compliant RADIUS Servers who want to receive all of the chunks reply with the packet below ๐ŸŒˆ The State value here is arbitrary and only exists as a unique token for example purposes. Just know that it MUST be temporally unique to the RADIUS Server โœจ

Access-Accept (ID = 23)
    Frag-Status = More-Data-Request
    Service-Type = Additional-Authorization
    State = 0xabc00001
    Message-Authenticator

Figure 3: Access-Accept (Chunk 1)

The RADIUS Client sees this response and uses the RADIUS Identifier field to link it to an ongoing chunking session ๐Ÿซถ Compliant RADIUS Clients then keep the chunking going. Non-compliant RADIUS Clients never see a response like this, because they never send a Frag-Status attribute ๐Ÿ™ˆ The Service-Type attribute is in the Access-Accept to signal that this response is part of the chunking process. So this packet doesn't provision any network service for the end user, bestie ๐ŸŒธ

Next, the client sends the next chunk, which brings along six (6) more attributes from the original packet ๐ŸŽ€ It includes the User-Name attribute again, so non-compliant proxies can still process the packet (see Section 11.1) ๐Ÿ’– It sets Frag-Status to More-Data-Pending, because more data is still waiting. It includes a Service-Type for the reasons we just covered โœจ It also carries the State attribute from the previous Access-Accept. It gets signed with Message-Authenticator, since there are no authentication attributes in this packet. And it uses a brand new RADIUS Identifier field ๐Ÿฆ‹

Access-Request (ID = 181)
    User-Name
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1
    Example-Long-2 [M]
    Example-Long-2 [MT]
    Frag-Status = More-Data-Pending
    Service-Type = Additional-Authorization
    State = 0xabc000001
    Message-Authenticator

Figure 4: Access-Request (Chunk 2)

Compliant RADIUS Servers receiving this packet see the Frag-Status attribute and go looking for a State attribute ๐Ÿ”ฅ Since one exists and it matches a State from an earlier Access-Accept, this packet is part of a chunking process ๐Ÿ’… The RADIUS Server associates these attributes with the previous chunk. Because the Frag-Status attribute has value More-Data-Request, the RADIUS Server answers with an Access-Accept, same as before. It MUST include a State attribute with a value that's different from the previous Access-Accept. This State MUST again be globally and temporally unique ๐ŸŒˆ

Access-Accept (ID = 181)
    Frag-Status = More-Data-Request
    Service-Type = Additional-Authorization
    State = 0xdef00002
    Message-Authenticator

Figure 5: Access-Accept (Chunk 2)

The RADIUS Client sees this response and uses the RADIUS Identifier field to link it to the ongoing chunking session ๐Ÿซถ Then it sends the next chunk, which carries the final attribute(s) from the original packet, and it again includes the original User-Name attribute ๐ŸŽ€ This time there's no Frag-Status attribute, because there are no more chunks left to send ๐Ÿ˜Œ The client includes the State attribute from the previous Access-Accept, signs the packet with Message-Authenticator (there are no authentication attributes in it), and uses yet another new RADIUS Identifier field ๐Ÿฆ‹

Access-Request (ID = 241)
    User-Name
    Example-Long-2
    State = 0xdef00002
    Message-Authenticator

Figure 6: Access-Request (Chunk 3)

When this last chunk lands, the RADIUS Server matches it to the ongoing session using the State attribute and notices there's no Frag-Status attribute ๐Ÿ‘‘ It then processes the received attributes as if they had all arrived in one RADIUS packet. See Section 8.4 for further details on this process. The server generates the appropriate response, which can be either Access-Accept or Access-Reject. In this example it's an Access-Accept ๐Ÿฅฐ The RADIUS Server MUST send a State attribute, which lets the received data get linked to the authentication process ๐Ÿ’œ

Access-Accept (ID = 241)
    State = 0x98700003
    Message-Authenticator

Figure 7: Access-Accept (Chunk 3)


That's the whole chunking process in practice, bestie ๐Ÿงš Now let's reiterate the implementation and security requirements, because they're super important ๐Ÿ˜ญ

Each chunk is a valid RADIUS packet (see Section 12.2 for some considerations about this), and all RADIUS format and security requirements MUST be followed before any chunking process is applied. Think of it like this: every chunk has to be legit on its own before anyone starts splitting things up ๐Ÿ”

Every chunk except for the last one from a RADIUS Client MUST include a Frag-Status attribute, with value More-Data-Pending. The last chunk MUST NOT contain a Frag-Status attribute. Each chunk except for the last one from a RADIUS Client MUST include a Service-Type attribute, with value Additional-Authorization. Each chunk MUST include a User-Name attribute, which MUST be identical in all chunks. Each chunk except for the first one from a RADIUS Client MUST include a State attribute, which MUST be copied from a previous Access-Accept. ๐ŸŽ€

Each Access-Accept MUST include a State attribute. The value for this attribute MUST change in every new Access-Accept and MUST be globally and temporally unique. That's the fuel for the whole chunking queen era ๐Ÿ‘‘๐ŸŒธ

5.2. Post-Authorization โœจ

okay so when the RADIUS Server wants to send a big pile of authorization data to the RADIUS Client after authentication, it's basically the same vibe as pre-authorization ๐Ÿ’…. The presence of a Service-Type = Additional-Authorization attribute makes sure a RADIUS Client that doesn't support this spec treats that unrecognized Service-Type as if an Access-Reject had been received instead ([RFC2865], Section 5.6). If the original big Access-Accept had a Service-Type attribute, it gets included with its original value in the last chunk, so it doesn't get mixed up with the one used for fragmentation signaling ๐Ÿซถ. It is RECOMMENDED that RADIUS Servers include a State attribute in their original Access-Accept packets, even if fragmentation isn't happening, so the RADIUS Client can send more authorization data in later exchanges โœจ. That State attribute gets included in the last chunk too, to avoid confusion with the ones used for fragmentation signaling.

Clients supporting this spec MUST include a Frag-Status = Fragmentation-Supported attribute in the first Access-Request they send to the RADIUS Server. This tells the server they'd accept fragmented data from it ๐ŸŽ€. It's not required if pre-authorization was already carried out, since it's implicit.

Here's an Access-Accept the RADIUS Server wants to send to a RADIUS Client. BUT due to a combo of issues (PMTU, large attributes, etc.), the content doesn't fit into one Access-Accept packet ๐Ÿ˜ญ.

Access-Accept
    User-Name
    EAP-Message
    Service-Type = Login
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1
    Example-Long-2 [M]
    Example-Long-2 [M]
    Example-Long-2
    State = 0xcba00003

                   Figure 8: Desired Access-Accept

So the RADIUS Server has to send those attributes in a series of chunks ๐Ÿงš. The first chunk has seven (7) attributes from the original Access-Accept, plus a Frag-Status attribute. Since the last attribute is "Example-Long-1" with the M flag set, the chunking process also sets the T flag in that attribute. The Access-Accept goes out with a RADIUS Identifier field of 30, matching a previous Access-Request that isn't shown here. The Frag-Status attribute has the value More-Data-Pending, which means the server wants to send more data in a later Access-Accept. The server also adds a Service-Type attribute with the value Additional-Authorization, showing this packet is part of the chunking process. The original Service-Type is NOT included in this chunk, bestie. Finally, a State attribute is added so later requests can be matched to this conversation, and the packet is signed with the Message-Authenticator attribute. That makes it the maximum of 11 attributes ๐Ÿ”ฅ.

Access-Accept (ID = 30)
    User-Name
    EAP-Message
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [MT]
    Frag-Status = More-Data-Pending
    Service-Type = Additional-Authorization
    State = 0xcba00004
    Message-Authenticator

                  Figure 9: Access-Accept (Chunk 1)

Compliant RADIUS Clients that receive this packet will see the Frag-Status attribute and suspend all authorization handling until every chunk has arrived ๐Ÿซง. Non-compliant RADIUS Clients should also see the Service-Type that signals provisioning for an unknown service, and they'll treat it as an Access-Reject ๐Ÿ’€.

RADIUS Clients that want all of the chunks reply with the packet below, and the State attribute value is taken from the received Access-Accept. They also include the User-Name attribute so non-compliant proxies can process the packet (Section 11.1) ๐Ÿ“.

Access-Request (ID = 131)
    User-Name
    Frag-Status = More-Data-Request
    Service-Type = Additional-Authorization
    State = 0xcba00004
    Message-Authenticator

                 Figure 10: Access-Request (Chunk 1)

The RADIUS Server gets this request and uses the State attribute to tie it to an ongoing chunking session. Compliant RADIUS Servers then keep the chunking process going. Non-compliant RADIUS Servers will never see a response like this, because they never send a Frag-Status attribute ๐Ÿ™ˆ.

The RADIUS Server continues by sending the next chunk, which has the final attribute(s) from the original packet. The Identifier field value is taken from the received Access-Request. A Frag-Status attribute is NOT included in this next Access-Accept, since no more chunks are coming ๐Ÿ‘‘. The RADIUS Server includes the original State attribute so the RADIUS Client can send more authorization data. The original Service-Type attribute is included as well.

Access-Accept (ID = 131)
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1 [M]
    Example-Long-1
    Example-Long-2 [M]
    Example-Long-2 [M]
    Example-Long-2
    Service-Type = Login
    State = 0xfda000003
    Message-Authenticator

                 Figure 11: Access-Accept (Chunk 2)

When the RADIUS Client gets this last chunk, it matches it to an ongoing session using the Identifier field and sees there's no Frag-Status attribute. It then processes all the received attributes as if they'd come in one RADIUS packet. See Section 8.4 for more on that ๐Ÿฆ‹.

6. Chunk Size

In a perfect world, every intermediate chunk would be exactly the size limit ๐ŸŒˆ. That way, the number of round trips needed to send a large packet would be optimal. Sadly, that's not possible, for several reasons ๐Ÿ˜ญ.

  1. RADIUS attributes have a variable length and must be included completely in a chunk. So even if there's some free space in the chunk, it might not be enough for the next attribute. This can leave up to 254 bytes of spare space in every chunk.
  2. RADIUS fragmentation needs some extra attributes for signaling. A Frag-Status attribute (7 bytes) is included in every chunk of a packet, EXCEPT the last one. A RADIUS State attribute (from 3 to 255 bytes) is also included in most chunks, so the RADIUS Server can bind an Access-Request with a previous Access-Challenge. User-Name attributes (from 3 to 255 bytes) are included in every chunk the RADIUS Client sends, because proxies require them to route the packet to its destination. Together, these attributes can generate from up to 13 to 517 bytes of signaling data, which cuts down the amount of payload that fits in each chunk ๐Ÿงšโ€โ™€๏ธ.
  3. RADIUS packets SHOULD be adjusted to avoid exceeding the network MTU. Otherwise, IP fragmentation may occur, with undesirable consequences. So the maximum chunk size would be decreased from 4096 to the actual MTU of the network.
  4. Proxy-State attributes added by intermediary proxies can reduce the usable space in the chunk. This is described in further detail in Section 8.1 ๐Ÿซถ.

7. Allowed Large Packet Size

There are no provisions for signaling how much data is sent via the fragmentation process as a whole. It's hard to define what "length" even means for fragmented data ๐Ÿค”. That data can be multiple attributes, including RADIUS attribute header fields, or it can be one or more "large" attributes (more than 256 bytes in length). Proxies can also filter these attributes, modifying, adding, or deleting them and their contents. These proxies act on a "packet by packet" basis and cannot know what kind of filtering they'll do on future packets. As a result, it's impossible to signal any meaningful value for the total amount of additional data.

okay now this part is kinda scary ngl ๐Ÿ’€. Unauthenticated end users are allowed to trigger the exchange of large amounts of fragmented data between the RADIUS Client and the RADIUS Server, which could enable denial-of-service (DoS) attacks. An attacker could open a huge number of connections, each one asking the RADIUS Server to store a large amount of data. That data could exhaust the server's memory and get authentic users denied access. It's worth noting that authentication mechanisms are already designed to avoid exceeding the size limit.

Hence, implementations of this specification MUST limit the total amount of data they send and/or receive via this specification. Its default value SHOULD be 100 kilobytes. Anything more than this may turn RADIUS into a generic transport protocol, which is undesirable ๐Ÿ™…โ€โ™€๏ธ. This limit SHOULD be configurable, so it can be changed if necessary.

Implementations of this specification MUST limit the total number of round trips used during the fragmentation process. Its default value SHOULD be 25. Anything more than this may indicate an implementation error, a misconfiguration, or a DoS attack ๐Ÿšจ. This limit SHOULD be configurable, so it can be changed if necessary.

Let's imagine the RADIUS Server wants to transport a SAML assertion that's 15000 bytes long to the RADIUS Client ๐Ÿฐ. In this hypothetical, there are three intermediate proxies, each inserting a Proxy-State attribute of 20 bytes. We also assume the State attributes generated by the RADIUS Server are 6 bytes and the User-Name attribute takes 50 bytes. So the free space in a chunk for transporting the SAML assertion attributes works out like this:

Total (4096 bytes) - RADIUS header (20 bytes) - User-Name (50 bytes)
- Frag-Status (7 bytes) - Service-Type (6 bytes) - State (6 bytes) -
Proxy-State (20 bytes) - Proxy-State (20 bytes) - Proxy-State
(20 bytes) - Message-Authenticator (18 bytes)

That gives a total of 3929 bytes. This amount of free space allows transmission of up to 15 attributes of 255 bytes each ๐ŸŽ€.

According to [RFC6929], a Long-Extended-Type provides a payload of 251 bytes. So the SAML assertion described above would result in 60 attributes, requiring four round trips to be completely transmitted ๐ŸŒธ.

8. Handling Special Attributes โœจ

8.1. Proxy-State Attribute ๐ŸŽ€

okay so RADIUS proxies are allowed to tack Proxy-State attributes onto any Access-Request packet they forward ๐Ÿ’… but if they can't fit that info in, they may silently discard the packet instead of forwarding it to its destination, and that would lead to DoS situations ๐Ÿ’€ Also, any Proxy-State attribute a RADIUS Server gets in an Access-Request packet MUST be copied into the matching reply packet. So yeah, Proxy-State attributes need special handling inside the packet fragmentation mechanism โœจ

When the RADIUS Server replies to an Access-Request as part of a conversation that involves fragmentation (either a chunk or a request for chunks), it MUST include every Proxy-State attribute it received in the reply packet ๐Ÿซถ That means the RADIUS Server MUST factor the size of these Proxy-State attributes into how big the next chunk is ๐Ÿงฎ

Here's the tea ๐Ÿต The RADIUS Server always knows how much room MUST be left in each reply packet for Proxy-State attributes, since it adds them itself. The RADIUS Client, though, can't know that, because the proxies strip their Proxy-State attributes off the reply before passing it back ๐Ÿ˜ญ So RADIUS Clients need a way to discover how much space the proxies will need for their Proxy-State attributes. The steps below describe a new mechanism for that discovery ๐Ÿฆ‹

  1. When a RADIUS Client doesn't know how much space the intermediate proxies will need for their Proxy-State attributes, it SHOULD start with a conservative chunk size (for example, 1024 bytes) ๐ŸŒธ
  2. When the RADIUS Server receives a chunk from the RADIUS Client, it can work out the total size of the Proxy-State attributes that the intermediary proxies along the path have added. That info MUST be sent back to the RADIUS Client in the next reply packet, encoded in a new attribute called Proxy-State-Length ๐Ÿ“ฆ The RADIUS Server MAY artificially bump up this number to cover situations where proxies act inconsistently (for example, they generate Proxy-State attributes of a different size for each packet), or where intermediary proxies remove Proxy-State attributes that other proxies generated. Bumping it up makes the RADIUS Client leave some free space for those situations ๐Ÿ›Ÿ
  3. The RADIUS Client SHOULD react to receiving this attribute by adjusting the maximum size of the next chunk to match ๐Ÿ”ฅ However, since Proxy-State-Length is only an estimate of the space the proxies need, the RADIUS Client MAY pick a smaller amount in environments known to be problematic ๐Ÿ™ˆ

8.2. State Attribute ๐Ÿ“

This RADIUS fragmentation mechanism uses the State attribute to link together all the chunks that belong to the same fragmented packet ๐Ÿ”— But the RADIUS Server needs to think carefully when it's fragmenting a packet that already carries a State attribute for some other, non-fragmentation purpose. If the procedure in Section 5 is followed, two different State attributes could end up in a single chunk, and that is something explicitly forbidden in [RFC2865] ๐Ÿ˜ฌ

A simple fix is for the RADIUS Server to send the original State attribute in the last chunk of the sequence (attributes can be reordered as specified in [RFC2865]) ๐Ÿช„ The last chunk generated by the RADIUS Server doesn't contain any State attribute because of the fragmentation mechanism, so both of the situations described above get avoided โœจ

Something similar happens when the RADIUS Client has to send a fragmented packet that contains a State attribute. The RADIUS Client MUST make sure this original State is included in the first chunk it sends to the RADIUS Server, since that first chunk never contains any State attribute due to fragmentation ๐Ÿ’œ

8.3. Service-Type Attribute ๐Ÿ‘‘

This RADIUS fragmentation mechanism uses the Service-Type attribute to signal that an Access-Accept packet is not granting access to the service yet, because an additional authorization exchange still needs to happen ๐Ÿ” Just like with State, the RADIUS Server has to send the original Service-Type attribute in the last Access-Accept of the RADIUS conversation so there's no ambiguity ๐Ÿง

8.4. Rebuilding the Original Large Packet ๐Ÿงฉ

The RADIUS Client stores the RADIUS attributes it gets in each chunk in a list, so it can rebuild the original large packet once the last chunk arrives ๐Ÿ“‹ But some of those received attributes MUST NOT go into that list, because they were introduced as part of the fragmentation signaling and aren't part of the original packet ๐Ÿ™…โ€โ™€๏ธ

  • State (except the one in the last chunk, if present)
  • Service-Type = Additional-Authorization
  • Frag-Status
  • Proxy-State-Length

Same energy on the RADIUS Server side. The RADIUS Server MUST NOT store the following attributes as part of the original large packet:

  • State (except the one in the first chunk, if present)
  • Service-Type = Additional-Authorization
  • Frag-Status
  • Proxy-State (except the ones in the last chunk)
  • User-Name (except the one in the first chunk)

9. New T Flag for the Long Extended Type Attribute Definition ๐Ÿฆ‹

This document adds a new field to the Long Extended Type attribute format ๐ŸŒˆ It's one bit wide, it's called "T" for Truncation, and it says that the attribute was intentionally truncated in this chunk and will be continued in the next chunk of the sequence โœ‚๏ธ The combo of the M flag and the T flag tells you the attribute is fragmented (M flag) but not all of its fragments are available in this chunk (T flag) ๐Ÿง 

Proxies implementing [RFC6929] will see these attributes as invalid (they won't be able to reconstruct them), but they'll still forward them anyway, because Section 5.2 of [RFC6929] says they SHOULD forward unknown attributes regardless ๐Ÿšš

Because of this addition, the Reserved field is now 6 bits long (see Section 12.1 for some considerations) ๐Ÿฐ Here's the new attribute format:

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |     Type      |    Length     | Extended-Type |M|T| Reserved  |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |     Value ...
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

          Figure 12: Updated Long Extended Type Attribute Format

10. New Attribute Definition ๐Ÿ’…

This document proposes two new extended type attributes, Frag-Status and Proxy-State-Length ๐ŸŽ€ Their format follows the rules for an Extended Type attribute defined in [RFC6929] ๐Ÿ“

10.1. Frag-Status Attribute ๐Ÿšฆ

This attribute is for fragmentation signaling, and what it means depends on the code value carried inside it ๐Ÿ”ค Here's the format of the Frag-Status attribute:

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |   Type        |    Length     | Extended-Type |     Code
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                        Code (cont)                   |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                       Figure 13: Frag-Status Format

The fields are:

  • Type: 241
  • Length: 7
  • Extended-Type: 1
  • Code: 4 bytes. An integer indicating the code. The values defined in this specification are:
    • 0 - Reserved
    • 1 - Fragmentation-Supported
    • 2 - More-Data-Pending
    • 3 - More-Data-Request

This attribute MAY be present in Access-Request, Access-Challenge, and Access-Accept packets. It MUST NOT be included in Access-Reject packets. RADIUS Clients that support this specification MUST include a Frag-Status = Fragmentation-Supported attribute in the first Access-Request they send to the RADIUS Server, to say that they'd accept fragmented data from the server ๐Ÿซถ

10.2. Proxy-State-Length Attribute ๐Ÿ“

This attribute tells the RADIUS Client how long the Proxy-State attributes received by the RADIUS Server are. That info is handy for adjusting how long the chunks sent by the RADIUS Client are โœ‚๏ธ Here's the format of this Proxy-State-Length attribute:

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |   Type        |    Length     | Extended-Type |     Value
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                  Value (cont)                        |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                   Figure 14: Proxy-State-Length Format

The fields are:

  • Type: 241
  • Length: 7
  • Extended-Type: 2
  • Value: 4 bytes. Total length (in bytes) of the received Proxy-State attributes (including headers). Since the RADIUS Length field can't take values over 4096 bytes, values of Proxy-State-Length MUST be less than that maximum length ๐Ÿ“

This attribute MAY be present in Access-Challenge and Access-Accept packets. It MUST NOT be included in Access-Request or Access-Reject packets ๐Ÿšซ

10.3. Table of Attributes ๐Ÿ“Š

Here's a table showing the different attributes defined in this document, along with the types of RADIUS packets they can show up in ๐Ÿ‘€

                            |     Type of Packet    |
                            +-----+-----+-----+-----+
      Attribute Name        | Req | Acc | Rej | Cha |
      ----------------------+-----+-----+-----+-----+
      Frag-Status           | 0-1 | 0-1 |  0  | 0-1 |
      ----------------------+-----+-----+-----+-----+
      Proxy-State-Length    | 0   | 0-1 |  0  | 0-1 |
      ----------------------+-----+-----+-----+-----+

11. Operation with Proxies ๐Ÿงš

The fragmentation mechanism defined above is designed to be transparent to legacy proxies, as long as they don't want to modify any fragmented attribute ๐Ÿชถ That said, updated proxies that support this specification can even modify fragmented attributes ๐Ÿ†™

11.1. Legacy Proxies ๐Ÿ•ฐ๏ธ

Every chunk is just a RADIUS packet, so legacy proxies treat them like any other packets and route them to their destination ๐Ÿ›ฃ๏ธ Proxies can add Proxy-State attributes to Access-Request packets even when those are chunks, and that won't affect how fragmentation is managed ๐Ÿ’– The RADIUS Server includes all the received Proxy-State attributes in the response it generates, as described in [RFC2865]. So honestly, proxies can't tell a regular RADIUS packet apart from a chunk ๐Ÿฅน

11.2. Updated Proxies ๐Ÿฆ‹

okay so updated proxies are the glow-up ๐Ÿ’… They can talk to RADIUS Clients and Servers to grab the complete large packet before they start forwarding it. That means they can manipulate (modify and/or remove) any attribute or introduce new ones, and they don't have to stress about crossing the chunk size boundary ๐Ÿ˜ญ Once the edited packet is ready, it gets sent to the original destination using the fragmentation mechanism (if needed) โœจ

Figure 15 shows an updated proxy chatting with the RADIUS Client to (1) grab a large Access-Request and (2) modify an attribute, which makes the packet even bigger ๐Ÿ‘€ Then, as Figure 16 shows, the proxy talks to the RADIUS Server to finish sending the modified packet ๐Ÿซถ

     +-+-+-+-+-+                                          +-+-+-+-+-+
     | RADIUS  |                                          | RADIUS  |
     | Client  |                                          | Proxy   |
     +-+-+-+-+-+                                          +-+-+-+-+-+
         |                                                    |
         | Access-Request(1){User-Name,Calling-Station-Id,    |
         |        Example-Long-1[M],Example-Long-1[M],        |
         |        Example-Long-1[M],Example-Long-1[M],        |
         |        Example-Long-1[MT],Frag-Status(MDP)}        |
         |--------------------------------------------------->|
         |                                                    |
         |                     Access-Challenge(1){User-Name, |
         |                           Frag-Status(MDR),State1} |
         |<---------------------------------------------------|
         |                                                    |
         | Access-Request(2){User-Name,State1,                |
         |        Example-Long-1[M],Example-Long-1[M],        |
         |        Example-Long-1[M],Example-Long-1}           |
         |--------------------------------------------------->|

              Proxy Modifies Attribute Data, Increasing Its
                 Size from 9 Fragments to 11 Fragments

           Figure 15: Updated Proxy Interacts with RADIUS Client
     +-+-+-+-+-+                                          +-+-+-+-+-+
     | RADIUS  |                                          | RADIUS  |
     | Proxy   |                                          | Server  |
     +-+-+-+-+-+                                          +-+-+-+-+-+
         |                                                    |
         | Access-Request(3){User-Name,Calling-Station-Id,    |
         |        Example-Long-1[M],Example-Long-1[M],        |
         |        Example-Long-1[M],Example-Long-1[M],        |
         |        Example-Long-1[MT],Frag-Status(MDP)}        |
         |--------------------------------------------------->|
         |                                                    |
         |                     Access-Challenge(1){User-Name, |
         |                           Frag-Status(MDR),State2} |
         |<---------------------------------------------------|
         |                                                    |
         | Access-Request(4){User-Name,State2,                |
         |        Example-Long-1[M],Example-Long-1[M],        |
         |        Example-Long-1[M],Example-Long-1[M],        |
         |        Example-Long-1[MT],Frag-Status(MDP)}        |
         |--------------------------------------------------->|
         |                                                    |
         |                     Access-Challenge(1){User-Name, |
         |                           Frag-Status(MDR),State3} |
         |<---------------------------------------------------|
         |                                                    |
         | Access-Request(5){User-Name,State3,Example-Long-1} |
         |--------------------------------------------------->|

           Figure 16: Updated Proxy Interacts with RADIUS Server

12. General Considerations โœจ

12.1. T Flag ๐ŸŽ€

So, as we covered in Section 9, this document changes the definition of the Reserved field of the Long Extended Type attribute [RFC6929] by adding an extra flag called the T flag. The meaning and position of this flag are defined here and nowhere else ๐Ÿ‘€ That could be a problem later on, because if another spec wants to allocate a new flag too, there's no direct way for them to know which parts of the Reserved field are already taken ๐Ÿ˜ฌ

An immediate and reasonable fix would be declaring that this RFC updates [RFC6929]. That way, [RFC6929] would get an "Updated by" clause pointing readers over to this document. Another option would be creating an IANA registry for the Reserved field. However, the RADIUS Extensions (RADEXT) working group thinks that's overkill, since a large number of specifications extending that field aren't expected ๐Ÿ™„

So in the end, the proposed solution is that this experimental RFC should not update RFC 6929. Instead, we rely on the collective memory of the working group to remember that this T flag is being used as specified by this Experimental document. If the experiment is successful, the T flag will be properly assigned ๐Ÿคž

12.2. Violation of RFC 2865 ๐Ÿ’€

Section 5.1 says all authorization and authentication handling gets postponed until all the chunks have been received. This postponement also applies to checking that the Access-Request packet contains some kind of authentication attribute (e.g., User-Password, CHAP-Password, State, or other future attribute), as required by [RFC2865]. That check gets delayed until the original large packet has been rebuilt, because some of the chunks may not contain any of them ๐Ÿงฉ

The authors admit that this specification violates the "MUST" requirement of [RFC2865], Section 4.1, which states that "An Access-Request MUST contain either a User-Password or a CHAP-Password or a State." We note that a proxy enforcing that requirement would be unable to support future RADIUS authentication extensions, so extensions to the protocol would be impossible to deploy ๐Ÿšซ All known implementations have chosen the vibe of "be liberal in what you accept." In other words, they accept traffic that violates the requirement of [RFC2865], Section 4.1. So we expect no operational issues with this specification ๐Ÿคž After we gain more operational experience with it, it can be reissued as a Standards Track document and can update [RFC2865] ๐ŸŒˆ

12.3. Proxying Based on User-Name ๐Ÿ“

This proposal assumes that legacy proxies base their routing decisions on the value of the User-Name attribute. Because of that, every packet sent from the RADIUS Client to the RADIUS Server (either chunks or requests for more chunks) MUST contain a User-Name attribute ๐Ÿซถ

12.4. Transport Behavior ๐ŸŒธ

This proposal doesn't change how RADIUS interacts with the underlying transport (UDP) ๐Ÿฆ‹ RADIUS keeps following a lock-step behavior that requires receiving an explicit acknowledgement for each chunk sent. So bursts of traffic that could congest links between peers aren't an issue โœจ

Another perk of RADIUS's lock-step nature is that there are no security issues with overlapping fragments ๐Ÿ™Œ Each chunk simply has a length, with no Fragment Offset field like IPv4 has. The order of the fragments is determined by the order they're received in. There's no ambiguity about the size or placement of each chunk, so there are no security issues associated with overlapping chunks ๐Ÿ’œ


13. Security Considerations ๐Ÿ’€

As noted in many earlier specifications ([RFC5080], [RFC6158], etc.), RADIUS security is problematic ๐Ÿ˜ญ This specification changes nothing related to the security of the RADIUS protocol. It requires that all Access-Request packets associated with fragmentation are authenticated using the existing Message-Authenticator attribute. This signature prevents forging and replay, to the limits of the existing security ๐Ÿ”

The ability to send bulk data from one party to another creates new security considerations ๐Ÿšจ RADIUS Clients and Servers may have to store large amounts of data per session. That amount can be significant, leading to the potential for resource exhaustion. So we suggest that implementations limit the amount of bulk data stored per session. The exact method for this limitation is implementation-specific. Section 7 gives some indications of what could be reasonable limits ๐Ÿ“

The bulk data can often be pushed off to storage methods other than the memory of the RADIUS implementation. For example, it can be stored in an external database or in files. This approach mitigates the resource exhaustion issue, since RADIUS Servers today already store large amounts of accounting data ๐Ÿ—„๏ธโœจ


14. IANA Considerations ๐Ÿงš

The Internet Assigned Numbers Authority (IANA) has registered the Attribute Types and Attribute Values defined in this document in the RADIUS namespaces, as described in the "IANA Considerations" section of [RFC3575], in accordance with BCP 26 [RFC5226]. For RADIUS packets, attributes, and registries created by this document, IANA has updated http://www.iana.org/assignments/radius-types accordingly ๐Ÿ“‹

In particular, this document defines two new RADIUS attributes, entitled "Frag-Status" (value 241.1) and "Proxy-State-Length" (value 241.2), which have been allocated from the short extended space as described in [RFC6929]:

Type     Name                 Length  Meaning
----     ----                 ------  -------
241.1    Frag-Status          7       Signals fragmentation
241.2    Proxy-State-Length   7       Indicates the length of the
                                      received Proxy-State attributes

The Frag-Status attribute also defines an 8-bit "Code" field, for which IANA has created and now maintains a new sub-registry entitled "Code Values for RADIUS Attribute 241.1, Frag-Status". Initial values for the RADIUS Frag-Status "Code" registry are given below. Future assignments are to be made through "RFC Required" [RFC5226]. Assignments consist of a Frag-Status "Code" name and its associated value ๐ŸŽ€

      Value    Frag-Status Code Name           Definition
      ----     ------------------------        ----------
      0        Reserved                        See Section 10.1
      1        Fragmentation-Supported         See Section 10.1
      2        More-Data-Pending               See Section 10.1
      3        More-Data-Request               See Section 10.1
      4-255    Unassigned

Additionally, IANA has allocated a new Service-Type value for "Additional-Authorization" ๐Ÿ‘‘

      Value    Service Type Value              Definition
      ----     ------------------------        ----------
      19       Additional-Authorization        See Section 5.1

15. References ๐Ÿ“š

15.1. Normative References ๐Ÿ“šโœจ

Okay bestie, these are the references you need to read to actually understand this doc. No skipping, no cap ๐Ÿ’…

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997, <http://www.rfc-editor.org/info/rfc2119>.

[RFC2865] Rigney, C., Willens, S., Rubens, A., and W. Simpson, "Remote Authentication Dial In User Service (RADIUS)", RFC 2865, June 2000, <http://www.rfc-editor.org/info/rfc2865>.

[RFC3575] Aboba, B., "IANA Considerations for RADIUS (Remote Authentication Dial In User Service)", RFC 3575, July 2003, <http://www.rfc-editor.org/info/rfc3575>.

[RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 5226, May 2008, <http://www.rfc-editor.org/info/rfc5226>.

[RFC6158] DeKok, A., Ed., and G. Weber, "RADIUS Design Guidelines", BCP 158, RFC 6158, March 2011, <http://www.rfc-editor.org/info/rfc6158>.

[RFC6929] DeKok, A. and A. Lior, "Remote Authentication Dial In User Service (RADIUS) Protocol Extensions", RFC 6929, April 2013, <http://www.rfc-editor.org/info/rfc6929>.

15.2. Informative References ๐ŸŒธ

These ones are the bonus reading. Lowkey the best context for the vibes ๐Ÿงš

[ABFAB-Arch] Howlett, J., Hartman, S., Tschofenig, H., Lear, E., and J. Schaad, "Application Bridging for Federated Access Beyond Web (ABFAB) Architecture", Work in Progress, draft-ietf-abfab-arch-13, July 2014.

[RADIUS-Larger-Pkts] Hartman, S., "Larger Packets for RADIUS over TCP", Work in Progress, draft-ietf-radext-bigger-packets-03, March 2015.

[RFC2866] Rigney, C., "RADIUS Accounting", RFC 2866, June 2000, <http://www.rfc-editor.org/info/rfc2866>.

[RFC3579] Aboba, B. and P. Calhoun, "RADIUS (Remote Authentication Dial In User Service) Support For Extensible Authentication Protocol (EAP)", RFC 3579, September 2003, <http://www.rfc-editor.org/info/rfc3579>.

[RFC4849] Congdon, P., Sanchez, M., and B. Aboba, "RADIUS Filter Rule Attribute", RFC 4849, April 2007, <http://www.rfc-editor.org/info/rfc4849>.

[RFC5080] Nelson, D. and A. DeKok, "Common Remote Authentication Dial In User Service (RADIUS) Implementation Issues and Suggested Fixes", RFC 5080, December 2007, <http://www.rfc-editor.org/info/rfc5080>.

[RFC5176] Chiba, M., Dommety, G., Eklund, M., Mitton, D., and B. Aboba, "Dynamic Authorization Extensions to Remote Authentication Dial In User Service (RADIUS)", RFC 5176, January 2008, <http://www.rfc-editor.org/info/rfc5176>.

[SAML-RADIUS] Howlett, J., Hartman, S., and A. Perez-Mendez, Ed., "A RADIUS Attribute, Binding, Profiles, Name Identifier Format, and Confirmation Methods for SAML", Work in Progress, draft-ietf-abfab-aaa-saml-10, February 2015.


Acknowledgements ๐Ÿซถ

Huge shoutout to the members of the RADEXT working group!! ๐Ÿ’– They helped build this spec by joining the discussions on the mailing lists and sending in comments about our RFC. Literally iconic behaviour ๐Ÿ‘‘

The authors also want to thank David Cuenca (University of Murcia) ๐ŸŽ€ for building a proof-of-concept implementation of this RFC. It helped make the spec way better, which is so slay.

This work was partly funded by the GEANT GN3+ SA5 and CLASSe (http://www.um.es/classe/) projects. ๐ŸŒˆ


Authors' Addresses ๐Ÿ’…

Here's how to reach the squad ๐Ÿฆ‹

Alejandro Perez-Mendez (editor)
University of Murcia
Campus de Espinardo S/N, Faculty of Computer Science
Murcia  30100
Spain

Phone: +34 868 88 46 44
EMail: alex@um.es


Rafa Marin-Lopez
University of Murcia
Campus de Espinardo S/N, Faculty of Computer Science
Murcia  30100
Spain

Phone: +34 868 88 85 01
EMail: rafa@um.es


Fernando Pereniguez-Garcia
University of Murcia
Campus de Espinardo S/N, Faculty of Computer Science
Murcia  30100
Spain

Phone: +34 868 88 78 82
EMail: pereniguez@um.es

Gabriel Lopez-Millan
University of Murcia
Campus de Espinardo S/N, Faculty of Computer Science
Murcia  30100
Spain

Phone: +34 868 88 85 04
EMail: gabilm@um.es


Diego R. Lopez
Telefonica I+D
Don Ramon de la Cruz, 84
Madrid  28006
Spain

Phone: +34 913 129 041
EMail: diego@tid.es


Alan DeKok
Network RADIUS SARL
57bis Boulevard des Alpes
Meylan  38240
France

EMail: aland@networkradius.com
URI:   http://networkradius.com
๐Ÿ“ฆ where this page comes from