RFC 5080

Common Remote Authentication Dial In User Service (RADIUS) Implementation Issues and Suggested Fixes

πŸ“… published December 2007, from ietf

RFC 5080 πŸŽ€ Common Remote Authentication Dial In User Service (RADIUS) Implementation Issues and Suggested Fixes

Okay bestie, this is RFC 5080 πŸ’–. It's a Standards Track doc from the Network Working Group, dated December 2007, written by D. Nelson (Elbrys Networks, Inc) and A. DeKok (FreeRADIUS) πŸ¦‹. It updates RFC 2865, RFC 2866, RFC 2869, and RFC 3579, which means it's here to clean up stuff in those four specs ✨. The title block only lists those updates, so don't go looking for an "obsoletes" line πŸ™ˆ.

Status of This Memo ✨

This document specifies an Internet standards track protocol for the Internet community, and it's asking for discussion and suggestions for improvements πŸ’…. For the standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1) πŸ“š. Distribution of this memo is unlimited 🌸.

Abstract πŸ¦‹

This doc is about common issues people run into when they implement Remote Authentication Dial In User Service (RADIUS) 🫢. It also suggests some fixes. Where it makes sense, it clears up ambiguities and errors in earlier RADIUS specs πŸ”₯.

Table of Contents 🧚

1. Introduction ....................................................2
   1.1. Terminology ................................................3
   1.2. Requirements Language ......................................3
2. Issues ..........................................................3
   2.1. Session Definition .........................................3
        2.1.1. State Attribute .....................................3
        2.1.2. Request-ID Supplementation ..........................6
   2.2. Overload Conditions ........................................7
        2.2.1. Retransmission Behavior .............................7
        2.2.2. Duplicate Detection and Orderly Delivery ...........10
        2.2.3. Server Response to Overload ........................11
   2.3. Accounting Issues .........................................12
        2.3.1. Attributes Allowed in an Interim Update ............12
        2.3.2. Acct-Session-Id and Acct-Multi-Session-Id ..........12
        2.3.3. Request Authenticator ..............................13
        2.3.4. Interim-Accounting-Interval ........................13
        2.3.5. Counter Values in the RADIUS Management
               Information Base (MIB) .............................14
   2.4. Multiple Filter-ID Attributes .............................15
   2.5. Mandatory and Optional Attributes .........................16
   2.6. Interpretation of Access-Reject ...........................18
        2.6.1. Improper Use of Access-Reject ......................18
        2.6.2. Service Request Denial .............................19
   2.7. Addressing ................................................20
        2.7.1. Link-Local Addresses ...............................20
        2.7.2. Multiple Addresses .................................20
   2.8. Idle-Timeout ..............................................21
   2.9. Unknown Identity ..........................................21
   2.10. Responses After Retransmissions ..........................22
   2.11. Framed-IPv6-Prefix .......................................23
3. Security Considerations ........................................24
4. References .....................................................25
   4.1. Normative References ......................................25
   4.2. Informative References ....................................25

1. Introduction 🌈

RADIUS clients and servers have been showing up everywhere over the last few years, and it's giving growth πŸ“ˆβœ¨. This doc goes over common issues that show up in RADIUS implementations and suggests some fixes πŸ”§. Where it's needed, it also clears up ambiguities and errors in previous RADIUS specs πŸ’œ.

1.1. Terminology πŸ“–

This doc uses the following terms, so let's get the vocab down first πŸŽ€.

Network Access Server (NAS) : The device that gives access to the network 🌐. It's also called the Authenticator in IEEE 802.1X or Extensible Authentication Protocol (EAP) terminology, or the RADIUS client πŸ¦‹.

service : The NAS gives a service to the user, like network access over 802.11 or Point to Point Protocol (PPP) πŸ“Ά.

session : Every service the NAS provides to a peer counts as a session 🧚. A session starts at the point where service is first provided and ends at the point where service stops 🏁. A peer can have multiple sessions running in parallel or in series if the NAS supports it, and each session makes its own separate start and stop accounting record πŸ“.

silently discard : This means the implementation throws the packet away without doing any more processing πŸ—‘οΈ. The implementation SHOULD be able to log the error, including the contents of the silently discarded packet πŸ“‹, and SHOULD record the event in a statistics counter πŸ“Š.

Quick aside: "silently discard" is a term with a very specific meaning here. It's not "ignore and forget," it's "toss it and then (ideally) log it and count it" πŸ’€.

1.2. Requirements Language πŸ’…

In this document, a few words are used to show the requirements of the spec 🫢. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" are to be read as described in [RFC2119] πŸ“šβœ¨.

2. Issues πŸ”₯

2.1. Session Definition πŸ¦‹

2.1.1. State Attribute 🌸

Okay so, the State attribute is kind of a big deal, bestie πŸ’…. [RFC2865] Section 5.24 says:

This Attribute is available to be sent by the server to the client in an Access-Challenge and MUST be sent unmodified from the client to the server in the new Access-Request reply to that challenge, if any.
This Attribute is available to be sent by the server to the client in an Access-Accept that also includes a Termination-Action Attribute with the value of RADIUS-Request. If the NAS performs the Termination-Action by sending a new Access-Request upon termination of the current session, it MUST include the State attribute unchanged in that Access-Request.

Some RADIUS clients are lowkey sloppy with State 😬, so they can't tell a brand-new EAP auth run apart from a continuation of an ongoing one (same user, same NAS, same port). So when an EAP-Message attribute shows up in an Access-Challenge or Access-Accept, RADIUS servers SHOULD also include a State attribute. Check out Section 2.1.2 on Request ID supplementation for more perks of using State like this ✨.

As defined in [RFC2865] Table 5.44, Access-Request packets may contain a State attribute. The table doesn't add any qualifiers to that, but the text in Section 5.24 (quoted above) adds other requirements that aren't in the table πŸ€”.

We extend the requirements of [RFC2865] to say that Access-Requests that are part of an ongoing Access-Request / Access-Challenge authentication process SHOULD contain a State attribute. It's the server's job to send a State attribute in an Access-Challenge packet if that server needs one in a later Access-Request to tie multiple Access-Requests together into one authentication session πŸ¦‹. As defined in [RFC2865] Section 5.24, the State MUST be sent unmodified from the client to the server in the new Access-Request reply to that challenge, if any.

