hi, a little something that I've been meaning to send out for a while. basically, a small addition to policy.conf (that probably could do with a few little extra additions) that will allow sites to easily check for NAI 4282 compliance - simply, that a User-Name is valid for proxying to other locations - a great boon for sites using eduroam , for example, as it stops end sites filling up the heirarchical proxy system with junk requests.... many sites have a lot of messy rules in place...with this addition to policy.conf all they need to do is call check_nai_compliance in their authorize section and things are nice. attached (should be all okay for 2.1.13 and 3.x ) alan
On Fri, Jun 01, 2012 at 07:47:24PM +0100, alan buxey wrote:
a little something that I've been meaning to send out for a while. basically, a small addition to policy.conf (that probably could do with a few little extra additions) that will allow sites to easily check for NAI 4282 compliance
Which appears to be buggy:
# Realm begins with a dot e.g. user@.site.com # if (User-Name !~ /@\\./) { update reply { Reply-Message = "misconfigured client. Realm begins with a dot" } reject }
Unless I am mistaken, that code will reject users whose realm *doesn't* start with a dot. There are also a number of simplifications possible, e.g.
if(User-Name =~ /@(.+)?@/i ) {
could be more directly written as:
if(User-Name =~ /@.*@/ ) {
HTH, Brian.
Hi,
Which appears to be buggy:
yep - some of which was due to a couple of last minute additions...but thats why we have open source and many eye ;-)
# Realm begins with a dot e.g. user@.site.com # if (User-Name !~ /@\\./) { update reply { Reply-Message = "misconfigured client. Realm begins with a dot" } reject }
Unless I am mistaken, that code will reject users whose realm *doesn't* start with a dot.
# Realm begins with a dot e.g. user@.site.com # if (User-Name =~ /@\\./) { update reply { Reply-Message = "misconfigured client. Realm begins with a dot" } reject }
There are also a number of simplifications possible, e.g.
if(User-Name =~ /@(.+)?@/i ) {
could be more directly written as:
if(User-Name =~ /@.*@/ ) {
cheers - some peoples styles differ. I will test/verify the other operation. I'm also keen on those who can supply combined REGEX foo - such as making a single check for e.g. begins with . or ends with . (or would people prefer each rule to be seperate so that locally they could easily just comment out a rule that wouldnt apply to them?) alan
On Sat, Jun 02, 2012 at 10:34:25PM +0100, alan buxey wrote:
cheers - some peoples styles differ. I will test/verify the other operation. I'm also keen on those who can supply combined REGEX foo - such as making a single check for e.g. begins with . or ends with . (or would people prefer each rule to be seperate so that locally they could easily just comment out a rule that wouldnt apply to them?)
I think your ruleset is more or less equivalent to: User-Name =~ /^[^@]*$| |@.*@|\\.\\.|@[^.]*$|\\.$|@\\./ --> invalid But I don't really see the point. Why not simply proxy it to the authoritative server, and let that server reply that it's invalid? Why distribute policy about which realms may (or may not) be valid all over the place? Such policy, if it is ever wrong, is likely to lead to difficult-to-debug problems. For an example of how this breaks things, look at all those websites which validate domains to only .com, .net, .org and so on. Now that hundreds of new TLDs are coming along, those sites will all erroneously reject perfectly valid domains. The DNS is a database, so you may as well just query it, and get the additional benefit of rejecting specific non-existent domains. The same argument applies to RADIUS proxying IMO.
Hi,
I think your ruleset is more or less equivalent to:
User-Name =~ /^[^@]*$| |@.*@|\\.\\.|@[^.]*$|\\.$|@\\./ --> invalid
yes - but as I said in previous email, it might be better to have each rule as a seperate entity so that sites/systems that allow certain things could edit/comment a single rule out - having one single REGEX means that the admin would have to 'play around' with the regex - resulting, probably, with a big mess (many admins have little skills these days it seems :-( )
But I don't really see the point. Why not simply proxy it to the authoritative server, and let that server reply that it's invalid? Why distribute policy about which realms may (or may not) be valid all over the place? Such policy, if it is ever wrong, is likely to lead to difficult-to-debug problems.
the reason for doing it is because otherwise all the junk floats to the top - the end sites proxy to the next tier, who then proxy up until finally the top heirarchy are swamped with junk.....spending their time dealing with rejecting (and logs filling with junk rather than the more interesting issues) - RADIUS protocol is weak....whilst the proxy chain waits for the reject to come back through its length, its using up precious limited state in the RADIUS proxy.
For an example of how this breaks things, look at all those websites which validate domains to only .com, .net, .org and so on. Now that hundreds of new TLDs are coming along, those sites will all erroneously reject perfectly valid domains. The DNS is a database, so you may as well just query it, and get the additional benefit of rejecting specific non-existent domains.
the NAI ruleset is quite simple - and DOESNT require any policing of current and future domains.... the realm must contain a strong-dot-string minimum. it cannot start with a dot , end with a dot, have multiple consecutive dots or contain illegal characters (havent even added those rules yet). as a national operator of a federated authentication system which is using RADIUS this issue is very close to my own personal interests - and remote sites sending junk upstream is the cause of several issues - easily solved if the RADIUS servers at all sites could have a simple policy rule to turn on. of course, when we move 100% to using tech such as dynamic server discovery then end sites will instantly know its a duff realm and we wont be bothered...but I'd rather fix the CURRENT problem than wait for some future world. alan
Hi,
For an example of how this breaks things, look at all those websites which validate domains to only .com, .net, .org and so on. Now that hundreds of new TLDs are coming along, those sites will all erroneously reject perfectly valid domains. The DNS is a database, so you may as well just query it, and get the additional benefit of rejecting specific non-existent domains.
the NAI ruleset is quite simple - and DOESNT require any policing of current and future domains.... the realm must contain a strong-dot-string minimum. it cannot start with a dot , end with a dot, have multiple consecutive dots or contain illegal characters (havent even added those rules yet).
Fully agree with Alan here. The NAI is part of an RFC, so there's reason in creating a ruleset that sanitizes inputs to conformance with that RFC. As simple as that. FreeRADIUS has many places where it polices malformedness of various parts of the RADIUS protocol, like whether an attribute is allowed in a specific datagram or not. Since using the NAI spec for User-Name is optional, it needs to be configurable in FreeRADIUS whether to make that syntax check or not. I believe policy.conf is the perfect place to put these checks into. NB, of course it is a dumb idea to block TLDs just because one doesn't like them or doesn't know about them yet. But this has nothing to do with the NAI compliance checks in this thread. NB2: Yes, the RFC4282 that contains the NAI spec is broken in some aspects (most notably, internationalisation). So creating a policy.conf which goes to great lengths of enforcing the more dubious aspects is not a good thing - especially given that RFC4282 is going to be revised soon. But the regex checks in this thread are only doing the basic stuff anyway, i.e. the parts that will extremely likely survive the RFC revision.
as a national operator of a federated authentication system which is using RADIUS this issue is very close to my own personal interests - and remote sites sending junk upstream is the cause of several issues - easily solved if the RADIUS servers at all sites could have a simple policy rule to turn on.
of course, when we move 100% to using tech such as dynamic server discovery then end sites will instantly know its a duff realm and we wont be bothered...but I'd rather fix the CURRENT problem than wait for some future world.
Many roaming consortia/enterprises use NAIs for their User-Name. Even in a non-proxy world, there's some resources to be saved: If you do a full TLS exchange for every incoming request vs. reject nonsense in the first packet can make a difference for your server if your environment is busy... Greetings, Stefan Winter -- Stefan WINTER Ingenieur de Recherche Fondation RESTENA - Réseau Téléinformatique de l'Education Nationale et de la Recherche 6, rue Richard Coudenhove-Kalergi L-1359 Luxembourg Tel: +352 424409 1 Fax: +352 422473
Brian Candler wrote:
But I don't really see the point. Why not simply proxy it to the authoritative server, and let that server reply that it's invalid? Why distribute policy about which realms may (or may not) be valid all over the place? Such policy, if it is ever wrong, is likely to lead to difficult-to-debug problems.
As Alan && Stefan pointed out, that's a bad idea. When problems are created at the edge of the network, it's best to stop them there. Sending them to the core makes it harder for everyone.
For an example of how this breaks things, look at all those websites which validate domains to only .com, .net, .org and so on. Now that hundreds of new TLDs are coming along, those sites will all erroneously reject perfectly valid domains. The DNS is a database, so you may as well just query it, and get the additional benefit of rejecting specific non-existent domains.
The same argument applies to RADIUS proxying IMO.
Except the regexes that Alan posted don't verify domain *names*. They verify realm *format*. It's like looking for non-ASCII in DNS packets. If you see it, it's definitively wrong. The protocol specifically forbids it. In RADIUS proxying, the realm format is largely email addresses. Most other formats have disappeared. So checking for that, and discarding *known bad* formats is a good idea. Alan DeKok.
On 06/03/2012 08:38 PM, Brian Candler wrote:
The same argument applies to RADIUS proxying IMO.
As others have suggested, this is not a great idea. One specific technical problem is that, for a given source port & destination proxy, you can only have ~255 radius packets in-flight at any given moment, because of the limited radius ID space. If you don't sanitise input before proxying, an accidental or malicious attempt to authenticate to a roaming consortium member could potentially cause denial of service on one or more proxies in the hierarchy (and in fact, this very thing has happened in eduroam). I do agree that blacklisting specific domains (a "bogon" list) isn't a good idea, because they get out of date; but the syntactic checks are a no-brainer (optionally enabled, of course) because such rules are specified in some (many?) roaming consortia as a matter of policy. One possible middle ground would be for an upstream proxy to return a specific error attribute / message format if the target realm is invalid, and for edge radius servers to cache these bad realms and locally execute an immediate reject. We have implemented this in a basic fashion using an SQL insert in "post-proxy", and a SQL query summing the fails per-realm over a time range in "authorize". You could probably do this better with an "rlm"; maintain a hash table of key/value pairs, the value being a list of timestamps of failures, allowing you to sum over timeranges. Do people think this would be useful?
On Mon, Jun 04, 2012 at 10:45:53AM +0100, Phil Mayers wrote:
On 06/03/2012 08:38 PM, Brian Candler wrote:
The same argument applies to RADIUS proxying IMO.
As others have suggested, this is not a great idea.
One specific technical problem is that, for a given source port & destination proxy, you can only have ~255 radius packets in-flight at any given moment, because of the limited radius ID space.
If you don't sanitise input before proxying, an accidental or malicious attempt to authenticate to a roaming consortium member could potentially cause denial of service on one or more proxies in the hierarchy (and in fact, this very thing has happened in eduroam).
If I wanted to do a DoS attack, I would simply submit valid-looking (but non-existent) realms, or indeed invalid usernames at valid realms, which would force the proxying all the way through to the end server for that realm. Also, I would expect that the majority of typos would result in "valid" domains, or at least valid by that regexp's definition of valid. A robust network would be able to cope with those sort of typos too. However I won't argue with you guys who have operational experience of eduroam. If you say pre-validation is a good idea then it is. In that case though, I would be inclined to write a validation regexp which fully matches the ABNF in RFC 2486. Regards, Brian.
Hi,
In that case though, I would be inclined to write a validation regexp which fully matches the ABNF in RFC 2486.
Elsewhere in the thread I presented arguments why a full check is a bad idea. Do you have arguments to back up your "inclinedness" or is it just a gut feeling? Greetings, Stefan Winter
On Mon, Jun 04, 2012 at 10:31:10PM +0200, Stefan Winter wrote:
Hi,
In that case though, I would be inclined to write a validation regexp which fully matches the ABNF in RFC 2486.
Elsewhere in the thread I presented arguments why a full check is a bad idea.
Do you have arguments to back up your "inclinedness" or is it just a gut feeling?
Only a gut feeling of "either enforce RFC 2486, or don't". Anything else seems to be a kludge to me. Has anyone actually *measured* what proportion of their failed logins are due to usernames containing two dots, or realms which start or end with a dot, or the other things the OP's regexp tests rejected?
On Tue, Jun 05, 2012 at 05:34:30PM +0100, Brian Candler wrote:
Only a gut feeling of "either enforce RFC 2486, or don't". Anything else seems to be a kludge to me.
As another eduroam member, the amount of cr*p out there is unbelieveable. From this perspective only, doing /anything/ to stop that from going off-site is a good thing for the rest of the system, RFC or no RFC. But from a FreeRADIUS package point of view, RFCs are a good place to base code and configuration on. So a policy that enforces certain rules, based on RFC recommendations, that can be locally enhanced can only be a good thing.
Has anyone actually *measured* what proportion of their failed logins are due to usernames containing two dots, or realms which start or end with a dot, or the other things the OP's regexp tests rejected?
Random sample - the whole month of May. awk/grep stats at 1am, and I'm ill and tired - so you choose whether to trust it or not: Less than 10 logins that had '..', or '@.' or ended in '.'. However, 19 unique usernames that included a ' ', which consisted of over 15,000 login attempts, of which 11,000 were one user. That's one of the problems - some broken (IMO) supplicants just keep trying. That individual's problem? A space on the end. Number of unique usernames with random characters - '=', '/', '#', ';', ',', etc. You name it, it's probably there! - around 50. Number of login attempts to *.3gppnetwork.org - over 3,000. Anything to help block this sort of thing (easily, or by default) is useful, especially in a large federation like eduroam where the national proxies can be a choke point. (As to the whole national proxy thing, I'd happily scrap it for national RADIUS, go peer-to-peer, and just use it for international proxying, but it's what we live with at the moment, and that debate is definitely off-topic!) Cheers, Matthew -- Matthew Newton, Ph.D. <mcn4@le.ac.uk> Systems Architect (UNIX and Networks), Network Services, I.T. Services, University of Leicester, Leicester LE1 7RH, United Kingdom For IT help contact helpdesk extn. 2253, <ithelp@le.ac.uk>
On Wed, Jun 06, 2012 at 01:33:35AM +0100, Matthew Newton wrote:
Has anyone actually *measured* what proportion of their failed logins are due to usernames containing two dots, or realms which start or end with a dot, or the other things the OP's regexp tests rejected?
Random sample - the whole month of May. awk/grep stats at 1am, and I'm ill and tired - so you choose whether to trust it or not:
Less than 10 logins that had '..', or '@.' or ended in '.'.
However, 19 unique usernames that included a ' ', which consisted of over 15,000 login attempts, of which 11,000 were one user. That's one of the problems - some broken (IMO) supplicants just keep trying. That individual's problem? A space on the end.
Number of unique usernames with random characters - '=', '/', '#', ';', ',', etc. You name it, it's probably there! - around 50.
Number of login attempts to *.3gppnetwork.org - over 3,000.
Out of interest, the total number of login attempts for the month? And the total number of rejects for the month? (So the above figures can be visualised as "percentage of total authentications" and "percentage of total rejects" respectively) A more general approach would be to throttle auth attempts for any particular username after a configured number of failures, which I think could be done quite efficiently using the new rlm_redis module - but that involves rather more work to set up than a simple regexp test. Regards, Brian.
Hi,
Out of interest, the total number of login attempts for the month? And the total number of rejects for the month? (So the above figures can be visualised as "percentage of total authentications" and "percentage of total rejects" respectively)
eduroam is an open consortium, so all these stats are available online for your viewing pleasure. Click here: http://monitor.eduroam.org/f-ticks/matrix.php?gtype=matrix&obid=all&country=... That's for the last full hour. You can change the interval to a day or month in self-service on that page ("Change interval").
A more general approach would be to throttle auth attempts for any particular username after a configured number of failures, which I think could be done quite efficiently using the new rlm_redis module - but that involves rather more work to set up than a simple regexp test.
To be honest, I firmly believe it is a good Access Point's job to kill annoying clients. There's no use to send packets via the RADIUS infrastructure if it's just a broken piece of device. Unfortunately, not all APs are good :-/ Stefan
Regards,
Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
On Wed, Jun 06, 2012 at 11:15:17AM +0100, Brian Candler wrote:
Out of interest, the total number of login attempts for the month? And the total number of rejects for the month? (So the above figures can be visualised as "percentage of total authentications" and "percentage of total rejects" respectively)
The stats will start to get a bit murky without full details, and a lot of digging. However, as a basic answer to your query (and yes, this really is getting off-topic now, so no more posts from me after this...) Of the auth requests we sent off-site to the proxy during May, 15283 were rejected 20946 were accepted and then of course another ~15,000 or so, above, mostly weren't actually sent upstream (there will be some overlap, hence statistical murkiness). This doesn't count any local users who authenticated (or not) here without proxying. So there were in the region of 50,000 requests that would have gone to the proxy (intentially or otherwise), we filtered out a load, around 35,000 did get sent, and only 20,000 were granted access. That's not a great number per day for just one site, but there are a lot more sites than just us. Cheers, Matthew -- Matthew Newton, Ph.D. <mcn4@le.ac.uk> Systems Architect (UNIX and Networks), Network Services, I.T. Services, University of Leicester, Leicester LE1 7RH, United Kingdom For IT help contact helpdesk extn. 2253, <ithelp@le.ac.uk>
Hi,
If I wanted to do a DoS attack, I would simply submit valid-looking (but non-existent) realms, or indeed invalid usernames at valid realms, which would force the proxying all the way through to the end server for that realm.
well, HOPEFULLY you wouldnt be able to do that as any sane site will have a maximum number of EAP attempts within a threshold time after which your requests are blocked locally by the NAS - I believe that Cisco, for example, has 3 attempts and you're blocked for 60s by default. from looking at logs, however, a LOT of sites dont have such mitigation turned on and we see continous attempts with a duff username - even though we send REJECT back (duff clients or NAS - however, with mitigation on the NAS these requests arent a problem) the biggest problem comes from remote RADIUS servers that dont respond.......
In that case though, I would be inclined to write a validation regexp which fully matches the ABNF in RFC 2486.
as said..and Stefan points out - this isnt as useful as then sites/systems that are okay with, e.g. underscores or some 'illegal character' couldnt just comment that bit out. after all, this is an OPTION. its there for people to use IF THEY WANT, noones forcing you to use it - just like all the other options in the policy.conf provided...it would just be very very useful to have there by default :-) alan
On 06/04/2012 05:53 PM, Brian Candler wrote:
If I wanted to do a DoS attack, I would simply submit valid-looking (but non-existent) realms, or indeed invalid usernames at valid realms, which would force the proxying all the way through to the end server for that realm.
Sure. Sanitising doesn't protect against even slightly determined attacks. But it is an improvement over no sanitisation at all - experience in the eduroam environment has demonstrated that.
Also, I would expect that the majority of typos would result in "valid"
You'd be surprised! We see some extraordinary stuff; I'm not even sure how some of it gets typed in by the user. I think the username with a newline / "\n" in it was the most impressive...
domains, or at least valid by that regexp's definition of valid. A robust network would be able to cope with those sort of typos too.
Ideally, yes. Unfortunately RADIUS is an old protocol, and layering the kind of semantics required on top of it, especially when some participants in the roaming network insist on using crappy RADIUS servers (i.e. NOT FR) is tricky. Sanitisation is really a very small part of that, but it's helpful nonetheless.
However I won't argue with you guys who have operational experience of eduroam. If you say pre-validation is a good idea then it is.
In that case though, I would be inclined to write a validation regexp which fully matches the ABNF in RFC 2486.
IIRC that's actually very difficult, maybe impossible, with classic regexps. Maybe it's possible with the PCRE path I added a while back, but I'm not sure.
However I won't argue with you guys who have operational experience of eduroam. If you say pre-validation is a good idea then it is.
In that case though, I would be inclined to write a validation regexp which fully matches the ABNF in RFC 2486.
IIRC that's actually very difficult, maybe impossible, with classic regexps. Maybe it's possible with the PCRE path I added a while back, but I'm not sure.
It's impossible with classic regexps, it's possible with PCRE - I wrote one many years ago. I did it for the deploying eduroam at sussex docs, but then junked the compliant regexp when I figured out FreeRADIUS didn't support PCRE. IIRC you need atomic look around for some stuff. -Arran
On 06/02/2012 10:34 PM, alan buxey wrote:
cheers - some peoples styles differ. I will test/verify the other operation. I'm also keen on those who can supply combined REGEX foo - such as making a single
We use the following: if (User-Name =~ /^([^@]*)@([-A-Z0-9]+(\\.[-A-Z0-9]+)+)$/) { update request { Stripped-User-Name := "%{1}" Realm := "%{toupper:%{2}}" } } else { update control { Reply-Message := "username is not RFC2486 compliant" } reject } A few things to note about this regexp: 1. It doesn't check any syntactic validity of the username part; just the realm. I'm not confident enough that an inclusive list e.g. a-zA-Z0-9 is "safe" for usernames; especially since in theory they're UTF-8 2. It will allow realms of the form -a.-b.-c because I just use a single range for all characters in the realm. 3. It doesn't blacklist any common typos e.g. ax.uk, uk.ac, etc. I'm not certain this is a sensible thing for end sites to do; bogon lists have a nasty habit of getting stale unless they're fed from a central source in a totally automated fashion. I know AlexC was keen on rlm_is_realm_in_dns (or something) but equally that prevents people having legit realms that aren't resovable (either publicly or at all)
check for e.g. begins with . or ends with . (or would people prefer each rule to be seperate so that locally they could easily just comment out a rule that wouldnt apply to them?)
Ideally, it should be so simple that no-one ever has cause to do anything other than enable the policy. Separate entries allow for more granular reply-message values I guess.
Hi, one nit / smartass comment :-) on this one: # # Realm ends with a dot e.g. user@site.com. # if (User-Name =~ /\\.$/) { update reply { Reply-Message = "misconfigured client. Realm ends with a dot" } reject } It's correct that RFC4282 forbids this construct. However, the trailing dot is a perfectly valid construct for domain names (in fact, every FQDN ends in a dot, it's just that convenience in local resolvers "magically" adds them and users don't realise it). When using DNS dynamic discovery, the realms foo.bar and foo.bar. are the SAME target, and both perfectly valid. This is one area where RFC4282bis should give another thought - why forbid these? Well, for FreeRADIUS I guess it doesn't really matter... this is a 4282 syntax check, and the rule above is correct in rejecting realms with a trailing dot. It's just a little uncomforting that things are as they are :-/ Stefan -- Stefan WINTER Ingenieur de Recherche Fondation RESTENA - Réseau Téléinformatique de l'Education Nationale et de la Recherche 6, rue Richard Coudenhove-Kalergi L-1359 Luxembourg Tel: +352 424409 1 Fax: +352 422473
participants (7)
-
alan buxey -
Alan DeKok -
Arran Cudbard-Bell -
Brian Candler -
Matthew Newton -
Phil Mayers -
Stefan Winter