Subject: [radext] Adam Roach's Discuss on draft-ietf-radext-coa-proxy-05: (with DISCUSS and COMMENT)

From: Adam Roach <[email-masked]>
Date: Mon, 13 Aug 2018 19:06:51 -0700

Adam Roach has entered the following ballot position for
draft-ietf-radext-coa-proxy-05: Discuss

When responding, please keep the subject line intact and reply to all
email addresses included in the To and CC lines. (Feel free to cut this
introductory paragraph, however.)

Please refer to https://www.ietf.org/iesg/statement/discuss-criteria.html
for more information about IESG DISCUSS and COMMENT positions.

The document, along with other ballot positions, can be found here:
https://datatracker.ietf.org/doc/draft-ietf-radext-coa-proxy/

----------------------------------------------------------------------
DISCUSS:
----------------------------------------------------------------------

I'd like to thank the author and all other involved parties for the work that
has gone into making CoA transactions work across multiple domains. I have a
couple of DISCUSS points that I think need to be cleared up.

---------------------------------------------------------------------------

This is a concern with the general mechanism, and might be due to a
misunderstanding on my part (which I hope you can clear up); but if I'm not
wrong, then I'm concerned that the mechanism as described can introduce RADIUS
message routing loops in some very common deployment scenarios.

Consider a setup involving three networks: a Visited network (with its NAS and
a Radius server), a Clearinghouse network (with one or more proxies), and a
Home network (with a border proxy and a Home Server). Both the Home and Visited
network also have federated networks that they communicate directly with without
traversing the Clearinghouse network.

The Clearinghouse determines the destination of any request message by looking
at the realm portion of the NAI present in the "User-Name" attribute, which I
believe is pretty common routing logic in these kinds of cases.

Now, consider what happens when the Home network updates to use this mechanism
(in order to better work with their federated partners), and the Visited network
also updates to use this mechanism (for the same reason), but the Clearinghouse
is not yet updated. I'll try to step through section 5 with this scenario:

1) The NAS in the Visited network sends an Access-Request packet to the
   Visited Radius server. The visited RADIUS server will see that the
   user is roaming, and will add an Operator-Name attribute, with value
   "1" followed by it's own realm name.  e.g. "1example.com".

2) The visited RADIUS server will then proxy the authentication request
   to the Clearinghouse network, which uses the NAI in the User-Name to forward
   it to the Home network.

3) The Home Server records the Operator-Name along with other information
   about the users session

4) When the Home Server determines that a user should be disconnected,
   it looks up the Operator-Name, along with other user session identifiers as
   described in [RFC5176].

5) The Home Server sends the Disconnect-Request to the Home domain's border
   proxy.

6) The Home domain's border proxy looks up the Operator-Name in the
   Disconnect-Request message, determines that it is an operator that it is
   not federated with, and consequently sends the Disconnect-Request to the
   Clearinghouse.

7) The Clearinghouse receives the Disconnect-Request message. Since it has not
   yet been updated to handle the Operator-Name attribute as described in this
   document, it follows its normal logic of routing according to the NAI in the
   User-Name attribute.

8) Go to 6

---------------------------------------------------------------------------

§4.2:

>  The value SHOULD be cryptographically strong, and SHOULD be
>  verifiable by the Visited Network, without requiring it to track in a
>  database every individual value of Operator-NAS-identifier which was
>  issued.

I don't think this is really phrased in a way that means what you want to say.
If I had to guess, you mean to say that the value must be encrypted, and that it
must be integrity-protected. If integrity protection is important, then you also
need to consider techniques to avoid replay of previously-seen tokens (e.g., the
integrity protection needs to be over not just the Operator-NAS-Identifier,
but also over some portion of the session that prevents its replay). Most
notably, this desire for encryption and integrity protection is almost
certainly at odds with the assertion (in §3.3) that "A twenty octet string is
more than sufficient to individually address all of the NASes on the planet."
For example, the naïve approach of appending a SHA-256 hash to the end of an
encrypted, salted index into a table of NAS devices would require over 32 bytes
at its absolute minimum. So, if integrity protection is something that any
operator might ever want, you need to revisit the 20-byte limit.

>  Exactly how this requirement is implemented is outside of the scope
>  of this document.

That's fair, but I think you need a proof-of-concept example of how it could be
done, so that you find any additional corner cases beyond the one I've
identified above.