While most server implementations require a State attribute in an Access-Challenge packet, some challenge-response systems can tell the initial request apart from the challenge response without using State to track the session. The Access-Challenge and later Access-Request packets for those systems don't need to contain a State attribute 🧚.

Other authentication mechanisms need to tie a sequence of Access-Request / Access-Challenge packets together into one ongoing session. Servers implementing those mechanisms SHOULD include a State attribute in Access-Challenge packets.

In general, if the authentication process involves one or more Access-Request / Access-Challenge sequences, the State attribute SHOULD be sent by the server in the Access-Challenge packets. Using State to build a multi-packet session is the simplest method RADIUS has today πŸ‘‘. Other ways of making multi-packet sessions are possible (e.g., [RFC3579] Section 2.6.1), but those methods are NOT RECOMMENDED πŸ™ˆ.

The only permissible values for a State attribute are the ones provided in an Access-Accept, Access-Challenge, CoA-Request or Disconnect-Request packet. A RADIUS client MUST use only those values for State that it has previously received from a server. An Access-Request sent as the result of a new or restarted authentication run MUST NOT include the State attribute, even if a State attribute was previously received in an Access-Challenge for the same user and port πŸ’€.

Access-Request packets that contain a Service-Type attribute with the value Authorize Only (17) MUST contain a State attribute. Access-Request packets that contain a Service-Type attribute with the value Call Check (10) SHOULD NOT contain a State attribute. Any other Access-Request packet that performs authorization checks MUST contain a State attribute. That last rule often means an Access-Accept needs to include a State attribute, which can then be used in a later Access-Request that performs authorization checks πŸŽ€.

The standard use case for Call Check is pre-screening authentication based only on end-point identifier info, like a phone number or Media Access Control (MAC) address in Calling-Station-ID and optionally Called-Station-ID. In this case, the NAS has no way to get a State attribute suitable for an Access-Request. Other, non-standard uses of Call Check may require or permit a State attribute, but those are beyond the scope of this document 🌈.

In an Access-Request with a Service-Type attribute with the value Call Check, it is NOT RECOMMENDED for the User-Name and User-Password attributes to contain the same values (e.g., a MAC address). Implementing MAC address checking without using a Service-Type of Call Check is NOT RECOMMENDED. This practice gives an attacker both the clear-text and cipher-text of the User-Password field, which enables many attacks on the security of the RADIUS protocol. For example, if the Request Authenticator does not satisfy the [RFC2865] requirements on global and temporal uniqueness, the practice described above may lead to the compromise of the User-Password attribute in other Access-Requests for unrelated users. Access to the cipher-text enables offline dictionary attacks, potentially exposing the shared secret and compromising the entire RADIUS protocol 🚨.

Any Access-Request packet that performs authorization checks, including Call Check, SHOULD contain a Message-Authenticator attribute. Any response to an Access-Request performing an authorization check MUST NOT contain confidential information about any user (such as Tunnel-Password), unless that Access-Request contains a State attribute. The use of State here lets the authorization check be tied to an earlier user authentication. In that case, the server MAY respond to the NAS with confidential information about that user. The server MUST NOT respond to that authorization check with confidential information about any other user πŸ”.

For an Access-Request packet performing an authorization check that does not contain a State attribute, the server MUST respond with an Access-Reject πŸ™…β€β™€οΈ.

2.1.2. Request-ID Supplementation πŸ¦‹

[RFC3579] Section 2.6.1 states:

In EAP, each session has its own unique Identifier space. RADIUS server implementations MUST be able to distinguish between EAP packets with the same Identifier existing within distinct sessions, originating on the same NAS. For this purpose, sessions can be distinguished based on NAS and session identification attributes. NAS identification attributes include NAS-Identifier, NAS-IPv6-Address and NAS-IPv4-Address. Session identification attributes include User-Name, NAS-Port, NAS-Port-Type, NAS-Port-Id, Called-Station-Id, Calling-Station-Id and Originating-Line-Info.

Okay so there are issues with the suggested algorithm 😩. Since proxies may modify Access-Request attributes such as NAS-IP-Address, depending on any attribute under the NAS's control to tell request identifiers apart can cause deployment problems.

The FreeRADIUS implementation doesn't track EAP identifiers by NAS-IP-Address or other non-EAP attributes sent by the NAS. Instead, it uses the EAP identifier, source Internet Protocol (IP) address, and the State attribute as a "key" to uniquely identify each EAP session πŸ”‘. Since State is under the control of the RADIUS server, the uniqueness of each session is controlled by the server, not the NAS. The algorithm FreeRADIUS uses goes like this:

if (EAP start, or EAP identity) {
  allocate unique State Attribute
  insert session into "active session" table with
       key=(EAP identifier, State, source IP)
} else {
  look up active session in table, with above key
}

This algorithm seems to work really well in a bunch of situations, including ones where home servers get messages through intermediate RADIUS proxies 🌸.

Implementations that don't use this algorithm are often stuck with an EAP Identifier space per NAS, or maybe one that's global to the whole implementation. Those restrictions aren't needed when the algorithm above is used, since it gives each session its own unique EAP Identifier space πŸ’–. The above algorithm SHOULD be used to track EAP sessions in preference to any other method πŸ‘‘.

2.2. Overload Conditions ✨

2.2.1. Retransmission Behavior πŸ”βœ¨

Okay so [RFC2865] Section 2.4 is all about how RADIUS clients should handle retransmissions, and it describes two extremes πŸ’…:

At one extreme, RADIUS does not require a "responsive" detection of lost data. The user is willing to wait several seconds for the authentication to complete. The generally aggressive Transmission Control Protocol (TCP) retransmission (based on average round trip time) is not required, nor is the acknowledgment overhead of TCP. At the other extreme, the user is not willing to wait several minutes for authentication. Therefore the reliable delivery of TCP data two minutes later is not useful. The faster use of an alternate server allows the user to gain access before giving up.

So on one end, nobody's asking RADIUS to be super twitchy 🫢. On the other end, a user won't sit around for minutes, so it's better to hop to an alternate server than to keep waiting. Iconic balance 😭.

Here's the tea though. Some existing RADIUS clients are way too aggressive πŸ’€. They use default retransmission timeouts of one second or less and don't back off when things are congested. At scale, that's a recipe for congestive collapse 🫠. For example, say a power failure hits and a network has 3,000 NAS devices, each with a fixed one-second retransmission timer. That's 3,000 RADIUS Access-Requests per second, and that's enough to overwhelm most RADIUS servers. Not it πŸ™ˆ.

Suggested solutions include:

  • [a] Jitter. To avoid synchronization, a RADIUS client SHOULD incorporate induced jitter within its retransmission algorithm, as specified below.
  • [b] Congestive backoff. While it is not necessary for RADIUS client implementations to implement complex retransmission algorithms, implementations SHOULD support congestive backoff.

Now the retransmission timers are based on the model used in Dynamic Host Configuration Protocol for IPv6 (DHCPv6) [RFC3315], and the variables are borrowed from that spec too 🧚. RADIUS is request/response based. The message exchange ends when the requester successfully gets the answer, or when the exchange is considered failed under the RECOMMENDED retransmission mechanism described below. Other retransmission mechanisms are possible, as long as they satisfy the requirements on jitter and congestive backoff. Options, but make sure you're still meeting those two vibes ✨.

These algorithms apply to any client that originates RADIUS packets, including but not limited to Access-Request, Accounting-Request, Disconnect-Request, and CoA-Request [RFC3576] πŸ“¦.

The retransmission behavior is controlled and described by these variables:

RT     Retransmission timeout
IRT    Initial retransmission time  (default 2 seconds)
MRC    Maximum retransmission count (default 5 attempts)
MRT    Maximum retransmission time (default 16 seconds)
MRD    Maximum retransmission duration (default 30 seconds)
RAND   Randomization factor

With each message transmission or retransmission, the sender sets RT according to the rules below. If RT expires before the message exchange terminates, the sender re-computes RT and retransmits the message πŸ”„.

Every new RT computation includes a randomization factor (RAND), which is a random number chosen with a uniform distribution between -0.1 and +0.1. It's there to minimize the synchronization of messages, aka the thing that caused the 3,000-NAS disaster 🌈.

The algorithm for choosing a random number does not need to be cryptographically sound. The algorithm SHOULD produce a different sequence of random numbers from each invocation.

RT for the first message transmission is based on IRT:

RT = IRT + RAND*IRT

RT for each subsequent message retransmission is based on the previous value of RT:

RT = 2*RTprev + RAND*RTprev

MRT sets an upper bound on the value of RT (ignoring the randomization added by RAND). If MRT is 0, there's no upper limit on RT. Otherwise:

if (RT > MRT)
   RT = MRT + RAND*MRT

MRD sets an upper bound on how long a sender may keep retransmitting a message. The message exchange fails once MRD seconds have passed since the client first sent the message. MRD MUST be set, and SHOULD have a value between 5 and 30 seconds. These values mirror the values for a server's duplicate detection cache, which is covered in the next section πŸͺž.

MRC sets an upper bound on how many times a sender may retransmit a message. If MRC is zero, the message exchange fails once MRD seconds have passed since the client first sent the message. If MRC is non-zero, the message exchange fails when either the sender has transmitted the message MRC times, or when MRD seconds have passed since the client first sent the message πŸ•°οΈ.

For Accounting-Request packets, the default values for MRC, MRD, and MRT SHOULD be zero. These settings let a RADIUS client keep sending accounting requests to a RADIUS server until the request is acknowledged πŸ“¬. If any of MRC, MRD, or MRT are non-zero, then the accounting information could potentially be discarded without being recorded. Accounting data going poof is the worst 😭.


2.2.2. Duplicate Detection and Orderly Delivery 🧐

When a client retransmits packets, the server may receive duplicate requests. The limitations of the transport protocol RADIUS uses, the User Datagram Protocol (UDP), mean that Access-Request packets may be received, and potentially processed, in a different order from the one they were sent in. But the discussion of the Identifier field in Section 3 of [RFC2865] says:

The RADIUS server can detect a duplicate request if it has the same client source IP address and source UDP port and Identifier within a short span of time.

Also, Section 7 of [RFC4669] defines a radiusAuthServDupAccessRequests object as:

The number of duplicate Access-Request packets received.

Okay, so this has a few implications πŸ”. First, without duplicate detection, a RADIUS server might process an authentication request twice, which leads to the wrong conclusion that a user logged in twice. That's undesirable, so duplicate detection is desirable πŸ™…β€β™€οΈ. Second, the server can track not just the duplicate request but also the replies to those requests. That lets the server send duplicate replies in response to duplicate requests, which helps network stability 🌸.

Access-Request packets may also be sent by the client in response to an Access-Challenge from the server. Those packets form a logically ordered stream, so they have extra ordering requirements over Access-Request packets for different sessions 🧡. Implementing duplicate detection means new packets get processed only once, which keeps the order intact. Main character ordering energy πŸ‘‘.

RADIUS servers MUST therefore implement duplicate detection for Access-Request packets, as described in Section 3 of [RFC2865]. Implementations MUST also cache the Responses (Access-Accept, Access-Challenge, or Access-Reject) that they send in response to Access-Request packets. If a server receives a valid duplicate Access-Request for which it has already sent a Response, it MUST resend its original Response without reprocessing the request. The server MUST silently discard any duplicate Access-Requests for which a Response has not yet been sent 🀫.

Each cache entry SHOULD be purged after a period of time. This time SHOULD be no less than 5 seconds, and no more than 30 seconds. After about 30 seconds, most RADIUS clients and end users will have given up on the authentication request, so there's little value in having a longer cache timeout ⏳.

Cache entries MUST also be purged if the server receives a valid Access-Request packet that matches a cached Access-Request packet in source address, source port, RADIUS Identifier, and receiving socket, but where the Request Authenticator field is different from the one in the cached packet. If the request contains a Message-Authenticator attribute, the request MUST be processed as described in [RFC3580] Section 3.2. Packets with invalid Message-Authenticators MUST NOT affect the cache in any way πŸ›‘οΈ.