I think these aspects of this attribute need a lot more treatment in Section 6.

----------------------------------------------------------------------
COMMENT:
----------------------------------------------------------------------

All of my comments are editorial nits.

---------------------------------------------------------------------------

ID Nits reports:

  ** The abstract seems to contain references ([RFC7542]), which it
     shouldn't.  Please replace those with straight textual mentions of the
     documents in question (e.g., "RFC 7542").

---------------------------------------------------------------------------

§2.1:

>  Other methods are
>  possible, but we restrict ourselves to this usage, as it is the most
>  common one.

This needs to be clear whether the *description* is restricted to NAI-based
routing, or whether the *mechanism* is. I suspect it's the former; in any case,
please add text.

---------------------------------------------------------------------------

§2.1:

>  Once
>  a response has been received by the proxy, it can discard all
>  information about the request packet.

Nit: "Once a response has been sent by the proxy..."
                               ^^^^

---------------------------------------------------------------------------

§3.2:

>  We therefore need a way to identifier a NAS in the Visited Network,

Nit: "...to identify a NAS..."

---------------------------------------------------------------------------

§3.3:

>  We suggest that the contents of the NAS-Identifier be the Realm name
>  of the Visited Network.  That is, for everyone outside of the Visited
>  Network, there is only one NAS: the Visited Network itself.  For the
>  Visited Network, the identity of the NAS is private information,
>  which is opaque to everyone else.

Please be clear that this recommendation is for the (existing) NAS-Identifier
attribute rather than the (new) Operator-NAS-Identifier attribute.

---------------------------------------------------------------------------

§3.3:

>     This token MUST allow the Visited Network to direct the packet to
>     the NAS for the users session.

Nit: "...user's session..."

---------------------------------------------------------------------------

§4.2:

>  CoA server (i.e. NAS).  This requirement is phrase more generically
>  below, in Section 4.3.2.

Nit: "...phrased..."

---------------------------------------------------------------------------

§4.3.1:

>  it SHOULD return a
>  CoA-NAK or Disconnect-NAK packet, that contains an Error-Cause
>  attribute having value 503 ("Session Context Not Found").

Nit: "...packet that contains..."

---

From: Alan DeKok <[email-masked]>
Date: Tue, 14 Aug 2018 09:02:30 -0400

> message routing loops in some very common deployment scenarios.

  I don't think so, for the simple reason that clearing houses don't accept CoA packets right now.

  There are other reasons.

>   not federated with, and consequently sends the Disconnect-Request to the

  Note that 6 depends on 5.  i.e. the Home domain border proxy should *not* accept random packets, even from trusted parties, and proxy them to random destinations.  Doing so would be a violation of a host of security issues.

  The Home domain border proxy MUST implement the following rules:

- CoA packets from inside the network (i.e. trusted packets) can be proxied externally

- CoA packets from outside the network (i.e. less trusted packets) MUST contain the realm of the Home domain.  All other packets MUST be NAKd.

  These rules are already applied for Access-Request and Accounting-Request packets.

>   document,

  ... it discards the packet as unknown.  At the *network* layer, because nothing is even listening on the CoA port (3759).

  If the clearing house receives the CoA packet on one of the normal RADIUS ports (1812 or 1813), it also discards the packet, as those ports are only supposed to be for Access-Request and Accounting-Request packets.

  If the clearing house implements RADIUS over TCP/TLS, then it's permitted to accept any packet (CoA or otherwise) on that port.  However... it must also have processing rules for those packets in place.  And since there is currently no way to proxy CoA packets, it will discard the packet.

> it follows its normal logic of routing according to the NAI in the
>   User-Name attribute.

  It should not follow the normal logic of routing according to the NAI.  For one, clearing houses currently only deal with Access-Request and Accounting-Request packets.  Any *other* packet they receive is silently discarded.

  So in order for a loop to exist, multiple things have to go wrong:

- the clearing house has to accept CoA packets (none do right now)

- the clearing house has to be configured to use the NAI for forwarding CoA packets (no RADIUS server does this)

- the home domain proxy has to accept external packets for third-party domains, and forward them (all these systems have rules in place now to prevent this).

  I'll see if I can clarify this issue in the document.

> need to consider techniques to avoid replay of previously-seen tokens

  Why is replay an issue?  The point of obfuscating the information is to hide internal / private information about the network.  e.g. private IP of the NAS.

  If a home server replays a previously-seen token, then one of two things will happen:

- the packet will go to the NAS which hosts the user session, and will be processed normally

- the packet will go to a different NAS, and will be NAKd

> (e.g., the

  32 bytes is fine.  I'll update that.

> done, so that you find any additional corner cases beyond the one I've

  Fair enough.

> I think these aspects of this attribute need a lot more treatment in Section 6.

  I'll add some text.

>     documents in question (e.g., "RFC 7542").

  Fixed.

> routing, or whether the *mechanism* is. I suspect it's the former; in any case,

  This spec documents NAI-based CoA proxying.  Other methods can be used, but aren't discussed here.

  The mechanism for discovering next hop is specific to NAI-based proxying.

  Fixed.

  Fixed.

  I'll update the text.

  Fixed.

  Fixed.

  Fixed.

  Alan DeKok.

---

From: Alan DeKok <[email-masked]>
Date: Tue, 14 Aug 2018 09:18:32 -0400

> message routing loops in some very common deployment scenarios.

  Just to be clear: RFC 7542 (NAI) doesn't say that home networks only accept packets for their own Realms.  This could perhaps be said explicitly.

  I've submitted an errata to RFC 7542 with some text.

  I'll also update this document to clarify this situation.

  Alan DeKok.

---

From: Adam Roach <[email-masked]>
Date: Tue, 14 Aug 2018 08:43:23 -0500

>    I don't think so, for the simple reason that clearing houses don't accept CoA packets right now.

Thanks. This (and the rest of your explanation) makes sense.

>    Why is replay an issue?  The point of obfuscating the information is to hide internal / private information about the network.  e.g. private IP of the NAS.

Generally, when integrity is important, so is anti-replay. If you care 
that remote parties can't create their own novel values, it would be 
surprising not to care about them squirreling away values they've seen 
before and using them later. Conversely, if you don't care about replay, 
you probably need to think really hard about why you care about integrity.

Of course, it's completely possible that I'm misunderstanding what you 
mean by "verifiable" in the original text (which gets to the heart of my 
original comment: there are terms of art for the properties that 
cryptography provides, and you really want to use them for the purpose 
of clarity.)

> - the packet will go to a different NAS, and will be NAKd

Sure. If that's the answer, then it seems like it's the same answer if 
the home server creates a new, invalid token; and that would mean that 
integrity isn't needed.

I'm afraid you need to go back and figure out what your actual security 
requirements are here by asking what attacks might exist, and what their 
consequences are. The current text seems to be kind of an afterthought 
without any real analysis.

>    32 bytes is fine.  I'll update that.

Sorry, by "more than 32 bytes," I meant that the hash itself would take 
32 bytes. You'd also have however long the Visited domain's identifier 
for the NAS is (which you originally thought would take 20 bytes), plus 
some number of nonce bytes (to prevent other networks from simply 
counting unique token values). You're really looking at more like 96 
bytes or so.

Note that this gets somewhat smaller if integrity protection isn't 
important.

>    The mechanism for discovering next hop is specific to NAI-based proxying.

Okay; make this clearer, please.

Thanks!

/a

---

From: Alan DeKok <[email-masked]>
Date: Tue, 14 Aug 2018 11:01:27 -0400

On Aug 14, 2018, at 9:43 AM, Adam Roach <[email-masked]> wrote:
> Generally, when integrity is important, so is anti-replay. If you care that remote parties can't create their own novel values, it would be surprising not to care about them squirreling away values they've seen before and using them later. Conversely, if you don't care about replay, you probably need to think really hard about why you care about integrity.
> 
> Of course, it's completely possible that I'm misunderstanding what you mean by "verifiable" in the original text (which gets to the heart of my original comment: there are terms of art for the properties that cryptography provides, and you really want to use them for the purpose of clarity.)

  In this situation, all we really care about is that the opaque token is known.  And it really should be opaque.  It's just bits, and not necessarily containing anything in particular.

> Sure. If that's the answer, then it seems like it's the same answer if the home server creates a new, invalid token; and that would mean that integrity isn't needed.

  Yes.

> I'm afraid you need to go back and figure out what your actual security requirements are here by asking what attacks might exist, and what their consequences are. The current text seems to be kind of an afterthought without any real analysis.

  Maybe I'm missing something, but it's pretty hard to "attack" an opaque token.  It can be (a) modified, or (b) replayed.  If it's modified, it doesn't match anything and it gets ignored.  If it's replayed, it's still a recognized token, and that's OK.

  All of the attacks here *also* depend on systems knowing the RADIUS shared secret.  i.e. these systems are already part of a trusted network.  They are already trusted to not replay accounting packets, authentication packets, forge accounting traffic (to increase bills), etc.

  The attacks for CoA here are nothing new.  The security is terrible, but we've lived with it for 25+ years, and it's what we have.

  Finally, if trusted parties attack you, the fix is usually legal, not technical.

  I'll update the Security Considerations section with some text on why roaming consortiums are open to forging.  But I think the risks here are fairly well known.

> Sorry, by "more than 32 bytes," I meant that the hash itself would take 32 bytes. You'd also have however long the Visited domain's identifier for the NAS is (which you originally thought would take 20 bytes), plus some number of nonce bytes (to prevent other networks from simply counting unique token values). You're really looking at more like 96 bytes or so.
> 
> Note that this gets somewhat smaller if integrity protection isn't important.

  Integrity protection isn't important.

  Alan DeKok.

---

From: Adam Roach <[email-masked]>
Date: Tue, 14 Aug 2018 10:51:19 -0500

>    In this situation, all we really care about is that the opaque token is known.  And it really should be opaque.  It's just bits, and not necessarily containing anything in particular.

I think we're getting off in the weeds here exactly because the language 
in the document is ambiguous. I think I made some assumptions that might 
not match yours. Let's try a level set.

The document says that the token "SHOULD be cryptographically strong." 
What does this mean, and why do you need it?

The document says that the token "SHOULD be verifiable by the Visited 
Network." What does this mean, and why do you need it?

/a

---

From: Alan DeKok <[email-masked]>
Date: Tue, 14 Aug 2018 12:11:04 -0400

On Aug 14, 2018, at 11:51 AM, Adam Roach <[email-masked]> wrote:
> I think we're getting off in the weeds here exactly because the language in the document is ambiguous. I think I made some assumptions that might not match yours. Let's try a level set.
> 
> The document says that the token "SHOULD be cryptographically strong." What does this mean, and why do you need it?

  The Operator-NAS-Identifier may contain information, such as an encrypted IP address.  In which case it should use sane encryption methods.

  If it's just an opaque token, then the token value should be created via some sane method.  Mainly to avoid accidental re-use.

> The document says that the token "SHOULD be verifiable by the Visited Network." What does this mean, and why do you need it?

  The visited network needs to know that the token maps to an actual NAS.

  If the token is an encrypted blob, it can decrypt the blob and verify it that way.  If the token is an opaque value, then the network needs to store the values it sends out.  Incoming values are then checked against the list to see if they're known.

  I think part of the confusion is that I don't want to restrict how people use it.  It might be simpler to just give one recommendation, and leave it at that.

  Alan DeKok.

---

From: Adam Roach <[email-masked]>
Date: Tue, 14 Aug 2018 12:16:28 -0500

>    If it's just an opaque token, then the token value should be created via some sane method.  Mainly to avoid accidental re-use.

You've described what you mean, without saying why you need it, and so 
I'm not sure what you mean achieves what you think you need -- and I 
have have a creeping suspicion that it does not.

I *think* the idea here is hiding things like how many NASes you have 
deployed in your network [1]. If that's the case, you'll minimally need 
some guidance here about each token being encrypted separately, using a 
unique nonce.

I'll note that the creation of opaque tokens that don't differ between 
requests (as you seem to suggest above) doesn't achieve the goal of 
hiding the number of NASes -- it's not harder to count unique opaque 
tokens than it is to count IP addresses.

>    If the token is an encrypted blob, it can decrypt the blob and verify it that way.

Sorry, verify it how?

Let's say my token generation scheme is to take the IP address of the 
NAS, pack it up in network byte order, and run it through some 
encryption algorithm. So, I get a blob in a Disconnect-Request message, 
run it through decryption, and get four bytes:  136, 35, 8, and 43. That 
looks like a valid IP address to me. I still can't tell whether I 
generated the blob, or whether someone else just created a random blob 
and that's what it happened to decrypt to -- because most four-byte 
sequences are valid IPv4 addresses.

And, as for needing to know that it maps to an actual NAS: why? If the 
something is messing up these tokens and the worst thing that happens is 
that the transaction fails, that seems to be fine.

/a

____
[1] I'm basing this in part on the text from §6: "This ensures that 
anyone observing unencrypted RADIUS traffic gains no information about 
the internals of the Visited Network."

---

From: Alan DeKok <[email-masked]>
Date: Tue, 14 Aug 2018 13:31:38 -0400

On Aug 14, 2018, at 1:16 PM, Adam Roach <[email-masked]> wrote:
> You've described what you mean, without saying why you need it, and so I'm not sure what you mean achieves what you think you need -- and I have have a creeping suspicion that it does not.

  Let me back up.

  The scheme could work just as well if Operator-NAS-Identifier contained the actual IP address of the NAS.

  The main reason to make it private is that there is no compelling reason to make it public.  And as a general rule, keeping private things private is a good idea.

> I *think* the idea here is hiding things like how many NASes you have deployed in your network [1]. If that's the case, you'll minimally need some guidance here about each token being encrypted separately, using a unique nonce.

  I don't think that's necessary.  See below.

> I'll note that the creation of opaque tokens that don't differ between requests (as you seem to suggest above) doesn't achieve the goal of hiding the number of NASes -- it's not harder to count unique opaque tokens than it is to count IP addresses.

  Of course.  That being said... Access-Request and Accounting-Request packets typically contain the MAC address of the NAS.  So the number of NASes is already public information.

>>   If the token is an encrypted blob, it can decrypt the blob and verify it that way.

  It's probably better to just not refer to verifying the value.

> Let's say my token generation scheme is to take the IP address of the NAS, pack it up in network byte order, and run it through some encryption algorithm. So, I get a blob in a Disconnect-Request message, run it through decryption, and get four bytes:  136, 35, 8, and 43. That looks like a valid IP address to me. I still can't tell whether I generated the blob, or whether someone else just created a random blob and that's what it happened to decrypt to -- because most four-byte sequences are valid IPv4 addresses.
> 
> And, as for needing to know that it maps to an actual NAS: why? If the something is messing up these tokens and the worst thing that happens is that the transaction fails, that seems to be fine.

  Sure.

  To be honest, this is really getting into details which I don't think matter in the real world.  CoA packets are only accepted from trusted parties.  Or transitively, from parties they trust.  All of those parties have access to all of the user session identification information.  If the parties mangle the Operator-NAS-Identfifier, then the transaction fails.  So they have no reason to do so.  And much of the information about a NAS (and their number) is already public.

  Which means that there is substantially less reason to make the Operator-NAS-Identifier unique, verifiable, etc.  Just encrypt the IP address, and it's fine.  Or, create an opaque token per NAS, store token/IP in a table, and it's fine.

  Any security issues with the contents of Operator-NAS-Identifier are largely mitigated by the utter crap-fest that's the rest of RADIUS.  Which means that it doesn't really matter how the values of Operator-NAS-Identifier are created, stored, or used.

  Alan DeKok.

---

From: Benjamin Kaduk <[email-masked]>
Date: Tue, 14 Aug 2018 12:32:44 -0500

> some guidance here about each token being encrypted separately, using a 

I think when I read this, I was thinking "I don't want to expose the
specific IP addresses of my NASes".  Maybe because I'm squatting on some IP
space that I shouldn't be, or maybe because I'm trying to set up a crisp
shell around a soft gooey interior, or maybe something else.  The mindset
would then be more of a lookup table than "real" encryption.  And if
someone wants to muck around with my lookup table, they either miss and get
NAK or they go to the wrong NAS and also get a NAK.

-Benjamin

> _______________________________________________
> radext mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/radext

---

From: Adam Roach <[email-masked]>
Date: Tue, 14 Aug 2018 12:43:49 -0500

>    Any security issues with the contents of Operator-NAS-Identifier are largely mitigated by the utter crap-fest that's the rest of RADIUS.  Which means that it doesn't really matter how the values…

Perfect! That's what the document should say.

Mostly, I was taking issue with language that implies that there is some 
level of security being applied to this token, and that the guidance and 
mechanisms in this draft were sufficient to even allow doing so (see, 
e.g., my comment on field sizes). Securing this field would be fine, if 
done correctly. Leaving it unsecured -- as is done with similar 
information in Radius -- is fine also. It's the middle-ground of 
security theater -- and, in this case, RFC-2119-language normative 
security theater --  that I think is dangerous.

/a