However, Access-Request packets without a Message-Authenticator attribute always affect the cache, even though they may be trivially forged 🫣. To avoid this issue, server implementations may be configured to require the presence of a Message-Authenticator attribute in Access-Request packets. Requests without a Message-Authenticator attribute MAY then be silently discarded.

Client implementations SHOULD include a Message-Authenticator attribute in every Access-Request to further help mitigate this issue πŸ’–.

When sending requests, RADIUS clients MUST NOT reuse Identifiers for a source IP address and source UDP port until either a valid response has been received, or the request has timed out. Clients SHOULD allocate Identifiers via a least-recently-used (LRU) method for a particular source IP address and source UDP port πŸ”’.

RADIUS clients don't have to perform duplicate detection. When a client sends a request, it processes the first response that has a valid Response Authenticator as defined in [RFC2865] Section 3. Any later responses MUST be silently discarded, since they don't match a pending request. Basically, later responses are treated exactly the same as unsolicited responses, and get silently discarded πŸ«₯.


2.2.3. Server Response to Overload 🚦

Some RADIUS server implementations aren't very robust under overload. They drop packets with even probability across multiple sessions 😬. In an overload situation, that means a high failure rate for multi-round authentication protocols such as EAP [RFC3579]. Users keep retrying to get in, which pushes the load even higher. It's a whole spiral πŸŒ€.

A more sensible approach is for a RADIUS server to preferentially accept RADIUS Access-Request packets containing a valid State attribute, so that multi-round authentication conversations, once started, are more likely to succeed ✨. Similarly, a server that is proxying requests should preferentially process Access-Accept, Access-Challenge, or Access-Reject packets from home servers before processing new requests from a NAS 🏠.

These methods will let some users get onto the network, which reduces the load created by ongoing access attempts. Less chaos, more vibes 🫢.


2.3. Accounting Issues πŸ“Š

2.3.1. Attributes Allowed in an Interim Update

Okay, so [RFC2866] says that Acct-Input-Octets, Acct-Output-Octets, Acct-Session-Time, Acct-Input-Packets, Acct-Output-Packets and Acct-Terminate-Cause attributes:

"can only be present in Accounting-Request records where the Acct-Status-Type is set to Stop".

But [RFC2869] Section 2.1 says something a bit different πŸ‘€:

It is envisioned that an Interim Accounting record (with Acct-Status-Type = Interim-Update (3)) would contain all of the attributes normally found in an Accounting Stop message with the exception of the Acct-Term-Cause attribute.

Plot twist πŸŽ€. Although [RFC2869] doesn't say it updates [RFC2866], this is an oversight, and the above attributes are allowed in an Interim Accounting record. Iykyk, and now you do πŸ’…πŸŒˆ.

2.3.2. Acct-Session-Id and Acct-Multi-Session-Id ✨

okay so [RFC2866] Section 5.5 describes Acct-Session-Id as Text in the figure that summarizes the attribute format πŸ’…, but then the same section says "The String field SHOULD be a string of UTF-8 encoded 10646 characters". Bestie, that's a contradiction 😭

[RFC2865] defines the Text type as "containing UTF-8 encoded 10646 characters", which matches what Acct-Session-Id is supposed to be. Every other attribute is called "Text" in both the format figure and its own definition, so this is almost certainly a typo. Acct-Session-Id is of type Text, not String πŸ¦‹

The Acct-Multi-Session-Id definition has typos too πŸ™ˆ It says:

A summary of the Acct-Session-Id attribute format ...

It should say:

A summary of the Acct-Multi-Session-Id attribute format ...

Then there's the type problem. Acct-Multi-Session-Id is also defined as String, but the wording in its own text strongly recommends that implementors treat it as Text. Nobody explains why String was picked when Text would do the job just fine πŸ€·β€β™€οΈ So this attribute SHOULD be treated as Text πŸŽ€

2.3.3. Request Authenticator πŸ”

[RFC2866] Section 4.1 says:

The Request Authenticator of an Accounting-Request contains a 16-
octet MD5 hash value calculated according to the method described
in "Request Authenticator" above.

The problem is that the text never says what to do when an Accounting-Request has an invalid Request Authenticator 😀 Here's the missing piece that should be considered part of the description above:

The Request Authenticator field MUST contain the correct data, as
given by the above calculation.  Invalid packets are silently
discarded.  Note that some early implementations always set the
Request Authenticator to all zeros.  New implementations of RADIUS
clients MUST use the above algorithm to calculate the Request
Authenticator field.  New RADIUS server implementations MUST
silently discard invalid packets.

The vibe is: early implementations sometimes zeroed this field out, which is giving outdated πŸ™ƒ New RADIUS clients MUST use the algorithm, and new RADIUS servers MUST silently drop invalid packets. No drama, just rules πŸ’œ

2.3.4. Interim-Accounting-Interval ⏱️

[RFC2869] Section 2.1 says:

It is also possible to statically configure an interim value on
the NAS itself.  Note that a locally configured value on the NAS
MUST override the value found in an Access-Accept.

Honestly? This one might be phrased a little too strongly πŸ™ˆ Picture a NAS with a setting for a "minimum" Interim-Accounting-Interval, based on its own resource limits and how busy the local network is. In that case, the value the admin set on the NAS should not be overridden by a smaller value from an Access-Accept. A larger value from an Access-Accept could still override it, though πŸ“

The big-picture goal is: the NAS sends accounting info at fixed intervals that are short enough that lost billable revenue stays small, but long enough that the NAS, the network, and the RADIUS server don't get overloaded. It's a balancing act, and it's lowkey iconic πŸ‘‘

2.3.5. Counter Values in the RADIUS Management Information Base (MIB) πŸ“Š

The RADIUS Authentication and Authorization Client MIB module ([RFC2618] [RFC4668]) has counters for packet statistics. Its descriptive text gives formulas for some counter objects, and implementors noticed those formulas can produce negative values 😭

The original MIB module from [RFC2618] was already widely implemented, so the RADEXT WG chose not to change the object definitions or add new ones in the revised MIB module [RFC4668]. This section explains the issues and gives implementors guidance on reading the textual descriptions and comments for certain MIB objects 🧚

Here's the quick summary of the issues.

Issue (1):

-- TotalIncomingPackets = Accepts + Rejects + Challenges +
-- UnknownTypes
--
-- TotalIncomingPackets - MalformedResponses - BadAuthenticators -
-- UnknownTypes - PacketsDropped = Successfully received
--
-- AccessRequests + PendingRequests + ClientTimeouts =
-- Successfully Received

"Successfully Received" could be negative, since several counters get subtracted from TotalIncomingPackets even though they aren't part of how TotalIncomingPackets gets calculated πŸ’€ And the line "AccessRequests + PendingRequests + ClientTimeouts = Successfully Received" should really read "AccessRequests + PendingRequests + ClientTimeouts = Successfully Transmitted" ✨

"TotalIncomingPackets" and "Successfully Received" are temporary variables, not objects in the MIB module. So the comments are only there to help you understand things. What really matters is that the object values stay consistent, and that doesn't look affected by these mix-ups. The "Successfully Received" variable should still be relabeled "Successfully Transmitted" though πŸŽ€

There's another wrinkle. The definition of the Accept, Reject, and Challenge counters says they MUST be incremented before the message is validated. If the message turns out to be invalid, one of MalformedResponses, BadAuthenticators, or PacketsDropped gets incremented too. With that order, the first two equations are consistent, so "Successfully Received" couldn't go negative after all πŸ™Œ

Issue (2):

It looks like the radiusAuthClientPendingRequests counter gets decremented when a packet is retransmitted πŸ€” That means a retransmitted packet isn't counted as pending, even though it can still be a pending request.

The definition in [RFC2618] reads:

The number of RADIUS Access-Request packets destined for this
server that have not yet timed out or received a response.  This
variable is incremented when an Access-Request is sent and
decremented due to receipt of an Access-Accept, Access-Reject or
Access-Challenge, a timeout or retransmission.

This object is supposed to count pending request packets, but it's open to interpretation whether retransmissions count as extra pending packets. Either way, it makes sense to handle retransmissions the same way when incrementing and decrementing this counter πŸ’–

2.4. Multiple Filter-ID Attributes 🌸

[RFC2865] Section 5.11 says:

Zero or more Filter-Id attributes MAY be sent in an Access-Accept
packet.

In practice, what a RADIUS client does with multiple Filter-ID attributes depends on the implementation πŸ™ƒ Some treat them as alternative filters: the first Filter-ID whose name matches a locally defined filter gets used, and the rest are thrown away. Other implementations may combine the matching filters instead.

So multiple Filter-ID attributes don't have a defined meaning within RADIUS. Sending several inside one Access-Accept SHOULD be avoided in heterogeneous deployments and roaming scenarios, because it's likely to produce unpredictable results 😭

2.5. Mandatory and Optional Attributes 🧠

RADIUS attributes don't explicitly say whether they're optional or mandatory. Even so, there are cases where RADIUS attributes do need to be treated as mandatory πŸ’œ

[RFC2865] Section 1.1 says:

A NAS that does not implement a given service MUST NOT implement
the RADIUS attributes for that service.  For example, a NAS that
is unable to offer Apple Remote Access Protocol (ARAP) service
MUST NOT implement the RADIUS attributes for ARAP.  A NAS MUST
treat a RADIUS access-accept authorizing an unavailable service as
an access-reject instead.

About Service-Type, [RFC2865] Section 5.6 says:

This Attribute indicates the type of service the user has
requested, or the type of service to be provided.  It MAY be used
in both Access-Request and Access-Accept packets.  A NAS is not
required to implement all of these service types, and MUST treat
unknown or unsupported Service-Types as though an Access-Reject
had been received instead.

[RFC2865] Section 5 says:

A RADIUS server MAY ignore Attributes with an unknown Type.

A RADIUS client MAY ignore Attributes with an unknown Type.

And for Vendor-Specific Attributes (VSAs), [RFC2865] Section 5.26 says:

Servers not equipped to interpret the vendor-specific information
sent by a client MUST ignore it (although it may be reported).
Clients which do not receive desired vendor-specific information
SHOULD make an attempt to operate without it, although they may do
so (and report they are doing so) in a degraded mode.

Here's the tricky bit πŸ‘€ A standard attribute or a VSA can both represent a request for an unavailable service. But if the Type, Vendor-ID, or Vendor-Type is unknown, a RADIUS client has no way of knowing whether the attribute defines a service.

Generally, it's best for a RADIUS client to play it safe πŸ›‘οΈ If it receives an Access-Accept with an attribute of known Type for an unimplemented service, it MUST treat that as an Access-Reject, as [RFC2865] Section 1.1 directs. If it receives an Access-Accept with an attribute of unknown Type, it SHOULD assume the attribute could be a service definition and treat it as an Access-Reject. Unknown VSAs SHOULD be ignored by RADIUS clients 🫢

Existing implementations that don't follow this recommendation should make the behavior configurable, with the legacy behavior turned on by default, so default behavior doesn't change out from under people 🌈 An admin-facing flag such as "treat unknown attributes as reject" would do the trick. If the flag is true, Access-Accepts containing unknown attributes are treated as Access-Rejects. If it's false, unknown attributes in Access-Accepts are silently ignored ✨

When a RADIUS authentication server gets a packet with an attribute of unknown Type, it SHOULD ignore that attribute. Accounting servers are different: they usually don't need to understand an attribute to write it to stable storage or pass it along to the billing engine. So accounting server implementations SHOULD be equipped to handle unknown attributes πŸ’…

To avoid misreading service requests encoded in VSAs, RADIUS servers SHOULD NOT send VSAs containing service requests to RADIUS clients that aren't known to understand them. For example, a RADIUS server shouldn't send a VSA encoding a filter unless it knows the RADIUS client supports that VSA πŸ¦‹

2.6. Interpretation of Access-Reject πŸŽ€

2.6.1. Improper Use of Access-Reject πŸ™ˆ

okay so the whole point of an Access-Reject is to deny access to the requested service 🚫. [RFC2865] Section 2 says:

If any condition is not met, the RADIUS server sends an "Access-Reject" response indicating that this user request is invalid. If desired, the server MAY include a text message in the Access-Reject which MAY be displayed by the client to the user. No other Attributes (except Proxy-State) are permitted in an Access-Reject.

bestie, this makes it crystal clear that RADIUS does not allow provisioning services inside an Access-Reject πŸ’…. If you want to give someone limited access, you send an Access-Accept with attributes that provision that limited access ✨. Inside an Access-Reject, the only things allowed are the ones needed to route the message (like Proxy-State), the ones telling the user access was denied (like an EAP-Message holding an EAP-Failure), and the ones carrying an error message (like Reply-Message or Error-Cause) πŸŽ€.

Unfortunately, some people have misread this rule 😭. [RFC2869] Section 2.2 says:

If that authentication fails, the RADIUS server should return an Access-Reject packet to the NAS, with optional Password-Retry and Reply-Messages attributes. The presence of Password-Retry indicates the ARAP NAS MAY choose to initiate another challenge-response cycle...

this paragraph is problematic for two reasons πŸ™ƒ. First, a Password-Retry attribute is being returned inside an Access-Reject, and that attribute doesn't fit into the categories set out in [RFC2865]. Second, an Access-Reject is being sent in the middle of an ongoing authentication conversation, and [RFC2865] requires an Access-Challenge for that 🌸. [RFC2869] uses the phrase "challenge-response" to describe this use of Access-Reject, which tells you the semantics of Access-Challenge are being used.

[RFC2865] Section 4.4 covers the case where Access-Challenge is treated like an Access-Reject:

If the NAS does not support challenge/response, it MUST treat an Access-Challenge as though it had received an Access-Reject instead.

it's hard to fix existing [RFC2869] deployments, but here's what we recommend πŸ’–:

  • [1] New RADIUS specifications and implementations MUST NOT use Access-Reject where the semantics of Access-Challenge are intended.
  • [2] Access-Reject MUST mean denial of access to the requested service. In response to an Access-Reject, the NAS MUST NOT send any additional Access-Request packets for that user session.
  • [3] New deployments of ARAP [RFC2869] SHOULD use Access-Challenge instead of Access-Reject packets in the conversations described in [RFC2869] Section 2.2.

also, the attribute table in [RFC2869] Section 5.19 has a mistake for Password-Retry πŸ“. It currently reads:

Request  Accept  Reject  Challenge   #    Attribute
0        0       0-1     0           75   Password-Retry

but [RFC2869] Section 2.3.2 says Password-Retry can show up in an Access-Challenge for EAP authentication sessions 🧚. So we suggest fixing the table by moving the "0-1" from the Reject column over to the Challenge column, and adding a "Note 2" to go with the existing "Note 1" πŸ¦‹:

Request  Accept  Reject  Challenge   #    Attribute
0        0       0       0-1         75   Password-Retry [Note 2]
[Note 2] As per RFC 3579, the use of the Password-Retry in EAP authentications is deprecated. The Password-Retry attribute can be used only for ARAP authentication.

2.6.2. Service Request Denial 🌈

RADIUS has been deployed for way more than network access authentication, authorization, and accounting πŸ‘‘. For example, it's been used as a "back-end" for authenticating Voice Over IP (VOIP) connections, Hypertext Transfer Protocol (HTTP) sessions (e.g., Apache), File Transfer Protocol (FTP) sessions (e.g., proftpd), and machine logins for multiple operating systems (e.g., bsdi, pam, and gina) 🫢. In all of those contexts, an Access-Reject sent to the RADIUS client MUST be interpreted as a rejection of the request for service, and the RADIUS client MUST NOT offer that service to the user πŸ”₯.

for example, if an authentication failure happens during an FTP session, the normal rules for rejecting FTP services apply πŸŽ€. The rejection doesn't necessarily cause the FTP server to kill the underlying TCP connection, but the FTP server MUST NOT offer any services protected by user authentication ✨.

users may request multiple services from the NAS. Where those services are independent, the deployment MUST treat the RADIUS sessions as being independent πŸ¦‹.

for example, a NAS may offer multi-link services, where a user can have several connections running at once 🌸. In that case, an Access-Reject for a later multi-link connection request doesn't necessarily mean the earlier multi-link connections get torn down. Likewise, if a NAS offers both dialup and VOIP services, rejecting a VOIP attempt doesn't mean the dialup session gets torn down either πŸ’œ.


2.7. Addressing πŸ—ΊοΈ

Link-Local addresses are only unique on the local link πŸ™ˆ. So if the NAS and RADIUS server aren't on the same link, an IPv6 Link-Local address [RFC4862] or an IPv4 Link-Local Address [RFC3927] can't be used to uniquely identify the NAS. A NAS SHOULD NOT use a link-scope address within a NAS-IPv6-Address or NAS-IP-Address attribute. A RADIUS server that receives a NAS-IPv6-Address or NAS-IP-Address attribute containing a Link-Local address SHOULD NOT count that attribute toward satisfying the requirements of [RFC3162] Section 2.1:

NAS-IPv6-Address and/or NAS-IP-Address MAY be present in an Access-Request packet; however, if neither attribute is present then NAS-Identifier MUST be present.

2.7.2. Multiple Addresses πŸ’…

sometimes a RADIUS client or server has more than one address 🌈. A dual stack host can have both IPv4 and IPv6 addresses. A host in multiple VLANs could have IPv4 and/or IPv6 addresses on each VLAN. A host can also have several IPv4 or IPv6 addresses on a single interface. The catch is that [RFC2865] Section 5.44 only permits zero or one NAS-IP-Address attributes in an Access-Request, and [RFC3162] Section 3 only permits zero or one NAS-IPv6-Address attributes in an Access-Request 😭. So when a NAS has more than one global address and no way to figure out which one is used for identification in a particular request, it is RECOMMENDED that the NAS include the NAS-Identifier attribute in an Access-Request to identify itself to the RADIUS server 🫢.

[RFC2865] Section 3 says:

A RADIUS server MUST use the source IP address of the RADIUS UDP packet to decide which shared secret to use, so that RADIUS requests can be proxied.

therefore, if a RADIUS client sends packets from more than one source address, a shared secret will need to be configured on both the client and the server for each source address πŸ”‘.


2.8. Idle-Timeout ⏳

For the Idle-Timeout attribute, [RFC2865] Section 5.28 says:

This Attribute sets the maximum number of consecutive seconds of idle connection allowed to the user before termination of the session or prompt. This Attribute is available to be sent by the server to the client in an Access-Accept or Access-Challenge.

[RFC3580] Section 3.12 adds:

The Idle-Timeout attribute is described in [RFC2865]. For IEEE 802 media other than 802.11 the media are always on. As a result the Idle-Timeout attribute is typically only used with wireless media such as IEEE 802.11. It is possible for a wireless device to wander out of range of all Access Points. In this case, the Idle-Timeout attribute indicates the maximum time that a wireless device may remain idle.

in the paragraphs above, "idle" doesn't automatically mean "no traffic" πŸ™ƒ. The NAS may support filters that define which traffic counts toward the idle time, so an "idle connection" is defined by local policy when no other attributes are present 🧚.


2.9. Unknown Identity πŸ€·β€β™€οΈ

[RFC3748] Section 5.1 says:

If the Identity is unknown, the Identity Response field should be zero bytes in length.

but [RFC2865] Section 5.1 describes the User-Name attribute like this:

The String field is one or more octets.

so how should the RADIUS client behave if it gets an EAP-Response/Identity that's zero octets long? πŸ€”

[RFC2865] Section 5.1 says:

This Attribute indicates the name of the user to be authenticated. It MUST be sent in Access-Request packets if available.

this kind of suggests that User-Name can be left out when it's not available πŸ™ˆ.

BUT [RFC3579] Section 2.1 says:

In order to permit non-EAP aware RADIUS proxies to forward the Access-Request packet, if the NAS initially sends an EAP-Request/Identity message to the peer, the NAS MUST copy the contents of the Type-Data field of the EAP-Response/Identity received from the peer into the User-Name attribute and MUST include the Type-Data field of the EAP-Response/Identity in the User-Name attribute in every subsequent Access-Request.

this suggests User-Name should hold the contents of the Type-Data field of the EAP-Response/Identity, even if that's zero octets long πŸ’œ.

note that [RFC4282] doesn't allow a Network Access Identifier (NAI) of zero octets πŸ”. So an EAP-Response/Identity with a zero-octet Type-Data field MUST NOT be read as a request for privacy (for example, an anonymous NAI) 🫣.

when a NAS gets an EAP-Response/Identity with a zero-octet Type-Data field, it is RECOMMENDED that it either leave the User-Name attribute out of the Access-Request, or put the Calling-Station-Id in the User-Name attribute along with a Calling-Station-Id attribute 🌟.

2.10. Responses After Retransmissions πŸ”

Okay so some implementations just don't handle RADIUS responses that show up after a retransmission correctly 😭. [RFC2865] Section 2.5 says:

   If the NAS is retransmitting a RADIUS request to the same server
   as before, and the attributes haven't changed, you MUST use the
   same Request Authenticator, ID, and source port.  If any
   attributes have changed, you MUST use a new Request Authenticator
   and ID.

Changing the Request ID on a retransmission can have side effects you really don't want πŸ™ˆ. RADIUS doesn't have a clear definition of a "session", so it's totally valid for a server to treat a retransmission as a brand-new session request and reject it because of something like a limit on multiple simultaneous logins. Drama, bestie πŸ’….

So the NAS might get a late Access-Accept for the first request and an Access-Reject for the retransmitted one, and both of them are about the same "session" πŸ’€.

Here's the vibe we suggest: the contents of Access-Request packets SHOULD NOT be changed during retransmissions. If they have to change, like for an Event-Timestamp attribute, then responses to earlier transmissions MUST be silently discarded. Any response to the current request MUST be treated as the definitive response, even if it disagrees with the earlier ones 🫢.

This gets worse with implementations that use a fixed retransmission timeout (30 seconds is common) 😩. We reiterate the suggestions in Section 2.1 about using congestive backoff. Even so, responses to earlier transmissions MAY be used as data points for congestive backoff, even if their contents are discarded.

2.11. Framed-IPv6-Prefix 🌸

[RFC3162] Section 2.3 says:

   This Attribute indicates an IPv6 prefix (and corresponding route)
   to be configured for the user.  It MAY be used in Access-Accept
   packets, and can appear multiple times.  It MAY be used in an
   Access-Request packet as a hint by the NAS to the server that it
   would prefer these prefix(es), but the server is not required to
   honor the hint.  Since it is assumed that the NAS will plumb a
   route corresponding to the prefix, it is not necessary for the
   server to also send a Framed-IPv6-Route attribute for the same
   prefix.

An Internet Service Provider (ISP) might want to support Prefix Delegation [RFC4818] and also assign a prefix for the link between the NAS and the user at the same time 🧚. The point of this paragraph was to let the NAS advertise the prefix, like through a Router Advertisement. If the Framed-Routing attribute is used, the prefix could also get advertised in a routing protocol such as Routing Information Protocol Next Generation (RIPNG) πŸ›£οΈ. [RFC2865] Section 5.10 describes the purpose of Framed-Routing:

   This Attribute indicates the routing method for the user, when the
   user is a router to a network.  It is only used in Access-Accept
   packets.

Now the Prefix-Length description in RFC 3162 gives way too much wiggle room πŸ™ƒ:

   The length of the prefix, in bits.  At least 0 and no larger than
   128.

It's giving too broad, because it isn't clear what a NAS should do with a prefix more specific than /64. For example, the Framed-IPv6-Prefix might contain a /128. That does not mean the NAS should assign an IPv6 address to the end user, because RFC 3162 already defines a Framed-IPv6-Identifier attribute to handle the Identifier portion πŸŽ€.

The Framed-IPv6-Prefix only seems to be used for the link between the NAS and Customer Premises Equipment (CPE) if a /64 prefix is assigned πŸ’œ. When a /64 or larger prefix is sent, the NAS is supposed to send a routing advertisement with the info from the Framed-IPv6-Prefix attribute.

The CPE might also need its own delegated prefix if it decrements the Hop Limit field of IP headers. In that case, the NAS should delegate it a prefix via the Delegated-IPv6-Prefix attribute [RFC4818]. If the CPE isn't decrementing Hop Limit, it doesn't need a delegated prefix ✨.


3. Security Considerations πŸ”

Okay, this section is serious, so please read it carefully 🚨.

The contents of the State attribute are available to both the RADIUS client and to observers of the RADIUS protocol. RADIUS server implementations should make sure the State attribute doesn't disclose sensitive information to a RADIUS client or to third parties observing the RADIUS protocol.

The cache mechanism described in Section 2.2.2 is vulnerable to attacks when Access-Request packets don't contain a Message-Authenticator attribute. If the server accepts requests without a Message-Authenticator, RADIUS packets can be trivially forged by an attacker πŸ’€. Cache entries can then be forcibly expired, which totally negates the point of the cache. This attack can be mitigated by following the suggestions in [RFC3579] Section 4, or by requiring the presence of Message-Authenticator, as described in Sections 2.1.1 and 2.2.2 πŸ›‘οΈ.

This document describes using RADIUS for authentication, authorization, and accounting across a wide variety of networks. That means applications using these specifications are vulnerable to all of the threats that are present in other RADIUS applications. For a discussion of these threats, see [RFC2865], [RFC2607], [RFC3162], [RFC3579], and [RFC3580] πŸ“š.


4. References πŸ“–

4.1. Normative References

[RFC2119]   Bradner, S., "Key words for use in RFCs to Indicate
            Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC2865]   Rigney, C., Willens, S., Rubens, A., and W. Simpson,
            "Remote Authentication Dial In User Service (RADIUS)",
            RFC 2865, June 2000.

[RFC4818]   Salowey, J. and R. Droms, "RADIUS Delegated-IPv6-Prefix
            Attribute", RFC 4818, April 2007.

4.2. Informative References

[RFC2607]   Aboba, B. and J. Vollbrecht, "Proxy Chaining and Policy
            Implementation in Roaming", RFC 2607, June 1999.

[RFC2618]   Aboba, B. and G. Zorn, "RADIUS Authentication Client
            MIB", RFC 2618, June 1999.

[RFC2866]   Rigney, C., "RADIUS Accounting", RFC 2866, June 2000.

[RFC2869]   Rigney, C., Willats, W., and P. Calhoun, "RADIUS
            Extensions", RFC 2869, June 2000.

[RFC3162]   Aboba, B., Zorn, G., and D. Mitton, "RADIUS and IPv6",
            RFC 3162, August 2001.

[RFC3315]   Droms, R., Ed., Bound, J., Volz, B., Lemon, T., Perkins,
            C., and M. Carney, "Dynamic Host Configuration Protocol
            for IPv6 (DHCPv6)", RFC 3315, July 2003.

[RFC3576]   Chiba, M., Dommety, G., Eklund, M., Mitton, D., and B.
            Aboba, "Dynamic Authorization Extensions to Remote
            Authentication Dial In User Service (RADIUS)", RFC 3576,
            July 2003.

[RFC3579]   Aboba, B. and P. Calhoun, "RADIUS (Remote Authentication
            Dial In User Service) Support For Extensible
            Authentication Protocol (EAP)", RFC 3579, September 2003.

[RFC3580]   Congdon, P., Aboba, B., Smith, A., Zorn, G., and J.
            Roese, "IEEE 802.1X Remote Authentication Dial In User
            Service (RADIUS) Usage Guidelines", RFC 3580, September
            2003.

[RFC3748]   Aboba, B., Blunk, L., Vollbrecht, J., Carlson, J., and H.
            Levkowetz, Ed., "Extensible Authentication Protocol
            (EAP)", RFC 3748, June 2004.

[RFC3927]   Cheshire, S., Aboba, B., and E. Guttman, "Dynamic
            Configuration of IPv4 Link-Local Addresses", RFC 3927,
            May 2005.

[RFC4282]   Aboba, B., Beadles, M., Arkko, J., and P. Eronen, "The
            Network Access Identifier", RFC 4282, December 2005.

[RFC4668]   Nelson, D., "RADIUS Authentication Client MIB for IPv6",
            RFC 4668, August 2006.

[RFC4669]   Nelson, D., "RADIUS Authentication Server MIB for IPv6",
            RFC 4669, August 2006.

[RFC4862]   Thomson, S., Narten, T., and T. Jinmei, "IPv6 Stateless
            Address Autoconfiguration", RFC 4862, September 2007.

[PANA]      Forsberg, D., Ohba, Y.,Ed., Patil, B., Tschofenig, H.,
            and A. Yegin, "Protocol for Carrying Authentication for
            Network Access (PANA)", Work in Progress.

Acknowledgments 🫢

The authors want to give a huge shout-out to Glen Zorn and Bernard Aboba for their contributions to this document πŸ₯°.

The alternate algorithm to [RFC3579] Section 2.6.1, which is described in Section 2.1.2 of this document, was designed by Raghu Dendukuri 🧠.

The text discussing retransmissions in Section 2.2.1 is taken with minor edits from Section 9 of" Protocol for Carrying Authentication for Network Access (PANA)" [PANA] πŸ™Œ.

Alan DeKok wants to acknowledge the support of Quiconnect Inc., where he was employed during much of the work on this document πŸ’–.

David Nelson wants to acknowledge the support of Enterasys Networks, where he was employed during much of the work on this document πŸ’–.


Authors' Addresses πŸ’Œ

David B. Nelson
Elbrys Networks, Inc.
75 Rochester Ave., Unit 3
Portsmouth, N.H. 03801 USA

Phone: +1.603.570.2636
EMail: dnelson@elbrysnetworks.com


Alan DeKok
The FreeRADIUS Server Project
http://freeradius.org/

EMail: aland@freeradius.org

Copyright (C) The IETF Trust (2007).

This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.


Intellectual Property πŸ”

The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document, or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.

Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.

The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org πŸŽ‰.

πŸ“¦ where this page comes from